1
0
Fork 0
mirror of synced 2024-04-26 08:42:07 +12:00

GTK 4 Port (#466)

This commit is contained in:
Rafał Mikrut 2022-05-22 10:59:09 +02:00 committed by GitHub
parent 849eb5a637
commit 6d8b33d8cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 3603 additions and 6687 deletions

View file

@ -14,7 +14,7 @@ jobs:
matrix:
toolchain: [ stable ]
type: [ release ]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
@ -32,20 +32,20 @@ jobs:
linux-cli-${{github.ref}}-${{github.sha}}
- name: Install basic libraries
run: sudo apt-get update; sudo apt install libgtk-3-dev libasound2-dev -y
run: sudo apt-get update; sudo apt install libgtk-4-dev libasound2-dev -y
- name: Build CLI Debug
run: cargo build --bin czkawka_cli
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings"
RUSTFLAGS: "-C debuginfo=0"
if: ${{ matrix.type == 'debug'}}
- name: Build CLI Release
run: cargo build --release --bin czkawka_cli
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings"
RUSTFLAGS: "-C debuginfo=0"
if: ${{ matrix.type == 'release'}}
- name: Store Linux CLI
@ -132,7 +132,7 @@ jobs:
matrix:
toolchain: [ stable, 1.60.0 ]
type: [ release ]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
@ -150,20 +150,20 @@ jobs:
linux-gui-${{github.ref}}-${{github.sha}}
- name: Install Gtk, Mingw, unzip, zip and wget
run: sudo apt-get update; sudo apt install libgtk-3-dev libasound2-dev -y
run: sudo apt-get update; sudo apt install libgtk-4-dev libasound2-dev fuse libfuse2 -y
- name: Build GUI Debug
run: cargo build --bin czkawka_gui
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings"
RUSTFLAGS: "-C debuginfo=0"
if: ${{ matrix.type == 'debug'}}
- name: Build GUI Release
run: cargo build --release --bin czkawka_gui
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings"
RUSTFLAGS: "-C debuginfo=0"
if: ${{ matrix.type == 'release'}}
- name: Store Linux GUI
@ -196,7 +196,7 @@ jobs:
matrix:
toolchain: [ stable ]
type: [ release ]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
@ -214,13 +214,13 @@ jobs:
linux-appimage-gui-${{github.ref}}-${{github.sha}}
- name: Install Gtk,
run: sudo apt-get update; sudo apt install libgtk-3-dev libasound2-dev librsvg2-dev wget -y
run: sudo apt-get update; sudo apt install libgtk-4-dev libasound2-dev librsvg2-dev wget fuse libfuse2 -y
- name: Build GUI Release
run: cargo build --release --bin czkawka_gui
env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings"
RUSTFLAGS: "-C debuginfo=0"
- name: Download appimage dependiences
run: |

View file

@ -72,8 +72,8 @@ jobs:
- name: Override link[WORKAROUND] # Looks that this is a bug with current homebrew or Github CI
run: rm '/usr/local/bin/2to3'
- name: Install GTK3
run: brew install rust gtk+3
- name: Install GTK4
run: brew install rust gtk4
- name: Build GUI Debug
run: cargo build --bin czkawka_gui

View file

@ -29,7 +29,7 @@ jobs:
override: true
- name: Install Gtk
run: sudo apt-get update; sudo apt install -y libgtk-3-dev libasound2-dev
run: sudo apt-get update; sudo apt install -y libgtk-4-dev libasound2-dev
- name: Check the format
run: cargo fmt --all -- --check

View file

@ -152,7 +152,7 @@ jobs:
matrix:
toolchain: [ stable ]
type: [ release ]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
@ -162,7 +162,7 @@ jobs:
override: true
- name: Install Gtk, Mingw, unzip, zip and wget
run: sudo apt-get update; sudo apt install mingw-w64 libgtk-3-dev unzip wget zip -y
run: sudo apt-get update; sudo apt install mingw-w64 libgtk-4-dev unzip wget zip -y
- name: Build GUI Release Cross Compile
run: |
@ -176,8 +176,8 @@ jobs:
GTK_APP="$(pwd)/gtk_app"
GTK_THEME="$(pwd)/gtk_theme"
wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/mingw64.zip
unzip mingw64.zip -d $GTK_LIBRARY
wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/gtk4_4_2_test.zip
unzip gtk4_4_2_test.zip -d $GTK_LIBRARY
GTK_LIBRARY="$GTK_LIBRARY/mingw64"
wget https://github.com/nrhodes91/AdMin/archive/master.zip
@ -242,7 +242,7 @@ jobs:
matrix:
toolchain: [ stable ]
type: [ release ]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
@ -252,7 +252,7 @@ jobs:
override: true
- name: Install Gtk, Mingw, unzip, zip and wget
run: sudo apt-get update; sudo apt install mingw-w64 libgtk-3-dev unzip wget zip -y
run: sudo apt-get update; sudo apt install mingw-w64 libgtk-4-dev unzip wget zip -y
- name: Build GUI Release Cross Compile
run: |
@ -333,7 +333,7 @@ jobs:
# matrix:
# toolchain: [ stable ]
# type: [ release ]
# runs-on: ubuntu-20.04
# runs-on: ubuntu-22.04
# steps:
# - uses: actions/checkout@v2
#
@ -343,7 +343,7 @@ jobs:
# override: true
#
# - name: Install Gtk, Mingw, unzip, zip and wget
# run: sudo apt-get update; sudo apt install mingw-w64 libgtk-3-dev unzip wget zip -y
# run: sudo apt-get update; sudo apt install mingw-w64 libgtk-4-dev unzip wget zip -y
#
# - name: Build GUI Debug Cross Compile
# run: |
@ -424,7 +424,7 @@ jobs:
# matrix:
# toolchain: [ stable ]
# type: [ release ]
# runs-on: ubuntu-20.04
# runs-on: ubuntu-22.04
# steps:
# - uses: actions/checkout@v2
#
@ -434,7 +434,7 @@ jobs:
# override: true
#
# - name: Install Gtk, Mingw, unzip, zip and wget
# run: sudo apt-get update; sudo apt install mingw-w64 libgtk-3-dev unzip wget zip -y
# run: sudo apt-get update; sudo apt install mingw-w64 libgtk-4-dev unzip wget zip -y
#
# - name: Build GUI Debug Cross Compile
# run: |

232
Cargo.lock generated
View file

@ -93,30 +93,6 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
[[package]]
name = "atk"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd"
dependencies = [
"atk-sys",
"bitflags",
"glib",
"libc",
]
[[package]]
name = "atk-sys"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -328,9 +304,9 @@ dependencies = [
[[package]]
name = "cfg-expr"
version = "0.10.2"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e068cb2806bbc15b439846dc16c5f89f8599f2c3e4d73d4449d38f9b2f0b6c5"
checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db"
dependencies = [
"smallvec",
]
@ -528,9 +504,9 @@ dependencies = [
"directories-next",
"fs_extra",
"futures",
"gdk",
"gdk4",
"glib",
"gtk",
"gtk4",
"humansize",
"i18n-embed",
"i18n-embed-fl",
@ -904,22 +880,6 @@ dependencies = [
"slab",
]
[[package]]
name = "gdk"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6e05c1f572ab0e1f15be94217f0dc29088c248b14f792a5ff0af0d84bcda9e8"
dependencies = [
"bitflags",
"cairo-rs",
"gdk-pixbuf",
"gdk-sys",
"gio",
"glib",
"libc",
"pango",
]
[[package]]
name = "gdk-pixbuf"
version = "0.15.11"
@ -947,10 +907,26 @@ dependencies = [
]
[[package]]
name = "gdk-sys"
version = "0.15.1"
name = "gdk4"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88"
checksum = "d4a2fc0bd03d59383fc10b71a8cb731a1fac2998732a36a0c03e9b1de1513218"
dependencies = [
"bitflags",
"cairo-rs",
"gdk-pixbuf",
"gdk4-sys",
"gio",
"glib",
"libc",
"pango",
]
[[package]]
name = "gdk4-sys"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48a39e34abe35ee2cf54a1e29dd983accecd113ad30bdead5050418fa92f2a1b"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@ -1089,60 +1065,117 @@ dependencies = [
]
[[package]]
name = "gtk"
version = "0.15.5"
name = "graphene-rs"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92e3004a2d5d6d8b5057d2b57b3712c9529b62e82c77f25c1fecde1fd5c23bd0"
checksum = "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570"
dependencies = [
"atk",
"bitflags",
"cairo-rs",
"field-offset",
"futures-channel",
"gdk",
"gdk-pixbuf",
"gio",
"glib",
"gtk-sys",
"gtk3-macros",
"graphene-sys",
"libc",
"once_cell",
"pango",
"pkg-config",
]
[[package]]
name = "gtk-sys"
version = "0.15.3"
name = "graphene-sys"
version = "0.15.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84"
checksum = "fa691fc7337ba1df599afb55c3bcb85c04f1b3f17362570e9bb0ff0d1bc3028a"
dependencies = [
"glib-sys",
"libc",
"pkg-config",
"system-deps",
]
[[package]]
name = "gsk4"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14d5a47a78c682bb67496b562495ed84972c0512ba0654888c4dc92b80a85bd3"
dependencies = [
"bitflags",
"cairo-rs",
"gdk4",
"glib",
"graphene-rs",
"gsk4-sys",
"libc",
"pango",
]
[[package]]
name = "gsk4-sys"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31d21d7ce02ba261bb24c50c4ab238a10b41a2c97c32afffae29471b7cca69b"
dependencies = [
"atk-sys",
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk-sys",
"gio-sys",
"gdk4-sys",
"glib-sys",
"gobject-sys",
"graphene-sys",
"libc",
"pango-sys",
"system-deps",
]
[[package]]
name = "gtk3-macros"
version = "0.15.4"
name = "gtk4"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24f518afe90c23fba585b2d7697856f9e6a7bbc62f65588035e66f6afb01a2e9"
checksum = "eb5d40303dabe4608fc260de2bd7563da6f85bc90af956323f0cd8ae0abcfe03"
dependencies = [
"bitflags",
"cairo-rs",
"field-offset",
"futures-channel",
"gdk-pixbuf",
"gdk4",
"gio",
"glib",
"graphene-rs",
"gsk4",
"gtk4-macros",
"gtk4-sys",
"libc",
"once_cell",
"pango",
]
[[package]]
name = "gtk4-macros"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f3c4aa605fb3d78205c7aef0eeaa6db61d8cc4dd05a465dc6ffdfdaee84f825"
dependencies = [
"anyhow",
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
"quick-xml",
"quote",
"syn",
]
[[package]]
name = "gtk4-sys"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c47c075e8f795c38f6e9a47b51a73eab77b325f83c0154979ed4d4245c36490d"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk4-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"graphene-sys",
"gsk4-sys",
"libc",
"pango-sys",
"system-deps",
]
[[package]]
name = "half"
version = "1.8.2"
@ -1460,9 +1493,9 @@ checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff"
[[package]]
name = "libc"
version = "0.2.125"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "linked-hash-map"
@ -1495,9 +1528,9 @@ dependencies = [
[[package]]
name = "lofty"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9b0ac50022c34427688f83800b865c8a324ba2fe9f41f232b899b7517b3786c"
checksum = "9e09702a8eff21fa1cf105d189d8eea3609d7074ab1503d7c49d5b37b7403a65"
dependencies = [
"base64 0.13.0",
"byteorder",
@ -1729,9 +1762,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.10.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
checksum = "7b10983b38c53aebdf33f542c6275b0f58a238129d00c4ae0e6fb59738d783ca"
[[package]]
name = "opaque-debug"
@ -1999,11 +2032,20 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.38"
version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "quick-xml"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b"
dependencies = [
"memchr",
]
[[package]]
@ -2106,9 +2148,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.5.5"
version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
dependencies = [
"aho-corasick",
"memchr",
@ -2117,9 +2159,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.25"
version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "remove_dir_all"
@ -2642,13 +2684,13 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.94"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a"
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
"unicode-ident",
]
[[package]]
@ -2877,6 +2919,12 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
[[package]]
name = "unicode-normalization"
version = "0.1.19"
@ -2898,12 +2946,6 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
[[package]]
name = "uuid"
version = "1.0.0"

View file

@ -2,6 +2,13 @@
**Czkawka** (_tch•kav•ka_ (IPA: [ʈ͡ʂkafka]), "hiccup" in Polish) is a simple, fast and free app to remove unnecessary files from your computer.
## UNSTABLE WARNING
**Currently master branch of this repository contains unstable GTK 4 port, so multiple regression, broken features etc. are expected.**
**You can use old stable version built with GTK 3 - [4.1.0](https://github.com/qarmin/czkawka/releases/tag/4.1.0) or compile app from git before GTK 4 PR merge.**
**Due build problems Windows binaries are not available yet, you can help by creating/modifying CI to produce valid windows binaries**
## Features
- Written in memory-safe Rust
- Amazingly fast - due to using more or less advanced algorithms and multithreading
@ -9,7 +16,7 @@
- Multiplatform - works on Linux, Windows, macOS, FreeBSD and many more
- Cache support - second and further scans should be much faster than the first one
- CLI frontend - for easy automation
- GUI frontend - uses modern GTK 3 and looks similar to FSlint
- GUI frontend - uses GTK 4 framework and looks similar to FSlint
- No spying - Czkawka does not have access to the Internet, nor does it collect any user information or statistics
- Multilingual - support multiple languages like Polish, English or Italian
- Multiple tools to use:
@ -96,7 +103,7 @@ Bleachbit is a master at finding and removing temporary files, while Czkawka onl
|:------------------------:|:-----------:|:----------:|:-----------------:|:-----------:|
| Language | Rust | Python | Python/Obj-C | Python |
| OS | Lin,Mac,Win | Lin | Lin,Mac,Win | Lin,Mac,Win |
| Framework | GTK 3 | PyGTK2 | Qt 5 (PyQt)/Cocoa | PyGTK3 |
| Framework | GTK 4 | PyGTK2 | Qt 5 (PyQt)/Cocoa | PyGTK3 |
| Duplicate finder | • | • | • | |
| Empty files | • | • | | |
| Empty folders | • | • | | |

View file

@ -482,7 +482,7 @@ impl BrokenFiles {
Some(Some(file_entry_clone))
}
},
Err(_inspected) => Some(None), // TODO maybe throw error or something
Err(_inspected) => Some(None),
},
TypeOfFile::PDF => {

View file

@ -14,15 +14,15 @@ pub const RAW_IMAGE_EXTENSIONS: &[&str] = &[
".cr2", ".ari",
];
pub const IMAGE_RS_EXTENSIONS: &[&str] = &[
".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".webp", ".gif", ".ico", ".exr", ".hdr", "dds",
".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".webp", ".gif", ".ico", ".exr", ".hdr", ".dds",
];
pub const IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS: &[&str] = &[
".jpg", ".jpeg", ".png", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".bmp", ".webp", ".exr", ".hdr", "dds",
".jpg", ".jpeg", ".png", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".bmp", ".webp", ".exr", ".hdr", ".dds",
];
pub const IMAGE_RS_BROKEN_FILES_EXTENSIONS: &[&str] = &[
".jpg", ".jpeg", ".png", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".gif", ".bmp", ".ico", ".jfif", ".jpe", ".pnz", ".dib", ".webp", ".exr", ".hdr", "dds",
".jpg", ".jpeg", ".png", ".tiff", ".tif", ".tga", ".ff", ".jif", ".jfi", ".gif", ".bmp", ".ico", ".jfif", ".jpe", ".pnz", ".dib", ".webp", ".exr", ".hdr", ".dds",
];
pub const ZIP_FILES_EXTENSIONS: &[&str] = &[".zip"];

View file

@ -10,7 +10,7 @@ repository = "https://github.com/qarmin/czkawka"
[dependencies]
czkawka_core = { path = "../czkawka_core", version = "4.1.0"}
gdk = "0.15.4"
gdk4 = "0.4.7"
glib = "0.15.11"
humansize = "1.1.1"
@ -52,8 +52,8 @@ once_cell = "1.10.0"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["combaseapi", "objbase", "shobjidl_core", "windef", "winerror", "wtypesbase", "winuser"] }
[dependencies.gtk]
version = "0.15.5"
[dependencies.gtk4]
version = "0.4.7"
default-features = false # just in case
features = ["v3_24_9"]
features = ["v4_6"]

View file

@ -247,6 +247,7 @@ bottom_show_upper_notebook_tooltip = Show/Hide upper notebook panel.
# Progress Window
progress_stop_button = Stop
progress_stop_additional_message = Stop requested
# About Window
about_repository_button_tooltip = Link to repository page with source code.

View file

@ -5,7 +5,7 @@ use std::rc::Rc;
use chrono::NaiveDateTime;
use glib::Receiver;
use gtk::prelude::*;
use gtk4::prelude::*;
use humansize::{file_size_opts as options, FileSize};
use czkawka_core::common_dir_traversal::CheckingMethod;
@ -81,9 +81,9 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
entry_info.set_text(&flg!("compute_stopped_by_user"));
} else {
if df.get_use_reference() {
tree_view_duplicate_finder.selection().set_select_function(Some(Box::new(select_function_always_true)));
tree_view_duplicate_finder.selection().set_select_function(select_function_always_true);
} else {
tree_view_duplicate_finder.selection().set_select_function(Some(Box::new(select_function_duplicates)));
tree_view_duplicate_finder.selection().set_select_function(select_function_duplicates);
}
let information = df.get_information();
@ -167,7 +167,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// HEADER
let (directory, file) = split_path(&base_file_entry.path);
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&base_file_entry.size.file_size(options::BINARY).unwrap())),
@ -179,6 +179,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
@ -187,7 +188,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// MEAT
for entry in vector {
let (directory, file) = split_path(&entry.path);
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())),
@ -199,6 +200,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -224,7 +226,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// HEADER
let (directory, file) = split_path(&base_file_entry.path);
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&base_file_entry.size.file_size(options::BINARY).unwrap())),
@ -236,6 +238,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
@ -244,7 +247,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for entry in vector {
let (directory, file) = split_path(&entry.path);
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())),
@ -256,6 +259,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
@ -282,7 +286,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// HEADER
let (directory, file) = split_path(&base_file_entry.path);
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&base_file_entry.size.file_size(options::BINARY).unwrap())),
@ -294,6 +298,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
@ -301,7 +306,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
list_store.set(&list_store.append(), &values);
for entry in vector {
let (directory, file) = split_path(&entry.path);
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())),
@ -313,6 +318,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -341,7 +347,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
vector.clone()
};
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&"".to_string())),
@ -350,13 +356,14 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
(ColumnsDuplicates::Modification as u32, (&"".to_string())), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, (&(0))), // Not used here
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(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); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())),
@ -372,6 +379,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -395,7 +403,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
vector.clone()
};
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&"".to_string())),
@ -404,6 +412,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
(ColumnsDuplicates::Modification as u32, &"".to_string()), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, &(0)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
@ -411,7 +420,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for entry in vector {
let (directory, file) = split_path(&entry.path);
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())),
@ -423,6 +432,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
@ -446,7 +456,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
} else {
vector.clone()
};
let values: [(u32, &dyn ToValue); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&"".to_string())),
@ -455,13 +465,14 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
(ColumnsDuplicates::Modification as u32, &"".to_string()), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, &(0)), // Not used here
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(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); 9] = [
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())),
@ -473,6 +484,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -782,11 +794,9 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
entry_info.set_text(&flg!("compute_stopped_by_user"));
} else {
if sf.get_use_reference() {
tree_view_similar_images_finder.selection().set_select_function(Some(Box::new(select_function_always_true)));
tree_view_similar_images_finder.selection().set_select_function(select_function_always_true);
} else {
tree_view_similar_images_finder
.selection()
.set_select_function(Some(Box::new(select_function_similar_images)));
tree_view_similar_images_finder.selection().set_select_function(select_function_similar_images);
}
let information = sf.get_information();
let text_messages = sf.get_text_messages();
@ -809,8 +819,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
let list_store = get_list_store(&tree_view_similar_images_finder);
if sf.get_use_reference() {
let vec_struct_similar: &Vec<(czkawka_core::similar_images::FileEntry, Vec<czkawka_core::similar_images::FileEntry>)> =
sf.get_similar_images_referenced();
let vec_struct_similar: &Vec<(similar_images::FileEntry, Vec<similar_images::FileEntry>)> = sf.get_similar_images_referenced();
for (base_file_entry, vec_file_entry) in vec_struct_similar.iter() {
// Sort
let vec_file_entry = if vec_file_entry.len() >= 2 {
@ -826,7 +835,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Header
let (directory, file) = split_path(&base_file_entry.path);
let values: [(u32, &dyn ToValue); 12] = [
let values: [(u32, &dyn ToValue); 13] = [
(ColumnsSimilarImages::ActivatableSelectButton as u32, &false),
(ColumnsSimilarImages::SelectionButton as u32, &false),
(ColumnsSimilarImages::Similarity as u32, &"".to_string()),
@ -841,6 +850,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSimilarImages::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsSimilarImages::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarImages::IsHeader as u32, &true),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -848,7 +858,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Meat
for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 12] = [
let values: [(u32, &dyn ToValue); 13] = [
(ColumnsSimilarImages::ActivatableSelectButton as u32, &true),
(ColumnsSimilarImages::SelectionButton as u32, &false),
(
@ -866,6 +876,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSimilarImages::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarImages::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarImages::IsHeader as u32, &false),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -887,7 +898,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
};
// Header
let values: [(u32, &dyn ToValue); 12] = [
let values: [(u32, &dyn ToValue); 13] = [
(ColumnsSimilarImages::ActivatableSelectButton as u32, &false),
(ColumnsSimilarImages::SelectionButton as u32, &false),
(ColumnsSimilarImages::Similarity as u32, &"".to_string()),
@ -899,6 +910,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
(ColumnsSimilarImages::Modification as u32, &"".to_string()),
(ColumnsSimilarImages::ModificationAsSecs as u32, &(0)),
(ColumnsSimilarImages::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarImages::IsHeader as u32, &true),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -906,7 +918,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Meat
for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 12] = [
let values: [(u32, &dyn ToValue); 13] = [
(ColumnsSimilarImages::ActivatableSelectButton as u32, &true),
(ColumnsSimilarImages::SelectionButton as u32, &false),
(
@ -924,6 +936,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSimilarImages::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarImages::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarImages::IsHeader as u32, &false),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -966,11 +979,9 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
entry_info.set_text(&flg!("compute_stopped_by_user"));
} else {
if ff.get_use_reference() {
tree_view_similar_videos_finder.selection().set_select_function(Some(Box::new(select_function_always_true)));
tree_view_similar_videos_finder.selection().set_select_function(select_function_always_true);
} else {
tree_view_similar_videos_finder
.selection()
.set_select_function(Some(Box::new(select_function_similar_videos)));
tree_view_similar_videos_finder.selection().set_select_function(select_function_similar_videos);
}
let information = ff.get_information();
let text_messages = ff.get_text_messages();
@ -1009,7 +1020,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Header
let (directory, file) = split_path(&base_file_entry.path);
let values: [(u32, &dyn ToValue); 10] = [
let values: [(u32, &dyn ToValue); 11] = [
(ColumnsSimilarVideos::ActivatableSelectButton as u32, &false),
(ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &base_file_entry.size.file_size(options::BINARY).unwrap()),
@ -1022,6 +1033,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSimilarVideos::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsSimilarVideos::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarVideos::IsHeader as u32, &true),
(ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -1029,7 +1041,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Meat
for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 10] = [
let values: [(u32, &dyn ToValue); 11] = [
(ColumnsSimilarVideos::ActivatableSelectButton as u32, &true),
(ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()),
@ -1042,6 +1054,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSimilarVideos::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarVideos::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarVideos::IsHeader as u32, &false),
(ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -1064,7 +1077,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
};
// Header
let values: [(u32, &dyn ToValue); 10] = [
let values: [(u32, &dyn ToValue); 11] = [
(ColumnsSimilarVideos::ActivatableSelectButton as u32, &false),
(ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &"".to_string()),
@ -1074,6 +1087,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
(ColumnsSimilarVideos::Modification as u32, &"".to_string()),
(ColumnsSimilarVideos::ModificationAsSecs as u32, &(0)),
(ColumnsSimilarVideos::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarVideos::IsHeader as u32, &true),
(ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -1081,7 +1095,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Meat
for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 10] = [
let values: [(u32, &dyn ToValue); 11] = [
(ColumnsSimilarVideos::ActivatableSelectButton as u32, &true),
(ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()),
@ -1094,6 +1108,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSimilarVideos::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarVideos::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarVideos::IsHeader as u32, &false),
(ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -1135,9 +1150,9 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
entry_info.set_text(&flg!("compute_stopped_by_user"));
} else {
if mf.get_use_reference() {
tree_view_same_music_finder.selection().set_select_function(Some(Box::new(select_function_always_true)));
tree_view_same_music_finder.selection().set_select_function(select_function_always_true);
} else {
tree_view_same_music_finder.selection().set_select_function(Some(Box::new(select_function_same_music)));
tree_view_same_music_finder.selection().set_select_function(select_function_same_music);
}
let information = mf.get_information();
@ -1186,7 +1201,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
};
let (directory, file) = split_path(&base_file_entry.path);
let values: [(u32, &dyn ToValue); 17] = [
let values: [(u32, &dyn ToValue); 18] = [
(ColumnsSameMusic::ActivatableSelectButton as u32, &false),
(ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &base_file_entry.size.file_size(options::BINARY).unwrap()),
@ -1206,12 +1221,13 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSameMusic::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsSameMusic::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSameMusic::IsHeader as u32, &true),
(ColumnsSameMusic::TextColor as u32, &(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); 17] = [
let values: [(u32, &dyn ToValue); 18] = [
(ColumnsSameMusic::ActivatableSelectButton as u32, &true),
(ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()),
@ -1231,6 +1247,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSameMusic::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSameMusic::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSameMusic::IsHeader as u32, &false),
(ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -1254,7 +1271,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
vec_file_entry.clone()
};
let values: [(u32, &dyn ToValue); 17] = [
let values: [(u32, &dyn ToValue); 18] = [
(ColumnsSameMusic::ActivatableSelectButton as u32, &false),
(ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &"".to_string()),
@ -1307,12 +1324,13 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
(ColumnsSameMusic::Modification as u32, &"".to_string()),
(ColumnsSameMusic::ModificationAsSecs as u32, &(0)),
(ColumnsSameMusic::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSameMusic::IsHeader as u32, &true),
(ColumnsSameMusic::TextColor as u32, &(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); 17] = [
let values: [(u32, &dyn ToValue); 18] = [
(ColumnsSameMusic::ActivatableSelectButton as u32, &true),
(ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()),
@ -1332,6 +1350,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
),
(ColumnsSameMusic::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSameMusic::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSameMusic::IsHeader as u32, &false),
(ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);

View file

@ -1,4 +1,4 @@
use gtk::prelude::*;
use gtk4::prelude::*;
use crate::gui_structs::gui_data::GuiData;

View file

@ -1,12 +1,12 @@
use crate::flg;
use gdk::gdk_pixbuf::{InterpType, Pixbuf};
use gtk::prelude::*;
use gtk::{CheckButton, Image, ListStore, Orientation, ScrolledWindow, TreeIter, TreeModel, TreePath, TreeSelection};
use gdk4::gdk_pixbuf::{InterpType, Pixbuf};
use gtk4::prelude::*;
use gtk4::{CheckButton, Image, ListStore, Orientation, ScrolledWindow, TreeIter, TreeModel, TreePath, TreeSelection, Widget};
use std::cell::RefCell;
use std::rc::Rc;
use crate::gui_structs::gui_data::GuiData;
use crate::help_functions::{count_number_of_groups, get_full_name_from_path_name, get_max_file_name, resize_pixbuf_dimension, NotebookObject, HEADER_ROW_COLOR, NOTEBOOKS_INFOS};
use crate::help_functions::{count_number_of_groups, get_all_children, get_full_name_from_path_name, get_max_file_name, resize_pixbuf_dimension, NotebookObject, NOTEBOOKS_INFOS};
use crate::localizer_core::generate_translation_hashmap;
const BIG_PREVIEW_SIZE: i32 = 600;
@ -36,20 +36,22 @@ pub fn connect_button_compare(gui_data: &GuiData) {
let image_compare_left = gui_data.compare_images.image_compare_left.clone();
let image_compare_right = gui_data.compare_images.image_compare_right.clone();
window_compare.set_default_size(700, 700);
button_compare.connect_clicked(move |_| {
let nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
let model = tree_view.model().unwrap();
let group_number = count_number_of_groups(tree_view, nb_object.column_color.unwrap());
let group_number = count_number_of_groups(tree_view, nb_object.column_header.unwrap());
if group_number == 0 {
return;
}
// Check selected items
let (current_group, tree_path) = get_current_group_and_iter_from_selection(&model, tree_view.selection(), nb_object.column_color.unwrap());
let (current_group, tree_path) = get_current_group_and_iter_from_selection(&model, tree_view.selection(), nb_object.column_header.unwrap());
*shared_current_of_groups.borrow_mut() = current_group;
*shared_numbers_of_groups.borrow_mut() = group_number;
@ -84,7 +86,8 @@ pub fn connect_button_compare(gui_data: &GuiData) {
let window_compare = gui_data.compare_images.window_compare.clone();
let image_compare_left = gui_data.compare_images.image_compare_left.clone();
let image_compare_right = gui_data.compare_images.image_compare_right.clone();
window_compare.connect_delete_event(move |window_compare, _| {
window_compare.connect_close_request(move |window_compare| {
// TODO GTK4
window_compare.hide();
*shared_image_cache.borrow_mut() = Vec::new();
*shared_current_path.borrow_mut() = None;
@ -93,7 +96,7 @@ pub fn connect_button_compare(gui_data: &GuiData) {
*shared_using_for_preview.borrow_mut() = (None, None);
image_compare_left.set_from_pixbuf(None);
image_compare_right.set_from_pixbuf(None);
gtk::Inhibit(true)
gtk4::Inhibit(true)
});
let button_go_previous_compare_group = gui_data.compare_images.button_go_previous_compare_group.clone();
@ -126,7 +129,7 @@ pub fn connect_button_compare(gui_data: &GuiData) {
let current_group = *shared_current_of_groups.borrow();
let group_number = *shared_numbers_of_groups.borrow();
let tree_path = move_iter(&model, shared_current_path.borrow().as_ref().unwrap(), nb_object.column_color.unwrap(), false);
let tree_path = move_iter(&model, shared_current_path.borrow().as_ref().unwrap(), nb_object.column_header.unwrap(), false);
populate_groups_at_start(
nb_object,
@ -178,7 +181,7 @@ pub fn connect_button_compare(gui_data: &GuiData) {
let current_group = *shared_current_of_groups.borrow();
let group_number = *shared_numbers_of_groups.borrow();
let tree_path = move_iter(&model, shared_current_path.borrow().as_ref().unwrap(), nb_object.column_color.unwrap(), true);
let tree_path = move_iter(&model, shared_current_path.borrow().as_ref().unwrap(), nb_object.column_header.unwrap(), true);
populate_groups_at_start(
nb_object,
@ -205,7 +208,7 @@ pub fn connect_button_compare(gui_data: &GuiData) {
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let shared_current_path = gui_data.compare_images.shared_current_path.clone();
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
check_button_left_preview_text.connect_clicked(move |check_button_left_preview_text| {
check_button_left_preview_text.connect_toggled(move |check_button_left_preview_text| {
let nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
@ -227,7 +230,8 @@ pub fn connect_button_compare(gui_data: &GuiData) {
let shared_current_path = gui_data.compare_images.shared_current_path.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
check_button_right_preview_text.connect_clicked(move |check_button_right_preview_text| {
check_button_right_preview_text.connect_toggled(move |check_button_right_preview_text| {
let nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
@ -251,18 +255,18 @@ fn populate_groups_at_start(
model: &TreeModel,
shared_current_path: Rc<RefCell<Option<TreePath>>>,
tree_path: TreePath,
image_compare_left: &gtk::Image,
image_compare_right: &gtk::Image,
image_compare_left: &gtk4::Image,
image_compare_right: &gtk4::Image,
current_group: u32,
group_number: u32,
check_button_left_preview_text: &gtk::CheckButton,
check_button_right_preview_text: &gtk::CheckButton,
scrolled_window_compare_choose_images: &gtk::ScrolledWindow,
label_group_info: &gtk::Label,
shared_image_cache: Rc<RefCell<Vec<(String, String, gtk::Image, gtk::Image, gtk::TreePath)>>>,
check_button_left_preview_text: &gtk4::CheckButton,
check_button_right_preview_text: &gtk4::CheckButton,
scrolled_window_compare_choose_images: &gtk4::ScrolledWindow,
label_group_info: &gtk4::Label,
shared_image_cache: Rc<RefCell<Vec<(String, String, gtk4::Image, gtk4::Image, gtk4::TreePath)>>>,
shared_using_for_preview: Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>,
button_go_previous_compare_group: &gtk::Button,
button_go_next_compare_group: &gtk::Button,
button_go_previous_compare_group: &gtk4::Button,
button_go_next_compare_group: &gtk4::Button,
) {
if current_group == 1 {
button_go_previous_compare_group.set_sensitive(false);
@ -275,19 +279,19 @@ fn populate_groups_at_start(
button_go_next_compare_group.set_sensitive(true);
}
let all_vec = get_all_path(model, &tree_path, nb_object.column_color.unwrap(), nb_object.column_path, nb_object.column_name);
let all_vec = get_all_path(model, &tree_path, nb_object.column_header.unwrap(), nb_object.column_path, nb_object.column_name);
*shared_current_path.borrow_mut() = Some(tree_path);
let cache_all_images = generate_cache_for_results(all_vec);
// This is safe, because cache have at least 2 results
image_compare_left.set_from_pixbuf(cache_all_images[0].2.pixbuf().as_ref());
image_compare_right.set_from_pixbuf(cache_all_images[1].2.pixbuf().as_ref());
image_compare_left.set_paintable(cache_all_images[0].2.paintable().as_ref());
image_compare_right.set_paintable(cache_all_images[1].2.paintable().as_ref());
*shared_using_for_preview.borrow_mut() = (Some(cache_all_images[0].4.clone()), Some(cache_all_images[1].4.clone()));
check_button_left_preview_text.set_label(&format!("1. {}", get_max_file_name(&cache_all_images[0].0, 70)));
check_button_right_preview_text.set_label(&format!("2. {}", get_max_file_name(&cache_all_images[1].0, 70)));
check_button_left_preview_text.set_label(Some(&format!("1. {}", get_max_file_name(&cache_all_images[0].0, 60))));
check_button_right_preview_text.set_label(Some(&format!("2. {}", get_max_file_name(&cache_all_images[1].0, 60))));
label_group_info.set_text(
flg!(
@ -317,9 +321,9 @@ fn populate_groups_at_start(
*shared_image_cache.borrow_mut() = cache_all_images.clone();
let mut found = false;
for i in scrolled_window_compare_choose_images.child().unwrap().downcast::<gtk::Viewport>().unwrap().children() {
for i in get_all_children(&scrolled_window_compare_choose_images.child().unwrap().downcast::<gtk4::Viewport>().unwrap()) {
if i.widget_name() == "all_box" {
let gtk_box = i.downcast::<gtk::Box>().unwrap();
let gtk_box = i.downcast::<gtk4::Box>().unwrap();
update_bottom_buttons(&gtk_box, shared_using_for_preview, shared_image_cache);
found = true;
break;
@ -327,20 +331,20 @@ fn populate_groups_at_start(
}
assert!(found);
let is_active = model.value(&model.iter(&cache_all_images[0].4).unwrap(), nb_object.column_selection).get::<bool>().unwrap();
let is_active = model.get::<bool>(&model.iter(&cache_all_images[0].4).unwrap(), nb_object.column_selection);
check_button_left_preview_text.set_active(is_active);
let is_active = model.value(&model.iter(&cache_all_images[1].4).unwrap(), nb_object.column_selection).get::<bool>().unwrap();
let is_active = model.get::<bool>(&model.iter(&cache_all_images[1].4).unwrap(), nb_object.column_selection);
check_button_right_preview_text.set_active(is_active);
}
/// Generate images which will be used later as preview images without needing to open them again and again
fn generate_cache_for_results(vector_with_path: Vec<(String, String, gtk::TreePath)>) -> Vec<(String, String, gtk::Image, gtk::Image, gtk::TreePath)> {
fn generate_cache_for_results(vector_with_path: Vec<(String, String, gtk4::TreePath)>) -> Vec<(String, String, gtk4::Image, gtk4::Image, gtk4::TreePath)> {
// TODO use here threads,
// For now threads cannot be used because Image and TreeIter cannot be used in threads
let mut cache_all_images = Vec::new();
for (full_path, name, tree_path) in vector_with_path {
let small_img = gtk::Image::new();
let big_img = gtk::Image::new();
let small_img = gtk4::Image::new();
let big_img = gtk4::Image::new();
match Pixbuf::from_file(&full_path) {
Ok(pixbuf) =>
@ -362,8 +366,8 @@ fn generate_cache_for_results(vector_with_path: Vec<(String, String, gtk::TreePa
Some(pixbuf) => pixbuf,
};
big_img.set_pixbuf(Some(&pixbuf_big));
small_img.set_pixbuf(Some(&pixbuf_small));
big_img.set_from_pixbuf(Some(&pixbuf_big));
small_img.set_from_pixbuf(Some(&pixbuf_small));
break;
}
}
@ -378,21 +382,21 @@ fn generate_cache_for_results(vector_with_path: Vec<(String, String, gtk::TreePa
}
/// Takes info about current items in groups like path
fn get_all_path(model: &TreeModel, current_path: &TreePath, column_color: i32, column_path: i32, column_name: i32) -> Vec<(String, String, gtk::TreePath)> {
fn get_all_path(model: &TreeModel, current_path: &TreePath, column_header: i32, column_path: i32, column_name: i32) -> Vec<(String, String, gtk4::TreePath)> {
let used_iter = model.iter(current_path).unwrap();
assert_eq!(model.value(&used_iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR);
let using_reference = !model.value(&used_iter, column_path).get::<String>().unwrap().is_empty();
assert!(model.get::<bool>(&used_iter, column_header));
let using_reference = !model.get::<String>(&used_iter, column_path).is_empty();
let mut returned_vector = Vec::new();
if using_reference {
let name = model.value(&used_iter, column_name).get::<String>().unwrap();
let path = model.value(&used_iter, column_path).get::<String>().unwrap();
let name = model.get::<String>(&used_iter, column_name);
let path = model.get::<String>(&used_iter, column_path);
let full_name = get_full_name_from_path_name(&path, &name);
returned_vector.push((full_name, name, model.path(&used_iter).unwrap()));
returned_vector.push((full_name, name, model.path(&used_iter)));
}
if !model.iter_next(&used_iter) {
@ -400,20 +404,18 @@ fn get_all_path(model: &TreeModel, current_path: &TreePath, column_color: i32, c
}
loop {
let name = model.value(&used_iter, column_name).get::<String>().unwrap();
let path = model.value(&used_iter, column_path).get::<String>().unwrap();
let name = model.get::<String>(&used_iter, column_name);
let path = model.get::<String>(&used_iter, column_path);
let full_name = get_full_name_from_path_name(&path, &name);
returned_vector.push((full_name, name, model.path(&used_iter).unwrap()));
returned_vector.push((full_name, name, model.path(&used_iter)));
if !model.iter_next(&used_iter) {
break;
}
let color = model.value(&used_iter, column_color).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
if model.get::<bool>(&used_iter, column_header) {
break;
}
}
@ -424,10 +426,10 @@ fn get_all_path(model: &TreeModel, current_path: &TreePath, column_color: i32, c
}
/// Moves iterator to previous/next header
fn move_iter(model: &gtk::TreeModel, tree_path: &TreePath, column_color: i32, go_next: bool) -> TreePath {
fn move_iter(model: &gtk4::TreeModel, tree_path: &TreePath, column_header: i32, go_next: bool) -> TreePath {
let tree_iter = model.iter(tree_path).unwrap();
assert_eq!(model.value(&tree_iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR);
assert!(model.get::<bool>(&tree_iter, column_header));
if go_next {
if !model.iter_next(&tree_iter) {
@ -450,13 +452,11 @@ fn move_iter(model: &gtk::TreeModel, tree_path: &TreePath, column_color: i32, go
}
}
let color = model.value(&tree_iter, column_color).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
if model.get::<bool>(&tree_iter, column_header) {
break;
}
}
model.path(&tree_iter).unwrap()
model.path(&tree_iter)
}
/// Populate bottom Scrolled View with small thumbnails
@ -466,28 +466,26 @@ fn populate_similar_scrolled_view(
image_compare_left: &Image,
image_compare_right: &Image,
shared_using_for_preview: Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>,
shared_image_cache: Rc<RefCell<Vec<(String, String, gtk::Image, gtk::Image, gtk::TreePath)>>>,
shared_image_cache: Rc<RefCell<Vec<(String, String, gtk4::Image, gtk4::Image, gtk4::TreePath)>>>,
check_button_left_preview_text: &CheckButton,
check_button_right_preview_text: &CheckButton,
model: &TreeModel,
column_selection: i32,
) {
if let Some(child) = scrolled_window.child() {
scrolled_window.remove(&child);
};
scrolled_window.set_child(None::<&Widget>);
scrolled_window.set_propagate_natural_height(true);
let all_gtk_box = gtk::Box::new(Orientation::Horizontal, 5);
let all_gtk_box = gtk4::Box::new(Orientation::Horizontal, 5);
all_gtk_box.set_widget_name("all_box");
for (number, (path, _name, big_thumbnail, small_thumbnail, tree_path)) in image_cache.iter().enumerate() {
let small_box = gtk::Box::new(Orientation::Vertical, 3);
let small_box = gtk4::Box::new(Orientation::Vertical, 3);
let smaller_box = gtk::Box::new(Orientation::Horizontal, 2);
let smaller_box = gtk4::Box::new(Orientation::Horizontal, 2);
let button_left = gtk::Button::builder().label(&flg!("compare_move_left_button")).build();
let label = gtk::Label::builder().label(&(number + 1).to_string()).build();
let button_right = gtk::Button::builder().label(&flg!("compare_move_right_button")).build();
let button_left = gtk4::Button::builder().label(&flg!("compare_move_left_button")).build();
let label = gtk4::Label::builder().label(&(number + 1).to_string()).build();
let button_right = gtk4::Button::builder().label(&flg!("compare_move_right_button")).build();
let image_compare_left = image_compare_left.clone();
let image_compare_right = image_compare_right.clone();
@ -504,11 +502,11 @@ fn populate_similar_scrolled_view(
button_left.connect_clicked(move |_button_left| {
shared_using_for_preview_clone.borrow_mut().0 = Some(tree_path_clone.clone());
update_bottom_buttons(&all_gtk_box_clone, shared_using_for_preview_clone.clone(), shared_image_cache_clone.clone());
image_compare_left.set_from_pixbuf(big_thumbnail_clone.pixbuf().as_ref());
image_compare_left.set_paintable(big_thumbnail_clone.paintable().as_ref());
let is_active = model_clone.value(&model_clone.iter(&tree_path_clone).unwrap(), column_selection).get::<bool>().unwrap();
let is_active = model_clone.get::<bool>(&model_clone.iter(&tree_path_clone).unwrap(), column_selection);
check_button_left_preview_text_clone.set_active(is_active);
check_button_left_preview_text_clone.set_label(&format!("{}. {}", number + 1, get_max_file_name(&path_clone, 70)));
check_button_left_preview_text_clone.set_label(Some(&format!("{}. {}", number + 1, get_max_file_name(&path_clone, 60))));
});
let big_thumbnail_clone = big_thumbnail.clone();
@ -523,51 +521,51 @@ fn populate_similar_scrolled_view(
button_right.connect_clicked(move |_button_right| {
shared_using_for_preview_clone.borrow_mut().1 = Some(tree_path_clone.clone());
update_bottom_buttons(&all_gtk_box_clone, shared_using_for_preview_clone.clone(), shared_image_cache_clone.clone());
image_compare_right.set_from_pixbuf(big_thumbnail_clone.pixbuf().as_ref());
image_compare_right.set_paintable(big_thumbnail_clone.paintable().as_ref());
let is_active = model_clone.value(&model_clone.iter(&tree_path_clone).unwrap(), column_selection).get::<bool>().unwrap();
let is_active = model_clone.get::<bool>(&model_clone.iter(&tree_path_clone).unwrap(), column_selection);
check_button_right_preview_text_clone.set_active(is_active);
check_button_right_preview_text_clone.set_label(&format!("{}. {}", number + 1, get_max_file_name(&path_clone, 70)));
check_button_right_preview_text_clone.set_label(Some(&format!("{}. {}", number + 1, get_max_file_name(&path_clone, 60))));
});
smaller_box.add(&button_left);
smaller_box.add(&label);
smaller_box.add(&button_right);
smaller_box.append(&button_left);
smaller_box.append(&label);
smaller_box.append(&button_right);
small_box.add(&smaller_box);
small_box.add(small_thumbnail);
small_box.append(&smaller_box);
small_box.append(small_thumbnail);
all_gtk_box.add(&small_box);
all_gtk_box.append(&small_box);
}
all_gtk_box.show_all();
scrolled_window.add(&all_gtk_box);
all_gtk_box.show();
scrolled_window.set_child(Some(&all_gtk_box));
}
/// Disables/Enables L/R buttons at the bottom scrolled view
fn update_bottom_buttons(
all_gtk_box: &gtk::Box,
all_gtk_box: &gtk4::Box,
shared_using_for_preview: Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>,
image_cache: Rc<RefCell<Vec<(String, String, Image, Image, TreePath)>>>,
) {
let left_tree_view = (*shared_using_for_preview.borrow()).0.clone().unwrap();
let right_tree_view = (*shared_using_for_preview.borrow()).1.clone().unwrap();
for (number, i) in all_gtk_box.children().into_iter().enumerate() {
for (number, i) in get_all_children(all_gtk_box).into_iter().enumerate() {
let cache_tree_path = (*image_cache.borrow())[number].4.clone();
let is_chosen = cache_tree_path != right_tree_view && cache_tree_path != left_tree_view;
let bx = i.downcast::<gtk::Box>().unwrap();
let smaller_bx = bx.children()[0].clone().downcast::<gtk::Box>().unwrap();
for items in smaller_bx.children() {
if let Ok(btn) = items.downcast::<gtk::Button>() {
let bx = i.downcast::<gtk4::Box>().unwrap();
let smaller_bx = get_all_children(&bx)[0].clone().downcast::<gtk4::Box>().unwrap();
for items in get_all_children(&smaller_bx) {
if let Ok(btn) = items.downcast::<gtk4::Button>() {
btn.set_sensitive(is_chosen);
}
}
}
}
fn get_current_group_and_iter_from_selection(model: &TreeModel, selection: TreeSelection, column_color: i32) -> (u32, TreePath) {
fn get_current_group_and_iter_from_selection(model: &TreeModel, selection: TreeSelection, column_header: i32) -> (u32, TreePath) {
let mut current_group = 1;
let mut possible_group = 1;
let mut header_clone: TreeIter;
@ -578,7 +576,7 @@ fn get_current_group_and_iter_from_selection(model: &TreeModel, selection: TreeS
let iter = model.iter_first().unwrap(); // Checking that treeview is not empty should be done before
header_clone = iter; // if nothing selected, use first group
possible_header = iter; // if nothing selected, use first group
assert_eq!(model.value(&iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR); // First element should be header
assert!(model.get::<bool>(&iter, column_header)); // First element should be header
if !selected_records.is_empty() {
let first_selected_record = selected_records[0].clone();
@ -587,17 +585,17 @@ fn get_current_group_and_iter_from_selection(model: &TreeModel, selection: TreeS
break;
}
if model.value(&iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&iter, column_header) {
possible_group += 1;
possible_header = iter;
}
if model.path(&iter).unwrap() == first_selected_record {
if model.path(&iter) == first_selected_record {
header_clone = possible_header;
current_group = possible_group;
}
}
}
(current_group, model.path(&header_clone).unwrap())
(current_group, model.path(&header_clone))
}

View file

@ -2,8 +2,8 @@ use std::collections::BTreeMap;
use std::fs;
use std::fs::Metadata;
use gtk::prelude::*;
use gtk::{Align, CheckButton, Dialog, ResponseType, TextView};
use gtk4::prelude::*;
use gtk4::{Align, CheckButton, Dialog, Orientation, ResponseType, TextView};
use crate::flg;
@ -46,7 +46,7 @@ pub async fn delete_things(gui_data: GuiData) {
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
let (number_of_selected_items, number_of_selected_groups) = check_how_much_elements_is_selected(tree_view, nb_object.column_color, nb_object.column_selection);
let (number_of_selected_items, number_of_selected_groups) = check_how_much_elements_is_selected(tree_view, nb_object.column_header, nb_object.column_selection);
// Nothing is selected
if number_of_selected_items == 0 {
@ -57,11 +57,11 @@ pub async fn delete_things(gui_data: GuiData) {
return;
}
if let Some(column_color) = nb_object.column_color {
if let Some(column_header) = nb_object.column_header {
if !check_button_settings_confirm_group_deletion.is_active()
|| !check_if_deleting_all_files_in_group(
tree_view,
column_color,
column_header,
nb_object.column_selection,
nb_object.column_path,
&window_main,
@ -73,7 +73,7 @@ pub async fn delete_things(gui_data: GuiData) {
tree_view,
nb_object.column_name,
nb_object.column_path,
column_color,
column_header,
nb_object.column_selection,
&check_button_settings_use_trash,
&text_view_errors,
@ -115,8 +115,8 @@ pub async fn delete_things(gui_data: GuiData) {
}
pub async fn check_if_can_delete_files(
check_button_settings_confirm_deletion: &gtk::CheckButton,
window_main: &gtk::Window,
check_button_settings_confirm_deletion: &gtk4::CheckButton,
window_main: &gtk4::Window,
number_of_selected_items: u64,
number_of_selected_groups: u64,
) -> bool {
@ -124,7 +124,7 @@ pub async fn check_if_can_delete_files(
let (confirmation_dialog_delete, check_button) = create_dialog_ask_for_deletion(window_main, number_of_selected_items, number_of_selected_groups);
let response_type = confirmation_dialog_delete.run_future().await;
if response_type == gtk::ResponseType::Ok {
if response_type == gtk4::ResponseType::Ok {
if !check_button.is_active() {
check_button_settings_confirm_deletion.set_active(false);
}
@ -139,41 +139,45 @@ pub async fn check_if_can_delete_files(
true
}
fn create_dialog_ask_for_deletion(window_main: &gtk::Window, number_of_selected_items: u64, number_of_selected_groups: u64) -> (Dialog, CheckButton) {
let dialog = gtk::Dialog::builder().title(&flg!("delete_title_dialog")).transient_for(window_main).modal(true).build();
fn create_dialog_ask_for_deletion(window_main: &gtk4::Window, number_of_selected_items: u64, number_of_selected_groups: u64) -> (Dialog, CheckButton) {
let dialog = gtk4::Dialog::builder().title(&flg!("delete_title_dialog")).transient_for(window_main).modal(true).build();
let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
let label: gtk::Label = gtk::Label::new(Some(&flg!("delete_question_label")));
let label2: gtk::Label = match number_of_selected_groups {
0 => gtk::Label::new(Some(&flg!(
dialog.set_default_size(300, 0);
let label: gtk4::Label = gtk4::Label::new(Some(&flg!("delete_question_label")));
let label2: gtk4::Label = match number_of_selected_groups {
0 => gtk4::Label::new(Some(&flg!(
"delete_items_label",
generate_translation_hashmap(vec![("items", number_of_selected_items.to_string())])
))),
_ => gtk::Label::new(Some(&flg!(
_ => gtk4::Label::new(Some(&flg!(
"delete_items_groups_label",
generate_translation_hashmap(vec![("items", number_of_selected_items.to_string()), ("groups", number_of_selected_groups.to_string())])
))),
};
let check_button: gtk::CheckButton = gtk::CheckButton::with_label(&flg!("dialogs_ask_next_time"));
let check_button: gtk4::CheckButton = gtk4::CheckButton::with_label(&flg!("dialogs_ask_next_time"));
check_button.set_active(true);
check_button.set_halign(Align::Center);
button_ok.grab_focus();
let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label);
internal_box.add(&label2);
internal_box.add(&check_button);
internal_box.set_margin(5);
let parent = button_ok.parent().unwrap().parent().unwrap().downcast::<gtk4::Box>().unwrap(); // TODO Hack, but not so ugly as before
parent.set_orientation(Orientation::Vertical);
parent.insert_child_after(&label, None::<&gtk4::Widget>);
parent.insert_child_after(&label2, Some(&label));
parent.insert_child_after(&check_button, Some(&label2));
// parent.set_margin(5); // TODO
check_button.set_margin_top(5);
dialog.show_all();
dialog.show();
(dialog, check_button)
}
fn create_dialog_group_deletion(window_main: &gtk::Window) -> (Dialog, CheckButton) {
let dialog = gtk::Dialog::builder()
fn create_dialog_group_deletion(window_main: &gtk4::Window) -> (Dialog, CheckButton) {
let dialog = gtk4::Dialog::builder()
.title(&flg!("delete_all_files_in_group_title"))
.transient_for(window_main)
.modal(true)
@ -181,40 +185,40 @@ fn create_dialog_group_deletion(window_main: &gtk::Window) -> (Dialog, CheckButt
let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
let label: gtk::Label = gtk::Label::new(Some(&flg!("delete_all_files_in_group_label1")));
let label2: gtk::Label = gtk::Label::new(Some(&flg!("delete_all_files_in_group_label2")));
let check_button: gtk::CheckButton = gtk::CheckButton::with_label(&flg!("dialogs_ask_next_time"));
let label: gtk4::Label = gtk4::Label::new(Some(&flg!("delete_all_files_in_group_label1")));
let label2: gtk4::Label = gtk4::Label::new(Some(&flg!("delete_all_files_in_group_label2")));
let check_button: gtk4::CheckButton = gtk4::CheckButton::with_label(&flg!("dialogs_ask_next_time"));
check_button.set_active(true);
check_button.set_halign(Align::Center);
button_ok.grab_focus();
let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label);
internal_box.add(&label2);
internal_box.add(&check_button);
internal_box.append(&label);
internal_box.append(&label2);
internal_box.append(&check_button);
dialog.show_all();
dialog.show();
(dialog, check_button)
}
pub async fn check_if_deleting_all_files_in_group(
tree_view: &gtk::TreeView,
column_color: i32,
tree_view: &gtk4::TreeView,
column_header: i32,
column_selection: i32,
column_path: i32,
window_main: &gtk::Window,
check_button_settings_confirm_group_deletion: &gtk::CheckButton,
window_main: &gtk4::Window,
check_button_settings_confirm_group_deletion: &gtk4::CheckButton,
) -> bool {
let model = get_list_store(tree_view);
let mut selected_all_records: bool = true;
if let Some(iter) = model.iter_first() {
assert_eq!(model.value(&iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR); // First element should be header
assert!(model.get::<bool>(&iter, column_header)); // First element should be header
// It is safe to remove any number of files in reference mode
if !model.value(&iter, column_path).get::<String>().unwrap().is_empty() {
if !model.get::<String>(&iter, column_path).is_empty() {
return false;
}
@ -223,13 +227,13 @@ pub async fn check_if_deleting_all_files_in_group(
break;
}
if model.value(&iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&iter, column_header) {
if selected_all_records {
break;
}
selected_all_records = true;
} else {
if !model.value(&iter, column_selection).get::<bool>().unwrap() {
if !model.get::<bool>(&iter, column_selection) {
selected_all_records = false;
}
}
@ -244,7 +248,7 @@ pub async fn check_if_deleting_all_files_in_group(
let (confirmation_dialog_group_delete, check_button) = create_dialog_group_deletion(window_main);
let response_type = confirmation_dialog_group_delete.run_future().await;
if response_type == gtk::ResponseType::Ok {
if response_type == gtk4::ResponseType::Ok {
if !check_button.is_active() {
check_button_settings_confirm_group_deletion.set_active(false);
}
@ -261,7 +265,7 @@ pub async fn check_if_deleting_all_files_in_group(
}
pub fn empty_folder_remover(
tree_view: &gtk::TreeView,
tree_view: &gtk4::TreeView,
column_file_name: i32,
column_path: i32,
column_selection: i32,
@ -276,8 +280,8 @@ pub fn empty_folder_remover(
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
selected_rows.push(model.path(&iter).unwrap());
if model.get::<bool>(&iter, column_selection) {
selected_rows.push(model.path(&iter));
}
if !model.iter_next(&iter) {
break;
@ -292,12 +296,11 @@ pub fn empty_folder_remover(
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 (counter, tree_path) in selected_rows.iter().rev().enumerate() {
handle_gtk_pending_event_counter(counter);
for tree_path in selected_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap();
let name = model.value(&iter, column_file_name).get::<String>().unwrap();
let path = model.value(&iter, column_path).get::<String>().unwrap();
let name = model.get::<String>(&iter, column_file_name);
let path = model.get::<String>(&iter, column_path);
// We must check if folder is really empty or contains only other empty folders
let mut error_happened = false;
@ -373,11 +376,11 @@ pub fn empty_folder_remover(
}
}
text_view_errors.buffer().unwrap().set_text(messages.as_str());
text_view_errors.buffer().set_text(messages.as_str());
}
pub fn basic_remove(
tree_view: &gtk::TreeView,
tree_view: &gtk4::TreeView,
column_file_name: i32,
column_path: i32,
column_selection: i32,
@ -394,8 +397,8 @@ pub fn basic_remove(
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
selected_rows.push(model.path(&iter).unwrap());
if model.get::<bool>(&iter, column_selection) {
selected_rows.push(model.path(&iter));
}
if !model.iter_next(&iter) {
@ -409,12 +412,11 @@ pub fn basic_remove(
}
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
for (counter, tree_path) in selected_rows.iter().rev().enumerate() {
handle_gtk_pending_event_counter(counter);
for tree_path in selected_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap();
let name = model.value(&iter, column_file_name).get::<String>().unwrap();
let path = model.value(&iter, column_path).get::<String>().unwrap();
let name = model.get::<String>(&iter, column_file_name);
let path = model.get::<String>(&iter, column_path);
if !use_trash {
match fs::remove_file(get_full_name_from_path_name(&path, &name)) {
@ -448,15 +450,15 @@ pub fn basic_remove(
}
}
text_view_errors.buffer().unwrap().set_text(messages.as_str());
text_view_errors.buffer().set_text(messages.as_str());
}
// Remove all occurrences - remove every element which have same path and name as even non selected ones
pub fn tree_remove(
tree_view: &gtk::TreeView,
tree_view: &gtk4::TreeView,
column_file_name: i32,
column_path: i32,
column_color: i32,
column_header: i32,
column_selection: i32,
check_button_settings_use_trash: &CheckButton,
text_view_errors: &TextView,
@ -474,9 +476,9 @@ pub fn tree_remove(
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
selected_rows.push(model.path(&iter).unwrap());
if model.get::<bool>(&iter, column_selection) {
if !model.get::<bool>(&iter, column_header) {
selected_rows.push(model.path(&iter));
} else {
panic!("Header row shouldn't be selected, please report bug.");
}
@ -496,8 +498,8 @@ pub fn tree_remove(
for tree_path in selected_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap();
let file_name = model.value(&iter, column_file_name).get::<String>().unwrap();
let path = model.value(&iter, column_path).get::<String>().unwrap();
let file_name = model.get::<String>(&iter, column_file_name);
let path = model.get::<String>(&iter, column_path);
model.remove(&iter);
@ -506,13 +508,10 @@ pub fn tree_remove(
}
// Delete duplicated entries, and remove real files
let mut counter = 0_usize;
for (path, mut vec_file_name) in map_with_path_to_delete {
vec_file_name.sort();
vec_file_name.dedup();
for file_name in vec_file_name {
handle_gtk_pending_event_counter(counter);
counter += 1;
if !use_trash {
if let Err(e) = fs::remove_file(get_full_name_from_path_name(&path, &file_name)) {
messages += flg!(
@ -535,7 +534,7 @@ pub fn tree_remove(
}
}
clean_invalid_headers(&model, column_color, column_path);
clean_invalid_headers(&model, column_header, column_path);
text_view_errors.buffer().unwrap().set_text(messages.as_str());
text_view_errors.buffer().set_text(messages.as_str());
}

View file

@ -1,8 +1,8 @@
use std::fs;
use std::path::PathBuf;
use gtk::prelude::*;
use gtk::{Align, CheckButton, Dialog, ResponseType, TextView, TreeIter, TreePath};
use gtk4::prelude::*;
use gtk4::{Align, CheckButton, Dialog, ResponseType, TextView, TreeIter, TreePath};
use crate::flg;
use czkawka_core::duplicate::make_hard_link;
@ -57,11 +57,11 @@ async fn sym_hard_link_things(gui_data: GuiData, hardlinking: TypeOfTool) {
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
let column_color = nb_object.column_color.expect("Linking can be only used for tree views with grouped results");
let column_header = nb_object.column_header.expect("Linking can be only used for tree views with grouped results");
let check_button_settings_confirm_link = gui_data.settings.check_button_settings_confirm_link.clone();
if !check_if_anything_is_selected_async(tree_view, column_color, nb_object.column_selection).await {
if !check_if_anything_is_selected_async(tree_view, column_header, nb_object.column_selection).await {
return;
}
@ -69,7 +69,7 @@ async fn sym_hard_link_things(gui_data: GuiData, hardlinking: TypeOfTool) {
return;
}
if !check_if_changing_one_item_in_group_and_continue(tree_view, column_color, nb_object.column_selection, &window_main).await {
if !check_if_changing_one_item_in_group_and_continue(tree_view, column_header, nb_object.column_selection, &window_main).await {
return;
}
@ -77,7 +77,7 @@ async fn sym_hard_link_things(gui_data: GuiData, hardlinking: TypeOfTool) {
tree_view,
nb_object.column_name,
nb_object.column_path,
column_color,
column_header,
nb_object.column_selection,
hardlinking,
&text_view_errors,
@ -97,10 +97,10 @@ async fn sym_hard_link_things(gui_data: GuiData, hardlinking: TypeOfTool) {
}
fn hardlink_symlink(
tree_view: &gtk::TreeView,
tree_view: &gtk4::TreeView,
column_file_name: i32,
column_path: i32,
column_color: i32,
column_header: i32,
column_selection: i32,
hardlinking: TypeOfTool,
text_view_errors: &TextView,
@ -125,9 +125,9 @@ fn hardlink_symlink(
let mut selected_rows = Vec::new();
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
selected_rows.push(model.path(&iter).unwrap());
if model.get::<bool>(&iter, column_selection) {
if !model.get::<bool>(&iter, column_header) {
selected_rows.push(model.path(&iter));
} else {
panic!("Header row shouldn't be selected, please report bug.");
}
@ -145,7 +145,7 @@ fn hardlink_symlink(
let mut current_symhardlink_data: Option<SymHardlinkData> = None;
let mut current_selected_index = 0;
loop {
if model.value(&current_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&current_iter, column_header) {
if let Some(current_symhardlink_data) = current_symhardlink_data {
if !current_symhardlink_data.files_to_symhardlink.is_empty() {
vec_symhardlink_data.push(current_symhardlink_data);
@ -159,13 +159,13 @@ fn hardlink_symlink(
continue;
}
if model.path(&current_iter).unwrap() == selected_rows[current_selected_index] {
let file_name = model.value(&current_iter, column_file_name).get::<String>().unwrap();
let path = model.value(&current_iter, column_path).get::<String>().unwrap();
if model.path(&current_iter) == selected_rows[current_selected_index] {
let file_name = model.get::<String>(&current_iter, column_file_name);
let path = model.get::<String>(&current_iter, column_path);
let full_file_path = get_full_name_from_path_name(&path, &file_name);
if current_symhardlink_data.is_some() {
vec_tree_path_to_remove.push(model.path(&current_iter).unwrap());
vec_tree_path_to_remove.push(model.path(&current_iter));
let mut temp_data = current_symhardlink_data.unwrap();
temp_data.files_to_symhardlink.push(full_file_path);
current_symhardlink_data = Some(temp_data);
@ -200,8 +200,7 @@ fn hardlink_symlink(
}
if hardlinking == TypeOfTool::Hardlinking {
for symhardlink_data in vec_symhardlink_data {
for (counter, file_to_hardlink) in symhardlink_data.files_to_symhardlink.into_iter().enumerate() {
handle_gtk_pending_event_counter(counter);
for file_to_hardlink in symhardlink_data.files_to_symhardlink.into_iter() {
if let Err(e) = make_hard_link(&PathBuf::from(&symhardlink_data.original_data), &PathBuf::from(&file_to_hardlink)) {
add_text_to_text_view(text_view_errors, format!("{} {}, reason {}", flg!("hardlink_failed"), file_to_hardlink, e).as_str());
continue;
@ -210,8 +209,7 @@ fn hardlink_symlink(
}
} else {
for symhardlink_data in vec_symhardlink_data {
for (counter, file_to_symlink) in symhardlink_data.files_to_symhardlink.into_iter().enumerate() {
handle_gtk_pending_event_counter(counter);
for file_to_symlink in symhardlink_data.files_to_symhardlink.into_iter() {
if let Err(e) = fs::remove_file(&file_to_symlink) {
add_text_to_text_view(
text_view_errors,
@ -259,11 +257,11 @@ fn hardlink_symlink(
model.remove(&model.iter(tree_path).unwrap());
}
clean_invalid_headers(&model, column_color, column_path);
clean_invalid_headers(&model, column_header, column_path);
}
fn create_dialog_non_group(window_main: &gtk::Window) -> Dialog {
let dialog = gtk::Dialog::builder()
fn create_dialog_non_group(window_main: &gtk4::Window) -> Dialog {
let dialog = gtk4::Dialog::builder()
.title(&flg!("hard_sym_invalid_selection_title_dialog"))
.transient_for(window_main)
.modal(true)
@ -271,41 +269,41 @@ fn create_dialog_non_group(window_main: &gtk::Window) -> Dialog {
let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
let label: gtk::Label = gtk::Label::new(Some(&flg!("hard_sym_invalid_selection_label_1")));
let label2: gtk::Label = gtk::Label::new(Some(&flg!("hard_sym_invalid_selection_label_2")));
let label3: gtk::Label = gtk::Label::new(Some(&flg!("hard_sym_invalid_selection_label_3")));
let label: gtk4::Label = gtk4::Label::new(Some(&flg!("hard_sym_invalid_selection_label_1")));
let label2: gtk4::Label = gtk4::Label::new(Some(&flg!("hard_sym_invalid_selection_label_2")));
let label3: gtk4::Label = gtk4::Label::new(Some(&flg!("hard_sym_invalid_selection_label_3")));
button_ok.grab_focus();
let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label);
internal_box.add(&label2);
internal_box.add(&label3);
internal_box.append(&label);
internal_box.append(&label2);
internal_box.append(&label3);
dialog.show_all();
dialog.show();
dialog
}
pub async fn check_if_changing_one_item_in_group_and_continue(tree_view: &gtk::TreeView, column_color: i32, column_selection: i32, window_main: &gtk::Window) -> bool {
pub async fn check_if_changing_one_item_in_group_and_continue(tree_view: &gtk4::TreeView, column_header: i32, column_selection: i32, window_main: &gtk4::Window) -> bool {
let model = get_list_store(tree_view);
let mut selected_values_in_group = 0;
if let Some(iter) = model.iter_first() {
assert_eq!(model.value(&iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR); // First element should be header
assert!(model.get::<bool>(&iter, column_header)); // First element should be header
loop {
if !model.iter_next(&iter) {
break;
}
if model.value(&iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&iter, column_header) {
if selected_values_in_group == 1 {
break;
}
selected_values_in_group = 0;
} else {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
if model.get::<bool>(&iter, column_selection) {
selected_values_in_group += 1;
}
}
@ -318,7 +316,7 @@ pub async fn check_if_changing_one_item_in_group_and_continue(tree_view: &gtk::T
let confirmation_dialog = create_dialog_non_group(window_main);
let response_type = confirmation_dialog.run_future().await;
if response_type != gtk::ResponseType::Ok {
if response_type != gtk4::ResponseType::Ok {
confirmation_dialog.hide();
confirmation_dialog.close();
return false;
@ -330,18 +328,18 @@ pub async fn check_if_changing_one_item_in_group_and_continue(tree_view: &gtk::T
true
}
pub async fn check_if_anything_is_selected_async(tree_view: &gtk::TreeView, column_color: i32, column_selection: i32) -> bool {
pub async fn check_if_anything_is_selected_async(tree_view: &gtk4::TreeView, column_header: i32, column_selection: i32) -> bool {
let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() {
assert_eq!(model.value(&iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR); // First element should be header
assert!(model.get::<bool>(&iter, column_header)); // First element should be header
loop {
if !model.iter_next(&iter) {
break;
}
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR && model.value(&iter, column_selection).get::<bool>().unwrap() {
if !model.get::<bool>(&iter, column_header) && model.get::<bool>(&iter, column_selection) {
return true;
}
}
@ -350,12 +348,12 @@ pub async fn check_if_anything_is_selected_async(tree_view: &gtk::TreeView, colu
false
}
pub async fn check_if_can_link_files(check_button_settings_confirm_link: &gtk::CheckButton, window_main: &gtk::Window) -> bool {
pub async fn check_if_can_link_files(check_button_settings_confirm_link: &gtk4::CheckButton, window_main: &gtk4::Window) -> bool {
if check_button_settings_confirm_link.is_active() {
let (confirmation_dialog_link, check_button) = create_dialog_ask_for_linking(window_main);
let response_type = confirmation_dialog_link.run_future().await;
if response_type == gtk::ResponseType::Ok {
if response_type == gtk4::ResponseType::Ok {
if !check_button.is_active() {
check_button_settings_confirm_link.set_active(false);
}
@ -370,8 +368,8 @@ pub async fn check_if_can_link_files(check_button_settings_confirm_link: &gtk::C
true
}
fn create_dialog_ask_for_linking(window_main: &gtk::Window) -> (Dialog, CheckButton) {
let dialog = gtk::Dialog::builder()
fn create_dialog_ask_for_linking(window_main: &gtk4::Window) -> (Dialog, CheckButton) {
let dialog = gtk4::Dialog::builder()
.title(&flg!("hard_sym_link_title_dialog"))
.transient_for(window_main)
.modal(true)
@ -379,17 +377,17 @@ fn create_dialog_ask_for_linking(window_main: &gtk::Window) -> (Dialog, CheckBut
let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
let label: gtk::Label = gtk::Label::new(Some(&flg!("hard_sym_link_label")));
let check_button: gtk::CheckButton = gtk::CheckButton::with_label(&flg!("dialogs_ask_next_time"));
let label: gtk4::Label = gtk4::Label::new(Some(&flg!("hard_sym_link_label")));
let check_button: gtk4::CheckButton = gtk4::CheckButton::with_label(&flg!("dialogs_ask_next_time"));
check_button.set_active(true);
check_button.set_halign(Align::Center);
button_ok.grab_focus();
let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label);
internal_box.add(&check_button);
internal_box.append(&label);
internal_box.append(&check_button);
dialog.show_all();
dialog.show();
(dialog, check_button)
}

View file

@ -1,7 +1,7 @@
use std::path::{Path, PathBuf};
use gtk::prelude::*;
use gtk::{ResponseType, TreePath};
use gtk4::prelude::*;
use gtk4::{ResponseType, TreePath};
use crate::flg;
@ -31,7 +31,7 @@ pub fn connect_button_move(gui_data: &GuiData) {
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
let (number_of_selected_items, _number_of_selected_groups) = check_how_much_elements_is_selected(tree_view, nb_object.column_color, nb_object.column_selection);
let (number_of_selected_items, _number_of_selected_groups) = check_how_much_elements_is_selected(tree_view, nb_object.column_header, nb_object.column_selection);
// Nothing is selected
if number_of_selected_items == 0 {
@ -41,7 +41,7 @@ pub fn connect_button_move(gui_data: &GuiData) {
tree_view,
nb_object.column_name,
nb_object.column_path,
nb_object.column_color,
nb_object.column_header,
nb_object.column_selection,
&entry_info,
&text_view_errors,
@ -64,20 +64,20 @@ pub fn connect_button_move(gui_data: &GuiData) {
// TODO add progress bar
fn move_things(
tree_view: &gtk::TreeView,
tree_view: &gtk4::TreeView,
column_file_name: i32,
column_path: i32,
column_color: Option<i32>,
column_header: Option<i32>,
column_selection: i32,
entry_info: &gtk::Entry,
text_view_errors: &gtk::TextView,
window_main: &gtk::Window,
entry_info: &gtk4::Entry,
text_view_errors: &gtk4::TextView,
window_main: &gtk4::Window,
) {
reset_text_view(text_view_errors);
let chooser = gtk::FileChooserDialog::builder()
let chooser = gtk4::FileChooserDialog::builder()
.title(&flg!("move_files_title_dialog"))
.action(gtk::FileChooserAction::SelectFolder)
.action(gtk4::FileChooserAction::SelectFolder)
.transient_for(window_main)
.modal(true)
.build();
@ -85,28 +85,24 @@ fn move_things(
chooser.add_button(&flg!("general_close_button"), ResponseType::Cancel);
chooser.set_select_multiple(false);
chooser.show_all();
chooser.show();
let entry_info = entry_info.clone();
let text_view_errors = text_view_errors.clone();
let tree_view = tree_view.clone();
chooser.connect_response(move |file_chooser, response_type| {
if response_type == gtk::ResponseType::Ok {
let folders: Vec<PathBuf> = file_chooser.filenames();
// GTK 4
// folders = Vec::new();
// if let Some(g_files) = file_chooser.files() {
// for index in 0..g_files.n_items() {
// let file = &g_files.item(index);
// if let Some(file) = file {
// println!("{:?}", file);
// let ss = file.clone().downcast::<gtk4::gio::File>().unwrap();
// if let Some(path_buf) = ss.path() {
// folders.push(path_buf);
// }
// }
// }
// }
if response_type == gtk4::ResponseType::Ok {
let mut folders: Vec<PathBuf> = Vec::new();
let g_files = file_chooser.files();
for index in 0..g_files.n_items() {
let file = &g_files.item(index);
if let Some(file) = file {
let ss = file.clone().downcast::<gtk4::gio::File>().unwrap();
if let Some(path_buf) = ss.path() {
folders.push(path_buf);
}
}
}
if folders.len() != 1 {
add_text_to_text_view(
@ -119,12 +115,12 @@ fn move_things(
);
} else {
let folder = folders[0].clone();
if let Some(column_color) = column_color {
if let Some(column_header) = column_header {
move_with_tree(
&tree_view,
column_file_name,
column_path,
column_color,
column_header,
column_selection,
folder,
&entry_info,
@ -140,14 +136,14 @@ fn move_things(
}
fn move_with_tree(
tree_view: &gtk::TreeView,
tree_view: &gtk4::TreeView,
column_file_name: i32,
column_path: i32,
column_color: i32,
column_header: i32,
column_selection: i32,
destination_folder: PathBuf,
entry_info: &gtk::Entry,
text_view_errors: &gtk::TextView,
entry_info: &gtk4::Entry,
text_view_errors: &gtk4::TextView,
) {
let model = get_list_store(tree_view);
@ -155,9 +151,9 @@ fn move_with_tree(
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
selected_rows.push(model.path(&iter).unwrap());
if model.get::<bool>(&iter, column_selection) {
if !model.get::<bool>(&iter, column_header) {
selected_rows.push(model.path(&iter));
} else {
panic!("Header row shouldn't be selected, please report bug.");
}
@ -175,17 +171,17 @@ fn move_with_tree(
move_files_common(&selected_rows, &model, column_file_name, column_path, &destination_folder, entry_info, text_view_errors);
clean_invalid_headers(&model, column_color, column_path);
clean_invalid_headers(&model, column_header, column_path);
}
fn move_with_list(
tree_view: &gtk::TreeView,
tree_view: &gtk4::TreeView,
column_file_name: i32,
column_path: i32,
column_selection: i32,
destination_folder: PathBuf,
entry_info: &gtk::Entry,
text_view_errors: &gtk::TextView,
entry_info: &gtk4::Entry,
text_view_errors: &gtk4::TextView,
) {
let model = get_list_store(tree_view);
@ -193,8 +189,8 @@ fn move_with_list(
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
selected_rows.push(model.path(&iter).unwrap());
if model.get::<bool>(&iter, column_selection) {
selected_rows.push(model.path(&iter));
}
if !model.iter_next(&iter) {
@ -212,24 +208,23 @@ fn move_with_list(
fn move_files_common(
selected_rows: &[TreePath],
model: &gtk::ListStore,
model: &gtk4::ListStore,
column_file_name: i32,
column_path: i32,
destination_folder: &Path,
entry_info: &gtk::Entry,
text_view_errors: &gtk::TextView,
entry_info: &gtk4::Entry,
text_view_errors: &gtk4::TextView,
) {
let mut messages: String = "".to_string();
let mut moved_files: u32 = 0;
// Save to variable paths of files, and remove it when not removing all occurrences.
'next_result: for (counter, tree_path) in selected_rows.iter().rev().enumerate() {
handle_gtk_pending_event_counter(counter);
'next_result: for tree_path in selected_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap();
let file_name = model.value(&iter, column_file_name).get::<String>().unwrap();
let path = model.value(&iter, column_path).get::<String>().unwrap();
let file_name = model.get::<String>(&iter, column_file_name);
let path = model.get::<String>(&iter, column_path);
let thing = get_full_name_from_path_name(&path, &file_name);
let destination_file = destination_folder.join(file_name);
@ -259,5 +254,5 @@ fn move_files_common(
.as_str(),
);
text_view_errors.buffer().unwrap().set_text(messages.as_str());
text_view_errors.buffer().set_text(messages.as_str());
}

View file

@ -2,8 +2,8 @@ use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use gtk::prelude::*;
use gtk::{Button, Entry};
use gtk4::prelude::*;
use gtk4::{Button, Entry};
use crate::flg;
use czkawka_core::common_traits::SaveResults;

View file

@ -3,7 +3,7 @@ use std::sync::Arc;
use std::thread;
use glib::Sender;
use gtk::prelude::*;
use gtk4::prelude::*;
use czkawka_core::bad_extensions::BadExtensions;
use czkawka_core::big_file::BigFile;
@ -55,13 +55,13 @@ pub fn connect_button_search(
let buttons_names = gui_data.bottom_buttons.buttons_names;
let buttons_search_clone = gui_data.bottom_buttons.buttons_search.clone();
let check_button_duplicates_use_prehash_cache = gui_data.settings.check_button_duplicates_use_prehash_cache.clone();
let check_button_duplicate_case_sensitive_name: gtk::CheckButton = gui_data.main_notebook.check_button_duplicate_case_sensitive_name.clone();
let check_button_music_artist: gtk::CheckButton = gui_data.main_notebook.check_button_music_artist.clone();
let check_button_music_title: gtk::CheckButton = gui_data.main_notebook.check_button_music_title.clone();
let check_button_music_year: gtk::CheckButton = gui_data.main_notebook.check_button_music_year.clone();
let check_button_music_genre: gtk::CheckButton = gui_data.main_notebook.check_button_music_genre.clone();
let check_button_music_length: gtk::CheckButton = gui_data.main_notebook.check_button_music_length.clone();
let check_button_music_bitrate: gtk::CheckButton = gui_data.main_notebook.check_button_music_bitrate.clone();
let check_button_duplicate_case_sensitive_name: gtk4::CheckButton = gui_data.main_notebook.check_button_duplicate_case_sensitive_name.clone();
let check_button_music_artist: gtk4::CheckButton = gui_data.main_notebook.check_button_music_artist.clone();
let check_button_music_title: gtk4::CheckButton = gui_data.main_notebook.check_button_music_title.clone();
let check_button_music_year: gtk4::CheckButton = gui_data.main_notebook.check_button_music_year.clone();
let check_button_music_genre: gtk4::CheckButton = gui_data.main_notebook.check_button_music_genre.clone();
let check_button_music_length: gtk4::CheckButton = gui_data.main_notebook.check_button_music_length.clone();
let check_button_music_bitrate: gtk4::CheckButton = gui_data.main_notebook.check_button_music_bitrate.clone();
let check_button_recursive = gui_data.upper_notebook.check_button_recursive.clone();
let check_button_settings_duplicates_delete_outdated_cache = gui_data.settings.check_button_settings_duplicates_delete_outdated_cache.clone();
let check_button_settings_hide_hard_links = gui_data.settings.check_button_settings_hide_hard_links.clone();
@ -143,6 +143,8 @@ pub fn connect_button_search(
let show_dialog = Arc::new(AtomicBool::new(true));
window_progress.set_title(Some(&flg!("window_progress_title")));
hide_all_buttons(&buttons_array);
notebook_main.set_sensitive(false);
@ -168,8 +170,8 @@ pub fn connect_button_search(
image_preview_duplicates.hide();
label_stage.show();
grid_progress_stages.show_all();
window_progress.resize(1, 1);
grid_progress_stages.show();
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_duplicate_finder).clear();
@ -214,7 +216,7 @@ pub fn connect_button_search(
NotebookMainEnum::EmptyFiles => {
label_stage.show();
grid_progress_stages.hide();
window_progress.resize(1, 1);
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_empty_files_finder).clear();
@ -235,7 +237,7 @@ pub fn connect_button_search(
NotebookMainEnum::EmptyDirectories => {
label_stage.show();
grid_progress_stages.hide();
window_progress.resize(1, 1);
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_empty_folder_finder).clear();
@ -253,7 +255,7 @@ pub fn connect_button_search(
NotebookMainEnum::BigFiles => {
label_stage.show();
grid_progress_stages.hide();
window_progress.resize(1, 1);
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_big_files_finder).clear();
@ -277,7 +279,7 @@ pub fn connect_button_search(
NotebookMainEnum::Temporary => {
label_stage.show();
grid_progress_stages.hide();
window_progress.resize(1, 1);
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_temporary_files_finder).clear();
@ -298,8 +300,8 @@ pub fn connect_button_search(
image_preview_similar_images.hide();
label_stage.show();
grid_progress_stages.show_all();
window_progress.resize(1, 1);
grid_progress_stages.show();
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_similar_images_finder).clear();
@ -348,8 +350,8 @@ pub fn connect_button_search(
}
NotebookMainEnum::SimilarVideos => {
label_stage.show();
grid_progress_stages.show_all();
window_progress.resize(1, 1);
grid_progress_stages.show();
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_similar_videos_finder).clear();
@ -383,8 +385,8 @@ pub fn connect_button_search(
}
NotebookMainEnum::SameMusic => {
label_stage.show();
grid_progress_stages.show_all();
window_progress.resize(1, 1);
grid_progress_stages.show();
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_same_music_finder).clear();
@ -444,7 +446,7 @@ pub fn connect_button_search(
NotebookMainEnum::Symlinks => {
label_stage.show();
grid_progress_stages.hide();
window_progress.resize(1, 1);
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_invalid_symlinks).clear();
@ -465,7 +467,7 @@ pub fn connect_button_search(
NotebookMainEnum::BrokenFiles => {
label_stage.show();
grid_progress_stages.show();
window_progress.resize(1, 1);
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_broken_files).clear();
@ -487,8 +489,8 @@ pub fn connect_button_search(
}
NotebookMainEnum::BadExtensions => {
label_stage.show();
grid_progress_stages.show_all();
window_progress.resize(1, 1);
grid_progress_stages.show();
window_progress.set_default_size(1, 1);
get_list_store(&tree_view_bad_extensions).clear();

View file

@ -1,4 +1,4 @@
use gtk::prelude::*;
use gtk4::prelude::*;
use crate::gui_structs::gui_data::GuiData;
use crate::gui_structs::gui_popovers::GuiPopovers;
@ -8,12 +8,10 @@ use crate::notebook_enums::*;
pub fn connect_button_select(gui_data: &GuiData) {
let popovers = gui_data.popovers.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let popover_select = gui_data.popovers.popover_select.clone();
let buttons_select = gui_data.bottom_buttons.buttons_select.clone();
let gc_buttons_select = gui_data.bottom_buttons.gc_buttons_select.clone();
buttons_select.connect_clicked(move |_| {
gc_buttons_select.connect_pressed(move |_, _, _, _| {
show_required_popovers(&popovers, &to_notebook_main_enum(notebook_main.current_page().unwrap()));
popover_select.popup();
});
}

View file

@ -1,8 +1,9 @@
use crossbeam_channel::{Sender, TrySendError};
use gtk::prelude::*;
use crate::flg;
use crate::gui_structs::gui_data::GuiData;
use crate::help_functions::KEY_ENTER;
use gtk4::prelude::*;
fn send_stop_message(stop_sender: &Sender<()>) {
stop_sender
@ -13,25 +14,22 @@ fn send_stop_message(stop_sender: &Sender<()>) {
pub fn connect_button_stop(gui_data: &GuiData) {
let evk_button_stop_in_dialog = gui_data.progress_window.evk_button_stop_in_dialog.clone();
let stop_dialog = gui_data.progress_window.window_progress.clone();
let stop_sender = gui_data.stop_sender.clone();
evk_button_stop_in_dialog.connect_key_released(move |_, _, key_code, _| {
if key_code == KEY_ENTER {
// Only accept enter key to stop search
stop_dialog.set_title(Some(&format!("{} ({})", flg!("window_progress_title"), flg!("progress_stop_additional_message"))));
send_stop_message(&stop_sender);
}
});
let button_stop_in_dialog = gui_data.progress_window.button_stop_in_dialog.clone();
let stop_dialog = gui_data.progress_window.window_progress.clone();
let stop_sender = gui_data.stop_sender.clone();
button_stop_in_dialog.connect_button_release_event(move |_, _e| {
send_stop_message(&stop_sender);
gtk::Inhibit(false)
});
// TODO GTK 4 change this to connect released, not sure why not works here
// let gc_button_stop_in_dialog = gui_data.progress_window.gc_button_stop_in_dialog.clone();
// let stop_sender = gui_data.stop_sender.clone();
// gc_button_stop_in_dialog.connect_button_release_event(move |_, _e| {
// stop_sender.send(()).unwrap();
// gtk::Inhibit(false)
// });
button_stop_in_dialog.connect_clicked(move |_a| {
stop_dialog.set_title(Some(&format!("{} ({})", flg!("window_progress_title"), flg!("progress_stop_additional_message"))));
send_stop_message(&stop_sender);
});
}

View file

@ -1,4 +1,4 @@
use gtk::prelude::*;
use gtk4::prelude::*;
use i18n_embed::unic_langid::LanguageIdentifier;
use i18n_embed::DesktopLanguageRequester;

View file

@ -1,4 +1,4 @@
use gtk::prelude::*;
use gtk4::prelude::*;
use czkawka_core::common_dir_traversal::CheckingMethod;

View file

@ -1,4 +1,5 @@
use gtk::prelude::*;
use gtk4::prelude::*;
use gtk4::Inhibit;
use crate::gui_structs::gui_data::GuiData;
@ -9,7 +10,7 @@ pub fn connect_button_about(gui_data: &GuiData) {
about_dialog.show();
// Prevent from deleting dialog after close
about_dialog.connect_delete_event(|dialog, _| {
about_dialog.connect_close_request(|dialog| {
dialog.hide();
Inhibit(true)
});

View file

@ -1,5 +1,3 @@
use gtk::prelude::*;
use crate::gui_structs::gui_data::GuiData;
use crate::help_functions::*;
use crate::notebook_enums::*;

View file

@ -1,5 +1,5 @@
use gtk::prelude::*;
use gtk::{ResponseType, TreeIter, Window};
use gtk4::prelude::*;
use gtk4::{ResponseType, TreeIter, Window};
use regex::Regex;
use czkawka_core::common::Common;
@ -11,13 +11,13 @@ use crate::help_functions::*;
// 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: &gtk::Popover, tree_view: &gtk::TreeView, column_button_selection: u32, column_color: Option<i32>) {
fn popover_select_all(popover: &gtk4::Popover, tree_view: &gtk4::TreeView, column_button_selection: u32, column_header: Option<i32>) {
let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() {
if let Some(column_color) = column_color {
if let Some(column_header) = column_header {
loop {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
if !model.get::<bool>(&iter, column_header) {
model.set_value(&iter, column_button_selection, &true.to_value());
}
if !model.iter_next(&iter) {
@ -37,7 +37,7 @@ fn popover_select_all(popover: &gtk::Popover, tree_view: &gtk::TreeView, column_
popover.popdown();
}
fn popover_unselect_all(popover: &gtk::Popover, tree_view: &gtk::TreeView, column_button_selection: u32) {
fn popover_unselect_all(popover: &gtk4::Popover, tree_view: &gtk4::TreeView, column_button_selection: u32) {
let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() {
@ -52,14 +52,14 @@ fn popover_unselect_all(popover: &gtk::Popover, tree_view: &gtk::TreeView, colum
popover.popdown();
}
fn popover_reverse(popover: &gtk::Popover, tree_view: &gtk::TreeView, column_button_selection: u32, column_color: Option<i32>) {
fn popover_reverse(popover: &gtk4::Popover, tree_view: &gtk4::TreeView, column_button_selection: u32, column_header: Option<i32>) {
let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() {
if let Some(column_color) = column_color {
if let Some(column_header) = column_header {
loop {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
let current_value: bool = model.value(&iter, column_button_selection as i32).get::<bool>().unwrap();
if !model.get::<bool>(&iter, column_header) {
let current_value: bool = model.get::<bool>(&iter, column_button_selection as i32);
model.set_value(&iter, column_button_selection, &(!current_value).to_value());
}
if !model.iter_next(&iter) {
@ -68,7 +68,7 @@ fn popover_reverse(popover: &gtk::Popover, tree_view: &gtk::TreeView, column_but
}
} else {
loop {
let current_value: bool = model.value(&iter, column_button_selection as i32).get::<bool>().unwrap();
let current_value: bool = model.get::<bool>(&iter, column_button_selection as i32);
model.set_value(&iter, column_button_selection, &(!current_value).to_value());
if !model.iter_next(&iter) {
@ -81,9 +81,9 @@ fn popover_reverse(popover: &gtk::Popover, tree_view: &gtk::TreeView, column_but
}
fn popover_all_except_oldest_newest(
popover: &gtk::Popover,
tree_view: &gtk::TreeView,
column_color: i32,
popover: &gtk4::Popover,
tree_view: &gtk4::TreeView,
column_header: i32,
column_modification_as_secs: i32,
column_file_name: i32,
column_button_selection: u32,
@ -105,16 +105,15 @@ fn popover_all_except_oldest_newest(
let mut file_length: usize = 0;
loop {
let color = model.value(&iter, column_color).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
if model.get::<bool>(&iter, column_header) {
if !model.iter_next(&iter) {
end = true;
}
break;
}
tree_iter_array.push(iter);
let modification = model.value(&iter, column_modification_as_secs).get::<u64>().unwrap();
let current_file_length = model.value(&iter, column_file_name).get::<String>().unwrap().len();
let modification = model.get::<u64>(&iter, column_modification_as_secs);
let current_file_length = model.get::<String>(&iter, column_file_name).len();
if except_oldest {
if modification < modification_time_min_max || (modification == modification_time_min_max && current_file_length < file_length) {
file_length = current_file_length;
@ -156,9 +155,9 @@ fn popover_all_except_oldest_newest(
}
fn popover_one_oldest_newest(
popover: &gtk::Popover,
tree_view: &gtk::TreeView,
column_color: i32,
popover: &gtk4::Popover,
tree_view: &gtk4::TreeView,
column_header: i32,
column_modification_as_secs: i32,
column_file_name: i32,
column_button_selection: u32,
@ -180,16 +179,15 @@ fn popover_one_oldest_newest(
let mut file_length: usize = 0;
loop {
let color = model.value(&iter, column_color).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
if model.get::<bool>(&iter, column_header) {
if !model.iter_next(&iter) {
end = true;
}
break;
}
tree_iter_array.push(iter);
let modification = model.value(&iter, column_modification_as_secs).get::<u64>().unwrap();
let current_file_length = model.value(&iter, column_file_name).get::<String>().unwrap().len();
let modification = model.get::<u64>(&iter, column_modification_as_secs);
let current_file_length = model.get::<String>(&iter, column_file_name).len();
if check_oldest {
if modification < modification_time_min_max || (modification == modification_time_min_max && current_file_length > file_length) {
file_length = current_file_length;
@ -232,10 +230,10 @@ fn popover_one_oldest_newest(
}
fn popover_custom_select_unselect(
popover: &gtk::Popover,
popover: &gtk4::Popover,
window_main: &Window,
tree_view: &gtk::TreeView,
column_color: Option<i32>,
tree_view: &gtk4::TreeView,
column_header: Option<i32>,
column_file_name: i32,
column_path: i32,
column_button_selection: u32,
@ -250,26 +248,26 @@ fn popover_custom_select_unselect(
// Dialog for select/unselect items
{
let dialog = gtk::Dialog::builder().title(&window_title).transient_for(window_main).modal(true).build();
let dialog = gtk4::Dialog::builder().title(&window_title).transient_for(window_main).modal(true).build();
dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
let check_button_path = gtk::CheckButton::builder().label(&flg!("popover_custom_regex_path_label")).build();
let check_button_name = gtk::CheckButton::builder().label(&flg!("popover_custom_regex_name_label")).build();
let check_button_rust_regex = gtk::CheckButton::builder().label(&flg!("popover_custom_regex_regex_label")).build();
let check_button_path = gtk4::CheckButton::builder().label(&flg!("popover_custom_regex_path_label")).build();
let check_button_name = gtk4::CheckButton::builder().label(&flg!("popover_custom_regex_name_label")).build();
let check_button_rust_regex = gtk4::CheckButton::builder().label(&flg!("popover_custom_regex_regex_label")).build();
let check_button_case_sensitive = gtk::CheckButton::builder().label(&flg!("popover_custom_case_sensitive_check_button")).build();
let check_button_case_sensitive = gtk4::CheckButton::builder().label(&flg!("popover_custom_case_sensitive_check_button")).build();
check_button_case_sensitive.set_active(false);
let check_button_select_not_all_results = gtk::CheckButton::builder().label(&flg!("popover_custom_all_in_group_label")).build();
let check_button_select_not_all_results = gtk4::CheckButton::builder().label(&flg!("popover_custom_all_in_group_label")).build();
check_button_select_not_all_results.set_active(true);
let entry_path = gtk::Entry::new();
let entry_name = gtk::Entry::new();
let entry_rust_regex = gtk::Entry::new();
let entry_path = gtk4::Entry::new();
let entry_name = gtk4::Entry::new();
let entry_rust_regex = gtk4::Entry::new();
entry_rust_regex.set_sensitive(false); // By default check button regex is disabled
let label_regex_valid = gtk::Label::new(None);
let label_regex_valid = gtk4::Label::new(None);
// Tooltips
{
@ -337,7 +335,7 @@ fn popover_custom_select_unselect(
// Configure look of things
{
// TODO Label should have const width, and rest should fill entry, but for now is 50%-50%
let grid = gtk::Grid::new();
let grid = gtk4::Grid::new();
grid.set_row_homogeneous(true);
grid.set_column_homogeneous(true);
@ -358,9 +356,9 @@ fn popover_custom_select_unselect(
}
let box_widget = get_dialog_box_child(&dialog);
box_widget.add(&grid);
box_widget.append(&grid);
dialog.show_all();
dialog.show();
}
let tree_view = tree_view.clone();
@ -374,7 +372,7 @@ fn popover_custom_select_unselect(
#[cfg(target_family = "windows")]
let path_wildcard = path_wildcard.replace("/", "\\");
if response_type == gtk::ResponseType::Ok {
if response_type == gtk4::ResponseType::Ok {
let check_path = check_button_path.is_active();
let check_name = check_button_name.is_active();
let check_regex = check_button_rust_regex.is_active();
@ -409,9 +407,8 @@ fn popover_custom_select_unselect(
let mut number_of_already_selected_things = 0;
let mut vec_of_iters: Vec<TreeIter> = Vec::new();
loop {
if let Some(column_color) = column_color {
let color = model.value(&iter, column_color).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
if let Some(column_header) = column_header {
if model.get::<bool>(&iter, column_header) {
if select_things {
if check_all_selected && (number_of_all_things - number_of_already_selected_things == vec_of_iters.len()) {
vec_of_iters.pop();
@ -436,9 +433,9 @@ fn popover_custom_select_unselect(
}
}
let is_selected = model.value(&iter, column_button_selection as i32).get::<bool>().unwrap();
let path = model.value(&iter, column_path).get::<String>().unwrap();
let name = model.value(&iter, column_file_name).get::<String>().unwrap();
let is_selected = model.get::<bool>(&iter, column_button_selection as i32);
let path = model.get::<String>(&iter, column_path);
let name = model.get::<String>(&iter, column_file_name);
let path_and_name = get_full_name_from_path_name(&path, &name);
@ -510,9 +507,9 @@ fn popover_custom_select_unselect(
}
fn popover_all_except_biggest_smallest(
popover: &gtk::Popover,
tree_view: &gtk::TreeView,
column_color: i32,
popover: &gtk4::Popover,
tree_view: &gtk4::TreeView,
column_header: i32,
column_size_as_bytes: i32,
column_dimensions: Option<i32>,
column_button_selection: u32,
@ -536,19 +533,18 @@ fn popover_all_except_biggest_smallest(
};
loop {
let color = model.value(&iter, column_color).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
if model.get::<bool>(&iter, column_header) {
if !model.iter_next(&iter) {
end = true;
}
break;
}
tree_iter_array.push(iter);
let size_as_bytes = model.value(&iter, column_size_as_bytes).get::<u64>().unwrap();
let size_as_bytes = model.get::<u64>(&iter, column_size_as_bytes);
// If dimension exists, then needs to be checked images
if let Some(column_dimensions) = column_dimensions {
let dimensions_string = model.value(&iter, column_dimensions).get::<String>().unwrap();
let dimensions_string = model.get::<String>(&iter, column_dimensions);
let dimensions = change_dimension_to_krotka(dimensions_string);
let number_of_pixels = dimensions.0 * dimensions.1;
@ -618,7 +614,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
popover_select_all(&popover_select, tree_view, nb_object.column_selection as u32, nb_object.column_color);
popover_select_all(&popover_select, tree_view, nb_object.column_selection as u32, nb_object.column_header);
});
let popover_select = gui_data.popovers.popover_select.clone();
@ -642,7 +638,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
popover_reverse(&popover_select, tree_view, nb_object.column_selection as u32, nb_object.column_color);
popover_reverse(&popover_select, tree_view, nb_object.column_selection as u32, nb_object.column_header);
});
let popover_select = gui_data.popovers.popover_select.clone();
@ -657,7 +653,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_all_except_oldest_newest(
&popover_select,
tree_view,
nb_object.column_color.expect("AEO can't be used without headers"),
nb_object.column_header.expect("AEO can't be used without headers"),
nb_object.column_modification_as_secs.expect("AEO needs modification as secs column"),
nb_object.column_name,
nb_object.column_selection as u32,
@ -677,7 +673,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_all_except_oldest_newest(
&popover_select,
tree_view,
nb_object.column_color.expect("AEN can't be used without headers"),
nb_object.column_header.expect("AEN can't be used without headers"),
nb_object.column_modification_as_secs.expect("AEN needs modification as secs column"),
nb_object.column_name,
nb_object.column_selection as u32,
@ -697,7 +693,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_one_oldest_newest(
&popover_select,
tree_view,
nb_object.column_color.expect("OO can't be used without headers"),
nb_object.column_header.expect("OO can't be used without headers"),
nb_object.column_modification_as_secs.expect("OO needs modification as secs column"),
nb_object.column_name,
nb_object.column_selection as u32,
@ -717,7 +713,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_one_oldest_newest(
&popover_select,
tree_view,
nb_object.column_color.expect("ON can't be used without headers"),
nb_object.column_header.expect("ON can't be used without headers"),
nb_object.column_modification_as_secs.expect("ON needs modification as secs column"),
nb_object.column_name,
nb_object.column_selection as u32,
@ -739,7 +735,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
&popover_select,
&window_main,
tree_view,
nb_object.column_color,
nb_object.column_header,
nb_object.column_name,
nb_object.column_path,
nb_object.column_selection as u32,
@ -761,7 +757,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
&popover_select,
&window_main,
tree_view,
nb_object.column_color,
nb_object.column_header,
nb_object.column_name,
nb_object.column_path,
nb_object.column_selection as u32,
@ -781,7 +777,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_all_except_biggest_smallest(
&popover_select,
tree_view,
nb_object.column_color.expect("AEB can't be used without headers"),
nb_object.column_header.expect("AEB can't be used without headers"),
nb_object.column_size_as_bytes.expect("AEB needs size as bytes column"),
nb_object.column_dimensions,
nb_object.column_selection as u32,
@ -801,7 +797,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_all_except_biggest_smallest(
&popover_select,
tree_view,
nb_object.column_color.expect("AES can't be used without headers"),
nb_object.column_header.expect("AES can't be used without headers"),
nb_object.column_size_as_bytes.expect("AES needs size as bytes column"),
nb_object.column_dimensions,
nb_object.column_selection as u32,

View file

@ -1,6 +1,6 @@
use futures::channel::mpsc::UnboundedReceiver;
use futures::StreamExt;
use gtk::prelude::*;
use gtk4::prelude::*;
use czkawka_core::common_dir_traversal::ProgressData;
use czkawka_core::{big_file, broken_files, common_dir_traversal, similar_images, similar_videos, temporary};

View file

@ -1,14 +1,14 @@
use std::path::PathBuf;
use gtk::prelude::*;
use gtk::{ResponseType, TreeView, Window};
use gtk4::prelude::*;
use gtk4::{Orientation, ResponseType, TreeView, Window};
use crate::flg;
#[cfg(target_family = "windows")]
use czkawka_core::common::Common;
use crate::gui_structs::gui_data::GuiData;
use crate::help_functions::{get_dialog_box_child, get_list_store, ColumnsExcludedDirectory, ColumnsIncludedDirectory};
use crate::help_functions::{get_list_store, ColumnsExcludedDirectory, ColumnsIncludedDirectory};
pub fn connect_selection_of_directories(gui_data: &GuiData) {
// Add manually directory
@ -86,9 +86,9 @@ fn add_chosen_directories(window_main: &Window, tree_view: &TreeView, excluded_i
flg!("include_folders_dialog_title")
};
let file_chooser = gtk::FileChooserDialog::builder()
let file_chooser = gtk4::FileChooserDialog::builder()
.title(&folders_to)
.action(gtk::FileChooserAction::SelectFolder)
.action(gtk4::FileChooserAction::SelectFolder)
.transient_for(window_main)
.modal(true)
.build();
@ -96,26 +96,22 @@ fn add_chosen_directories(window_main: &Window, tree_view: &TreeView, excluded_i
file_chooser.add_button(&flg!("general_close_button"), ResponseType::Cancel);
file_chooser.set_select_multiple(true);
file_chooser.show_all();
file_chooser.show();
let tree_view = tree_view.clone();
file_chooser.connect_response(move |file_chooser, response_type| {
if response_type == gtk::ResponseType::Ok {
let folders: Vec<PathBuf> = file_chooser.filenames();
// GTK 4
// folders = Vec::new();
// if let Some(g_files) = file_chooser.files() {
// for index in 0..g_files.n_items() {
// let file = &g_files.item(index);
// if let Some(file) = file {
// println!("{:?}", file);
// let ss = file.clone().downcast::<gtk4::gio::File>().unwrap();
// if let Some(path_buf) = ss.path() {
// folders.push(path_buf);
// }
// }
// }
// }
if response_type == gtk4::ResponseType::Ok {
let mut folders: Vec<PathBuf> = Vec::new();
let g_files = file_chooser.files();
for index in 0..g_files.n_items() {
let file = &g_files.item(index);
if let Some(file) = file {
let ss = file.clone().downcast::<gtk4::gio::File>().unwrap();
if let Some(path_buf) = ss.path() {
folders.push(path_buf);
}
}
}
let list_store = get_list_store(&tree_view);
@ -139,23 +135,28 @@ fn add_chosen_directories(window_main: &Window, tree_view: &TreeView, excluded_i
}
fn add_manually_directories(window_main: &Window, tree_view: &TreeView, excluded_items: bool) {
let dialog = gtk::Dialog::builder()
let dialog = gtk4::Dialog::builder()
.title(&flg!("include_manually_directories_dialog_title"))
.transient_for(window_main)
.modal(true)
.build();
dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.set_default_size(300, 0);
let entry: gtk4::Entry = gtk4::Entry::new();
let added_button = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
let entry: gtk::Entry = gtk::Entry::new();
let parent = added_button.parent().unwrap().parent().unwrap().downcast::<gtk4::Box>().unwrap(); // TODO Hack, but not so ugly as before
parent.set_orientation(Orientation::Vertical);
parent.insert_child_after(&entry, None::<&gtk4::Widget>);
get_dialog_box_child(&dialog).add(&entry);
dialog.show_all();
dialog.show();
let tree_view = tree_view.clone();
dialog.connect_response(move |dialog, response_type| {
if response_type == gtk::ResponseType::Ok {
if response_type == gtk4::ResponseType::Ok {
let text = entry.text().to_string().trim().to_string();
#[cfg(target_family = "windows")]

View file

@ -2,9 +2,9 @@ use std::collections::BTreeMap;
use std::default::Default;
use directories_next::ProjectDirs;
use gtk::builders::LabelBuilder;
use gtk::prelude::*;
use gtk::{ResponseType, Window};
use gtk4::builders::LabelBuilder;
use gtk4::prelude::*;
use gtk4::{ResponseType, Window};
use image::imageops::FilterType;
use image_hasher::HashAlg;
@ -27,9 +27,9 @@ pub fn connect_settings(gui_data: &GuiData) {
let window_settings = gui_data.settings.window_settings.clone();
window_settings.connect_delete_event(move |window, _| {
window_settings.connect_close_request(move |window| {
window.hide();
gtk::Inhibit(true)
gtk4::Inhibit(true)
});
}
@ -97,7 +97,7 @@ pub fn connect_settings(gui_data: &GuiData) {
button_settings_duplicates_clear_cache.connect_clicked(move |_| {
let dialog = create_clear_cache_dialog(flg!("cache_clear_duplicates_title"), &settings_window);
dialog.show_all();
dialog.show();
let text_view_errors = text_view_errors.clone();
let entry_settings_cache_file_minimal_size = entry_settings_cache_file_minimal_size.clone();
@ -125,7 +125,7 @@ pub fn connect_settings(gui_data: &GuiData) {
}
messages.messages.push(flg!("cache_properly_cleared"));
text_view_errors.buffer().unwrap().set_text(messages.create_messages_text().as_str());
text_view_errors.buffer().set_text(messages.create_messages_text().as_str());
}
}
dialog.close();
@ -139,7 +139,7 @@ pub fn connect_settings(gui_data: &GuiData) {
button_settings_similar_images_clear_cache.connect_clicked(move |_| {
let dialog = create_clear_cache_dialog(flg!("cache_clear_similar_images_title"), &settings_window);
dialog.show_all();
dialog.show();
let text_view_errors = text_view_errors.clone();
@ -165,7 +165,7 @@ pub fn connect_settings(gui_data: &GuiData) {
}
messages.messages.push(flg!("cache_properly_cleared"));
text_view_errors.buffer().unwrap().set_text(messages.create_messages_text().as_str());
text_view_errors.buffer().set_text(messages.create_messages_text().as_str());
}
dialog.close();
});
@ -178,7 +178,7 @@ pub fn connect_settings(gui_data: &GuiData) {
button_settings_similar_videos_clear_cache.connect_clicked(move |_| {
let dialog = create_clear_cache_dialog(flg!("cache_clear_similar_videos_title"), &settings_window);
dialog.show_all();
dialog.show();
let text_view_errors = text_view_errors.clone();
@ -190,7 +190,7 @@ pub fn connect_settings(gui_data: &GuiData) {
}
messages.messages.push(flg!("cache_properly_cleared"));
text_view_errors.buffer().unwrap().set_text(messages.create_messages_text().as_str());
text_view_errors.buffer().set_text(messages.create_messages_text().as_str());
}
dialog.close();
});
@ -199,8 +199,8 @@ pub fn connect_settings(gui_data: &GuiData) {
}
}
fn create_clear_cache_dialog(title_str: String, window_settings: &Window) -> gtk::Dialog {
let dialog = gtk::Dialog::builder().title(&title_str).modal(true).transient_for(window_settings).build();
fn create_clear_cache_dialog(title_str: String, window_settings: &Window) -> gtk4::Dialog {
let dialog = gtk4::Dialog::builder().title(&title_str).modal(true).transient_for(window_settings).build();
dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
@ -210,9 +210,9 @@ fn create_clear_cache_dialog(title_str: String, window_settings: &Window) -> gtk
let label4 = LabelBuilder::new().label(&flg!("cache_clear_message_label_4")).build();
let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label);
internal_box.add(&label2);
internal_box.add(&label3);
internal_box.add(&label4);
internal_box.append(&label);
internal_box.append(&label2);
internal_box.append(&label3);
internal_box.append(&label4);
dialog
}

View file

@ -1,4 +1,4 @@
use gtk::prelude::*;
use gtk4::prelude::*;
use crate::gui_structs::gui_data::GuiData;

View file

@ -1,4 +1,4 @@
use gtk::prelude::*;
use gtk4::prelude::*;
use czkawka_core::similar_images::{get_string_from_similarity, Similarity, SIMILAR_VALUES};

View file

@ -1,41 +1,38 @@
use gtk::prelude::*;
use gtk::TreeViewColumn;
use gtk4::prelude::*;
use gtk4::TreeViewColumn;
use crate::help_functions::*;
// When adding new column do not forget to update translations
pub fn create_tree_view_included_directories(tree_view: &gtk::TreeView) {
pub fn create_tree_view_included_directories(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.set_title("Folders to check");
column.pack_start(&renderer, true);
column.add_attribute(&renderer, "text", ColumnsIncludedDirectory::Path as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsIncludedDirectory::ReferenceButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsIncludedDirectory::ReferenceButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsIncludedDirectory::ReferenceButton as u32, &fixed.to_value());
});
renderer.set_activatable(true);
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.set_title("Reference folder");
column.pack_start(&renderer, true);
column.add_attribute(&renderer, "active", ColumnsIncludedDirectory::ReferenceButton as i32);
tree_view.append_column(&column);
}
pub fn create_tree_view_excluded_directories(tree_view: &gtk::TreeView) {
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
pub fn create_tree_view_excluded_directories(tree_view: &gtk4::TreeView) {
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.add_attribute(&renderer, "text", ColumnsExcludedDirectory::Path as i32);
tree_view.append_column(&column);
@ -43,20 +40,17 @@ pub fn create_tree_view_excluded_directories(tree_view: &gtk::TreeView) {
tree_view.set_headers_visible(false);
}
pub fn create_tree_view_duplicates(tree_view: &gtk::TreeView) {
pub fn create_tree_view_duplicates(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsDuplicates::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsDuplicates::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsDuplicates::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
@ -65,8 +59,8 @@ pub fn create_tree_view_duplicates(tree_view: &gtk::TreeView) {
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();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Size");
column.set_resizable(true);
@ -76,8 +70,8 @@ pub fn create_tree_view_duplicates(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsDuplicates::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("File Name");
column.set_resizable(true);
@ -87,8 +81,8 @@ pub fn create_tree_view_duplicates(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsDuplicates::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -98,8 +92,8 @@ pub fn create_tree_view_duplicates(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsDuplicates::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -112,28 +106,25 @@ pub fn create_tree_view_duplicates(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_empty_folders(tree_view: &gtk::TreeView) {
pub fn create_tree_view_empty_folders(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsEmptyFolders::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsEmptyFolders::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsEmptyFolders::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsEmptyFolders::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Folder Name");
column.set_resizable(true);
@ -142,8 +133,8 @@ pub fn create_tree_view_empty_folders(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsEmptyFolders::Name as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -152,8 +143,8 @@ pub fn create_tree_view_empty_folders(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsEmptyFolders::Path as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -165,28 +156,25 @@ pub fn create_tree_view_empty_folders(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_big_files(tree_view: &gtk::TreeView) {
pub fn create_tree_view_big_files(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsBigFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsBigFiles::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsBigFiles::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsBigFiles::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Size");
column.set_resizable(true);
@ -195,8 +183,8 @@ pub fn create_tree_view_big_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsBigFiles::SizeAsBytes as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("File Name");
column.set_resizable(true);
@ -205,8 +193,8 @@ pub fn create_tree_view_big_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsBigFiles::Name as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -215,8 +203,8 @@ pub fn create_tree_view_big_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsBigFiles::Path as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -228,28 +216,25 @@ pub fn create_tree_view_big_files(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_temporary_files(tree_view: &gtk::TreeView) {
pub fn create_tree_view_temporary_files(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsTemporaryFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsTemporaryFiles::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsTemporaryFiles::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsTemporaryFiles::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("File Name");
column.set_resizable(true);
@ -258,8 +243,8 @@ pub fn create_tree_view_temporary_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsTemporaryFiles::Name as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -268,8 +253,8 @@ pub fn create_tree_view_temporary_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsTemporaryFiles::Path as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -281,28 +266,25 @@ pub fn create_tree_view_temporary_files(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_empty_files(tree_view: &gtk::TreeView) {
pub fn create_tree_view_empty_files(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsEmptyFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsEmptyFiles::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsEmptyFiles::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsEmptyFiles::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("File Name");
column.set_resizable(true);
@ -311,8 +293,8 @@ pub fn create_tree_view_empty_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsEmptyFiles::Name as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -321,8 +303,8 @@ pub fn create_tree_view_empty_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsEmptyFiles::Path as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -334,20 +316,17 @@ pub fn create_tree_view_empty_files(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
pub fn create_tree_view_similar_images(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsSimilarImages::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsSimilarImages::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsSimilarImages::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
@ -356,8 +335,8 @@ pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
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();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Similarity");
column.set_resizable(true);
@ -367,8 +346,8 @@ pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Size");
column.set_resizable(true);
@ -378,8 +357,8 @@ pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Dimensions");
column.set_resizable(true);
@ -389,8 +368,8 @@ pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("File Name");
column.set_resizable(true);
@ -400,8 +379,8 @@ pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -411,8 +390,8 @@ pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -425,20 +404,17 @@ pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_similar_videos(tree_view: &gtk::TreeView) {
pub fn create_tree_view_similar_videos(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsSimilarVideos::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsSimilarVideos::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsSimilarVideos::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
@ -447,8 +423,8 @@ pub fn create_tree_view_similar_videos(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "cell-background", ColumnsSimilarVideos::Color as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Size");
column.set_resizable(true);
@ -458,8 +434,8 @@ pub fn create_tree_view_similar_videos(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSimilarVideos::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("File Name");
column.set_resizable(true);
@ -469,8 +445,8 @@ pub fn create_tree_view_similar_videos(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSimilarVideos::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -480,8 +456,8 @@ pub fn create_tree_view_similar_videos(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSimilarVideos::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -494,20 +470,17 @@ pub fn create_tree_view_similar_videos(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
pub fn create_tree_view_same_music(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsSameMusic::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsSameMusic::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsSameMusic::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
@ -516,8 +489,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
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();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Size");
column.set_resizable(true);
@ -527,8 +500,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("File Name");
column.set_resizable(true);
@ -538,8 +511,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Title");
column.set_resizable(true);
@ -549,8 +522,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Artist");
column.set_resizable(true);
@ -560,8 +533,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Year");
column.set_resizable(true);
@ -571,8 +544,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Bitrate");
column.set_resizable(true);
@ -582,8 +555,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Length");
column.set_resizable(true);
@ -593,8 +566,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Genre");
column.set_resizable(true);
@ -604,8 +577,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -615,8 +588,8 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -629,28 +602,25 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_invalid_symlinks(tree_view: &gtk::TreeView) {
pub fn create_tree_view_invalid_symlinks(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsInvalidSymlinks::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsInvalidSymlinks::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsInvalidSymlinks::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsInvalidSymlinks::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Symlink File Name");
column.set_resizable(true);
@ -659,8 +629,8 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsInvalidSymlinks::Name as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Symlink Folder");
column.set_resizable(true);
@ -669,8 +639,8 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsInvalidSymlinks::Path as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Destination Path");
column.set_resizable(true);
@ -679,8 +649,8 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsInvalidSymlinks::DestinationPath as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Type of Error");
column.set_resizable(true);
@ -689,8 +659,8 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsInvalidSymlinks::TypeOfError as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);
@ -702,28 +672,25 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true);
}
pub fn create_tree_view_broken_files(tree_view: &gtk::TreeView) {
pub fn create_tree_view_broken_files(tree_view: &gtk4::TreeView) {
let model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new();
let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsBrokenFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
let mut fixed = model.get::<bool>(&iter, ColumnsBrokenFiles::SelectionButton as i32);
fixed = !fixed;
model.set_value(&iter, ColumnsBrokenFiles::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
let column = gtk4::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsBrokenFiles::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Name");
column.set_resizable(true);
@ -732,8 +699,8 @@ pub fn create_tree_view_broken_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsBrokenFiles::Name as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Path");
column.set_resizable(true);
@ -742,8 +709,8 @@ pub fn create_tree_view_broken_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsBrokenFiles::Path as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("ErrorType");
column.set_resizable(true);
@ -752,8 +719,8 @@ pub fn create_tree_view_broken_files(tree_view: &gtk::TreeView) {
column.set_sort_column_id(ColumnsBrokenFiles::ErrorType as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new();
let renderer = gtk4::CellRendererText::new();
let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_title("Modification Date");
column.set_resizable(true);

View file

@ -1,17 +1,18 @@
use gdk::gdk_pixbuf::Pixbuf;
use gtk::prelude::*;
use gtk::{Builder, Window};
use gdk4::gdk_pixbuf::Pixbuf;
use gtk4::prelude::*;
use gtk4::{Builder, Button, Orientation, Picture, Window};
use crate::flg;
use crate::help_functions::get_all_boxes_from_widget;
#[derive(Clone)]
pub struct GuiAbout {
pub about_dialog: gtk::AboutDialog,
pub about_dialog: gtk4::AboutDialog,
pub button_repository: gtk::Button,
pub button_donation: gtk::Button,
pub button_instruction: gtk::Button,
pub button_translation: gtk::Button,
pub button_repository: gtk4::Button,
pub button_donation: gtk4::Button,
pub button_instruction: gtk4::Button,
pub button_translation: gtk4::Button,
}
impl GuiAbout {
@ -19,15 +20,15 @@ impl GuiAbout {
let glade_src = include_str!("../../ui/about_dialog.ui").to_string();
let builder = Builder::from_string(glade_src.as_str());
let about_dialog: gtk::AboutDialog = builder.object("about_dialog").unwrap();
let about_dialog: gtk4::AboutDialog = builder.object("about_dialog").unwrap();
about_dialog.set_modal(true);
about_dialog.set_transient_for(Some(window_main));
about_dialog.set_logo(Some(logo));
about_dialog.set_logo(Picture::for_pixbuf(logo).paintable().as_ref());
// Taken from command - "git shortlog -s -n -e" - remember to remove duplicates
// This should be updated only before releasing new version
about_dialog.set_authors(&vec![
about_dialog.set_authors(&[
"Rafał Mikrut",
"Alexis Lefebvre",
"Thomas Andreas Jung",
@ -73,10 +74,20 @@ impl GuiAbout {
"tenninjas",
]);
let button_repository: gtk::Button = builder.object("button_repository").unwrap();
let button_donation: gtk::Button = builder.object("button_donation").unwrap();
let button_instruction: gtk::Button = builder.object("button_instruction").unwrap();
let button_translation: gtk::Button = builder.object("button_translation").unwrap();
let custom_box = get_all_boxes_from_widget(&about_dialog)[2].clone(); // TODO may not be stable enough between GTK versions
let new_box = gtk4::Box::new(Orientation::Horizontal, 5);
let button_repository = Button::builder().label("Repository").build();
let button_donation = Button::builder().label("Donation").build();
let button_instruction = Button::builder().label("Instruction").build();
let button_translation = Button::builder().label("Translation").build();
new_box.append(&button_repository);
new_box.append(&button_donation);
new_box.append(&button_instruction);
new_box.append(&button_translation);
custom_box.append(&new_box);
Self {
about_dialog,
@ -86,6 +97,7 @@ impl GuiAbout {
button_translation,
}
}
pub fn update_language(&self) {
let mut comment_text: String = "2020 - 2022 Rafał Mikrut(qarmin)\n\n".to_string();
comment_text += &flg!("about_window_motto");

View file

@ -1,7 +1,7 @@
use gtk::prelude::*;
use gtk::{Bin, Widget};
use gtk4::prelude::*;
use gtk4::{GestureClick, Widget};
use crate::help_functions::{get_custom_label_from_button_with_image, set_icon_of_button, set_icon_of_menubutton, BottomButtonsEnum};
use crate::help_functions::{get_custom_label_from_widget, set_icon_of_button, BottomButtonsEnum};
use crate::{
flg, CZK_ICON_COMPARE, CZK_ICON_HARDLINK, CZK_ICON_HIDE_DOWN, CZK_ICON_HIDE_UP, CZK_ICON_MOVE, CZK_ICON_SAVE, CZK_ICON_SEARCH, CZK_ICON_SELECT, CZK_ICON_SYMLINK,
CZK_ICON_TRASH,
@ -9,36 +9,43 @@ use crate::{
#[derive(Clone)]
pub struct GuiBottomButtons {
pub buttons_search: gtk::Button,
pub buttons_select: gtk::MenuButton,
pub buttons_delete: gtk::Button,
pub buttons_save: gtk::Button,
pub buttons_symlink: gtk::Button,
pub buttons_hardlink: gtk::Button,
pub buttons_move: gtk::Button,
pub buttons_compare: gtk::Button,
pub buttons_show_errors: gtk::Button,
pub buttons_show_upper_notebook: gtk::Button,
pub buttons_search: gtk4::Button,
pub buttons_select: gtk4::MenuButton,
pub buttons_delete: gtk4::Button,
pub buttons_save: gtk4::Button,
pub buttons_symlink: gtk4::Button,
pub buttons_hardlink: gtk4::Button,
pub buttons_move: gtk4::Button,
pub buttons_compare: gtk4::Button,
pub buttons_show_errors: gtk4::Button,
pub buttons_show_upper_notebook: gtk4::Button,
pub buttons_names: [BottomButtonsEnum; 8],
pub buttons_array: [Widget; 8],
pub gc_buttons_select: gtk4::GestureClick,
}
impl GuiBottomButtons {
pub fn create_from_builder(builder: &gtk::Builder, popover_select: &gtk::Popover) -> Self {
let buttons_search: gtk::Button = builder.object("buttons_search").unwrap();
let buttons_select: gtk::MenuButton = builder.object("buttons_select").unwrap();
let buttons_delete: gtk::Button = builder.object("buttons_delete").unwrap();
let buttons_save: gtk::Button = builder.object("buttons_save").unwrap();
let buttons_symlink: gtk::Button = builder.object("buttons_symlink").unwrap();
let buttons_hardlink: gtk::Button = builder.object("buttons_hardlink").unwrap();
let buttons_move: gtk::Button = builder.object("buttons_move").unwrap();
let buttons_compare: gtk::Button = builder.object("buttons_compare").unwrap();
pub fn create_from_builder(builder: &gtk4::Builder, popover_select: &gtk4::Popover) -> Self {
let buttons_search: gtk4::Button = builder.object("buttons_search").unwrap();
let buttons_select: gtk4::MenuButton = builder.object("buttons_select").unwrap();
let buttons_delete: gtk4::Button = builder.object("buttons_delete").unwrap();
let buttons_save: gtk4::Button = builder.object("buttons_save").unwrap();
let buttons_symlink: gtk4::Button = builder.object("buttons_symlink").unwrap();
let buttons_hardlink: gtk4::Button = builder.object("buttons_hardlink").unwrap();
let buttons_move: gtk4::Button = builder.object("buttons_move").unwrap();
let buttons_compare: gtk4::Button = builder.object("buttons_compare").unwrap();
let buttons_show_errors: gtk::Button = builder.object("buttons_show_errors").unwrap();
let buttons_show_upper_notebook: gtk::Button = builder.object("buttons_show_upper_notebook").unwrap();
let buttons_show_errors: gtk4::Button = builder.object("buttons_show_errors").unwrap();
let buttons_show_upper_notebook: gtk4::Button = builder.object("buttons_show_upper_notebook").unwrap();
let gc_buttons_select: GestureClick = GestureClick::new();
buttons_select.add_controller(&gc_buttons_select);
set_icon_of_button(&buttons_search, CZK_ICON_SEARCH);
set_icon_of_menubutton(&buttons_select, CZK_ICON_SELECT);
set_icon_of_button(&buttons_select, CZK_ICON_SELECT);
set_icon_of_button(&buttons_delete, CZK_ICON_TRASH);
set_icon_of_button(&buttons_save, CZK_ICON_SAVE);
set_icon_of_button(&buttons_symlink, CZK_ICON_SYMLINK);
@ -84,24 +91,17 @@ impl GuiBottomButtons {
buttons_show_upper_notebook,
buttons_names,
buttons_array,
gc_buttons_select,
}
}
pub fn update_language(&self) {
get_custom_label_from_button_with_image(&self.buttons_search.clone().upcast::<Bin>()).set_text(&flg!("bottom_search_button"));
get_custom_label_from_button_with_image(&self.buttons_select.clone().upcast::<Bin>()).set_text(&flg!("bottom_select_button"));
get_custom_label_from_button_with_image(&self.buttons_delete.clone().upcast::<Bin>()).set_text(&flg!("bottom_delete_button"));
get_custom_label_from_button_with_image(&self.buttons_save.clone().upcast::<Bin>()).set_text(&flg!("bottom_save_button"));
get_custom_label_from_button_with_image(&self.buttons_symlink.clone().upcast::<Bin>()).set_text(&flg!("bottom_symlink_button"));
get_custom_label_from_button_with_image(&self.buttons_hardlink.clone().upcast::<Bin>()).set_text(&flg!("bottom_hardlink_button"));
get_custom_label_from_button_with_image(&self.buttons_move.clone().upcast::<Bin>()).set_text(&flg!("bottom_move_button"));
// get_custom_label_from_button_with_image(&self.buttons_search.clone()).set_text(&flg!("bottom_search_button"));
// get_custom_label_from_button_with_image(&self.buttons_select.clone()).set_text(&flg!("bottom_select_button"));
// get_custom_label_from_button_with_image(&self.buttons_delete.clone()).set_text(&flg!("bottom_delete_button"));
// get_custom_label_from_button_with_image(&self.buttons_save.clone()).set_text(&flg!("bottom_save_button"));
// get_custom_label_from_button_with_image(&self.buttons_symlink.clone()).set_text(&flg!("bottom_symlink_button"));
// get_custom_label_from_button_with_image(&self.buttons_hardlink.clone()).set_text(&flg!("bottom_hardlink_button"));
// get_custom_label_from_button_with_image(&self.buttons_move.clone()).set_text(&flg!("bottom_move_button"));
get_custom_label_from_widget(&self.buttons_search.clone()).set_text(&flg!("bottom_search_button"));
get_custom_label_from_widget(&self.buttons_select.clone()).set_text(&flg!("bottom_select_button"));
get_custom_label_from_widget(&self.buttons_delete.clone()).set_text(&flg!("bottom_delete_button"));
get_custom_label_from_widget(&self.buttons_save.clone()).set_text(&flg!("bottom_save_button"));
get_custom_label_from_widget(&self.buttons_symlink.clone()).set_text(&flg!("bottom_symlink_button"));
get_custom_label_from_widget(&self.buttons_hardlink.clone()).set_text(&flg!("bottom_hardlink_button"));
get_custom_label_from_widget(&self.buttons_move.clone()).set_text(&flg!("bottom_move_button"));
self.buttons_search.set_tooltip_text(Some(&flg!("bottom_search_button_tooltip")));
self.buttons_select.set_tooltip_text(Some(&flg!("bottom_select_button_tooltip")));

View file

@ -1,56 +1,56 @@
use crate::help_functions::set_icon_of_button;
use crate::{flg, CZK_ICON_LEFT, CZK_ICON_RIGHT};
use gtk::prelude::*;
use gtk::{Builder, TreePath};
use gtk4::prelude::*;
use gtk4::{Builder, TreePath};
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Clone)]
pub struct GuiCompareImages {
pub window_compare: gtk::Window,
pub window_compare: gtk4::Window,
pub label_group_info: gtk::Label,
pub label_group_info: gtk4::Label,
pub button_go_previous_compare_group: gtk::Button,
pub button_go_next_compare_group: gtk::Button,
pub button_go_previous_compare_group: gtk4::Button,
pub button_go_next_compare_group: gtk4::Button,
pub check_button_left_preview_text: gtk::CheckButton,
pub check_button_right_preview_text: gtk::CheckButton,
pub check_button_left_preview_text: gtk4::CheckButton,
pub check_button_right_preview_text: gtk4::CheckButton,
pub image_compare_left: gtk::Image,
pub image_compare_right: gtk::Image,
pub image_compare_left: gtk4::Image,
pub image_compare_right: gtk4::Image,
pub scrolled_window_compare_choose_images: gtk::ScrolledWindow,
pub scrolled_window_compare_choose_images: gtk4::ScrolledWindow,
pub shared_numbers_of_groups: Rc<RefCell<u32>>,
pub shared_current_of_groups: Rc<RefCell<u32>>,
pub shared_current_path: Rc<RefCell<Option<TreePath>>>,
pub shared_image_cache: Rc<RefCell<Vec<(String, String, gtk::Image, gtk::Image, gtk::TreePath)>>>,
pub shared_using_for_preview: Rc<RefCell<(Option<gtk::TreePath>, Option<gtk::TreePath>)>>,
pub shared_image_cache: Rc<RefCell<Vec<(String, String, gtk4::Image, gtk4::Image, gtk4::TreePath)>>>,
pub shared_using_for_preview: Rc<RefCell<(Option<gtk4::TreePath>, Option<gtk4::TreePath>)>>,
}
impl GuiCompareImages {
pub fn create_from_builder(window_main: &gtk::Window) -> Self {
pub fn create_from_builder(window_main: &gtk4::Window) -> Self {
let glade_src = include_str!("../../ui/compare_images.ui").to_string();
let builder = Builder::from_string(glade_src.as_str());
let window_compare: gtk::Window = builder.object("window_compare").unwrap();
window_compare.set_title(&flg!("window_compare_images"));
let window_compare: gtk4::Window = builder.object("window_compare").unwrap();
window_compare.set_title(Some(&flg!("window_compare_images")));
window_compare.set_modal(true);
window_compare.set_transient_for(Some(window_main));
let label_group_info: gtk::Label = builder.object("label_group_info").unwrap();
let label_group_info: gtk4::Label = builder.object("label_group_info").unwrap();
let button_go_previous_compare_group: gtk::Button = builder.object("button_go_previous_compare_group").unwrap();
let button_go_next_compare_group: gtk::Button = builder.object("button_go_next_compare_group").unwrap();
let button_go_previous_compare_group: gtk4::Button = builder.object("button_go_previous_compare_group").unwrap();
let button_go_next_compare_group: gtk4::Button = builder.object("button_go_next_compare_group").unwrap();
let check_button_left_preview_text: gtk::CheckButton = builder.object("check_button_left_preview_text").unwrap();
let check_button_right_preview_text: gtk::CheckButton = builder.object("check_button_right_preview_text").unwrap();
let check_button_left_preview_text: gtk4::CheckButton = builder.object("check_button_left_preview_text").unwrap();
let check_button_right_preview_text: gtk4::CheckButton = builder.object("check_button_right_preview_text").unwrap();
let image_compare_left: gtk::Image = builder.object("image_compare_left").unwrap();
let image_compare_right: gtk::Image = builder.object("image_compare_right").unwrap();
let image_compare_left: gtk4::Image = builder.object("image_compare_left").unwrap();
let image_compare_right: gtk4::Image = builder.object("image_compare_right").unwrap();
let scrolled_window_compare_choose_images: gtk::ScrolledWindow = builder.object("scrolled_window_compare_choose_images").unwrap();
let scrolled_window_compare_choose_images: gtk4::ScrolledWindow = builder.object("scrolled_window_compare_choose_images").unwrap();
let shared_numbers_of_groups = Rc::new(RefCell::new(0));
let shared_current_of_groups = Rc::new(RefCell::new(0));
@ -79,6 +79,6 @@ impl GuiCompareImages {
}
}
pub fn update_language(&self) {
self.window_compare.set_title(&flg!("window_compare_images"));
self.window_compare.set_title(Some(&flg!("window_compare_images")));
}
}

View file

@ -4,9 +4,9 @@ use std::rc::Rc;
use crossbeam_channel::bounded;
use czkawka_core::bad_extensions::BadExtensions;
use gdk::gdk_pixbuf::Pixbuf;
use gtk::prelude::*;
use gtk::Builder;
use gdk4::gdk_pixbuf::Pixbuf;
use gtk4::prelude::*;
use gtk4::Builder;
use crate::flg;
use czkawka_core::big_file::BigFile;
@ -60,7 +60,7 @@ pub struct GuiData {
pub builder: Builder,
// Windows
pub window_main: gtk::Window,
pub window_main: gtk4::Window,
pub main_notebook: GuiMainNotebook,
pub upper_notebook: GuiUpperNotebook,
@ -94,11 +94,11 @@ pub struct GuiData {
pub preview_path: Rc<RefCell<String>>,
//// Entry
pub entry_info: gtk::Entry,
pub entry_info: gtk4::Entry,
//// Bottom
pub text_view_errors: gtk::TextView,
pub scrolled_window_errors: gtk::ScrolledWindow,
pub text_view_errors: gtk4::TextView,
pub scrolled_window_errors: gtk4::ScrolledWindow,
// Used for sending stop signal to thread
pub stop_sender: crossbeam_channel::Sender<()>,
@ -106,18 +106,18 @@ pub struct GuiData {
}
impl GuiData {
pub fn new_with_application(application: &gtk::Application) -> Self {
pub fn new_with_application(application: &gtk4::Application) -> Self {
//// Loading glade file content and build with it help UI
let glade_src = include_str!("../../ui/main_window.ui").to_string();
let builder = Builder::from_string(glade_src.as_str());
//// Windows
let window_main: gtk::Window = builder.object("window_main").unwrap();
window_main.set_title(&flg!("window_main_title"));
window_main.show_all();
let window_main: gtk4::Window = builder.object("window_main").unwrap();
window_main.set_title(Some(&flg!("window_main_title")));
window_main.show();
let pixbuf = Pixbuf::from_read(std::io::BufReader::new(&ICON_ABOUT[..])).unwrap();
window_main.set_icon(Some(&pixbuf));
// window_main.set_icon(Some(&pixbuf)); // TODO
window_main.set_application(Some(application));
@ -169,12 +169,12 @@ impl GuiData {
let preview_path: Rc<RefCell<_>> = Rc::new(RefCell::new("".to_string()));
//// Entry
let entry_info: gtk::Entry = builder.object("entry_info").unwrap();
let entry_info: gtk4::Entry = builder.object("entry_info").unwrap();
//// Bottom
let text_view_errors: gtk::TextView = builder.object("text_view_errors").unwrap();
let scrolled_window_errors: gtk::ScrolledWindow = builder.object("scrolled_window_errors").unwrap();
scrolled_window_errors.show_all(); // Not sure why needed, but without it text view errors sometimes hide itself
let text_view_errors: gtk4::TextView = builder.object("text_view_errors").unwrap();
let scrolled_window_errors: gtk4::ScrolledWindow = builder.object("scrolled_window_errors").unwrap();
scrolled_window_errors.show(); // Not sure why needed, but without it text view errors sometimes hide itself
// Used for sending stop signal to thread
let (stop_sender, stop_receiver): (crossbeam_channel::Sender<()>, crossbeam_channel::Receiver<()>) = bounded(1);
@ -215,7 +215,7 @@ impl GuiData {
}
pub fn update_language(&self) {
self.window_main.set_title(&flg!("window_main_title"));
self.window_main.set_title(Some(&flg!("window_main_title")));
self.main_notebook.update_language();
self.upper_notebook.update_language();

View file

@ -1,18 +1,18 @@
use gtk::prelude::*;
use gtk4::prelude::*;
use crate::help_functions::set_icon_of_button;
use crate::{flg, CZK_ICON_INFO, CZK_ICON_SETTINGS};
#[derive(Clone)]
pub struct GuiHeader {
pub button_settings: gtk::Button,
pub button_app_info: gtk::Button,
pub button_settings: gtk4::Button,
pub button_app_info: gtk4::Button,
}
impl GuiHeader {
pub fn create_from_builder(builder: &gtk::Builder) -> Self {
let button_settings: gtk::Button = builder.object("button_settings").unwrap();
let button_app_info: gtk::Button = builder.object("button_app_info").unwrap();
pub fn create_from_builder(builder: &gtk4::Builder) -> Self {
let button_settings: gtk4::Button = builder.object("button_settings").unwrap();
let button_app_info: gtk4::Button = builder.object("button_app_info").unwrap();
set_icon_of_button(&button_settings, CZK_ICON_SETTINGS);
set_icon_of_button(&button_app_info, CZK_ICON_INFO);

View file

@ -1,254 +1,241 @@
use czkawka_core::common_dir_traversal::CheckingMethod;
use czkawka_core::localizer_core::{fnc_get_similarity_minimal, fnc_get_similarity_very_high};
use gtk::prelude::*;
use gtk::{EventControllerKey, TreeView};
use gtk4::prelude::*;
use gtk4::{EventControllerKey, GestureClick, TreeView};
use czkawka_core::similar_images::{get_string_from_similarity, Similarity, SIMILAR_VALUES};
use crate::flg;
use crate::help_combo_box::{DUPLICATES_CHECK_METHOD_COMBO_BOX, IMAGES_HASH_SIZE_COMBO_BOX};
use crate::help_functions::get_all_children;
use crate::notebook_enums::{NotebookMainEnum, NUMBER_OF_NOTEBOOK_MAIN_TABS};
#[derive(Clone)]
pub struct GuiMainNotebook {
pub notebook_main: gtk::Notebook,
pub notebook_main: gtk4::Notebook,
pub scrolled_window_duplicate_finder: gtk::ScrolledWindow,
pub scrolled_window_empty_folder_finder: gtk::ScrolledWindow,
pub scrolled_window_empty_files_finder: gtk::ScrolledWindow,
pub scrolled_window_temporary_files_finder: gtk::ScrolledWindow,
pub scrolled_window_big_files_finder: gtk::ScrolledWindow,
pub scrolled_window_similar_images_finder: gtk::ScrolledWindow,
pub scrolled_window_similar_videos_finder: gtk::ScrolledWindow,
pub scrolled_window_same_music_finder: gtk::ScrolledWindow,
pub scrolled_window_invalid_symlinks: gtk::ScrolledWindow,
pub scrolled_window_broken_files: gtk::ScrolledWindow,
pub scrolled_window_bad_extensions: gtk::ScrolledWindow,
pub scrolled_window_duplicate_finder: gtk4::ScrolledWindow,
pub scrolled_window_empty_folder_finder: gtk4::ScrolledWindow,
pub scrolled_window_empty_files_finder: gtk4::ScrolledWindow,
pub scrolled_window_temporary_files_finder: gtk4::ScrolledWindow,
pub scrolled_window_big_files_finder: gtk4::ScrolledWindow,
pub scrolled_window_similar_images_finder: gtk4::ScrolledWindow,
pub scrolled_window_similar_videos_finder: gtk4::ScrolledWindow,
pub scrolled_window_same_music_finder: gtk4::ScrolledWindow,
pub scrolled_window_invalid_symlinks: gtk4::ScrolledWindow,
pub scrolled_window_broken_files: gtk4::ScrolledWindow,
pub scrolled_window_bad_extensions: gtk4::ScrolledWindow,
pub tree_view_duplicate_finder: gtk::TreeView,
pub tree_view_empty_folder_finder: gtk::TreeView,
pub tree_view_empty_files_finder: gtk::TreeView,
pub tree_view_temporary_files_finder: gtk::TreeView,
pub tree_view_big_files_finder: gtk::TreeView,
pub tree_view_similar_images_finder: gtk::TreeView,
pub tree_view_similar_videos_finder: gtk::TreeView,
pub tree_view_same_music_finder: gtk::TreeView,
pub tree_view_invalid_symlinks: gtk::TreeView,
pub tree_view_broken_files: gtk::TreeView,
pub tree_view_bad_extensions: gtk::TreeView,
pub tree_view_duplicate_finder: gtk4::TreeView,
pub tree_view_empty_folder_finder: gtk4::TreeView,
pub tree_view_empty_files_finder: gtk4::TreeView,
pub tree_view_temporary_files_finder: gtk4::TreeView,
pub tree_view_big_files_finder: gtk4::TreeView,
pub tree_view_similar_images_finder: gtk4::TreeView,
pub tree_view_similar_videos_finder: gtk4::TreeView,
pub tree_view_same_music_finder: gtk4::TreeView,
pub tree_view_invalid_symlinks: gtk4::TreeView,
pub tree_view_broken_files: gtk4::TreeView,
pub tree_view_bad_extensions: gtk4::TreeView,
// TODO, in GTK4 this can be changed to e.g. add_controller which is not 100% compatible with this - https://discourse.gnome.org/t/how-to-convert-code-to-use-eventcontrollerkey/8198/2
pub evk_tree_view_duplicate_finder: gtk::EventControllerKey,
pub evk_tree_view_empty_folder_finder: gtk::EventControllerKey,
pub evk_tree_view_empty_files_finder: gtk::EventControllerKey,
pub evk_tree_view_temporary_files_finder: gtk::EventControllerKey,
pub evk_tree_view_big_files_finder: gtk::EventControllerKey,
pub evk_tree_view_similar_images_finder: gtk::EventControllerKey,
pub evk_tree_view_similar_videos_finder: gtk::EventControllerKey,
pub evk_tree_view_same_music_finder: gtk::EventControllerKey,
pub evk_tree_view_invalid_symlinks: gtk::EventControllerKey,
pub evk_tree_view_broken_files: gtk::EventControllerKey,
pub evk_tree_view_bad_extensions: gtk::EventControllerKey,
pub evk_tree_view_duplicate_finder: gtk4::EventControllerKey,
pub evk_tree_view_empty_folder_finder: gtk4::EventControllerKey,
pub evk_tree_view_empty_files_finder: gtk4::EventControllerKey,
pub evk_tree_view_temporary_files_finder: gtk4::EventControllerKey,
pub evk_tree_view_big_files_finder: gtk4::EventControllerKey,
pub evk_tree_view_similar_images_finder: gtk4::EventControllerKey,
pub evk_tree_view_similar_videos_finder: gtk4::EventControllerKey,
pub evk_tree_view_same_music_finder: gtk4::EventControllerKey,
pub evk_tree_view_invalid_symlinks: gtk4::EventControllerKey,
pub evk_tree_view_broken_files: gtk4::EventControllerKey,
pub evk_tree_view_bad_extensions: gtk4::EventControllerKey,
// pub gc_tree_view_duplicate_finder: gtk4::GestureClick,
// pub gc_tree_view_empty_folder_finder: gtk::GestureClick,
// pub gc_tree_view_empty_files_finder: gtk::GestureClick,
// pub gc_tree_view_temporary_files_finder: gtk::GestureClick,
// pub gc_tree_view_big_files_finder: gtk::GestureClick,
// pub gc_tree_view_similar_images_finder: gtk::GestureClick,
// pub gc_tree_view_similar_videos_finder: gtk::GestureClick,
// pub gc_tree_view_same_music_finder: gtk::GestureClick,
// pub gc_tree_view_invalid_symlinks: gtk::GestureClick,
// pub gc_tree_view_broken_files: gtk::GestureClick,
// pub gc_tree_view_bad_extensions: gtk::GestureClick,
pub gc_tree_view_duplicate_finder: gtk4::GestureClick,
pub gc_tree_view_empty_folder_finder: gtk4::GestureClick,
pub gc_tree_view_empty_files_finder: gtk4::GestureClick,
pub gc_tree_view_temporary_files_finder: gtk4::GestureClick,
pub gc_tree_view_big_files_finder: gtk4::GestureClick,
pub gc_tree_view_similar_images_finder: gtk4::GestureClick,
pub gc_tree_view_similar_videos_finder: gtk4::GestureClick,
pub gc_tree_view_same_music_finder: gtk4::GestureClick,
pub gc_tree_view_invalid_symlinks: gtk4::GestureClick,
pub gc_tree_view_broken_files: gtk4::GestureClick,
pub gc_tree_view_bad_extensions: gtk4::GestureClick,
// General
// Duplicate
pub combo_box_duplicate_check_method: gtk::ComboBoxText,
pub combo_box_duplicate_hash_type: gtk::ComboBoxText,
pub label_duplicate_check_method: gtk::Label,
pub label_duplicate_hash_type: gtk::Label,
pub check_button_duplicate_case_sensitive_name: gtk::CheckButton,
pub combo_box_duplicate_check_method: gtk4::ComboBoxText,
pub combo_box_duplicate_hash_type: gtk4::ComboBoxText,
pub label_duplicate_check_method: gtk4::Label,
pub label_duplicate_hash_type: gtk4::Label,
pub check_button_duplicate_case_sensitive_name: gtk4::CheckButton,
pub image_preview_duplicates: gtk::Image,
pub image_preview_duplicates: gtk4::Image,
// Big file
pub label_big_shown_files: gtk::Label,
pub entry_big_files_number: gtk::Entry,
pub label_big_shown_files: gtk4::Label,
pub entry_big_files_number: gtk4::Entry,
// Similar Images
pub scale_similarity_similar_images: gtk::Scale,
pub scale_similarity_similar_images: gtk4::Scale,
pub label_image_resize_algorithm: gtk::Label,
pub label_image_hash_type: gtk::Label,
pub label_image_hash_size: gtk::Label,
pub label_image_resize_algorithm: gtk4::Label,
pub label_image_hash_type: gtk4::Label,
pub label_image_hash_size: gtk4::Label,
pub combo_box_image_resize_algorithm: gtk::ComboBoxText,
pub combo_box_image_hash_algorithm: gtk::ComboBoxText,
pub combo_box_image_hash_size: gtk::ComboBoxText,
pub combo_box_image_resize_algorithm: gtk4::ComboBoxText,
pub combo_box_image_hash_algorithm: gtk4::ComboBoxText,
pub combo_box_image_hash_size: gtk4::ComboBoxText,
pub check_button_image_ignore_same_size: gtk::CheckButton,
pub check_button_video_ignore_same_size: gtk::CheckButton,
pub check_button_image_ignore_same_size: gtk4::CheckButton,
pub check_button_video_ignore_same_size: gtk4::CheckButton,
pub check_button_image_fast_compare: gtk::CheckButton,
pub check_button_image_fast_compare: gtk4::CheckButton,
pub label_image_similarity: gtk::Label,
pub label_image_similarity_max: gtk::Label,
pub label_image_similarity: gtk4::Label,
pub label_image_similarity_max: gtk4::Label,
pub image_preview_similar_images: gtk::Image,
pub label_similar_images_minimal_similarity: gtk::Label,
pub image_preview_similar_images: gtk4::Image,
pub label_similar_images_minimal_similarity: gtk4::Label,
// Video
pub label_video_similarity: gtk::Label,
pub label_video_similarity_min: gtk::Label,
pub label_video_similarity_max: gtk::Label,
pub label_video_similarity: gtk4::Label,
pub label_video_similarity_min: gtk4::Label,
pub label_video_similarity_max: gtk4::Label,
pub scale_similarity_similar_videos: gtk::Scale,
pub scale_similarity_similar_videos: gtk4::Scale,
// Music
pub check_button_music_title: gtk::CheckButton,
pub check_button_music_artist: gtk::CheckButton,
pub check_button_music_year: gtk::CheckButton,
pub check_button_music_bitrate: gtk::CheckButton,
pub check_button_music_genre: gtk::CheckButton,
pub check_button_music_length: gtk::CheckButton,
pub check_button_music_approximate_comparison: gtk::CheckButton,
pub check_button_music_title: gtk4::CheckButton,
pub check_button_music_artist: gtk4::CheckButton,
pub check_button_music_year: gtk4::CheckButton,
pub check_button_music_bitrate: gtk4::CheckButton,
pub check_button_music_genre: gtk4::CheckButton,
pub check_button_music_length: gtk4::CheckButton,
pub check_button_music_approximate_comparison: gtk4::CheckButton,
}
impl GuiMainNotebook {
pub fn create_from_builder(builder: &gtk::Builder) -> Self {
let notebook_main: gtk::Notebook = builder.object("notebook_main").unwrap();
pub fn create_from_builder(builder: &gtk4::Builder) -> Self {
let notebook_main: gtk4::Notebook = builder.object("notebook_main").unwrap();
let scrolled_window_duplicate_finder: gtk::ScrolledWindow = builder.object("scrolled_window_duplicate_finder").unwrap();
let scrolled_window_empty_folder_finder: gtk::ScrolledWindow = builder.object("scrolled_window_empty_folder_finder").unwrap();
let scrolled_window_empty_files_finder: gtk::ScrolledWindow = builder.object("scrolled_window_empty_files_finder").unwrap();
let scrolled_window_temporary_files_finder: gtk::ScrolledWindow = builder.object("scrolled_window_temporary_files_finder").unwrap();
let scrolled_window_big_files_finder: gtk::ScrolledWindow = builder.object("scrolled_window_big_files_finder").unwrap();
let scrolled_window_similar_images_finder: gtk::ScrolledWindow = builder.object("scrolled_window_similar_images_finder").unwrap();
let scrolled_window_similar_videos_finder: gtk::ScrolledWindow = builder.object("scrolled_window_similar_videos_finder").unwrap();
let scrolled_window_same_music_finder: gtk::ScrolledWindow = builder.object("scrolled_window_same_music_finder").unwrap();
let scrolled_window_invalid_symlinks: gtk::ScrolledWindow = builder.object("scrolled_window_invalid_symlinks").unwrap();
let scrolled_window_broken_files: gtk::ScrolledWindow = builder.object("scrolled_window_broken_files").unwrap();
let scrolled_window_bad_extensions: gtk::ScrolledWindow = builder.object("scrolled_window_bad_extensions").unwrap();
let scrolled_window_duplicate_finder: gtk4::ScrolledWindow = builder.object("scrolled_window_duplicate_finder").unwrap();
let scrolled_window_empty_folder_finder: gtk4::ScrolledWindow = builder.object("scrolled_window_empty_folder_finder").unwrap();
let scrolled_window_empty_files_finder: gtk4::ScrolledWindow = builder.object("scrolled_window_empty_files_finder").unwrap();
let scrolled_window_temporary_files_finder: gtk4::ScrolledWindow = builder.object("scrolled_window_temporary_files_finder").unwrap();
let scrolled_window_big_files_finder: gtk4::ScrolledWindow = builder.object("scrolled_window_big_files_finder").unwrap();
let scrolled_window_similar_images_finder: gtk4::ScrolledWindow = builder.object("scrolled_window_similar_images_finder").unwrap();
let scrolled_window_similar_videos_finder: gtk4::ScrolledWindow = builder.object("scrolled_window_similar_videos_finder").unwrap();
let scrolled_window_same_music_finder: gtk4::ScrolledWindow = builder.object("scrolled_window_same_music_finder").unwrap();
let scrolled_window_invalid_symlinks: gtk4::ScrolledWindow = builder.object("scrolled_window_invalid_symlinks").unwrap();
let scrolled_window_broken_files: gtk4::ScrolledWindow = builder.object("scrolled_window_broken_files").unwrap();
let scrolled_window_bad_extensions: gtk4::ScrolledWindow = builder.object("scrolled_window_bad_extensions").unwrap();
let tree_view_duplicate_finder: gtk::TreeView = TreeView::new();
let tree_view_duplicate_finder: gtk4::TreeView = TreeView::new();
tree_view_duplicate_finder.set_widget_name("PIERD");
let tree_view_empty_folder_finder: gtk::TreeView = TreeView::new();
let tree_view_empty_files_finder: gtk::TreeView = TreeView::new();
let tree_view_temporary_files_finder: gtk::TreeView = TreeView::new();
let tree_view_big_files_finder: gtk::TreeView = TreeView::new();
let tree_view_similar_images_finder: gtk::TreeView = TreeView::new();
let tree_view_similar_videos_finder: gtk::TreeView = TreeView::new();
let tree_view_same_music_finder: gtk::TreeView = TreeView::new();
let tree_view_invalid_symlinks: gtk::TreeView = TreeView::new();
let tree_view_broken_files: gtk::TreeView = TreeView::new();
let tree_view_bad_extensions: gtk::TreeView = TreeView::new();
let tree_view_empty_folder_finder: gtk4::TreeView = TreeView::new();
let tree_view_empty_files_finder: gtk4::TreeView = TreeView::new();
let tree_view_temporary_files_finder: gtk4::TreeView = TreeView::new();
let tree_view_big_files_finder: gtk4::TreeView = TreeView::new();
let tree_view_similar_images_finder: gtk4::TreeView = TreeView::new();
let tree_view_similar_videos_finder: gtk4::TreeView = TreeView::new();
let tree_view_same_music_finder: gtk4::TreeView = TreeView::new();
let tree_view_invalid_symlinks: gtk4::TreeView = TreeView::new();
let tree_view_broken_files: gtk4::TreeView = TreeView::new();
let tree_view_bad_extensions: gtk4::TreeView = TreeView::new();
let evk_tree_view_duplicate_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_duplicate_finder);
let evk_tree_view_empty_folder_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_empty_folder_finder);
let evk_tree_view_empty_files_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_empty_files_finder);
let evk_tree_view_temporary_files_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_temporary_files_finder);
let evk_tree_view_big_files_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_big_files_finder);
let evk_tree_view_similar_images_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_similar_images_finder);
let evk_tree_view_similar_videos_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_similar_videos_finder);
let evk_tree_view_same_music_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_same_music_finder);
let evk_tree_view_invalid_symlinks: gtk::EventControllerKey = EventControllerKey::new(&tree_view_invalid_symlinks);
let evk_tree_view_broken_files: gtk::EventControllerKey = EventControllerKey::new(&tree_view_broken_files);
let evk_tree_view_bad_extensions: gtk::EventControllerKey = EventControllerKey::new(&tree_view_bad_extensions);
let evk_tree_view_duplicate_finder: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_duplicate_finder.add_controller(&evk_tree_view_duplicate_finder);
let evk_tree_view_empty_folder_finder: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_empty_folder_finder.add_controller(&evk_tree_view_empty_folder_finder);
let evk_tree_view_empty_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_empty_files_finder.add_controller(&evk_tree_view_empty_files_finder);
let evk_tree_view_temporary_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_temporary_files_finder.add_controller(&evk_tree_view_temporary_files_finder);
let evk_tree_view_big_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_big_files_finder.add_controller(&evk_tree_view_big_files_finder);
let evk_tree_view_similar_images_finder: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_similar_images_finder.add_controller(&evk_tree_view_similar_images_finder);
let evk_tree_view_similar_videos_finder: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_similar_videos_finder.add_controller(&evk_tree_view_similar_videos_finder);
let evk_tree_view_same_music_finder: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_same_music_finder.add_controller(&evk_tree_view_same_music_finder);
let evk_tree_view_invalid_symlinks: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_invalid_symlinks.add_controller(&evk_tree_view_invalid_symlinks);
let evk_tree_view_broken_files: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_broken_files.add_controller(&evk_tree_view_broken_files);
let evk_tree_view_bad_extensions: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_bad_extensions.add_controller(&evk_tree_view_bad_extensions);
// TODO GTK 4
// let evk_tree_view_duplicate_finder: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_duplicate_finder.add_controller(&evk_tree_view_duplicate_finder);
// let evk_tree_view_empty_folder_finder: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_empty_folder_finder.add_controller(&evk_tree_view_empty_folder_finder);
// let evk_tree_view_empty_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_empty_files_finder.add_controller(&evk_tree_view_empty_files_finder);
// let evk_tree_view_temporary_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_temporary_files_finder.add_controller(&evk_tree_view_temporary_files_finder);
// let evk_tree_view_big_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_big_files_finder.add_controller(&evk_tree_view_big_files_finder);
// let evk_tree_view_similar_images_finder: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_similar_images_finder.add_controller(&evk_tree_view_similar_images_finder);
// let evk_tree_view_similar_videos_finder: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_similar_videos_finder.add_controller(&evk_tree_view_similar_videos_finder);
// let evk_tree_view_same_music_finder: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_same_music_finder.add_controller(&evk_tree_view_same_music_finder);
// let evk_tree_view_invalid_symlinks: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_invalid_symlinks.add_controller(&evk_tree_view_invalid_symlinks);
// let evk_tree_view_broken_files: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_broken_files.add_controller(&evk_tree_view_broken_files);
// let evk_tree_view_bad_extensions: gtk4::EventControllerKey = EventControllerKey::new();
// tree_view_bad_extensions.add_controller(&evk_tree_view_bad_extensions);
let gc_tree_view_duplicate_finder: gtk4::GestureClick = GestureClick::new();
tree_view_duplicate_finder.add_controller(&gc_tree_view_duplicate_finder);
let gc_tree_view_empty_folder_finder: gtk4::GestureClick = GestureClick::new();
tree_view_empty_folder_finder.add_controller(&gc_tree_view_empty_folder_finder);
let gc_tree_view_empty_files_finder: gtk4::GestureClick = GestureClick::new();
tree_view_empty_files_finder.add_controller(&gc_tree_view_empty_files_finder);
let gc_tree_view_temporary_files_finder: gtk4::GestureClick = GestureClick::new();
tree_view_temporary_files_finder.add_controller(&gc_tree_view_temporary_files_finder);
let gc_tree_view_big_files_finder: gtk4::GestureClick = GestureClick::new();
tree_view_big_files_finder.add_controller(&gc_tree_view_big_files_finder);
let gc_tree_view_similar_images_finder: gtk4::GestureClick = GestureClick::new();
tree_view_similar_images_finder.add_controller(&gc_tree_view_similar_images_finder);
let gc_tree_view_similar_videos_finder: gtk4::GestureClick = GestureClick::new();
tree_view_similar_videos_finder.add_controller(&gc_tree_view_similar_videos_finder);
let gc_tree_view_same_music_finder: gtk4::GestureClick = GestureClick::new();
tree_view_same_music_finder.add_controller(&gc_tree_view_same_music_finder);
let gc_tree_view_invalid_symlinks: gtk4::GestureClick = GestureClick::new();
tree_view_invalid_symlinks.add_controller(&gc_tree_view_invalid_symlinks);
let gc_tree_view_broken_files: gtk4::GestureClick = GestureClick::new();
tree_view_broken_files.add_controller(&gc_tree_view_broken_files);
let gc_tree_view_bad_extensions: gtk4::GestureClick = GestureClick::new();
tree_view_bad_extensions.add_controller(&gc_tree_view_bad_extensions);
// let gc_tree_view_duplicate_finder: gtk4::GestureClick = GestureClick::new();
// tree_view_duplicate_finder.add_controller(&gc_tree_view_duplicate_finder);
// let gc_tree_view_empty_folder_finder: gtk4::GestureClick = GestureClick::new();
// tree_view_empty_folder_finder.add_controller(&gc_tree_view_empty_folder_finder);
// let gc_tree_view_empty_files_finder: gtk4::GestureClick = GestureClick::new();
// tree_view_empty_files_finder.add_controller(&gc_tree_view_empty_files_finder);
// let gc_tree_view_temporary_files_finder: gtk4::GestureClick = GestureClick::new();
// tree_view_temporary_files_finder.add_controller(&gc_tree_view_temporary_files_finder);
// let gc_tree_view_big_files_finder: gtk4::GestureClick = GestureClick::new();
// tree_view_big_files_finder.add_controller(&gc_tree_view_big_files_finder);
// let gc_tree_view_similar_images_finder: gtk4::GestureClick = GestureClick::new();
// tree_view_similar_images_finder.add_controller(&gc_tree_view_similar_images_finder);
// let gc_tree_view_similar_videos_finder: gtk4::GestureClick = GestureClick::new();
// tree_view_similar_videos_finder.add_controller(&gc_tree_view_similar_videos_finder);
// let gc_tree_view_same_music_finder: gtk4::GestureClick = GestureClick::new();
// tree_view_same_music_finder.add_controller(&gc_tree_view_same_music_finder);
// let gc_tree_view_invalid_symlinks: gtk4::GestureClick = GestureClick::new();
// tree_view_invalid_symlinks.add_controller(&gc_tree_view_invalid_symlinks);
// let gc_tree_view_broken_files: gtk4::GestureClick = GestureClick::new();
// tree_view_broken_files.add_controller(&gc_tree_view_broken_files);
// let gc_tree_view_bad_extensions: gtk4::GestureClick = GestureClick::new();
// tree_view_bad_extensions.add_controller(&gc_tree_view_bad_extensions);
let combo_box_duplicate_check_method: gtk4::ComboBoxText = builder.object("combo_box_duplicate_check_method").unwrap();
let combo_box_duplicate_hash_type: gtk4::ComboBoxText = builder.object("combo_box_duplicate_hash_type").unwrap();
let combo_box_duplicate_check_method: gtk::ComboBoxText = builder.object("combo_box_duplicate_check_method").unwrap();
let combo_box_duplicate_hash_type: gtk::ComboBoxText = builder.object("combo_box_duplicate_hash_type").unwrap();
let entry_big_files_number: gtk::Entry = builder.object("entry_big_files_number").unwrap();
let entry_big_files_number: gtk4::Entry = builder.object("entry_big_files_number").unwrap();
//// Check Buttons
let check_button_duplicate_case_sensitive_name: gtk::CheckButton = builder.object("check_button_duplicate_case_sensitive_name").unwrap();
let check_button_music_title: gtk::CheckButton = builder.object("check_button_music_title").unwrap();
let check_button_music_artist: gtk::CheckButton = builder.object("check_button_music_artist").unwrap();
let check_button_music_year: gtk::CheckButton = builder.object("check_button_music_year").unwrap();
let check_button_music_bitrate: gtk::CheckButton = builder.object("check_button_music_bitrate").unwrap();
let check_button_music_genre: gtk::CheckButton = builder.object("check_button_music_genre").unwrap();
let check_button_music_length: gtk::CheckButton = builder.object("check_button_music_length").unwrap();
let check_button_music_approximate_comparison: gtk::CheckButton = builder.object("check_button_music_approximate_comparison").unwrap();
let check_button_duplicate_case_sensitive_name: gtk4::CheckButton = builder.object("check_button_duplicate_case_sensitive_name").unwrap();
let check_button_music_title: gtk4::CheckButton = builder.object("check_button_music_title").unwrap();
let check_button_music_artist: gtk4::CheckButton = builder.object("check_button_music_artist").unwrap();
let check_button_music_year: gtk4::CheckButton = builder.object("check_button_music_year").unwrap();
let check_button_music_bitrate: gtk4::CheckButton = builder.object("check_button_music_bitrate").unwrap();
let check_button_music_genre: gtk4::CheckButton = builder.object("check_button_music_genre").unwrap();
let check_button_music_length: gtk4::CheckButton = builder.object("check_button_music_length").unwrap();
let check_button_music_approximate_comparison: gtk4::CheckButton = builder.object("check_button_music_approximate_comparison").unwrap();
//// Radio Buttons
let scale_similarity_similar_images: gtk::Scale = builder.object("scale_similarity_similar_images").unwrap();
let scale_similarity_similar_videos: gtk::Scale = builder.object("scale_similarity_similar_videos").unwrap();
let scale_similarity_similar_images: gtk4::Scale = builder.object("scale_similarity_similar_images").unwrap();
let scale_similarity_similar_videos: gtk4::Scale = builder.object("scale_similarity_similar_videos").unwrap();
let check_button_image_fast_compare: gtk::CheckButton = builder.object("check_button_image_fast_compare").unwrap();
let check_button_image_fast_compare: gtk4::CheckButton = builder.object("check_button_image_fast_compare").unwrap();
let combo_box_image_resize_algorithm: gtk::ComboBoxText = builder.object("combo_box_image_resize_algorithm").unwrap();
let combo_box_image_hash_algorithm: gtk::ComboBoxText = builder.object("combo_box_image_hash_algorithm").unwrap();
let combo_box_image_hash_size: gtk::ComboBoxText = builder.object("combo_box_image_hash_size").unwrap();
let combo_box_image_resize_algorithm: gtk4::ComboBoxText = builder.object("combo_box_image_resize_algorithm").unwrap();
let combo_box_image_hash_algorithm: gtk4::ComboBoxText = builder.object("combo_box_image_hash_algorithm").unwrap();
let combo_box_image_hash_size: gtk4::ComboBoxText = builder.object("combo_box_image_hash_size").unwrap();
let check_button_image_ignore_same_size: gtk::CheckButton = builder.object("check_button_image_ignore_same_size").unwrap();
let check_button_video_ignore_same_size: gtk::CheckButton = builder.object("check_button_video_ignore_same_size").unwrap();
let check_button_image_ignore_same_size: gtk4::CheckButton = builder.object("check_button_image_ignore_same_size").unwrap();
let check_button_video_ignore_same_size: gtk4::CheckButton = builder.object("check_button_video_ignore_same_size").unwrap();
let label_similar_images_minimal_similarity: gtk::Label = builder.object("label_similar_images_minimal_similarity").unwrap();
let label_similar_images_minimal_similarity: gtk4::Label = builder.object("label_similar_images_minimal_similarity").unwrap();
let label_duplicate_check_method: gtk::Label = builder.object("label_duplicate_check_method").unwrap();
let label_duplicate_hash_type: gtk::Label = builder.object("label_duplicate_hash_type").unwrap();
let label_big_shown_files: gtk::Label = builder.object("label_big_shown_files").unwrap();
let label_image_resize_algorithm: gtk::Label = builder.object("label_image_resize_algorithm").unwrap();
let label_image_hash_type: gtk::Label = builder.object("label_image_hash_type").unwrap();
let label_image_hash_size: gtk::Label = builder.object("label_image_hash_size").unwrap();
let label_image_similarity: gtk::Label = builder.object("label_image_similarity").unwrap();
let label_image_similarity_max: gtk::Label = builder.object("label_image_similarity_max").unwrap();
let label_video_similarity: gtk::Label = builder.object("label_video_similarity").unwrap();
let label_video_similarity_min: gtk::Label = builder.object("label_video_similarity_min").unwrap();
let label_video_similarity_max: gtk::Label = builder.object("label_video_similarity_max").unwrap();
let label_duplicate_check_method: gtk4::Label = builder.object("label_duplicate_check_method").unwrap();
let label_duplicate_hash_type: gtk4::Label = builder.object("label_duplicate_hash_type").unwrap();
let label_big_shown_files: gtk4::Label = builder.object("label_big_shown_files").unwrap();
let label_image_resize_algorithm: gtk4::Label = builder.object("label_image_resize_algorithm").unwrap();
let label_image_hash_type: gtk4::Label = builder.object("label_image_hash_type").unwrap();
let label_image_hash_size: gtk4::Label = builder.object("label_image_hash_size").unwrap();
let label_image_similarity: gtk4::Label = builder.object("label_image_similarity").unwrap();
let label_image_similarity_max: gtk4::Label = builder.object("label_image_similarity_max").unwrap();
let label_video_similarity: gtk4::Label = builder.object("label_video_similarity").unwrap();
let label_video_similarity_min: gtk4::Label = builder.object("label_video_similarity_min").unwrap();
let label_video_similarity_max: gtk4::Label = builder.object("label_video_similarity_max").unwrap();
let image_preview_similar_images: gtk::Image = builder.object("image_preview_similar_images").unwrap();
let image_preview_duplicates: gtk::Image = builder.object("image_preview_duplicates").unwrap();
let image_preview_similar_images: gtk4::Image = builder.object("image_preview_similar_images").unwrap();
let image_preview_duplicates: gtk4::Image = builder.object("image_preview_duplicates").unwrap();
Self {
notebook_main,
@ -318,6 +305,17 @@ impl GuiMainNotebook {
check_button_image_fast_compare,
check_button_duplicate_case_sensitive_name,
evk_tree_view_bad_extensions,
gc_tree_view_duplicate_finder,
gc_tree_view_empty_folder_finder,
gc_tree_view_empty_files_finder,
gc_tree_view_temporary_files_finder,
gc_tree_view_big_files_finder,
gc_tree_view_similar_images_finder,
gc_tree_view_similar_videos_finder,
gc_tree_view_same_music_finder,
gc_tree_view_invalid_symlinks,
gc_tree_view_broken_files,
gc_tree_view_bad_extensions,
}
}
@ -338,14 +336,14 @@ impl GuiMainNotebook {
}
pub fn update_language(&self) {
self.check_button_duplicate_case_sensitive_name.set_label(&flg!("duplicate_case_sensitive_name"));
self.check_button_music_title.set_label(&flg!("music_title_checkbox"));
self.check_button_music_artist.set_label(&flg!("music_artist_checkbox"));
self.check_button_music_year.set_label(&flg!("music_year_checkbox"));
self.check_button_music_bitrate.set_label(&flg!("music_bitrate_checkbox"));
self.check_button_music_genre.set_label(&flg!("music_genre_checkbox"));
self.check_button_music_length.set_label(&flg!("music_length_checkbox"));
self.check_button_music_approximate_comparison.set_label(&flg!("music_comparison_checkbox"));
self.check_button_duplicate_case_sensitive_name.set_label(Some(&flg!("duplicate_case_sensitive_name")));
self.check_button_music_title.set_label(Some(&flg!("music_title_checkbox")));
self.check_button_music_artist.set_label(Some(&flg!("music_artist_checkbox")));
self.check_button_music_year.set_label(Some(&flg!("music_year_checkbox")));
self.check_button_music_bitrate.set_label(Some(&flg!("music_bitrate_checkbox")));
self.check_button_music_genre.set_label(Some(&flg!("music_genre_checkbox")));
self.check_button_music_length.set_label(Some(&flg!("music_length_checkbox")));
self.check_button_music_approximate_comparison.set_label(Some(&flg!("music_comparison_checkbox")));
self.check_button_music_approximate_comparison
.set_tooltip_text(Some(&flg!("music_comparison_checkbox_tooltip")));
@ -382,10 +380,10 @@ impl GuiMainNotebook {
.set_tooltip_text(Some(&flg!("check_button_general_same_size_tooltip")));
self.check_button_video_ignore_same_size
.set_tooltip_text(Some(&flg!("check_button_general_same_size_tooltip")));
self.check_button_image_ignore_same_size.set_label(&flg!("check_button_general_same_size"));
self.check_button_video_ignore_same_size.set_label(&flg!("check_button_general_same_size"));
self.check_button_image_ignore_same_size.set_label(Some(&flg!("check_button_general_same_size")));
self.check_button_video_ignore_same_size.set_label(Some(&flg!("check_button_general_same_size")));
self.check_button_image_fast_compare.set_label(&flg!("main_notebook_image_fast_compare"));
self.check_button_image_fast_compare.set_label(Some(&flg!("main_notebook_image_fast_compare")));
self.check_button_image_fast_compare
.set_tooltip_text(Some(&flg!("main_notebook_image_fast_compare_tooltip")));
@ -413,10 +411,8 @@ impl GuiMainNotebook {
}
}
let vec_children: Vec<gtk::Widget> = self.notebook_main.children();
// let vec_children: Vec<gtk::Widget> = get_all_children(&self.notebook_main);
// let vec_children: Vec<gtk::Widget> = get_all_children(&vec_children[1]);
let vec_children: Vec<gtk4::Widget> = get_all_children(&self.notebook_main);
let vec_children: Vec<gtk4::Widget> = get_all_children(&vec_children[1]);
// Change name of main notebook tabs
for (main_enum, fl_thing) in [
@ -435,7 +431,7 @@ impl GuiMainNotebook {
self.notebook_main
.tab_label(&vec_children[main_enum])
.unwrap()
.downcast::<gtk::Label>()
.downcast::<gtk4::Label>()
.unwrap()
.set_text(&fl_thing);
}

View file

@ -1,32 +1,32 @@
use gtk::prelude::*;
use gtk::Builder;
use gtk4::prelude::*;
use gtk4::Builder;
use crate::flg;
#[derive(Clone)]
pub struct GuiPopovers {
pub buttons_popover_select_all: gtk::Button,
pub buttons_popover_unselect_all: gtk::Button,
pub buttons_popover_reverse: gtk::Button,
pub buttons_popover_select_all_except_oldest: gtk::Button,
pub buttons_popover_select_all_except_newest: gtk::Button,
pub buttons_popover_select_one_oldest: gtk::Button,
pub buttons_popover_select_one_newest: gtk::Button,
pub buttons_popover_select_custom: gtk::Button,
pub buttons_popover_unselect_custom: gtk::Button,
pub buttons_popover_select_all_images_except_biggest: gtk::Button,
pub buttons_popover_select_all_images_except_smallest: gtk::Button,
pub buttons_popover_select_all: gtk4::Button,
pub buttons_popover_unselect_all: gtk4::Button,
pub buttons_popover_reverse: gtk4::Button,
pub buttons_popover_select_all_except_oldest: gtk4::Button,
pub buttons_popover_select_all_except_newest: gtk4::Button,
pub buttons_popover_select_one_oldest: gtk4::Button,
pub buttons_popover_select_one_newest: gtk4::Button,
pub buttons_popover_select_custom: gtk4::Button,
pub buttons_popover_unselect_custom: gtk4::Button,
pub buttons_popover_select_all_images_except_biggest: gtk4::Button,
pub buttons_popover_select_all_images_except_smallest: gtk4::Button,
pub separator_select_image_size: gtk::Separator,
pub separator_select_reverse: gtk::Separator,
pub separator_select_date: gtk::Separator,
pub separator_select_custom: gtk::Separator,
pub separator_select_image_size: gtk4::Separator,
pub separator_select_reverse: gtk4::Separator,
pub separator_select_date: gtk4::Separator,
pub separator_select_custom: gtk4::Separator,
pub buttons_popover_right_click_open_file: gtk::Button,
pub buttons_popover_right_click_open_folder: gtk::Button,
pub buttons_popover_right_click_open_file: gtk4::Button,
pub buttons_popover_right_click_open_folder: gtk4::Button,
pub popover_select: gtk::Popover,
pub popover_right_click: gtk::Popover,
pub popover_select: gtk4::Popover,
pub popover_right_click: gtk4::Popover,
}
impl GuiPopovers {
@ -34,33 +34,33 @@ impl GuiPopovers {
let glade_src = include_str!("../../ui/popover_select.ui").to_string();
let builder = Builder::from_string(glade_src.as_str());
let buttons_popover_select_all: gtk::Button = builder.object("buttons_popover_select_all").unwrap();
let buttons_popover_unselect_all: gtk::Button = builder.object("buttons_popover_unselect_all").unwrap();
let buttons_popover_reverse: gtk::Button = builder.object("buttons_popover_reverse").unwrap();
let buttons_popover_select_all_except_oldest: gtk::Button = builder.object("buttons_popover_select_all_except_oldest").unwrap();
let buttons_popover_select_all_except_newest: gtk::Button = builder.object("buttons_popover_select_all_except_newest").unwrap();
let buttons_popover_select_one_oldest: gtk::Button = builder.object("buttons_popover_select_one_oldest").unwrap();
let buttons_popover_select_one_newest: gtk::Button = builder.object("buttons_popover_select_one_newest").unwrap();
let buttons_popover_select_custom: gtk::Button = builder.object("buttons_popover_select_custom").unwrap();
let buttons_popover_unselect_custom: gtk::Button = builder.object("buttons_popover_unselect_custom").unwrap();
let buttons_popover_select_all_images_except_biggest: gtk::Button = builder.object("buttons_popover_select_all_images_except_biggest").unwrap();
let buttons_popover_select_all_images_except_smallest: gtk::Button = builder.object("buttons_popover_select_all_images_except_smallest").unwrap();
let buttons_popover_select_all: gtk4::Button = builder.object("buttons_popover_select_all").unwrap();
let buttons_popover_unselect_all: gtk4::Button = builder.object("buttons_popover_unselect_all").unwrap();
let buttons_popover_reverse: gtk4::Button = builder.object("buttons_popover_reverse").unwrap();
let buttons_popover_select_all_except_oldest: gtk4::Button = builder.object("buttons_popover_select_all_except_oldest").unwrap();
let buttons_popover_select_all_except_newest: gtk4::Button = builder.object("buttons_popover_select_all_except_newest").unwrap();
let buttons_popover_select_one_oldest: gtk4::Button = builder.object("buttons_popover_select_one_oldest").unwrap();
let buttons_popover_select_one_newest: gtk4::Button = builder.object("buttons_popover_select_one_newest").unwrap();
let buttons_popover_select_custom: gtk4::Button = builder.object("buttons_popover_select_custom").unwrap();
let buttons_popover_unselect_custom: gtk4::Button = builder.object("buttons_popover_unselect_custom").unwrap();
let buttons_popover_select_all_images_except_biggest: gtk4::Button = builder.object("buttons_popover_select_all_images_except_biggest").unwrap();
let buttons_popover_select_all_images_except_smallest: gtk4::Button = builder.object("buttons_popover_select_all_images_except_smallest").unwrap();
let separator_select_image_size: gtk::Separator = builder.object("separator_select_image_size").unwrap();
let separator_select_reverse: gtk::Separator = builder.object("separator_select_reverse").unwrap();
let separator_select_date: gtk::Separator = builder.object("separator_select_date").unwrap();
let separator_select_custom: gtk::Separator = builder.object("separator_select_custom").unwrap();
let separator_select_image_size: gtk4::Separator = builder.object("separator_select_image_size").unwrap();
let separator_select_reverse: gtk4::Separator = builder.object("separator_select_reverse").unwrap();
let separator_select_date: gtk4::Separator = builder.object("separator_select_date").unwrap();
let separator_select_custom: gtk4::Separator = builder.object("separator_select_custom").unwrap();
let popover_select: gtk::Popover = builder.object("popover_select").unwrap();
let popover_select: gtk4::Popover = builder.object("popover_select").unwrap();
// Popover right click(not implemented for now)
let glade_src = include_str!("../../ui/popover_right_click.ui").to_string();
let builder = Builder::from_string(glade_src.as_str());
let buttons_popover_right_click_open_file: gtk::Button = builder.object("buttons_popover_right_click_open_file").unwrap();
let buttons_popover_right_click_open_folder: gtk::Button = builder.object("buttons_popover_right_click_open_folder").unwrap();
let buttons_popover_right_click_open_file: gtk4::Button = builder.object("buttons_popover_right_click_open_file").unwrap();
let buttons_popover_right_click_open_folder: gtk4::Button = builder.object("buttons_popover_right_click_open_folder").unwrap();
let popover_right_click: gtk::Popover = builder.object("popover_right_click").unwrap();
let popover_right_click: gtk4::Popover = builder.object("popover_right_click").unwrap();
Self {
buttons_popover_select_all,

View file

@ -1,25 +1,24 @@
use gtk::prelude::*;
use gtk::{Bin, Builder, EventControllerKey, Window};
use gtk4::prelude::*;
use gtk4::{Builder, EventControllerKey, Window};
use crate::help_functions::{get_custom_label_from_button_with_image, set_icon_of_button};
use crate::help_functions::{get_custom_label_from_widget, set_icon_of_button};
use crate::{flg, CZK_ICON_STOP};
#[derive(Clone)]
pub struct GuiProgressDialog {
pub window_progress: gtk::Dialog,
pub window_progress: gtk4::Dialog,
pub progress_bar_current_stage: gtk::ProgressBar,
pub progress_bar_all_stages: gtk::ProgressBar,
pub progress_bar_current_stage: gtk4::ProgressBar,
pub progress_bar_all_stages: gtk4::ProgressBar,
pub label_stage: gtk::Label,
pub label_progress_current_stage: gtk::Label,
pub label_progress_all_stages: gtk::Label,
pub label_stage: gtk4::Label,
pub label_progress_current_stage: gtk4::Label,
pub label_progress_all_stages: gtk4::Label,
pub grid_progress_stages: gtk::Grid,
pub grid_progress_stages: gtk4::Grid,
pub button_stop_in_dialog: gtk::Button,
pub evk_button_stop_in_dialog: gtk::EventControllerKey,
// pub gc_button_stop_in_dialog: gtk4::GestureClick,
pub button_stop_in_dialog: gtk4::Button,
pub evk_button_stop_in_dialog: gtk4::EventControllerKey,
}
impl GuiProgressDialog {
@ -27,26 +26,23 @@ impl GuiProgressDialog {
let glade_src = include_str!("../../ui/progress.ui").to_string();
let builder = Builder::from_string(glade_src.as_str());
let window_progress: gtk::Dialog = builder.object("window_progress").unwrap();
window_progress.set_title(&flg!("window_progress_title"));
let window_progress: gtk4::Dialog = builder.object("window_progress").unwrap();
window_progress.set_title(Some(&flg!("window_progress_title")));
window_progress.set_transient_for(Some(window_main));
window_progress.set_modal(true);
let progress_bar_current_stage: gtk::ProgressBar = builder.object("progress_bar_current_stage").unwrap();
let progress_bar_all_stages: gtk::ProgressBar = builder.object("progress_bar_all_stages").unwrap();
let progress_bar_current_stage: gtk4::ProgressBar = builder.object("progress_bar_current_stage").unwrap();
let progress_bar_all_stages: gtk4::ProgressBar = builder.object("progress_bar_all_stages").unwrap();
let label_stage: gtk::Label = builder.object("label_stage").unwrap();
let label_progress_current_stage: gtk::Label = builder.object("label_progress_current_stage").unwrap();
let label_progress_all_stages: gtk::Label = builder.object("label_progress_all_stages").unwrap();
let label_stage: gtk4::Label = builder.object("label_stage").unwrap();
let label_progress_current_stage: gtk4::Label = builder.object("label_progress_current_stage").unwrap();
let label_progress_all_stages: gtk4::Label = builder.object("label_progress_all_stages").unwrap();
let grid_progress_stages: gtk::Grid = builder.object("grid_progress_stages").unwrap();
let grid_progress_stages: gtk4::Grid = builder.object("grid_progress_stages").unwrap();
let button_stop_in_dialog: gtk::Button = builder.object("button_stop_in_dialog").unwrap();
let evk_button_stop_in_dialog = EventControllerKey::new(&button_stop_in_dialog);
// let evk_button_stop_in_dialog = EventControllerKey::new();
// button_stop_in_dialog.add_controller(&evk_button_stop_in_dialog);
// let gc_button_stop_in_dialog = gtk4::GestureClick::new();
// button_stop_in_dialog.add_controller(&gc_button_stop_in_dialog);
let button_stop_in_dialog: gtk4::Button = builder.object("button_stop_in_dialog").unwrap();
let evk_button_stop_in_dialog = EventControllerKey::new();
button_stop_in_dialog.add_controller(&evk_button_stop_in_dialog);
set_icon_of_button(&button_stop_in_dialog, CZK_ICON_STOP);
@ -63,9 +59,9 @@ impl GuiProgressDialog {
}
}
pub fn update_language(&self) {
self.window_progress.set_title(&flg!("window_progress_title"));
self.window_progress.set_title(Some(&flg!("window_progress_title")));
get_custom_label_from_button_with_image(&self.button_stop_in_dialog.clone().upcast::<Bin>()).set_text(&flg!("progress_stop_button"));
get_custom_label_from_widget(&self.button_stop_in_dialog.clone()).set_text(&flg!("progress_stop_button"));
self.label_progress_current_stage.set_label(&flg!("progress_current_stage"));
self.label_progress_all_stages.set_label(&flg!("progress_all_stages"));

View file

@ -1,54 +1,55 @@
use gtk::prelude::*;
use gtk::{Builder, Window};
use gtk4::prelude::*;
use gtk4::{Builder, Window};
use crate::flg;
use crate::help_functions::get_all_children;
#[derive(Clone)]
pub struct GuiSettings {
pub window_settings: gtk::Window,
pub window_settings: gtk4::Window,
pub notebook_settings: gtk::Notebook,
pub notebook_settings: gtk4::Notebook,
// General
pub check_button_settings_save_at_exit: gtk::CheckButton,
pub check_button_settings_load_at_start: gtk::CheckButton,
pub check_button_settings_confirm_deletion: gtk::CheckButton,
pub check_button_settings_confirm_link: gtk::CheckButton,
pub check_button_settings_confirm_group_deletion: gtk::CheckButton,
pub check_button_settings_show_text_view: gtk::CheckButton,
pub check_button_settings_use_cache: gtk::CheckButton,
pub check_button_settings_save_also_json: gtk::CheckButton,
pub check_button_settings_use_trash: gtk::CheckButton,
pub label_settings_general_language: gtk::Label,
pub combo_box_settings_language: gtk::ComboBoxText,
pub check_button_settings_save_at_exit: gtk4::CheckButton,
pub check_button_settings_load_at_start: gtk4::CheckButton,
pub check_button_settings_confirm_deletion: gtk4::CheckButton,
pub check_button_settings_confirm_link: gtk4::CheckButton,
pub check_button_settings_confirm_group_deletion: gtk4::CheckButton,
pub check_button_settings_show_text_view: gtk4::CheckButton,
pub check_button_settings_use_cache: gtk4::CheckButton,
pub check_button_settings_save_also_json: gtk4::CheckButton,
pub check_button_settings_use_trash: gtk4::CheckButton,
pub label_settings_general_language: gtk4::Label,
pub combo_box_settings_language: gtk4::ComboBoxText,
// Duplicates
pub check_button_settings_hide_hard_links: gtk::CheckButton,
pub entry_settings_cache_file_minimal_size: gtk::Entry,
pub entry_settings_prehash_cache_file_minimal_size: gtk::Entry,
pub check_button_duplicates_use_prehash_cache: gtk::CheckButton,
pub check_button_settings_show_preview_duplicates: gtk::CheckButton,
pub check_button_settings_duplicates_delete_outdated_cache: gtk::CheckButton,
pub button_settings_duplicates_clear_cache: gtk::Button,
pub label_settings_duplicate_minimal_size_cache: gtk::Label,
pub label_settings_duplicate_minimal_size_cache_prehash: gtk::Label,
pub check_button_settings_hide_hard_links: gtk4::CheckButton,
pub entry_settings_cache_file_minimal_size: gtk4::Entry,
pub entry_settings_prehash_cache_file_minimal_size: gtk4::Entry,
pub check_button_duplicates_use_prehash_cache: gtk4::CheckButton,
pub check_button_settings_show_preview_duplicates: gtk4::CheckButton,
pub check_button_settings_duplicates_delete_outdated_cache: gtk4::CheckButton,
pub button_settings_duplicates_clear_cache: gtk4::Button,
pub label_settings_duplicate_minimal_size_cache: gtk4::Label,
pub label_settings_duplicate_minimal_size_cache_prehash: gtk4::Label,
// Similar Images
pub check_button_settings_show_preview_similar_images: gtk::CheckButton,
pub check_button_settings_similar_images_delete_outdated_cache: gtk::CheckButton,
pub button_settings_similar_images_clear_cache: gtk::Button,
pub check_button_settings_show_preview_similar_images: gtk4::CheckButton,
pub check_button_settings_similar_images_delete_outdated_cache: gtk4::CheckButton,
pub button_settings_similar_images_clear_cache: gtk4::Button,
// Similar Videos
pub check_button_settings_similar_videos_delete_outdated_cache: gtk::CheckButton,
pub button_settings_similar_videos_clear_cache: gtk::Button,
pub check_button_settings_similar_videos_delete_outdated_cache: gtk4::CheckButton,
pub button_settings_similar_videos_clear_cache: gtk4::Button,
// Buttons
pub button_settings_save_configuration: gtk::Button,
pub button_settings_load_configuration: gtk::Button,
pub button_settings_reset_configuration: gtk::Button,
pub button_settings_save_configuration: gtk4::Button,
pub button_settings_load_configuration: gtk4::Button,
pub button_settings_reset_configuration: gtk4::Button,
pub button_settings_open_cache_folder: gtk::Button,
pub button_settings_open_settings_folder: gtk::Button,
pub button_settings_open_cache_folder: gtk4::Button,
pub button_settings_open_settings_folder: gtk4::Button,
}
impl GuiSettings {
@ -56,53 +57,53 @@ impl GuiSettings {
let glade_src = include_str!("../../ui/settings.ui").to_string();
let builder = Builder::from_string(glade_src.as_str());
let window_settings: gtk::Window = builder.object("window_settings").unwrap();
window_settings.set_title(&flg!("window_settings_title"));
let window_settings: gtk4::Window = builder.object("window_settings").unwrap();
window_settings.set_title(Some(&flg!("window_settings_title")));
window_settings.set_modal(true);
window_settings.set_transient_for(Some(window_main));
let notebook_settings: gtk::Notebook = builder.object("notebook_settings").unwrap();
let notebook_settings: gtk4::Notebook = builder.object("notebook_settings").unwrap();
// General
let check_button_settings_save_at_exit: gtk::CheckButton = builder.object("check_button_settings_save_at_exit").unwrap();
let check_button_settings_load_at_start: gtk::CheckButton = builder.object("check_button_settings_load_at_start").unwrap();
let check_button_settings_confirm_deletion: gtk::CheckButton = builder.object("check_button_settings_confirm_deletion").unwrap();
let check_button_settings_confirm_link: gtk::CheckButton = builder.object("check_button_settings_confirm_link").unwrap();
let check_button_settings_confirm_group_deletion: gtk::CheckButton = builder.object("check_button_settings_confirm_group_deletion").unwrap();
let check_button_settings_show_text_view: gtk::CheckButton = builder.object("check_button_settings_show_text_view").unwrap();
let check_button_settings_use_cache: gtk::CheckButton = builder.object("check_button_settings_use_cache").unwrap();
let check_button_settings_save_also_json: gtk::CheckButton = builder.object("check_button_settings_save_also_json").unwrap();
let check_button_settings_use_trash: gtk::CheckButton = builder.object("check_button_settings_use_trash").unwrap();
let label_settings_general_language: gtk::Label = builder.object("label_settings_general_language").unwrap();
let combo_box_settings_language: gtk::ComboBoxText = builder.object("combo_box_settings_language").unwrap();
let check_button_settings_save_at_exit: gtk4::CheckButton = builder.object("check_button_settings_save_at_exit").unwrap();
let check_button_settings_load_at_start: gtk4::CheckButton = builder.object("check_button_settings_load_at_start").unwrap();
let check_button_settings_confirm_deletion: gtk4::CheckButton = builder.object("check_button_settings_confirm_deletion").unwrap();
let check_button_settings_confirm_link: gtk4::CheckButton = builder.object("check_button_settings_confirm_link").unwrap();
let check_button_settings_confirm_group_deletion: gtk4::CheckButton = builder.object("check_button_settings_confirm_group_deletion").unwrap();
let check_button_settings_show_text_view: gtk4::CheckButton = builder.object("check_button_settings_show_text_view").unwrap();
let check_button_settings_use_cache: gtk4::CheckButton = builder.object("check_button_settings_use_cache").unwrap();
let check_button_settings_save_also_json: gtk4::CheckButton = builder.object("check_button_settings_save_also_json").unwrap();
let check_button_settings_use_trash: gtk4::CheckButton = builder.object("check_button_settings_use_trash").unwrap();
let label_settings_general_language: gtk4::Label = builder.object("label_settings_general_language").unwrap();
let combo_box_settings_language: gtk4::ComboBoxText = builder.object("combo_box_settings_language").unwrap();
// Duplicates
let check_button_settings_hide_hard_links: gtk::CheckButton = builder.object("check_button_settings_hide_hard_links").unwrap();
let entry_settings_cache_file_minimal_size: gtk::Entry = builder.object("entry_settings_cache_file_minimal_size").unwrap();
let check_button_settings_show_preview_duplicates: gtk::CheckButton = builder.object("check_button_settings_show_preview_duplicates").unwrap();
let check_button_settings_duplicates_delete_outdated_cache: gtk::CheckButton = builder.object("check_button_settings_duplicates_delete_outdated_cache").unwrap();
let button_settings_duplicates_clear_cache: gtk::Button = builder.object("button_settings_duplicates_clear_cache").unwrap();
let check_button_duplicates_use_prehash_cache: gtk::CheckButton = builder.object("check_button_duplicates_use_prehash_cache").unwrap();
let entry_settings_prehash_cache_file_minimal_size: gtk::Entry = builder.object("entry_settings_prehash_cache_file_minimal_size").unwrap();
let label_settings_duplicate_minimal_size_cache: gtk::Label = builder.object("label_settings_duplicate_minimal_size_cache").unwrap();
let label_settings_duplicate_minimal_size_cache_prehash: gtk::Label = builder.object("label_settings_duplicate_minimal_size_cache_prehash").unwrap();
let check_button_settings_hide_hard_links: gtk4::CheckButton = builder.object("check_button_settings_hide_hard_links").unwrap();
let entry_settings_cache_file_minimal_size: gtk4::Entry = builder.object("entry_settings_cache_file_minimal_size").unwrap();
let check_button_settings_show_preview_duplicates: gtk4::CheckButton = builder.object("check_button_settings_show_preview_duplicates").unwrap();
let check_button_settings_duplicates_delete_outdated_cache: gtk4::CheckButton = builder.object("check_button_settings_duplicates_delete_outdated_cache").unwrap();
let button_settings_duplicates_clear_cache: gtk4::Button = builder.object("button_settings_duplicates_clear_cache").unwrap();
let check_button_duplicates_use_prehash_cache: gtk4::CheckButton = builder.object("check_button_duplicates_use_prehash_cache").unwrap();
let entry_settings_prehash_cache_file_minimal_size: gtk4::Entry = builder.object("entry_settings_prehash_cache_file_minimal_size").unwrap();
let label_settings_duplicate_minimal_size_cache: gtk4::Label = builder.object("label_settings_duplicate_minimal_size_cache").unwrap();
let label_settings_duplicate_minimal_size_cache_prehash: gtk4::Label = builder.object("label_settings_duplicate_minimal_size_cache_prehash").unwrap();
// Similar Images
let check_button_settings_show_preview_similar_images: gtk::CheckButton = builder.object("check_button_settings_show_preview_similar_images").unwrap();
let check_button_settings_similar_images_delete_outdated_cache: gtk::CheckButton = builder.object("check_button_settings_similar_images_delete_outdated_cache").unwrap();
let button_settings_similar_images_clear_cache: gtk::Button = builder.object("button_settings_similar_images_clear_cache").unwrap();
let check_button_settings_show_preview_similar_images: gtk4::CheckButton = builder.object("check_button_settings_show_preview_similar_images").unwrap();
let check_button_settings_similar_images_delete_outdated_cache: gtk4::CheckButton = builder.object("check_button_settings_similar_images_delete_outdated_cache").unwrap();
let button_settings_similar_images_clear_cache: gtk4::Button = builder.object("button_settings_similar_images_clear_cache").unwrap();
// Similar Videos
let check_button_settings_similar_videos_delete_outdated_cache: gtk::CheckButton = builder.object("check_button_settings_similar_videos_delete_outdated_cache").unwrap();
let button_settings_similar_videos_clear_cache: gtk::Button = builder.object("button_settings_similar_videos_clear_cache").unwrap();
let check_button_settings_similar_videos_delete_outdated_cache: gtk4::CheckButton = builder.object("check_button_settings_similar_videos_delete_outdated_cache").unwrap();
let button_settings_similar_videos_clear_cache: gtk4::Button = builder.object("button_settings_similar_videos_clear_cache").unwrap();
// Saving/Loading/Resetting configuration
let button_settings_save_configuration: gtk::Button = builder.object("button_settings_save_configuration").unwrap();
let button_settings_load_configuration: gtk::Button = builder.object("button_settings_load_configuration").unwrap();
let button_settings_reset_configuration: gtk::Button = builder.object("button_settings_reset_configuration").unwrap();
let button_settings_save_configuration: gtk4::Button = builder.object("button_settings_save_configuration").unwrap();
let button_settings_load_configuration: gtk4::Button = builder.object("button_settings_load_configuration").unwrap();
let button_settings_reset_configuration: gtk4::Button = builder.object("button_settings_reset_configuration").unwrap();
let button_settings_open_cache_folder: gtk::Button = builder.object("button_settings_open_cache_folder").unwrap();
let button_settings_open_settings_folder: gtk::Button = builder.object("button_settings_open_settings_folder").unwrap();
let button_settings_open_cache_folder: gtk4::Button = builder.object("button_settings_open_cache_folder").unwrap();
let button_settings_open_settings_folder: gtk4::Button = builder.object("button_settings_open_settings_folder").unwrap();
Self {
window_settings,
@ -141,17 +142,18 @@ impl GuiSettings {
}
pub fn update_language(&self) {
self.window_settings.set_title(&flg!("window_settings_title"));
self.window_settings.set_title(Some(&flg!("window_settings_title")));
self.check_button_settings_save_at_exit.set_label(&flg!("settings_save_at_exit_button"));
self.check_button_settings_load_at_start.set_label(&flg!("settings_load_at_start_button"));
self.check_button_settings_confirm_deletion.set_label(&flg!("settings_confirm_deletion_button"));
self.check_button_settings_confirm_link.set_label(&flg!("settings_confirm_link_button"));
self.check_button_settings_confirm_group_deletion.set_label(&flg!("settings_confirm_group_deletion_button"));
self.check_button_settings_show_text_view.set_label(&flg!("settings_show_text_view_button"));
self.check_button_settings_use_cache.set_label(&flg!("settings_use_cache_button"));
self.check_button_settings_save_also_json.set_label(&flg!("settings_save_also_as_json_button"));
self.check_button_settings_use_trash.set_label(&flg!("settings_use_trash_button"));
self.check_button_settings_save_at_exit.set_label(Some(&flg!("settings_save_at_exit_button")));
self.check_button_settings_load_at_start.set_label(Some(&flg!("settings_load_at_start_button")));
self.check_button_settings_confirm_deletion.set_label(Some(&flg!("settings_confirm_deletion_button")));
self.check_button_settings_confirm_link.set_label(Some(&flg!("settings_confirm_link_button")));
self.check_button_settings_confirm_group_deletion
.set_label(Some(&flg!("settings_confirm_group_deletion_button")));
self.check_button_settings_show_text_view.set_label(Some(&flg!("settings_show_text_view_button")));
self.check_button_settings_use_cache.set_label(Some(&flg!("settings_use_cache_button")));
self.check_button_settings_save_also_json.set_label(Some(&flg!("settings_save_also_as_json_button")));
self.check_button_settings_use_trash.set_label(Some(&flg!("settings_use_trash_button")));
self.label_settings_general_language.set_label(&flg!("settings_language_label"));
self.check_button_settings_save_at_exit
@ -172,13 +174,15 @@ impl GuiSettings {
self.check_button_settings_use_trash.set_tooltip_text(Some(&flg!("settings_use_trash_button_tooltip")));
self.label_settings_general_language.set_tooltip_text(Some(&flg!("settings_language_label_tooltip")));
self.check_button_settings_hide_hard_links.set_label(&flg!("settings_duplicates_hide_hard_link_button"));
self.check_button_settings_hide_hard_links
.set_label(Some(&flg!("settings_duplicates_hide_hard_link_button")));
self.check_button_settings_show_preview_duplicates
.set_label(&flg!("settings_multiple_image_preview_checkbutton"));
.set_label(Some(&flg!("settings_multiple_image_preview_checkbutton")));
self.check_button_settings_duplicates_delete_outdated_cache
.set_label(&flg!("settings_multiple_delete_outdated_cache_checkbutton"));
.set_label(Some(&flg!("settings_multiple_delete_outdated_cache_checkbutton")));
self.button_settings_duplicates_clear_cache.set_label(&flg!("settings_multiple_clear_cache_button"));
self.check_button_duplicates_use_prehash_cache.set_label(&flg!("settings_duplicates_prehash_checkbutton"));
self.check_button_duplicates_use_prehash_cache
.set_label(Some(&flg!("settings_duplicates_prehash_checkbutton")));
self.label_settings_duplicate_minimal_size_cache
.set_label(&flg!("settings_duplicates_minimal_size_cache_label"));
self.label_settings_duplicate_minimal_size_cache_prehash
@ -200,9 +204,9 @@ impl GuiSettings {
.set_tooltip_text(Some(&flg!("settings_duplicates_prehash_minimal_entry_tooltip")));
self.check_button_settings_show_preview_similar_images
.set_label(&flg!("settings_multiple_image_preview_checkbutton"));
.set_label(Some(&flg!("settings_multiple_image_preview_checkbutton")));
self.check_button_settings_similar_images_delete_outdated_cache
.set_label(&flg!("settings_multiple_delete_outdated_cache_checkbutton"));
.set_label(Some(&flg!("settings_multiple_delete_outdated_cache_checkbutton")));
self.button_settings_similar_images_clear_cache.set_label(&flg!("settings_multiple_clear_cache_button"));
self.check_button_settings_show_preview_similar_images
@ -213,7 +217,7 @@ impl GuiSettings {
.set_tooltip_text(Some(&flg!("settings_multiple_clear_cache_button_tooltip")));
self.check_button_settings_similar_videos_delete_outdated_cache
.set_label(&flg!("settings_multiple_delete_outdated_cache_checkbutton"));
.set_label(Some(&flg!("settings_multiple_delete_outdated_cache_checkbutton")));
self.button_settings_similar_videos_clear_cache.set_label(&flg!("settings_multiple_clear_cache_button"));
self.check_button_settings_similar_videos_delete_outdated_cache
@ -236,10 +240,8 @@ impl GuiSettings {
self.button_settings_open_settings_folder
.set_tooltip_text(Some(&flg!("settings_folder_settings_open_tooltip")));
let vec_children: Vec<gtk::Widget> = self.notebook_settings.children();
// let vec_children: Vec<gtk::Widget> = get_all_children(&self.notebook_settings);
// let vec_children: Vec<gtk::Widget> = get_all_children(&vec_children[1]);
let vec_children: Vec<gtk4::Widget> = get_all_children(&self.notebook_settings);
let vec_children: Vec<gtk4::Widget> = get_all_children(&vec_children[1]);
// Change name of main notebook tabs
let names: [String; 4] = [
@ -252,7 +254,7 @@ impl GuiSettings {
self.notebook_settings
.tab_label(&vec_children[index])
.unwrap()
.downcast::<gtk::Label>()
.downcast::<gtk4::Label>()
.unwrap()
.set_text(fl_thing);
}

View file

@ -1,78 +1,88 @@
use gtk::prelude::*;
use gtk::{Bin, EventControllerKey, TreeView};
use gtk4::prelude::*;
use gtk4::{EventControllerKey, GestureClick, TreeView};
use crate::help_functions::{get_custom_label_from_button_with_image, set_icon_of_button};
use crate::help_functions::{get_all_children, get_custom_label_from_widget, set_icon_of_button};
use crate::notebook_enums::NotebookUpperEnum;
use crate::{flg, CZK_ICON_ADD, CZK_ICON_DELETE, CZK_ICON_MANUAL_ADD};
#[derive(Clone)]
pub struct GuiUpperNotebook {
pub notebook_upper: gtk::Notebook,
pub notebook_upper: gtk4::Notebook,
pub scrolled_window_included_directories: gtk::ScrolledWindow,
pub scrolled_window_excluded_directories: gtk::ScrolledWindow,
pub scrolled_window_included_directories: gtk4::ScrolledWindow,
pub scrolled_window_excluded_directories: gtk4::ScrolledWindow,
pub tree_view_included_directories: gtk::TreeView,
pub tree_view_excluded_directories: gtk::TreeView,
pub tree_view_included_directories: gtk4::TreeView,
pub tree_view_excluded_directories: gtk4::TreeView,
pub evk_tree_view_included_directories: gtk::EventControllerKey,
pub evk_tree_view_excluded_directories: gtk::EventControllerKey,
pub evk_tree_view_included_directories: gtk4::EventControllerKey,
pub evk_tree_view_excluded_directories: gtk4::EventControllerKey,
pub entry_excluded_items: gtk::Entry,
pub entry_allowed_extensions: gtk::Entry,
pub gc_tree_view_included_directories: gtk4::GestureClick,
pub gc_tree_view_excluded_directories: gtk4::GestureClick,
pub check_button_recursive: gtk::CheckButton,
pub entry_excluded_items: gtk4::Entry,
pub entry_allowed_extensions: gtk4::Entry,
pub buttons_manual_add_included_directory: gtk::Button,
pub buttons_add_included_directory: gtk::Button,
pub buttons_remove_included_directory: gtk::Button,
pub buttons_manual_add_excluded_directory: gtk::Button,
pub buttons_add_excluded_directory: gtk::Button,
pub buttons_remove_excluded_directory: gtk::Button,
pub check_button_recursive: gtk4::CheckButton,
pub label_excluded_items: gtk::Label,
pub label_allowed_extensions: gtk::Label,
pub buttons_manual_add_included_directory: gtk4::Button,
pub buttons_add_included_directory: gtk4::Button,
pub buttons_remove_included_directory: gtk4::Button,
pub buttons_manual_add_excluded_directory: gtk4::Button,
pub buttons_add_excluded_directory: gtk4::Button,
pub buttons_remove_excluded_directory: gtk4::Button,
pub entry_general_minimal_size: gtk::Entry,
pub entry_general_maximal_size: gtk::Entry,
pub label_general_size_bytes: gtk::Label,
pub label_general_min_size: gtk::Label,
pub label_general_max_size: gtk::Label,
pub label_excluded_items: gtk4::Label,
pub label_allowed_extensions: gtk4::Label,
pub entry_general_minimal_size: gtk4::Entry,
pub entry_general_maximal_size: gtk4::Entry,
pub label_general_size_bytes: gtk4::Label,
pub label_general_min_size: gtk4::Label,
pub label_general_max_size: gtk4::Label,
}
impl GuiUpperNotebook {
pub fn create_from_builder(builder: &gtk::Builder) -> Self {
let notebook_upper: gtk::Notebook = builder.object("notebook_upper").unwrap();
pub fn create_from_builder(builder: &gtk4::Builder) -> Self {
let notebook_upper: gtk4::Notebook = builder.object("notebook_upper").unwrap();
let scrolled_window_included_directories: gtk::ScrolledWindow = builder.object("scrolled_window_included_directories").unwrap();
let scrolled_window_excluded_directories: gtk::ScrolledWindow = builder.object("scrolled_window_excluded_directories").unwrap();
let scrolled_window_included_directories: gtk4::ScrolledWindow = builder.object("scrolled_window_included_directories").unwrap();
let scrolled_window_excluded_directories: gtk4::ScrolledWindow = builder.object("scrolled_window_excluded_directories").unwrap();
let tree_view_included_directories: gtk::TreeView = TreeView::new();
let tree_view_excluded_directories: gtk::TreeView = TreeView::new();
let tree_view_included_directories: gtk4::TreeView = TreeView::new();
let tree_view_excluded_directories: gtk4::TreeView = TreeView::new();
let evk_tree_view_included_directories: gtk::EventControllerKey = EventControllerKey::new(&tree_view_included_directories);
let evk_tree_view_excluded_directories: gtk::EventControllerKey = EventControllerKey::new(&tree_view_excluded_directories);
let evk_tree_view_included_directories: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_included_directories.add_controller(&evk_tree_view_included_directories);
let evk_tree_view_excluded_directories: gtk4::EventControllerKey = EventControllerKey::new();
tree_view_excluded_directories.add_controller(&evk_tree_view_excluded_directories);
let entry_allowed_extensions: gtk::Entry = builder.object("entry_allowed_extensions").unwrap();
let entry_excluded_items: gtk::Entry = builder.object("entry_excluded_items").unwrap();
let gc_tree_view_included_directories: gtk4::GestureClick = GestureClick::new();
tree_view_included_directories.add_controller(&gc_tree_view_included_directories);
let gc_tree_view_excluded_directories: gtk4::GestureClick = GestureClick::new();
tree_view_excluded_directories.add_controller(&gc_tree_view_excluded_directories);
let check_button_recursive: gtk::CheckButton = builder.object("check_button_recursive").unwrap();
let entry_allowed_extensions: gtk4::Entry = builder.object("entry_allowed_extensions").unwrap();
let entry_excluded_items: gtk4::Entry = builder.object("entry_excluded_items").unwrap();
let buttons_manual_add_included_directory: gtk::Button = builder.object("buttons_manual_add_included_directory").unwrap();
let buttons_add_included_directory: gtk::Button = builder.object("buttons_add_included_directory").unwrap();
let buttons_remove_included_directory: gtk::Button = builder.object("buttons_remove_included_directory").unwrap();
let buttons_manual_add_excluded_directory: gtk::Button = builder.object("buttons_manual_add_excluded_directory").unwrap();
let buttons_add_excluded_directory: gtk::Button = builder.object("buttons_add_excluded_directory").unwrap();
let buttons_remove_excluded_directory: gtk::Button = builder.object("buttons_remove_excluded_directory").unwrap();
let check_button_recursive: gtk4::CheckButton = builder.object("check_button_recursive").unwrap();
let label_excluded_items: gtk::Label = builder.object("label_excluded_items").unwrap();
let label_allowed_extensions: gtk::Label = builder.object("label_allowed_extensions").unwrap();
let buttons_manual_add_included_directory: gtk4::Button = builder.object("buttons_manual_add_included_directory").unwrap();
let buttons_add_included_directory: gtk4::Button = builder.object("buttons_add_included_directory").unwrap();
let buttons_remove_included_directory: gtk4::Button = builder.object("buttons_remove_included_directory").unwrap();
let buttons_manual_add_excluded_directory: gtk4::Button = builder.object("buttons_manual_add_excluded_directory").unwrap();
let buttons_add_excluded_directory: gtk4::Button = builder.object("buttons_add_excluded_directory").unwrap();
let buttons_remove_excluded_directory: gtk4::Button = builder.object("buttons_remove_excluded_directory").unwrap();
let entry_general_minimal_size: gtk::Entry = builder.object("entry_general_minimal_size").unwrap();
let entry_general_maximal_size: gtk::Entry = builder.object("entry_general_maximal_size").unwrap();
let label_general_size_bytes: gtk::Label = builder.object("label_general_size_bytes").unwrap();
let label_general_min_size: gtk::Label = builder.object("label_general_min_size").unwrap();
let label_general_max_size: gtk::Label = builder.object("label_general_max_size").unwrap();
let label_excluded_items: gtk4::Label = builder.object("label_excluded_items").unwrap();
let label_allowed_extensions: gtk4::Label = builder.object("label_allowed_extensions").unwrap();
let entry_general_minimal_size: gtk4::Entry = builder.object("entry_general_minimal_size").unwrap();
let entry_general_maximal_size: gtk4::Entry = builder.object("entry_general_maximal_size").unwrap();
let label_general_size_bytes: gtk4::Label = builder.object("label_general_size_bytes").unwrap();
let label_general_min_size: gtk4::Label = builder.object("label_general_min_size").unwrap();
let label_general_max_size: gtk4::Label = builder.object("label_general_max_size").unwrap();
set_icon_of_button(&buttons_add_included_directory, CZK_ICON_ADD);
set_icon_of_button(&buttons_manual_add_included_directory, CZK_ICON_MANUAL_ADD);
@ -89,6 +99,8 @@ impl GuiUpperNotebook {
tree_view_excluded_directories,
evk_tree_view_included_directories,
evk_tree_view_excluded_directories,
gc_tree_view_included_directories,
gc_tree_view_excluded_directories,
entry_excluded_items,
entry_allowed_extensions,
check_button_recursive,
@ -108,23 +120,15 @@ impl GuiUpperNotebook {
}
}
pub fn update_language(&self) {
self.check_button_recursive.set_label(&flg!("upper_recursive_button"));
self.check_button_recursive.set_label(Some(&flg!("upper_recursive_button")));
self.check_button_recursive.set_tooltip_text(Some(&flg!("upper_recursive_button_tooltip")));
get_custom_label_from_button_with_image(&self.buttons_manual_add_included_directory.clone().upcast::<Bin>()).set_text(&flg!("upper_manual_add_included_button"));
get_custom_label_from_button_with_image(&self.buttons_add_included_directory.clone().upcast::<Bin>()).set_text(&flg!("upper_add_included_button"));
get_custom_label_from_button_with_image(&self.buttons_remove_included_directory.clone().upcast::<Bin>()).set_text(&flg!("upper_remove_included_button"));
get_custom_label_from_button_with_image(&self.buttons_manual_add_excluded_directory.clone().upcast::<Bin>()).set_text(&flg!("upper_manual_add_excluded_button"));
get_custom_label_from_button_with_image(&self.buttons_add_excluded_directory.clone().upcast::<Bin>()).set_text(&flg!("upper_add_excluded_button"));
get_custom_label_from_button_with_image(&self.buttons_remove_excluded_directory.clone().upcast::<Bin>()).set_text(&flg!("upper_remove_excluded_button"));
// GTK 4
// get_custom_label_from_label_with_image(&self.buttons_manual_add_included_directory.clone()).set_text(&flg!("upper_manual_add_included_button"));
// get_custom_label_from_label_with_image(&self.buttons_add_included_directory.clone()).set_text(&flg!("upper_add_included_button"));
// get_custom_label_from_label_with_image(&self.buttons_remove_included_directory.clone()).set_text(&flg!("upper_remove_included_button"));
// get_custom_label_from_label_with_image(&self.buttons_manual_add_excluded_directory.clone()).set_text(&flg!("upper_manual_add_excluded_button"));
// get_custom_label_from_label_with_image(&self.buttons_add_excluded_directory.clone()).set_text(&flg!("upper_add_excluded_button"));
// get_custom_label_from_label_with_image(&self.buttons_remove_excluded_directory.clone()).set_text(&flg!("upper_remove_excluded_button"));
get_custom_label_from_widget(&self.buttons_manual_add_included_directory.clone()).set_text(&flg!("upper_manual_add_included_button"));
get_custom_label_from_widget(&self.buttons_add_included_directory.clone()).set_text(&flg!("upper_add_included_button"));
get_custom_label_from_widget(&self.buttons_remove_included_directory.clone()).set_text(&flg!("upper_remove_included_button"));
get_custom_label_from_widget(&self.buttons_manual_add_excluded_directory.clone()).set_text(&flg!("upper_manual_add_excluded_button"));
get_custom_label_from_widget(&self.buttons_add_excluded_directory.clone()).set_text(&flg!("upper_add_excluded_button"));
get_custom_label_from_widget(&self.buttons_remove_excluded_directory.clone()).set_text(&flg!("upper_remove_excluded_button"));
self.buttons_manual_add_included_directory
.set_tooltip_text(Some(&flg!("upper_manual_add_included_button_tooltip")));
@ -153,10 +157,8 @@ impl GuiUpperNotebook {
self.entry_general_minimal_size.set_tooltip_text(Some(&flg!("main_label_size_bytes_tooltip")));
self.entry_general_maximal_size.set_tooltip_text(Some(&flg!("main_label_size_bytes_tooltip")));
let vec_children: Vec<gtk::Widget> = self.notebook_upper.children();
// let vec_children: Vec<gtk::Widget> = get_all_children(&self.notebook_upper);
// let vec_children: Vec<gtk::Widget> = get_all_children(&vec_children[1]);
let vec_children: Vec<gtk4::Widget> = get_all_children(&self.notebook_upper);
let vec_children: Vec<gtk4::Widget> = get_all_children(&vec_children[1]);
// Change name of upper notebook tabs
for (upper_enum, fl_thing) in [
@ -167,7 +169,7 @@ impl GuiUpperNotebook {
self.notebook_upper
.tab_label(&vec_children[upper_enum])
.unwrap()
.downcast::<gtk::Label>()
.downcast::<gtk4::Label>()
.unwrap()
.set_text(&fl_thing);
}

View file

@ -1,11 +1,11 @@
use gdk::gdk_pixbuf::{InterpType, Pixbuf};
use gdk4::gdk_pixbuf::{InterpType, Pixbuf};
use std::cmp::Ordering;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use czkawka_core::bad_extensions::BadExtensions;
use gtk::prelude::*;
use gtk::{Bin, ListStore, TextView, TreeView, Widget};
use gtk4::prelude::*;
use gtk4::{ListStore, TextView, TreeView, Widget};
use crate::flg;
use czkawka_core::big_file::BigFile;
@ -39,8 +39,6 @@ pub const KEY_SPACE: u32 = 65;
// pub const KEY_HOME: u32 = 115;
// pub const KEY_END: u32 = 110;
pub const CHECK_GTK_EVENTS_INTERVAL: usize = 100;
#[derive(Eq, PartialEq)]
pub enum PopoverTypes {
All,
@ -70,7 +68,7 @@ pub struct NotebookObject {
pub column_path: i32,
pub column_name: i32,
pub column_selection: i32,
pub column_color: Option<i32>,
pub column_header: Option<i32>,
pub column_dimensions: Option<i32>,
pub column_size: Option<i32>,
pub column_size_as_bytes: Option<i32>,
@ -85,7 +83,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsDuplicates::Path as i32,
column_name: ColumnsDuplicates::Name as i32,
column_selection: ColumnsDuplicates::SelectionButton as i32,
column_color: Some(ColumnsDuplicates::Color as i32),
column_header: Some(ColumnsDuplicates::IsHeader as i32),
column_dimensions: None,
column_size: None, // Do not add, useless in hash and size mode
column_size_as_bytes: None, // Do not add, useless in hash and size mode
@ -98,7 +96,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsEmptyFolders::Path as i32,
column_name: ColumnsEmptyFolders::Name as i32,
column_selection: ColumnsEmptyFolders::SelectionButton as i32,
column_color: None,
column_header: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
@ -111,7 +109,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsBigFiles::Path as i32,
column_name: ColumnsBigFiles::Name as i32,
column_selection: ColumnsBigFiles::SelectionButton as i32,
column_color: None,
column_header: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
@ -124,7 +122,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsEmptyFiles::Path as i32,
column_name: ColumnsEmptyFiles::Name as i32,
column_selection: ColumnsEmptyFiles::SelectionButton as i32,
column_color: None,
column_header: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
@ -137,7 +135,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsTemporaryFiles::Path as i32,
column_name: ColumnsTemporaryFiles::Name as i32,
column_selection: ColumnsTemporaryFiles::SelectionButton as i32,
column_color: None,
column_header: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
@ -150,7 +148,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsSimilarImages::Path as i32,
column_name: ColumnsSimilarImages::Name as i32,
column_selection: ColumnsSimilarImages::SelectionButton as i32,
column_color: Some(ColumnsSimilarImages::Color as i32),
column_header: Some(ColumnsSimilarImages::IsHeader as i32),
column_dimensions: Some(ColumnsSimilarImages::Dimensions as i32),
column_size: Some(ColumnsSimilarImages::Size as i32),
column_size_as_bytes: Some(ColumnsSimilarImages::SizeAsBytes as i32),
@ -163,7 +161,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsSimilarVideos::Path as i32,
column_name: ColumnsSimilarVideos::Name as i32,
column_selection: ColumnsSimilarVideos::SelectionButton as i32,
column_color: Some(ColumnsSimilarVideos::Color as i32),
column_header: Some(ColumnsSimilarVideos::IsHeader as i32),
column_dimensions: None,
column_size: Some(ColumnsSimilarVideos::Size as i32),
column_size_as_bytes: Some(ColumnsSimilarVideos::SizeAsBytes as i32),
@ -176,7 +174,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsSameMusic::Path as i32,
column_name: ColumnsSameMusic::Name as i32,
column_selection: ColumnsSameMusic::SelectionButton as i32,
column_color: Some(ColumnsSameMusic::Color as i32),
column_header: Some(ColumnsSameMusic::IsHeader as i32),
column_dimensions: None,
column_size: None,
column_size_as_bytes: Some(ColumnsSameMusic::SizeAsBytes as i32),
@ -189,7 +187,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsInvalidSymlinks::Path as i32,
column_name: ColumnsInvalidSymlinks::Name as i32,
column_selection: ColumnsInvalidSymlinks::SelectionButton as i32,
column_color: None,
column_header: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
@ -202,7 +200,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsBrokenFiles::Path as i32,
column_name: ColumnsBrokenFiles::Name as i32,
column_selection: ColumnsBrokenFiles::SelectionButton as i32,
column_color: None,
column_header: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
@ -215,7 +213,7 @@ pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
column_path: ColumnsBadExtensions::Path as i32,
column_name: ColumnsBadExtensions::Name as i32,
column_selection: ColumnsBadExtensions::SelectionButton as i32,
column_color: None,
column_header: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
@ -247,6 +245,7 @@ pub enum ColumnsDuplicates {
Modification,
ModificationAsSecs,
Color,
IsHeader,
TextColor,
}
@ -307,6 +306,7 @@ pub enum ColumnsSimilarImages {
Modification,
ModificationAsSecs,
Color,
IsHeader,
TextColor,
}
@ -320,6 +320,7 @@ pub enum ColumnsSimilarVideos {
Modification,
ModificationAsSecs,
Color,
IsHeader,
TextColor,
}
@ -340,6 +341,7 @@ pub enum ColumnsSameMusic {
Modification,
ModificationAsSecs,
Color,
IsHeader,
TextColor,
}
@ -372,14 +374,12 @@ pub enum ColumnsBadExtensions {
ModificationAsSecs,
}
pub const MAIN_ROW_COLOR: &str = "#222222";
pub const HEADER_ROW_COLOR: &str = "#111111";
pub const TEXT_COLOR: &str = "#ffffff";
pub const MAIN_ROW_COLOR: &str = "#343434";
pub const HEADER_ROW_COLOR: &str = "#272727";
//pub const MAIN_ROW_COLOR: &str = "#f4f434"; // TEST
//pub const HEADER_ROW_COLOR: &str = "#010101"; // TEST
pub fn get_string_from_list_store(tree_view: &gtk::TreeView, column_full_path: i32, column_selection: Option<i32>) -> Vec<String> {
let list_store: gtk::ListStore = get_list_store(tree_view);
pub fn get_string_from_list_store(tree_view: &gtk4::TreeView, column_full_path: i32, column_selection: Option<i32>) -> Vec<String> {
let list_store: gtk4::ListStore = get_list_store(tree_view);
let mut string_vector: Vec<String> = Vec::new();
@ -391,15 +391,15 @@ pub fn get_string_from_list_store(tree_view: &gtk::TreeView, column_full_path: i
};
match column_selection {
Some(column_selection) => loop {
if list_store.value(&tree_iter, column_selection).get::<bool>().unwrap() {
string_vector.push(list_store.value(&tree_iter, column_full_path).get::<String>().unwrap());
if list_store.get::<bool>(&tree_iter, column_selection) {
string_vector.push(list_store.get::<String>(&tree_iter, column_full_path));
}
if !list_store.iter_next(&tree_iter) {
return string_vector;
}
},
None => loop {
string_vector.push(list_store.value(&tree_iter, column_full_path).get::<String>().unwrap());
string_vector.push(list_store.get::<String>(&tree_iter, column_full_path));
if !list_store.iter_next(&tree_iter) {
return string_vector;
}
@ -419,7 +419,7 @@ pub fn split_path(path: &Path) -> (String, String) {
}
}
pub fn print_text_messages_to_text_view(text_messages: &Messages, text_view: &gtk::TextView) {
pub fn print_text_messages_to_text_view(text_messages: &Messages, text_view: &gtk4::TextView) {
let mut messages: String = String::from("");
if !text_messages.messages.is_empty() {
messages += format!("############### {}({}) ###############\n", flg!("text_view_messages"), text_messages.messages.len()).as_str();
@ -452,19 +452,16 @@ pub fn print_text_messages_to_text_view(text_messages: &Messages, text_view: &gt
// messages += "\n";
// }
text_view.buffer().unwrap().set_text(messages.as_str());
text_view.buffer().set_text(messages.as_str());
}
pub fn reset_text_view(text_view: &TextView) {
text_view.buffer().unwrap().set_text("");
text_view.buffer().set_text("");
}
pub fn add_text_to_text_view(text_view: &TextView, string_to_append: &str) {
let buffer = text_view.buffer().unwrap();
let current_text = match buffer.text(&buffer.start_iter(), &buffer.end_iter(), true) {
Some(t) => t.to_string(),
None => "".to_string(),
};
let buffer = text_view.buffer();
let current_text = buffer.text(&buffer.start_iter(), &buffer.end_iter(), true).to_string();
if current_text.is_empty() {
buffer.set_text(string_to_append);
} else {
@ -472,7 +469,7 @@ pub fn add_text_to_text_view(text_view: &TextView, string_to_append: &str) {
}
}
pub fn set_buttons(hashmap: &mut HashMap<BottomButtonsEnum, bool>, buttons_array: &[gtk::Widget], button_names: &[BottomButtonsEnum]) {
pub fn set_buttons(hashmap: &mut HashMap<BottomButtonsEnum, bool>, buttons_array: &[gtk4::Widget], button_names: &[BottomButtonsEnum]) {
for (index, button) in buttons_array.iter().enumerate() {
if *hashmap.get_mut(&button_names[index]).unwrap() {
button.show();
@ -495,12 +492,12 @@ pub fn get_text_from_invalid_symlink_cause(error: &common_dir_traversal::ErrorTy
}
}
pub fn get_list_store(tree_view: &gtk::TreeView) -> ListStore {
tree_view.model().unwrap().downcast::<gtk::ListStore>().unwrap()
pub fn get_list_store(tree_view: &gtk4::TreeView) -> ListStore {
tree_view.model().unwrap().downcast::<gtk4::ListStore>().unwrap()
}
pub fn get_dialog_box_child(dialog: &gtk::Dialog) -> gtk::Box {
dialog.child().unwrap().downcast::<gtk::Box>().unwrap()
pub fn get_dialog_box_child(dialog: &gtk4::Dialog) -> gtk4::Box {
dialog.child().unwrap().downcast::<gtk4::Box>().unwrap()
}
pub fn change_dimension_to_krotka(dimensions: String) -> (u64, u64) {
@ -512,7 +509,7 @@ pub fn change_dimension_to_krotka(dimensions: String) -> (u64, u64) {
(number1, number2)
}
pub fn get_notebook_enum_from_tree_view(tree_view: &gtk::TreeView) -> NotebookMainEnum {
pub fn get_notebook_enum_from_tree_view(tree_view: &gtk4::TreeView) -> NotebookMainEnum {
match (*tree_view).widget_name().to_string().as_str() {
"tree_view_duplicate_finder" => NotebookMainEnum::Duplicate,
"tree_view_empty_folder_finder" => NotebookMainEnum::EmptyDirectories,
@ -531,7 +528,7 @@ pub fn get_notebook_enum_from_tree_view(tree_view: &gtk::TreeView) -> NotebookMa
}
}
pub fn get_notebook_upper_enum_from_tree_view(tree_view: &gtk::TreeView) -> NotebookUpperEnum {
pub fn get_notebook_upper_enum_from_tree_view(tree_view: &gtk4::TreeView) -> NotebookUpperEnum {
match (*tree_view).widget_name().to_string().as_str() {
"tree_view_upper_included_directories" => NotebookUpperEnum::IncludedDirectories,
"tree_view_upper_excluded_directories" => NotebookUpperEnum::ExcludedDirectories,
@ -541,7 +538,7 @@ pub fn get_notebook_upper_enum_from_tree_view(tree_view: &gtk::TreeView) -> Note
}
}
pub fn get_notebook_object_from_tree_view(tree_view: &gtk::TreeView) -> &NotebookObject {
pub fn get_notebook_object_from_tree_view(tree_view: &gtk4::TreeView) -> &NotebookObject {
let nb_enum = get_notebook_enum_from_tree_view(tree_view);
&NOTEBOOKS_INFOS[nb_enum as usize]
}
@ -555,12 +552,12 @@ pub fn get_full_name_from_path_name(path: &str, name: &str) -> String {
}
// After e.g. deleting files, header may become orphan or have one child, so should be deleted in this case
pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_path: i32) {
pub fn clean_invalid_headers(model: &gtk4::ListStore, column_header: i32, column_path: i32) {
// Remove only child from header
if let Some(first_iter) = model.iter_first() {
let mut vec_tree_path_to_delete: Vec<gtk::TreePath> = Vec::new();
let mut vec_tree_path_to_delete: Vec<gtk4::TreePath> = Vec::new();
let mut current_iter = first_iter;
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
if !model.get::<bool>(&current_iter, column_header) {
panic!("First deleted element, should be a header"); // First element should be header
};
@ -568,22 +565,22 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
let mut next_next_iter;
// Empty means default check type
if model.value(&current_iter, column_path).get::<String>().unwrap().is_empty() {
if model.get::<String>(&current_iter, column_path).is_empty() {
'main: loop {
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
if !model.get::<bool>(&current_iter, column_header) {
panic!("First deleted element, should be a header"); // First element should be header
};
next_iter = current_iter;
if !model.iter_next(&next_iter) {
// There is only single header left (H1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&current_iter));
break 'main;
}
if model.value(&next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&next_iter, column_header) {
// There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&current_iter));
current_iter = next_iter;
continue 'main;
}
@ -591,15 +588,15 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
next_next_iter = 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(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&current_iter));
vec_tree_path_to_delete.push(model.path(&next_iter));
break 'main;
}
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&next_next_iter, column_header) {
// One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&current_iter));
vec_tree_path_to_delete.push(model.path(&next_iter));
current_iter = next_next_iter;
continue 'main;
}
@ -610,7 +607,7 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
break 'main;
}
// Move to next header
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&next_next_iter, column_header) {
current_iter = next_next_iter;
continue 'main;
}
@ -623,20 +620,20 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
// Non empty means that header points at reference folder
else {
'reference: loop {
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
if !model.get::<bool>(&current_iter, column_header) {
panic!("First deleted element, should be a header"); // First element should be header
};
next_iter = current_iter;
if !model.iter_next(&next_iter) {
// There is only single header left (H1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&current_iter));
break 'reference;
}
if model.value(&next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&next_iter, column_header) {
// There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&current_iter));
current_iter = next_iter;
continue 'reference;
}
@ -647,7 +644,7 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
break 'reference;
}
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&next_next_iter, column_header) {
// One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
current_iter = next_next_iter;
continue 'reference;
@ -659,7 +656,7 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
break 'reference;
}
// Move to next header
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&next_next_iter, column_header) {
current_iter = next_next_iter;
continue 'reference;
}
@ -678,7 +675,7 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
}
}
}
pub fn check_how_much_elements_is_selected(tree_view: &TreeView, column_color: Option<i32>, column_selection: i32) -> (u64, u64) {
pub fn check_how_much_elements_is_selected(tree_view: &TreeView, column_header: Option<i32>, column_selection: i32) -> (u64, u64) {
let mut number_of_selected_items: u64 = 0;
let mut number_of_selected_groups: u64 = 0;
@ -688,18 +685,18 @@ pub fn check_how_much_elements_is_selected(tree_view: &TreeView, column_color: O
// First iter
if let Some(iter) = model.iter_first() {
if let Some(column_color) = column_color {
assert_eq!(model.value(&iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR); // First element should be header
if let Some(column_header) = column_header {
assert!(model.get::<bool>(&iter, column_header)); // First element should be header
loop {
if !model.iter_next(&iter) {
break;
}
if model.value(&iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&iter, column_header) {
is_item_currently_selected_in_group = false;
} else {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
if model.get::<bool>(&iter, column_selection) {
number_of_selected_items += 1;
if !is_item_currently_selected_in_group {
@ -710,12 +707,15 @@ pub fn check_how_much_elements_is_selected(tree_view: &TreeView, column_color: O
}
}
} else {
if model.get::<bool>(&iter, column_selection) {
number_of_selected_items += 1;
}
loop {
if !model.iter_next(&iter) {
break;
}
if model.value(&iter, column_selection).get::<bool>().unwrap() {
if model.get::<bool>(&iter, column_selection) {
number_of_selected_items += 1;
}
}
@ -726,13 +726,13 @@ pub fn check_how_much_elements_is_selected(tree_view: &TreeView, column_color: O
}
/// Counts how much headers/groups is in treeview
pub fn count_number_of_groups(tree_view: &TreeView, column_color: i32) -> u32 {
pub fn count_number_of_groups(tree_view: &TreeView, column_header: i32) -> u32 {
let mut number_of_selected_groups = 0;
let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() {
assert_eq!(model.value(&iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR); // First element should be header
assert!(model.get::<bool>(&iter, column_header)); // First element should be header
number_of_selected_groups += 1;
loop {
@ -740,7 +740,7 @@ pub fn count_number_of_groups(tree_view: &TreeView, column_color: i32) -> u32 {
break;
}
if model.value(&iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&iter, column_header) {
number_of_selected_groups += 1;
}
}
@ -783,99 +783,81 @@ pub fn get_max_file_name(file_name: &str, max_length: usize) -> String {
}
}
pub fn get_custom_label_from_button_with_image(button: &gtk::Bin) -> gtk::Label {
let internal_box = button.child().unwrap().downcast::<gtk::Box>().unwrap();
for child in internal_box.children() {
if let Ok(t) = child.downcast::<gtk::Label>() {
return t;
pub fn get_custom_label_from_widget<P: IsA<gtk4::Widget>>(item: &P) -> gtk4::Label {
let mut widgets_to_check = vec![item.clone().upcast::<gtk4::Widget>()];
while let Some(widget) = widgets_to_check.pop() {
if let Ok(label) = widget.clone().downcast::<gtk4::Label>() {
return label;
} else {
widgets_to_check.extend(get_all_children(&widget));
}
}
panic!("Button doesn't have proper custom label child");
}
pub fn get_custom_image_from_button_with_image(button: &gtk::Bin) -> gtk::Image {
let internal_box = match button.child().unwrap().downcast::<gtk::Box>() {
Ok(t) => t,
Err(wid) => {
return wid.downcast::<gtk::Image>().unwrap();
}
};
for child in internal_box.children() {
if let Ok(t) = child.downcast::<gtk::Image>() {
return t;
pub fn get_custom_image_from_widget<P: IsA<gtk4::Widget>>(item: &P) -> gtk4::Image {
let mut widgets_to_check = vec![item.clone().upcast::<gtk4::Widget>()];
while let Some(widget) = widgets_to_check.pop() {
if let Ok(image) = widget.clone().downcast::<gtk4::Image>() {
return image;
} else {
widgets_to_check.extend(get_all_children(&widget));
}
}
panic!("Button doesn't have proper custom label child");
}
pub fn handle_gtk_pending_event() -> bool {
let have_pending = gtk::events_pending();
if have_pending {
gtk::main_iteration();
#[allow(dead_code)]
pub fn debug_print_widget<P: IsA<gtk4::Widget>>(item: &P) {
let mut widgets_to_check = vec![(0, 0, item.clone().upcast::<gtk4::Widget>())];
let mut next_free_number = 1;
println!("{}, {}, {:?} ", widgets_to_check[0].0, widgets_to_check[0].1, widgets_to_check[0].2);
while let Some((current_number, parent_number, widget)) = widgets_to_check.pop() {
for widget in get_all_children(&widget) {
widgets_to_check.push((next_free_number, current_number, widget));
next_free_number += 1;
}
println!("{}, {}, {:?} ", current_number, parent_number, widget);
}
have_pending
}
pub fn get_all_boxes_from_widget<P: IsA<gtk4::Widget>>(item: &P) -> Vec<gtk4::Box> {
let mut widgets_to_check = vec![item.clone().upcast::<gtk4::Widget>()];
let mut boxes = Vec::new();
while let Some(widget) = widgets_to_check.pop() {
widgets_to_check.extend(get_all_children(&widget));
if let Ok(bbox) = widget.clone().downcast::<gtk4::Box>() {
boxes.push(bbox);
}
}
boxes
}
pub fn handle_gtk_pending_event_counter(counter: usize) -> bool {
if counter > 0 && (counter % CHECK_GTK_EVENTS_INTERVAL) == 0 {
return handle_gtk_pending_event();
pub fn get_all_children<P: IsA<gtk4::Widget>>(wid: &P) -> Vec<gtk4::Widget> {
let mut vector = vec![];
if let Some(mut child) = wid.first_child() {
vector.push(child.clone());
loop {
child = match child.next_sibling() {
Some(t) => t,
None => break,
};
vector.push(child.clone());
}
}
false
vector
}
// GTK 4
// pub fn get_custom_label_from_button_with_image<P: IsA<gtk4::Widget>>(button: &P) -> gtk4::Label {
// let internal_box = button.first_child().unwrap().downcast::<gtk4::Box>().unwrap();
// for child in get_all_children(&internal_box) {
// if let Ok(t) = child.downcast::<gtk4::Label>() {
// return t;
// }
// }
// panic!("Button doesn't have proper custom label child");
// }
// TODO needs GTK 4.6 to be able to set as child of menu button a box
// pub fn get_custom_label_from_menubutton_with_image<P: IsA<gtk4::Widget>>(button: &P) -> gtk4::Label {
// println!("{:?}", get_all_children(button));
// for c1 in get_all_children(button) {
// if let Ok(internal_box) = c1.downcast::<gtk4::Box>() {
// for child in get_all_children(&internal_box) {
// if let Ok(t) = child.downcast::<gtk4::Label>() {
// return t;
// }
// }
// }
// }
// panic!("Menu Button doesn't have proper custom label child");
// }
// GTK 4
// pub fn get_all_children<P: IsA<gtk::Widget>>(wid: &P) -> Vec<gtk::Widget> {
// let mut vector = vec![];
// if let Some(mut child) = wid.first_child() {
// vector.push(child.clone());
// loop {
// child = match child.next_sibling() {
// Some(t) => t,
// None => break,
// };
// vector.push(child.clone());
// }
// }
//
// return vector;
// }
const SIZE_OF_ICON: i32 = 18;
const TYPE_OF_INTERPOLATION: InterpType = InterpType::Tiles;
pub fn set_icon_of_button(button: &gtk::Button, data: &'static [u8]) {
let image = get_custom_image_from_button_with_image(&button.clone().upcast::<Bin>());
pub fn set_icon_of_button<P: IsA<gtk4::Widget>>(button: &P, data: &'static [u8]) {
let image = get_custom_image_from_widget(&button.clone());
let pixbuf = Pixbuf::from_read(std::io::BufReader::new(data)).unwrap();
let pixbuf = pixbuf.scale_simple(SIZE_OF_ICON, SIZE_OF_ICON, TYPE_OF_INTERPOLATION).unwrap();
image.set_pixbuf(Some(&pixbuf));
}
pub fn set_icon_of_menubutton(button: &gtk::MenuButton, data: &'static [u8]) {
let image = get_custom_image_from_button_with_image(&button.clone().upcast::<Bin>());
let pixbuf = Pixbuf::from_read(std::io::BufReader::new(data)).unwrap();
let pixbuf = pixbuf.scale_simple(SIZE_OF_ICON, SIZE_OF_ICON, TYPE_OF_INTERPOLATION).unwrap();
image.set_pixbuf(Some(&pixbuf));
image.set_from_pixbuf(Some(&pixbuf));
}

View file

@ -3,10 +3,10 @@ use std::ops::Deref;
use std::path::Path;
use std::rc::Rc;
use gdk::gdk_pixbuf::Pixbuf;
use gtk::gdk_pixbuf::InterpType;
use gtk::prelude::*;
use gtk::{CheckButton, Image, SelectionMode, TextView, TreeView};
use gdk4::gdk_pixbuf::Pixbuf;
use gtk4::gdk_pixbuf::InterpType;
use gtk4::prelude::*;
use gtk4::{CheckButton, Image, SelectionMode, TextView, TreeView};
use crate::flg;
use czkawka_core::common::{IMAGE_RS_EXTENSIONS, RAW_IMAGE_EXTENSIONS};
@ -124,7 +124,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
let image_preview = gui_data.main_notebook.image_preview_duplicates.clone();
image_preview.hide();
let col_types: [glib::types::Type; 9] = [
let col_types: [glib::types::Type; 10] = [
glib::types::Type::BOOL, // ActivatableSelectButton
glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Size
@ -133,19 +133,20 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
glib::types::Type::STRING, // Color
glib::types::Type::BOOL, // IsHeader
glib::types::Type::STRING, // TextColor
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
tree_view.selection().set_select_function(Some(Box::new(select_function_duplicates)));
tree_view.selection().set_select_function(select_function_duplicates);
create_tree_view_duplicates(&tree_view);
tree_view.set_widget_name("tree_view_duplicate_finder");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Empty Folders
{
@ -159,7 +160,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -168,8 +169,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
tree_view.set_widget_name("tree_view_empty_folder_finder");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Empty Files
{
@ -182,7 +183,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -190,8 +191,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_empty_files(&tree_view);
tree_view.set_widget_name("tree_view_empty_files_finder");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Temporary Files
{
@ -205,7 +206,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -213,8 +214,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_temporary_files(&tree_view);
tree_view.set_widget_name("tree_view_temporary_files_finder");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Big Files
{
@ -230,7 +231,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::U64, // SizeAsBytes
glib::types::Type::U64, // ModificationAsSecs
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -238,8 +239,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_big_files(&tree_view);
tree_view.set_widget_name("tree_view_big_files_finder");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Similar Images
{
@ -249,7 +250,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
let image_preview = gui_data.main_notebook.image_preview_similar_images.clone();
image_preview.hide();
let col_types: [glib::types::Type; 12] = [
let col_types: [glib::types::Type; 13] = [
glib::types::Type::BOOL, // ActivatableSelectButton
glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Similarity
@ -261,26 +262,27 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
glib::types::Type::STRING, // Color
glib::types::Type::BOOL, // IsHeader
glib::types::Type::STRING, // TextColor
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
tree_view.selection().set_select_function(Some(Box::new(select_function_similar_images)));
tree_view.selection().set_select_function(select_function_similar_images);
create_tree_view_similar_images(&tree_view);
tree_view.set_widget_name("tree_view_similar_images_finder");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Similar Videos
{
let scrolled_window = gui_data.main_notebook.scrolled_window_similar_videos_finder.clone();
let tree_view = gui_data.main_notebook.tree_view_similar_videos_finder.clone();
let col_types: [glib::types::Type; 10] = [
let col_types: [glib::types::Type; 11] = [
glib::types::Type::BOOL, // ActivatableSelectButton
glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Size
@ -290,26 +292,27 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
glib::types::Type::STRING, // Color
glib::types::Type::BOOL, // IsHeader
glib::types::Type::STRING, // TextColor
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
tree_view.selection().set_select_function(Some(Box::new(select_function_similar_videos)));
tree_view.selection().set_select_function(select_function_similar_videos);
create_tree_view_similar_videos(&tree_view);
tree_view.set_widget_name("tree_view_similar_videos_finder");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Same Music
{
let scrolled_window = gui_data.main_notebook.scrolled_window_same_music_finder.clone();
let tree_view = gui_data.main_notebook.tree_view_same_music_finder.clone();
let col_types: [glib::types::Type; 17] = [
let col_types: [glib::types::Type; 18] = [
glib::types::Type::BOOL, // ActivatableSelectButton
glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Size
@ -326,19 +329,20 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
glib::types::Type::STRING, // Color
glib::types::Type::BOOL, // IsHeader
glib::types::Type::STRING, // TextColor
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
tree_view.selection().set_select_function(Some(Box::new(select_function_same_music)));
tree_view.selection().set_select_function(select_function_same_music);
create_tree_view_same_music(&tree_view);
tree_view.set_widget_name("tree_view_same_music_finder");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Invalid Symlinks
{
@ -354,7 +358,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -362,8 +366,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_invalid_symlinks(&tree_view);
tree_view.set_widget_name("tree_view_invalid_symlinks");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Broken Files
{
@ -378,7 +382,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -386,8 +390,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_broken_files(&tree_view);
tree_view.set_widget_name("tree_view_broken_files");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
// Bad Extensions
{
@ -403,7 +407,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -411,8 +415,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_broken_files(&tree_view);
tree_view.set_widget_name("tree_view_bad_extensions");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
}
}
}
@ -424,12 +428,13 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
let scrolled_window = gui_data.upper_notebook.scrolled_window_included_directories.clone();
let tree_view = gui_data.upper_notebook.tree_view_included_directories.clone();
let evk = gui_data.upper_notebook.evk_tree_view_included_directories.clone();
let gc = gui_data.upper_notebook.gc_tree_view_included_directories.clone();
let col_types: [glib::types::Type; 2] = [
glib::types::Type::STRING, // Path
glib::types::Type::BOOL, // ReferenceButton
];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -437,10 +442,10 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_included_directories(&tree_view);
tree_view.set_widget_name("tree_view_upper_included_directories");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
tree_view.connect_button_press_event(opening_double_click_function_directories);
gc.connect_pressed(opening_double_click_function_directories);
evk.connect_key_pressed(opening_enter_function_ported_upper_directories);
evk.connect_key_released(move |_event_controller_key, _key_value, key_code, _modifier_type| {
if key_code == KEY_DELETE {
@ -460,9 +465,10 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
let scrolled_window = gui_data.upper_notebook.scrolled_window_excluded_directories.clone();
let tree_view = gui_data.upper_notebook.tree_view_excluded_directories.clone();
let evk = gui_data.upper_notebook.evk_tree_view_excluded_directories.clone();
let gc = gui_data.upper_notebook.gc_tree_view_excluded_directories.clone();
let col_types: [glib::types::Type; 1] = [glib::types::Type::STRING];
let list_store: gtk::ListStore = gtk::ListStore::new(&col_types);
let list_store: gtk4::ListStore = gtk4::ListStore::new(&col_types);
tree_view.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple);
@ -470,10 +476,10 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_excluded_directories(&tree_view);
tree_view.set_widget_name("tree_view_upper_excluded_directories");
scrolled_window.add(&tree_view);
scrolled_window.show_all();
scrolled_window.set_child(Some(&tree_view));
scrolled_window.show();
tree_view.connect_button_press_event(opening_double_click_function_directories);
gc.connect_pressed(opening_double_click_function_directories);
evk.connect_key_pressed(opening_enter_function_ported_upper_directories);
evk.connect_key_released(move |_event_controller_key, _key_value, key_code, _modifier_type| {
if key_code == KEY_DELETE {
@ -495,9 +501,9 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
let window_progress = gui_data.progress_window.window_progress.clone();
let stop_sender = gui_data.stop_sender.clone();
window_progress.connect_delete_event(move |_, _| {
window_progress.connect_close_request(move |_| {
stop_sender.send(()).unwrap();
gtk::Inhibit(true)
gtk4::Inhibit(true)
});
}
@ -507,9 +513,23 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
}
fn connect_event_mouse(gui_data: &GuiData) {
for tree_view in gui_data.main_notebook.get_main_tree_views() {
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_button_release_event(opening_middle_mouse_function);
// GTK 4
for gc in [
&gui_data.main_notebook.gc_tree_view_duplicate_finder,
&gui_data.main_notebook.gc_tree_view_empty_folder_finder,
&gui_data.main_notebook.gc_tree_view_empty_files_finder,
&gui_data.main_notebook.gc_tree_view_temporary_files_finder,
&gui_data.main_notebook.gc_tree_view_big_files_finder,
&gui_data.main_notebook.gc_tree_view_similar_images_finder,
&gui_data.main_notebook.gc_tree_view_similar_videos_finder,
&gui_data.main_notebook.gc_tree_view_same_music_finder,
&gui_data.main_notebook.gc_tree_view_invalid_symlinks,
&gui_data.main_notebook.gc_tree_view_broken_files,
&gui_data.main_notebook.gc_tree_view_bad_extensions,
] {
gc.set_button(0);
gc.connect_pressed(opening_double_click_function);
gc.connect_released(opening_middle_mouse_function); // TODO GTK 4 - https://github.com/gtk-rs/gtk4-rs/issues/1043
}
// Duplicate
@ -518,13 +538,16 @@ fn connect_event_mouse(gui_data: &GuiData) {
let check_button_settings_show_preview = gui_data.settings.check_button_settings_show_preview_duplicates.clone();
let image_preview = gui_data.main_notebook.image_preview_duplicates.clone();
let preview_path = gui_data.preview_path.clone();
let tree_view = gui_data.main_notebook.tree_view_duplicate_finder.clone();
tree_view.connect_button_release_event(move |tree_view, _event| {
let gc = gui_data.main_notebook.gc_tree_view_duplicate_finder.clone();
// TODO GTK 4, currently not works, connect_pressed shows previous thing
gc.connect_released(move |gc, _event, _, _| {
let tree_view = gc.widget().downcast::<gtk4::TreeView>().unwrap();
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
let preview_path = preview_path.clone();
show_preview(
tree_view,
&tree_view,
&text_view_errors,
&check_button_settings_show_preview,
&image_preview,
@ -532,23 +555,24 @@ fn connect_event_mouse(gui_data: &GuiData) {
nb_object.column_path,
nb_object.column_name,
);
gtk::Inhibit(false)
});
}
// Similar Images
{
let text_view_errors = gui_data.text_view_errors.clone();
let tree_view = gui_data.main_notebook.tree_view_similar_images_finder.clone();
let check_button_settings_show_preview = gui_data.settings.check_button_settings_show_preview_similar_images.clone();
let preview_path = gui_data.preview_path.clone();
let image_preview = gui_data.main_notebook.image_preview_similar_images.clone();
tree_view.connect_button_release_event(move |tree_view, _event| {
let gc = gui_data.main_notebook.gc_tree_view_similar_images_finder.clone();
// TODO GTK 4, currently not works, connect_pressed shows previous thing
gc.connect_released(move |gc, _event, _, _| {
let tree_view = gc.widget().downcast::<gtk4::TreeView>().unwrap();
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
let preview_path = preview_path.clone();
show_preview(
tree_view,
&tree_view,
&text_view_errors,
&check_button_settings_show_preview,
&image_preview,
@ -556,60 +580,8 @@ fn connect_event_mouse(gui_data: &GuiData) {
nb_object.column_path,
nb_object.column_name,
);
gtk::Inhibit(false)
});
}
// GTK 4
// for gc in [
// gui_data.main_notebook.gc_tree_view_duplicate_finder.clone(),
// gui_data.main_notebook.gc_tree_view_empty_folder_finder.clone(),
// gui_data.main_notebook.gc_tree_view_empty_files_finder.clone(),
// gui_data.main_notebook.gc_tree_view_temporary_files_finder.clone(),
// gui_data.main_notebook.gc_tree_view_big_files_finder.clone(),
// gui_data.main_notebook.gc_tree_view_similar_images_finder.clone(),
// gui_data.main_notebook.gc_tree_view_similar_videos_finder.clone(),
// gui_data.main_notebook.gc_tree_view_same_music_finder.clone(),
// gui_data.main_notebook.gc_tree_view_invalid_symlinks.clone(),
// gui_data.main_notebook.gc_tree_view_broken_files.clone(),
// gui_data.main_notebook.gc_tree_view_bad_extensions.clone(),
// ] {
// gc.set_button(0);
// gc.connect_pressed(opening_double_click_function);
// }
//
// // Duplicate
// {
// let text_view_errors = gui_data.text_view_errors.clone();
// let check_button_settings_show_preview = gui_data.settings.check_button_settings_show_preview_duplicates.clone();
// let image_preview = gui_data.main_notebook.image_preview_duplicates.clone();
// let preview_path = gui_data.preview_path.clone();
//
// let gc = gui_data.main_notebook.gc_tree_view_duplicate_finder.clone();
//
// gc.connect_released(move |gc, _event, _, _| {
// let tree_view = gc.widget().unwrap().downcast::<gtk4::TreeView>().unwrap();
// let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
// let preview_path = preview_path.clone();
// show_preview(&tree_view, &text_view_errors, &check_button_settings_show_preview, &image_preview, preview_path, nb_object.column_path, nb_object.column_name);
// });
// }
// // Similar Images
// {
// let text_view_errors = gui_data.text_view_errors.clone();
// let check_button_settings_show_preview = gui_data.settings.check_button_settings_show_preview_similar_images.clone();
// let preview_path = gui_data.preview_path.clone();
// let image_preview = gui_data.main_notebook.image_preview_similar_images.clone();
//
// let gc = gui_data.main_notebook.gc_tree_view_similar_images_finder.clone();
//
// gc.connect_released(move |gc, _event, _, _| {
// let tree_view = gc.widget().unwrap().downcast::<gtk4::TreeView>().unwrap();
// let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
// let preview_path = preview_path.clone();
// show_preview(&tree_view, &text_view_errors, &check_button_settings_show_preview, &image_preview, preview_path, nb_object.column_path, nb_object.column_name);
// });
// }
}
fn connect_event_buttons(gui_data: &GuiData) {
for evk in [
@ -652,7 +624,7 @@ fn connect_event_buttons(gui_data: &GuiData) {
let preview_path = preview_path.clone();
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
show_preview(
&event_controller_key.widget().unwrap().downcast::<gtk::TreeView>().unwrap(),
&event_controller_key.widget().downcast::<gtk4::TreeView>().unwrap(),
&text_view_errors,
&check_button_settings_show_preview,
&image_preview,
@ -680,7 +652,7 @@ fn connect_event_buttons(gui_data: &GuiData) {
let preview_path = preview_path.clone();
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
show_preview(
&event_controller_key.widget().unwrap().downcast::<gtk::TreeView>().unwrap(),
&event_controller_key.widget().downcast::<gtk4::TreeView>().unwrap(),
&text_view_errors,
&check_button_settings_show_preview_similar_images,
&image_preview,
@ -711,8 +683,8 @@ fn show_preview(
// TODO labels on {} are in testing stage, so we just ignore for now this warning until found better idea how to fix this
#[allow(clippy::never_loop)]
'dir: loop {
let path = tree_model.value(&tree_model.iter(&tree_path).unwrap(), column_path).get::<String>().unwrap();
let name = tree_model.value(&tree_model.iter(&tree_path).unwrap(), column_name).get::<String>().unwrap();
let path = tree_model.get::<String>(&tree_model.iter(&tree_path).unwrap(), column_path);
let name = tree_model.get::<String>(&tree_model.iter(&tree_path).unwrap(), column_name);
let file_name = get_full_name_from_path_name(&path, &name);
let file_name = file_name.as_str();
@ -749,7 +721,7 @@ fn show_preview(
}
};
pixbuf = match resize_pixbuf_dimension(pixbuf, (400, 400), InterpType::Nearest) {
pixbuf = match resize_pixbuf_dimension(pixbuf, (800, 800), InterpType::Nearest) {
None => {
add_text_to_text_view(
text_view_errors,
@ -760,7 +732,7 @@ fn show_preview(
Some(pixbuf) => pixbuf,
};
image_preview.set_pixbuf(Some(&pixbuf));
image_preview.set_from_pixbuf(Some(&pixbuf));
{
let mut preview_path = preview_path.borrow_mut();
*preview_path = file_name.to_string();

View file

@ -5,9 +5,10 @@
#![allow(clippy::type_complexity)]
#![allow(clippy::needless_late_init)]
use gtk::gio::ApplicationFlags;
use gtk::prelude::*;
use gtk::Application;
use gtk4::gio::ApplicationFlags;
use gtk4::prelude::*;
use gtk4::Application;
use gtk4::Inhibit;
use std::env;
use std::ffi::OsString;
@ -59,7 +60,7 @@ mod taskbar_progress_win;
mod tests;
fn main() {
let application = gtk::Application::new(None, ApplicationFlags::HANDLES_OPEN | ApplicationFlags::HANDLES_COMMAND_LINE);
let application = gtk4::Application::new(None, ApplicationFlags::HANDLES_OPEN | ApplicationFlags::HANDLES_COMMAND_LINE);
application.connect_command_line(move |app, cmdline| {
build_ui(app, cmdline.arguments());
0
@ -186,7 +187,7 @@ fn build_ui(application: &Application, arguments: Vec<OsString>) {
let window_main = gui_data.window_main.clone();
let taskbar_state = gui_data.taskbar_state.clone();
let used_additional_arguments = arguments.len() > 1;
window_main.connect_delete_event(move |_, _| {
window_main.connect_close_request(move |_| {
// Not save configuration when using non default arguments
if !used_additional_arguments {
save_configuration(false, &gui_data.upper_notebook, &gui_data.main_notebook, &gui_data.settings, &gui_data.text_view_errors);

View file

@ -1,32 +1,15 @@
use gdk::ModifierType;
use gtk::prelude::*;
use gdk4::{Key, ModifierType};
use glib::signal::Inhibit;
use gtk4::prelude::*;
use gtk4::GestureClick;
use crate::help_functions::*;
use crate::notebook_enums::NotebookUpperEnum;
// TODO add option to open files and folders from context menu activated by pressing ONCE with right mouse button
pub fn opening_enter_function_ported(event_controller: &gtk::EventControllerKey, _key_value: u32, key_code: u32, _modifier_type: ModifierType) -> bool {
let tree_view = event_controller.widget().unwrap().downcast::<gtk::TreeView>().unwrap();
#[cfg(debug_assertions)]
{
println!("key_code {}", key_code);
}
let nt_object = get_notebook_object_from_tree_view(&tree_view);
handle_tree_keypress(
&tree_view,
key_code,
nt_object.column_name,
nt_object.column_path,
nt_object.column_selection,
nt_object.column_color,
);
false // True catches signal, and don't send it to function, e.g. up button is catched and don't move selection
}
pub fn opening_enter_function_ported_upper_directories(event_controller: &gtk::EventControllerKey, _key_value: u32, key_code: u32, _modifier_type: ModifierType) -> bool {
let tree_view = event_controller.widget().unwrap().downcast::<gtk::TreeView>().unwrap();
pub fn opening_enter_function_ported_upper_directories(event_controller: &gtk4::EventControllerKey, _key_value: Key, key_code: u32, _modifier_type: ModifierType) -> Inhibit {
let tree_view = event_controller.widget().downcast::<gtk4::TreeView>().unwrap();
#[cfg(debug_assertions)]
{
println!("key_code {}", key_code);
@ -48,101 +31,101 @@ pub fn opening_enter_function_ported_upper_directories(event_controller: &gtk::E
panic!()
}
}
false // True catches signal, and don't send it to function, e.g. up button is catched and don't move selection
// false // True catches signal, and don't send it to function, e.g. up button is catched and don't move selection
Inhibit(false)
}
pub fn opening_double_click_function(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
let nt_object = get_notebook_object_from_tree_view(tree_view);
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, nt_object.column_name, nt_object.column_path, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, nt_object.column_name, nt_object.column_path, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_middle_mouse_function(gesture_click: &GestureClick, _number_of_clicks: i32, _b: f64, _c: f64) {
println!("MIDDLE MOUSE BUTTON CLICKED");
let tree_view = gesture_click.widget().downcast::<gtk4::TreeView>().unwrap();
pub fn opening_middle_mouse_function(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
let nt_object = get_notebook_object_from_tree_view(tree_view);
if let Some(column_color) = nt_object.column_color {
if event.button() == 2 {
reverse_selection(tree_view, column_color, nt_object.column_selection);
let nt_object = get_notebook_object_from_tree_view(&tree_view);
if let Some(column_header) = nt_object.column_header {
if gesture_click.current_button() == 2 {
reverse_selection(&tree_view, column_header, nt_object.column_selection);
}
}
gtk::Inhibit(false)
}
pub fn opening_double_click_function_directories(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && (event.button() == 1 || event.button() == 3) {
match get_notebook_upper_enum_from_tree_view(tree_view) {
pub fn opening_double_click_function_directories(gesture_click: &GestureClick, number_of_clicks: i32, _b: f64, _c: f64) {
let tree_view = gesture_click.widget().downcast::<gtk4::TreeView>().unwrap();
if number_of_clicks == 2 && (gesture_click.current_button() == 1 || gesture_click.current_button() == 3) {
match get_notebook_upper_enum_from_tree_view(&tree_view) {
NotebookUpperEnum::IncludedDirectories => {
common_open_function_upper_directories(tree_view, ColumnsIncludedDirectory::Path as i32);
common_open_function_upper_directories(&tree_view, ColumnsIncludedDirectory::Path as i32);
}
NotebookUpperEnum::ExcludedDirectories => {
common_open_function_upper_directories(tree_view, ColumnsExcludedDirectory::Path as i32);
common_open_function_upper_directories(&tree_view, ColumnsExcludedDirectory::Path as i32);
}
_ => {
panic!()
}
}
}
gtk::Inhibit(false)
}
// // GTK 4
// pub fn opening_enter_function_ported(event_controller: &gtk4::EventControllerKey, _key: gdk4::keys::Key, key_code: u32, _modifier_type: ModifierType) -> gtk4::Inhibit {
// let tree_view = event_controller.widget().unwrap().downcast::<gtk4::TreeView>().unwrap();
// #[cfg(debug_assertions)]
// {
// println!("key_code {}", key_code);
// }
//
// let nt_object = get_notebook_object_from_tree_view(&tree_view);
// handle_tree_keypress(&tree_view, key_code, nt_object.column_name, nt_object.column_path, nt_object.column_selection);
// Inhibit(false) // True catches signal, and don't send it to function, e.g. up button is catched and don't move selection
// }
//
// pub fn opening_double_click_function(gesture_click: &GestureClick, number_of_clicks: i32, _b: f64, _c: f64) {
// let tree_view = gesture_click.widget().unwrap().downcast::<gtk4::TreeView>().unwrap();
//
// let nt_object = get_notebook_object_from_tree_view(&tree_view);
// if number_of_clicks == 2 {
// if gesture_click.current_button() == 1 {
// common_open_function(&tree_view, nt_object.column_name, nt_object.column_path, OpenMode::PathAndName);
// } else if gesture_click.current_button() == 3 {
// common_open_function(&tree_view, nt_object.column_name, nt_object.column_path, OpenMode::OnlyPath);
// }
// }
// }
pub fn opening_enter_function_ported(event_controller: &gtk4::EventControllerKey, _key: gdk4::Key, key_code: u32, _modifier_type: ModifierType) -> gtk4::Inhibit {
let tree_view = event_controller.widget().downcast::<gtk4::TreeView>().unwrap();
#[cfg(debug_assertions)]
{
println!("key_code {}", key_code);
}
let nt_object = get_notebook_object_from_tree_view(&tree_view);
handle_tree_keypress(
&tree_view,
key_code,
nt_object.column_name,
nt_object.column_path,
nt_object.column_selection,
nt_object.column_header,
);
Inhibit(false) // True catches signal, and don't send it to function, e.g. up button is catched and don't move selection
}
pub fn opening_double_click_function(gesture_click: &GestureClick, number_of_clicks: i32, _b: f64, _c: f64) {
let tree_view = gesture_click.widget().downcast::<gtk4::TreeView>().unwrap();
let nt_object = get_notebook_object_from_tree_view(&tree_view);
if number_of_clicks == 2 {
if gesture_click.current_button() == 1 {
common_open_function(&tree_view, nt_object.column_name, nt_object.column_path, OpenMode::PathAndName);
} else if gesture_click.current_button() == 3 {
common_open_function(&tree_view, nt_object.column_name, nt_object.column_path, OpenMode::OnlyPath);
}
}
}
enum OpenMode {
OnlyPath,
PathAndName,
}
fn common_mark_function(tree_view: &gtk::TreeView, column_selection: i32, column_color: Option<i32>) {
fn common_mark_function(tree_view: &gtk4::TreeView, column_selection: i32, column_header: Option<i32>) {
let selection = tree_view.selection();
let (selected_rows, tree_model) = selection.selected_rows();
let model = get_list_store(tree_view);
for tree_path in selected_rows.iter().rev() {
if let Some(column_color) = column_color {
if model.value(&model.iter(tree_path).unwrap(), column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if let Some(column_header) = column_header {
if model.get::<bool>(&model.iter(tree_path).unwrap(), column_header) {
continue;
}
}
let value = !tree_model.value(&tree_model.iter(tree_path).unwrap(), column_selection).get::<bool>().unwrap();
let value = !tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), column_selection);
model.set_value(&tree_model.iter(tree_path).unwrap(), column_selection as u32, &value.to_value());
}
}
fn common_open_function(tree_view: &gtk::TreeView, column_name: i32, column_path: i32, opening_mode: OpenMode) {
fn common_open_function(tree_view: &gtk4::TreeView, column_name: i32, column_path: i32, opening_mode: OpenMode) {
let selection = tree_view.selection();
let (selected_rows, tree_model) = selection.selected_rows();
for tree_path in selected_rows.iter().rev() {
let name = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name).get::<String>().unwrap();
let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::<String>().unwrap();
let name = tree_model.get::<String>(&tree_model.iter(tree_path).unwrap(), column_name);
let path = tree_model.get::<String>(&tree_model.iter(tree_path).unwrap(), column_path);
let end_path = match opening_mode {
OpenMode::OnlyPath => path,
@ -156,9 +139,9 @@ fn common_open_function(tree_view: &gtk::TreeView, column_name: i32, column_path
// }
}
}
fn reverse_selection(tree_view: &gtk::TreeView, column_color: i32, column_selection: i32) {
fn reverse_selection(tree_view: &gtk4::TreeView, column_header: i32, column_selection: i32) {
let (selected_rows, model) = tree_view.selection().selected_rows();
let model = model.downcast::<gtk::ListStore>().unwrap();
let model = model.downcast::<gtk4::ListStore>().unwrap();
if selected_rows.len() != 1 {
return; // Multiple selection is not supported because it is a lot of harder to do it properly
@ -166,12 +149,12 @@ fn reverse_selection(tree_view: &gtk::TreeView, column_color: i32, column_select
let tree_path = selected_rows[0].clone();
let current_iter = model.iter(&tree_path).unwrap();
if model.value(&current_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&current_iter, column_header) {
return; // Selecting header is not supported(this is available by using reference)
}
// This will revert selection of current selected item, but I don't think that this is needed
// let current_value = model.value(&current_iter, column_selection).get::<bool>().unwrap();
// let current_value = model.get::<bool>(&current_iter, column_selection);
// model.set_value(&current_iter, column_selection as u32, &(!current_value).to_value());
let to_upper_iter = current_iter;
@ -179,11 +162,11 @@ fn reverse_selection(tree_view: &gtk::TreeView, column_color: i32, column_select
if !model.iter_previous(&to_upper_iter) {
break;
}
if model.value(&to_upper_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&to_upper_iter, column_header) {
break;
}
let current_value = model.value(&to_upper_iter, column_selection).get::<bool>().unwrap();
let current_value = model.get::<bool>(&to_upper_iter, column_selection);
model.set_value(&to_upper_iter, column_selection as u32, &(!current_value).to_value());
}
@ -192,27 +175,27 @@ fn reverse_selection(tree_view: &gtk::TreeView, column_color: i32, column_select
if !model.iter_next(&to_lower_iter) {
break;
}
if model.value(&to_lower_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
if model.get::<bool>(&to_lower_iter, column_header) {
break;
}
let current_value = model.value(&to_lower_iter, column_selection).get::<bool>().unwrap();
let current_value = model.get::<bool>(&to_lower_iter, column_selection);
model.set_value(&to_lower_iter, column_selection as u32, &(!current_value).to_value());
}
}
fn common_open_function_upper_directories(tree_view: &gtk::TreeView, column_full_path: i32) {
fn common_open_function_upper_directories(tree_view: &gtk4::TreeView, column_full_path: i32) {
let selection = tree_view.selection();
let (selected_rows, tree_model) = selection.selected_rows();
for tree_path in selected_rows.iter().rev() {
let full_path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_full_path).get::<String>().unwrap();
let full_path = tree_model.get::<String>(&tree_model.iter(tree_path).unwrap(), column_full_path);
open::that_in_background(&full_path);
}
}
fn handle_tree_keypress_upper_directories(tree_view: &gtk::TreeView, key_code: u32, full_path_column: i32, mark_column: Option<i32>) {
fn handle_tree_keypress_upper_directories(tree_view: &gtk4::TreeView, key_code: u32, full_path_column: i32, mark_column: Option<i32>) {
match key_code {
KEY_ENTER => {
common_open_function_upper_directories(tree_view, full_path_column);
@ -226,69 +209,33 @@ fn handle_tree_keypress_upper_directories(tree_view: &gtk::TreeView, key_code: u
}
}
fn handle_tree_keypress(tree_view: &gtk::TreeView, key_code: u32, name_column: i32, path_column: i32, mark_column: i32, column_color: Option<i32>) {
fn handle_tree_keypress(tree_view: &gtk4::TreeView, key_code: u32, name_column: i32, path_column: i32, mark_column: i32, column_header: Option<i32>) {
match key_code {
KEY_ENTER => {
common_open_function(tree_view, name_column, path_column, OpenMode::PathAndName);
}
KEY_SPACE => {
common_mark_function(tree_view, mark_column, column_color);
common_mark_function(tree_view, mark_column, column_header);
}
_ => {}
}
}
pub fn select_function_duplicates(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model
.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Color as i32)
.get::<String>()
.unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
pub fn select_function_duplicates(_tree_selection: &gtk4::TreeSelection, tree_model: &gtk4::TreeModel, tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
!tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::IsHeader as i32)
}
pub fn select_function_same_music(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model
.value(&tree_model.iter(tree_path).unwrap(), ColumnsSameMusic::Color as i32)
.get::<String>()
.unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
pub fn select_function_same_music(_tree_selection: &gtk4::TreeSelection, tree_model: &gtk4::TreeModel, tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
!tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), ColumnsSameMusic::IsHeader as i32)
}
pub fn select_function_similar_images(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model
.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarImages::Color as i32)
.get::<String>()
.unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
pub fn select_function_similar_images(_tree_selection: &gtk4::TreeSelection, tree_model: &gtk4::TreeModel, tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
!tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarImages::IsHeader as i32)
}
pub fn select_function_similar_videos(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model
.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarVideos::Color as i32)
.get::<String>()
.unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}
pub fn select_function_always_true(_tree_selection: &gtk::TreeSelection, _tree_model: &gtk::TreeModel, _tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
pub fn select_function_similar_videos(_tree_selection: &gtk4::TreeSelection, tree_model: &gtk4::TreeModel, tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
!tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarVideos::IsHeader as i32)
}
pub fn select_function_always_true(_tree_selection: &gtk4::TreeSelection, _tree_model: &gtk4::TreeModel, _tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
true
}

View file

@ -7,8 +7,8 @@ use std::{env, fs};
use czkawka_core::common_dir_traversal::CheckingMethod;
use directories_next::ProjectDirs;
use gtk::prelude::*;
use gtk::{ComboBoxText, ScrolledWindow, TextView};
use gtk4::prelude::*;
use gtk4::{ComboBoxText, ScrolledWindow, TextView};
use crate::flg;
use crate::gui_structs::gui_main_notebook::GuiMainNotebook;
@ -64,11 +64,11 @@ const DEFAULT_EXCLUDED_DIRECTORIES: &[&str] = &["C:\\Windows"];
struct LoadSaveStruct {
loaded_items: HashMap<String, Vec<String>>,
text_view: gtk::TextView,
text_view: gtk4::TextView,
}
impl LoadSaveStruct {
pub fn with_text_view(text_view: gtk::TextView) -> Self {
pub fn with_text_view(text_view: gtk4::TextView) -> Self {
Self {
loaded_items: Default::default(),
text_view,
@ -193,13 +193,13 @@ impl LoadSaveStruct {
self.loaded_items.insert(key, vec![value.to_string()]);
}
pub fn save_list_store(&mut self, key: String, tree_view: &gtk::TreeView, column_path: i32) {
pub fn save_list_store(&mut self, key: String, tree_view: &gtk4::TreeView, column_path: i32) {
let mut vec_string = vec![];
let list_store = get_list_store(tree_view);
if let Some(iter) = list_store.iter_first() {
loop {
// TODO maybe save also here reference directories?
vec_string.push(list_store.value(&iter, column_path).get::<String>().unwrap());
vec_string.push(list_store.get::<String>(&iter, column_path));
if !list_store.iter_next(&iter) {
break;
}

View file

@ -1,131 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 -->
<!-- Generated with glade 3.39.0
The MIT License (MIT)
Copyright (c)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Author: Rafał Mikrut
-->
<interface>
<!-- interface-name Czkawka -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. -->
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<object class="GtkAboutDialog" id="about_dialog">
<property name="can-focus">False</property>
<property name="comments" translatable="yes">2020 - 2022 Rafał Mikrut(qarmin)
This program is free to use and will always be.
</property>
<property name="license-type">mit-x11</property>
<property name="logo-icon-name">image-missing</property>
<property name="program-name">Czkawka</property>
<property name="type-hint">dialog</property>
<property name="version">4.1.0</property>
<property name="window-position">center</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-bottom">3</property>
<property name="visible">True</property>
<child>
<object class="GtkButton" id="button_repository">
<property name="can-focus">True</property>
<property name="label" translatable="yes">Repository</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_instruction">
<property name="can-focus">True</property>
<property name="label" translatable="yes">Instruction</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_donation">
<property name="can-focus">True</property>
<property name="label" translatable="yes">Donation</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_translation">
<property name="can-focus">True</property>
<property name="label" translatable="yes">Translation</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View file

@ -1,137 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.39.0
The MIT License (MIT)
Copyright (c)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Author: Rafał Mikrut
-->
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.1 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<!-- interface-license-type mit -->
<!-- interface-name Czkawka -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. -->
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-name about_dialog.ui -->
<requires lib="gtk" version="4.0"/>
<object class="GtkAboutDialog" id="about_dialog">
<property name="can-focus">False</property>
<property name="window-position">center</property>
<property name="type-hint">dialog</property>
<property name="program-name">Czkawka</property>
<property name="version">4.1.0</property>
<property name="comments" translatable="yes">2020 - 2022 Rafał Mikrut(qarmin)
This program is free to use and will always be.
</property>
<property name="authors">Rafał Mikrut(qarmin)</property>
<property name="logo-icon-name">help-about</property>
<property name="license-type">mit-x11</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-bottom">3</property>
<child>
<object class="GtkButton" id="button_repository">
<property name="label" translatable="yes">Repository</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_instruction">
<property name="label" translatable="yes">Instruction</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_donation">
<property name="label" translatable="yes">Donation</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_translation">
<property name="label" translatable="yes">Translation</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
<property name="logo-icon-name">help-about-symbolic</property>
<property name="program-name">Czkawka</property>
<property name="version">4.1.0</property>
</object>
</interface>

View file

@ -1,190 +1,79 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 -->
<!-- Generated with glade 3.39.0 -->
<!-- Created with Cambalache 0.9.1 -->
<interface>
<!-- interface-name compare_images.ui -->
<requires lib="gtk+" version="3.24"/>
<requires lib="gtk" version="4.0"/>
<object class="GtkDialog" id="window_compare">
<property name="can-focus">False</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<property name="vexpand">1</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="label_group_info">
<property name="halign">center</property>
<property name="hexpand">1</property>
<property name="label" translatable="yes">Group XD/PER XD (99 images in current group)</property>
</object>
</child>
<child>
<object class="GtkButton" id="button_go_next_compare_group">
<property name="focusable">1</property>
<property name="receives-default">1</property>
<child>
<object class="GtkImage">
<property name="icon-name">image-missing</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="button_go_previous_compare_group">
<property name="focusable">1</property>
<property name="receives-default">1</property>
<child>
<object class="GtkImage">
<property name="icon-name">image-missing</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<property name="homogeneous">1</property>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label_group_info">
<property name="can-focus">False</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Group XD/PER XD (99 images in current group)</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">-1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_go_next_compare_group">
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<child>
<object class="GtkImage">
<property name="can-focus">False</property>
<property name="icon-name">image-missing</property>
<property name="visible">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_go_previous_compare_group">
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<child>
<object class="GtkImage">
<property name="can-focus">False</property>
<property name="icon-name">image-missing</property>
<property name="visible">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<object class="GtkCheckButton" id="check_button_left_preview_text">
<property name="focusable">1</property>
<property name="label" translatable="yes">First Game</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="homogeneous">True</property>
<property name="visible">True</property>
<child>
<object class="GtkCheckButton" id="check_button_left_preview_text">
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">First Game</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_right_preview_text">
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Second Game</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<object class="GtkCheckButton" id="check_button_right_preview_text">
<property name="focusable">1</property>
<property name="label" translatable="yes">Second Game</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="homogeneous">True</property>
<property name="visible">True</property>
<child>
<object class="GtkImage" id="image_compare_left">
<property name="can-focus">False</property>
<property name="stock">gtk-missing-image</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image_compare_right">
<property name="can-focus">False</property>
<property name="stock">gtk-missing-image</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolled_window_compare_choose_images">
<property name="can-focus">True</property>
<property name="shadow-type">in</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="homogeneous">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkImage" id="image_compare_left"/>
</child>
<child>
<object class="GtkImage" id="image_compare_right"/>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolled_window_compare_choose_images">
<property name="focusable">1</property>
</object>
</child>
</object>
</child>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,73 +1,28 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 -->
<!-- Generated with glade 3.38.2
The MIT License (MIT)
Copyright (c)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Author: Rafał Mikrut
-->
<!-- Created with Cambalache 0.9.1 -->
<interface>
<!-- interface-name Czkawka -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. -->
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<!-- interface-name popover_right_click.ui -->
<requires lib="gtk" version="4.0"/>
<object class="GtkPopover" id="popover_right_click">
<property name="can-focus">False</property>
<property name="position">left</property>
<child>
<property name="child">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkButton" id="buttons_popover_right_click_open_file">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Open File</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttons_popover_right_click_open_folder">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Open Folder</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</property>
<property name="position">left</property>
</object>
</interface>

View file

@ -1,233 +1,102 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 -->
<!-- Generated with glade 3.38.2
The MIT License (MIT)
Copyright (c)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Author: Rafał Mikrut
-->
<!-- Created with Cambalache 0.9.1 -->
<interface>
<!-- interface-name Czkawka -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. -->
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<!-- interface-name popover_select.ui -->
<requires lib="gtk" version="4.0"/>
<object class="GtkPopover" id="popover_select">
<property name="can-focus">False</property>
<child>
<property name="child">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkButton" id="buttons_popover_select_custom">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Select custom</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttons_popover_unselect_custom">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Unselect custom</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSeparator" id="separator_select_custom">
<property name="can-focus">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
<object class="GtkSeparator" id="separator_select_custom"/>
</child>
<child>
<object class="GtkButton" id="buttons_popover_select_all_images_except_biggest">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Select all except biggest</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttons_popover_select_all_images_except_smallest">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Select all except smallest</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkSeparator" id="separator_select_image_size">
<property name="can-focus">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
<object class="GtkSeparator" id="separator_select_image_size"/>
</child>
<child>
<object class="GtkButton" id="buttons_popover_select_all_except_oldest">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Select all except oldest</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttons_popover_select_all_except_newest">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Select all except newest</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttons_popover_select_one_oldest">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Select one oldest</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">8</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttons_popover_select_one_newest">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Select one newest</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">9</property>
</packing>
</child>
<child>
<object class="GtkSeparator" id="separator_select_date">
<property name="can-focus">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">10</property>
</packing>
<object class="GtkSeparator" id="separator_select_date"/>
</child>
<child>
<object class="GtkButton" id="buttons_popover_reverse">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Reverse Selection</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">11</property>
</packing>
</child>
<child>
<object class="GtkSeparator" id="separator_select_reverse">
<property name="can-focus">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">12</property>
</packing>
<object class="GtkSeparator" id="separator_select_reverse"/>
</child>
<child>
<object class="GtkButton" id="buttons_popover_select_all">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Select All</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">13</property>
</packing>
</child>
<child>
<object class="GtkButton" id="buttons_popover_unselect_all">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Unselect All</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">14</property>
</packing>
</child>
</object>
</child>
</property>
</object>
</interface>

View file

@ -1,195 +1,94 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 -->
<!-- Generated with glade 3.39.0
The MIT License (MIT)
Copyright (c)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Author: Rafał Mikrut
-->
<!-- Created with Cambalache 0.9.1 -->
<interface>
<!-- interface-name Czkawka -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. -->
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<!-- interface-name progress.ui -->
<requires lib="gtk" version="4.0"/>
<object class="GtkDialog" id="window_progress">
<property name="can-focus">False</property>
<property name="gravity">center</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-bottom">10</property>
<property name="margin-end">10</property>
<property name="margin-start">10</property>
<property name="margin-top">10</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<property name="spacing">10</property>
<child>
<object class="GtkGrid" id="grid_progress_stages">
<property name="margin-end">2</property>
<property name="margin-start">2</property>
<property name="margin-top">2</property>
<property name="valign">center</property>
<property name="vexpand">1</property>
<child>
<object class="GtkLabel" id="label_progress_all_stages">
<property name="label" translatable="yes">All stages: </property>
<property name="name">label_progress_all_stages</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkProgressBar" id="progress_bar_all_stages">
<property name="hexpand">1</property>
<property name="pulse-step">0.099999999776482579</property>
<property name="show-text">1</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel" id="label_progress_current_stage">
<property name="label" translatable="yes">Current stage: </property>
<property name="name">label_progress_current_stage</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkProgressBar" id="progress_bar_current_stage">
<property name="show-text">1</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-bottom">10</property>
<property name="margin-end">10</property>
<property name="margin-start">10</property>
<property name="margin-top">10</property>
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<property name="visible">True</property>
<object class="GtkLabel" id="label_stage">
<property name="label" translatable="yes">Stage 1/2</property>
</object>
</child>
<child>
<object class="GtkButton" id="button_stop_in_dialog">
<property name="focusable">1</property>
<property name="halign">end</property>
<property name="margin-end">2</property>
<property name="receives-default">1</property>
<property name="valign">center</property>
<child>
<!-- n-columns=2 n-rows=2 -->
<object class="GtkGrid" id="grid_progress_stages">
<property name="can-focus">False</property>
<property name="margin-end">2</property>
<property name="margin-start">2</property>
<property name="margin-top">2</property>
<property name="valign">center</property>
<property name="visible">True</property>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="label_progress_all_stages">
<property name="can-focus">False</property>
<property name="label" translatable="yes">All stages: </property>
<property name="name">label_progress_all_stages</property>
<property name="visible">True</property>
<object class="GtkImage">
<property name="icon-name">image-missing</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkProgressBar" id="progress_bar_all_stages">
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="pulse-step">0.099999999776482579</property>
<property name="show-text">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_progress_current_stage">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Current stage: </property>
<property name="name">label_progress_current_stage</property>
<property name="visible">True</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkProgressBar" id="progress_bar_current_stage">
<property name="can-focus">False</property>
<property name="show-text">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_stage">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Stage 1/2</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_stop_in_dialog">
<property name="can-focus">True</property>
<property name="halign">end</property>
<property name="margin-end">2</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="visible">True</property>
<child>
<object class="GtkImage">
<property name="can-focus">False</property>
<property name="icon-name">image-missing</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Stop</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<object class="GtkLabel">
<property name="hexpand">1</property>
<property name="label" translatable="yes">Stop</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>

View file

@ -1,689 +1,343 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 -->
<!-- Generated with glade 3.39.0
The MIT License (MIT)
Copyright (c)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Author: Rafał Mikrut
-->
<!-- Created with Cambalache 0.9.1 -->
<interface>
<!-- interface-name Czkawka -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. -->
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<!-- interface-name settings.ui -->
<requires lib="gtk" version="4.0"/>
<object class="GtkDialog" id="window_settings">
<property name="can-focus">False</property>
<property name="modal">True</property>
<property name="modal">1</property>
<property name="title" translatable="yes">Czkawka Options</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<child>
<object class="GtkBox" id="potatoo">
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<property name="vexpand">1</property>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkComboBoxText">
<property name="can-focus">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<object class="GtkComboBoxText">
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkNotebook" id="notebook_settings">
<property name="focusable">1</property>
<property name="tab-pos">left</property>
<property name="vexpand">1</property>
<child>
<object class="GtkNotebook" id="notebook_settings">
<property name="can-focus">True</property>
<property name="tab-pos">left</property>
<property name="visible">True</property>
<child>
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-bottom">5</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<property name="valign">center</property>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label_settings_general_language">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Language</property>
<property name="margin-end">10</property>
<property name="margin-start">5</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="combo_box_settings_language">
<property name="can-focus">False</property>
<property name="visible">True</property>
<property name="hexpand">1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_load_at_start">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Load configuration at start</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_save_at_exit">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Save configuration at exit</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_confirm_deletion">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Show confirm dialog when deleting any files</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_confirm_link">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Show confirm dialog when hard/symlinks any files</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_confirm_group_deletion">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Show confirm dialog when deleting all files in group</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_show_text_view">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Show bottom text panel</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">6</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_use_cache">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Use cache</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
<property name="vexpand">1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_save_also_json">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Save cache also to JSON file</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
<property name="vexpand">1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">8</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_use_trash">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Move deleted files to trash</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">9</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="visible">True</property>
<property name="valign">center</property>
<child>
<object class="GtkButton" id="button_settings_open_cache_folder">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Open cache folder</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_settings_open_settings_folder">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Open settings folder</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="tab">
</property>
<property name="tab">
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">General</property>
<property name="visible">True</property>
</object>
<packing>
<property name="tab-fill">False</property>
</packing>
</child>
<child>
</property>
</object>
</child>
<child>
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkCheckButton" id="check_button_settings_hide_hard_links">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Hide hard links(only Linux and MacOS)</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_show_preview_duplicates">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Show image preview</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_duplicates_delete_outdated_cache">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Delete outdated cache entries automatically</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-end">4</property>
<property name="margin-start">4</property>
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label_settings_duplicate_minimal_size_cache">
<property name="can-focus">False</property>
<property name="hexpand">1</property>
<property name="label" translatable="yes">Minimal size of files in bytes saved to cache</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_settings_cache_file_minimal_size">
<property name="can-focus">True</property>
<property name="caps-lock-warning">False</property>
<property name="focusable">1</property>
<property name="halign">center</property>
<property name="input-purpose">number</property>
<property name="max-length">15</property>
<property name="text" translatable="yes">257144</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_duplicates_use_prehash_cache">
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Use prehash cache</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_settings_duplicates_clear_cache">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Remove outdated results from duplicates cache</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-end">4</property>
<property name="margin-start">4</property>
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label_settings_duplicate_minimal_size_cache_prehash">
<property name="can-focus">False</property>
<property name="hexpand">1</property>
<property name="label" translatable="yes">Minimal size of files in bytes saved to prehash cache</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_settings_prehash_cache_file_minimal_size">
<property name="can-focus">True</property>
<property name="caps-lock-warning">False</property>
<property name="focusable">1</property>
<property name="halign">center</property>
<property name="input-purpose">number</property>
<property name="max-length">15</property>
<property name="text" translatable="yes">1</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
</property>
<property name="position">1</property>
<property name="tab">
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Duplicate Finder</property>
<property name="visible">True</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab-fill">False</property>
</packing>
</child>
<child>
</property>
</object>
</child>
<child>
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkCheckButton" id="check_button_settings_show_preview_similar_images">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Show image preview</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_similar_images_delete_outdated_cache">
<property name="active">True</property>
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="active">1</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Delete outdated cache entries automatically</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_settings_similar_images_clear_cache">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Remove outdated results from images cache</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child type="tab">
</property>
<property name="position">2</property>
<property name="tab">
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Similar Images</property>
<property name="visible">True</property>
</object>
<packing>
<property name="position">2</property>
<property name="tab-fill">False</property>
</packing>
</child>
<child>
</property>
</object>
</child>
<child>
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkButton" id="button_settings_similar_videos_clear_cache">
<property name="can-focus">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Remove outdated results from videos cache</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
<property name="receives-default">1</property>
<property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_button_settings_similar_videos_delete_outdated_cache">
<property name="can-focus">True</property>
<property name="draw-indicator">True</property>
<property name="focusable">1</property>
<property name="label" translatable="yes">Delete outdated cache entries automatically</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child type="tab">
</property>
<property name="position">3</property>
<property name="tab">
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Similar Videos</property>
<property name="visible">True</property>
</object>
<packing>
<property name="position">3</property>
<property name="tab-fill">False</property>
</packing>
</child>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="margin-end">3</property>
<property name="margin-start">3</property>
<property name="spacing">3</property>
<child>
<object class="GtkButton" id="button_settings_load_configuration">
<property name="focusable">1</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Load configuration</property>
<property name="receives-default">1</property>
</object>
</child>
<child>
<object class="GtkButton" id="button_settings_reset_configuration">
<property name="focusable">1</property>
<property name="halign">center</property>
<property name="hexpand">1</property>
<property name="label" translatable="yes">Reset configuration</property>
<property name="receives-default">1</property>
</object>
</child>
<child>
<object class="GtkButton" id="button_settings_save_configuration">
<property name="focusable">1</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Save configuration</property>
<property name="receives-default">1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-end">3</property>
<property name="margin-start">3</property>
<property name="spacing">3</property>
<property name="visible">True</property>
<child>
<object class="GtkButton" id="button_settings_load_configuration">
<property name="can-focus">True</property>
<property name="label" translatable="yes">Load configuration</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_settings_reset_configuration">
<property name="can-focus">True</property>
<property name="label" translatable="yes">Reset configuration</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_settings_save_configuration">
<property name="can-focus">True</property>
<property name="label" translatable="yes">Save configuration</property>
<property name="receives-default">True</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack-type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">3</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>

View file

@ -16,7 +16,7 @@ FFmpeg is not included here because it is not needed to build - it is dynamicall
```shell
sudo apt install -y curl git build-essential # Needed by Rust update tool
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Download the latest stable Rust
sudo apt install -y libgtk-3-dev
sudo apt install -y libgtk-4-dev
```
#### Fedora / CentOS / Rocky Linux
@ -42,7 +42,7 @@ For Linux-to-Windows cross-building instruction look at the CI.
<!-- First you need to install Visual C++ components from Visual Studio installer - https://visualstudio.microsoft.com/downloads/
Next install Rust from site https://rustup.rs/
After that the latest GTK 3 runtime must be installed from https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases
After that the latest GTK 4 runtime must be installed from(not available yet for GTK 4) https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases
-->
### Docker

View file

@ -9,7 +9,7 @@ Broken files finder by default don't check for music files, but it is possible t
#### Ubuntu/Debian/Linux Mint
```
sudo apt install libgtk-3-dev ffmpeg
sudo apt install libgtk-4-dev ffmpeg
```
#### Fedora/Rocky Linux
```
@ -24,7 +24,7 @@ sudo xbps-install gcc pkg-config ffmpeg
```
### macOS
Currently, you need to manually install `GTK 3` libraries, `FFmpeg` and the Adwaita theme, because they are dynamically loaded from the OS.
Currently, you need to manually install `GTK 4` libraries, `FFmpeg` and the Adwaita theme, because they are dynamically loaded from the OS.
One very straight-forward way to do this is by using [Homebrew](https://brew.sh/).
Installation in the terminal:
```shell
@ -47,7 +47,7 @@ arch -x86_64 /usr/local/bin/brew install gtk+3 adwaita-icon-theme ffmpeg librsvg
```
### Windows
By default, all needed libraries are bundled with the app, inside `windows_czkawka_gui.zip`, but if you compile the app or just move `czkawka_gui.exe`, then you will need to install the `GTK 3`
By default, all needed libraries are bundled with the app, inside `windows_czkawka_gui.zip`, but if you compile the app or just move `czkawka_gui.exe`, then you will need to install the `GTK 4`
runtime from [**here**](https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases).
FFmpeg to be able to use Similar Videos, you can download and install from this [**link**](https://ffmpeg.org/).

View file

@ -2,7 +2,7 @@ FROM debian:11
# curl is needed by Rust update tool
RUN apt-get update \
&& apt-get install -y curl build-essential libgtk-3-dev \
&& apt-get install -y curl build-essential libgtk-4-dev \
&& apt-get clean ; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y # Download the latest stable Rust

View file

@ -4,7 +4,7 @@ version: '4.1.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Czkawka - fast data cleaner written in Rust # 79 char long summary
description: |
Czkawka is very fast and feature rich cleaner which finds file duplicates, empty folders and files, duplicated music, similar images or the biggest files in selected directories.
This program have frontend written in modern GTK 3.
This program have frontend written in GTK 4.
grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots
compression: lzo