1
0
Fork 0
mirror of synced 2024-05-06 21:42:42 +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: matrix:
toolchain: [ stable ] toolchain: [ stable ]
type: [ release ] type: [ release ]
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -32,20 +32,20 @@ jobs:
linux-cli-${{github.ref}}-${{github.sha}} linux-cli-${{github.ref}}-${{github.sha}}
- name: Install basic libraries - 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 - name: Build CLI Debug
run: cargo build --bin czkawka_cli run: cargo build --bin czkawka_cli
env: env:
CARGO_INCREMENTAL: 0 CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings" RUSTFLAGS: "-C debuginfo=0"
if: ${{ matrix.type == 'debug'}} if: ${{ matrix.type == 'debug'}}
- name: Build CLI Release - name: Build CLI Release
run: cargo build --release --bin czkawka_cli run: cargo build --release --bin czkawka_cli
env: env:
CARGO_INCREMENTAL: 0 CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings" RUSTFLAGS: "-C debuginfo=0"
if: ${{ matrix.type == 'release'}} if: ${{ matrix.type == 'release'}}
- name: Store Linux CLI - name: Store Linux CLI
@ -132,7 +132,7 @@ jobs:
matrix: matrix:
toolchain: [ stable, 1.60.0 ] toolchain: [ stable, 1.60.0 ]
type: [ release ] type: [ release ]
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -150,20 +150,20 @@ jobs:
linux-gui-${{github.ref}}-${{github.sha}} linux-gui-${{github.ref}}-${{github.sha}}
- name: Install Gtk, Mingw, unzip, zip and wget - 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 - name: Build GUI Debug
run: cargo build --bin czkawka_gui run: cargo build --bin czkawka_gui
env: env:
CARGO_INCREMENTAL: 0 CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings" RUSTFLAGS: "-C debuginfo=0"
if: ${{ matrix.type == 'debug'}} if: ${{ matrix.type == 'debug'}}
- name: Build GUI Release - name: Build GUI Release
run: cargo build --release --bin czkawka_gui run: cargo build --release --bin czkawka_gui
env: env:
CARGO_INCREMENTAL: 0 CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings" RUSTFLAGS: "-C debuginfo=0"
if: ${{ matrix.type == 'release'}} if: ${{ matrix.type == 'release'}}
- name: Store Linux GUI - name: Store Linux GUI
@ -196,7 +196,7 @@ jobs:
matrix: matrix:
toolchain: [ stable ] toolchain: [ stable ]
type: [ release ] type: [ release ]
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -214,13 +214,13 @@ jobs:
linux-appimage-gui-${{github.ref}}-${{github.sha}} linux-appimage-gui-${{github.ref}}-${{github.sha}}
- name: Install Gtk, - 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 - name: Build GUI Release
run: cargo build --release --bin czkawka_gui run: cargo build --release --bin czkawka_gui
env: env:
CARGO_INCREMENTAL: 0 CARGO_INCREMENTAL: 0
RUSTFLAGS: "-C debuginfo=0 -D warnings" RUSTFLAGS: "-C debuginfo=0"
- name: Download appimage dependiences - name: Download appimage dependiences
run: | run: |

View file

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

View file

@ -29,7 +29,7 @@ jobs:
override: true override: true
- name: Install Gtk - 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 - name: Check the format
run: cargo fmt --all -- --check run: cargo fmt --all -- --check

View file

@ -152,7 +152,7 @@ jobs:
matrix: matrix:
toolchain: [ stable ] toolchain: [ stable ]
type: [ release ] type: [ release ]
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -162,7 +162,7 @@ jobs:
override: true override: true
- name: Install Gtk, Mingw, unzip, zip and wget - 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 - name: Build GUI Release Cross Compile
run: | run: |
@ -176,8 +176,8 @@ jobs:
GTK_APP="$(pwd)/gtk_app" GTK_APP="$(pwd)/gtk_app"
GTK_THEME="$(pwd)/gtk_theme" GTK_THEME="$(pwd)/gtk_theme"
wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/mingw64.zip wget https://github.com/qarmin/gtk_library_store/releases/download/3.24.0/gtk4_4_2_test.zip
unzip mingw64.zip -d $GTK_LIBRARY unzip gtk4_4_2_test.zip -d $GTK_LIBRARY
GTK_LIBRARY="$GTK_LIBRARY/mingw64" GTK_LIBRARY="$GTK_LIBRARY/mingw64"
wget https://github.com/nrhodes91/AdMin/archive/master.zip wget https://github.com/nrhodes91/AdMin/archive/master.zip
@ -242,7 +242,7 @@ jobs:
matrix: matrix:
toolchain: [ stable ] toolchain: [ stable ]
type: [ release ] type: [ release ]
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -252,7 +252,7 @@ jobs:
override: true override: true
- name: Install Gtk, Mingw, unzip, zip and wget - 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 - name: Build GUI Release Cross Compile
run: | run: |
@ -333,7 +333,7 @@ jobs:
# matrix: # matrix:
# toolchain: [ stable ] # toolchain: [ stable ]
# type: [ release ] # type: [ release ]
# runs-on: ubuntu-20.04 # runs-on: ubuntu-22.04
# steps: # steps:
# - uses: actions/checkout@v2 # - uses: actions/checkout@v2
# #
@ -343,7 +343,7 @@ jobs:
# override: true # override: true
# #
# - name: Install Gtk, Mingw, unzip, zip and wget # - 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 # - name: Build GUI Debug Cross Compile
# run: | # run: |
@ -424,7 +424,7 @@ jobs:
# matrix: # matrix:
# toolchain: [ stable ] # toolchain: [ stable ]
# type: [ release ] # type: [ release ]
# runs-on: ubuntu-20.04 # runs-on: ubuntu-22.04
# steps: # steps:
# - uses: actions/checkout@v2 # - uses: actions/checkout@v2
# #
@ -434,7 +434,7 @@ jobs:
# override: true # override: true
# #
# - name: Install Gtk, Mingw, unzip, zip and wget # - 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 # - name: Build GUI Debug Cross Compile
# run: | # 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" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 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]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -328,9 +304,9 @@ dependencies = [
[[package]] [[package]]
name = "cfg-expr" name = "cfg-expr"
version = "0.10.2" version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e068cb2806bbc15b439846dc16c5f89f8599f2c3e4d73d4449d38f9b2f0b6c5" checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db"
dependencies = [ dependencies = [
"smallvec", "smallvec",
] ]
@ -528,9 +504,9 @@ dependencies = [
"directories-next", "directories-next",
"fs_extra", "fs_extra",
"futures", "futures",
"gdk", "gdk4",
"glib", "glib",
"gtk", "gtk4",
"humansize", "humansize",
"i18n-embed", "i18n-embed",
"i18n-embed-fl", "i18n-embed-fl",
@ -904,22 +880,6 @@ dependencies = [
"slab", "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]] [[package]]
name = "gdk-pixbuf" name = "gdk-pixbuf"
version = "0.15.11" version = "0.15.11"
@ -947,10 +907,26 @@ dependencies = [
] ]
[[package]] [[package]]
name = "gdk-sys" name = "gdk4"
version = "0.15.1" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" 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 = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs",
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
@ -1089,60 +1065,117 @@ dependencies = [
] ]
[[package]] [[package]]
name = "gtk" name = "graphene-rs"
version = "0.15.5" version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92e3004a2d5d6d8b5057d2b57b3712c9529b62e82c77f25c1fecde1fd5c23bd0" checksum = "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570"
dependencies = [ dependencies = [
"atk",
"bitflags",
"cairo-rs",
"field-offset",
"futures-channel",
"gdk",
"gdk-pixbuf",
"gio",
"glib", "glib",
"gtk-sys", "graphene-sys",
"gtk3-macros",
"libc", "libc",
"once_cell",
"pango",
"pkg-config",
] ]
[[package]] [[package]]
name = "gtk-sys" name = "graphene-sys"
version = "0.15.3" version = "0.15.10"
source = "registry+https://github.com/rust-lang/crates.io-index" 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 = [ dependencies = [
"atk-sys",
"cairo-sys-rs", "cairo-sys-rs",
"gdk-pixbuf-sys", "gdk4-sys",
"gdk-sys",
"gio-sys",
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
"graphene-sys",
"libc", "libc",
"pango-sys", "pango-sys",
"system-deps", "system-deps",
] ]
[[package]] [[package]]
name = "gtk3-macros" name = "gtk4"
version = "0.15.4" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" 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 = [ dependencies = [
"anyhow", "anyhow",
"proc-macro-crate", "proc-macro-crate",
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quick-xml",
"quote", "quote",
"syn", "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]] [[package]]
name = "half" name = "half"
version = "1.8.2" version = "1.8.2"
@ -1460,9 +1493,9 @@ checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.125" version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]] [[package]]
name = "linked-hash-map" name = "linked-hash-map"
@ -1495,9 +1528,9 @@ dependencies = [
[[package]] [[package]]
name = "lofty" name = "lofty"
version = "0.6.2" version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9b0ac50022c34427688f83800b865c8a324ba2fe9f41f232b899b7517b3786c" checksum = "9e09702a8eff21fa1cf105d189d8eea3609d7074ab1503d7c49d5b37b7403a65"
dependencies = [ dependencies = [
"base64 0.13.0", "base64 0.13.0",
"byteorder", "byteorder",
@ -1729,9 +1762,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.10.0" version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" checksum = "7b10983b38c53aebdf33f542c6275b0f58a238129d00c4ae0e6fb59738d783ca"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
@ -1999,11 +2032,20 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.38" version = "1.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
dependencies = [ 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]] [[package]]
@ -2106,9 +2148,9 @@ dependencies = [
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.5.5" version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -2117,9 +2159,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.25" version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
@ -2642,13 +2684,13 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.94" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a" checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
@ -2877,6 +2919,12 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
version = "0.1.19" version = "0.1.19"
@ -2898,12 +2946,6 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.0.0" 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. **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 ## Features
- Written in memory-safe Rust - Written in memory-safe Rust
- Amazingly fast - due to using more or less advanced algorithms and multithreading - 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 - Multiplatform - works on Linux, Windows, macOS, FreeBSD and many more
- Cache support - second and further scans should be much faster than the first one - Cache support - second and further scans should be much faster than the first one
- CLI frontend - for easy automation - 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 - 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 - Multilingual - support multiple languages like Polish, English or Italian
- Multiple tools to use: - 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 | | Language | Rust | Python | Python/Obj-C | Python |
| OS | Lin,Mac,Win | Lin | Lin,Mac,Win | Lin,Mac,Win | | 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 | • | • | • | | | Duplicate finder | • | • | • | |
| Empty files | • | • | | | | Empty files | • | • | | |
| Empty folders | • | • | | | | Empty folders | • | • | | |

View file

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

View file

@ -14,15 +14,15 @@ pub const RAW_IMAGE_EXTENSIONS: &[&str] = &[
".cr2", ".ari", ".cr2", ".ari",
]; ];
pub const IMAGE_RS_EXTENSIONS: &[&str] = &[ 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] = &[ 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] = &[ 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"]; pub const ZIP_FILES_EXTENSIONS: &[&str] = &[".zip"];

View file

@ -10,7 +10,7 @@ repository = "https://github.com/qarmin/czkawka"
[dependencies] [dependencies]
czkawka_core = { path = "../czkawka_core", version = "4.1.0"} czkawka_core = { path = "../czkawka_core", version = "4.1.0"}
gdk = "0.15.4" gdk4 = "0.4.7"
glib = "0.15.11" glib = "0.15.11"
humansize = "1.1.1" humansize = "1.1.1"
@ -52,8 +52,8 @@ once_cell = "1.10.0"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["combaseapi", "objbase", "shobjidl_core", "windef", "winerror", "wtypesbase", "winuser"] } winapi = { version = "0.3.9", features = ["combaseapi", "objbase", "shobjidl_core", "windef", "winerror", "wtypesbase", "winuser"] }
[dependencies.gtk] [dependencies.gtk4]
version = "0.15.5" version = "0.4.7"
default-features = false # just in case 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 Window
progress_stop_button = Stop progress_stop_button = Stop
progress_stop_additional_message = Stop requested
# About Window # About Window
about_repository_button_tooltip = Link to repository page with source code. 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 chrono::NaiveDateTime;
use glib::Receiver; use glib::Receiver;
use gtk::prelude::*; use gtk4::prelude::*;
use humansize::{file_size_opts as options, FileSize}; use humansize::{file_size_opts as options, FileSize};
use czkawka_core::common_dir_traversal::CheckingMethod; 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")); entry_info.set_text(&flg!("compute_stopped_by_user"));
} else { } else {
if df.get_use_reference() { 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 { } 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(); let information = df.get_information();
@ -167,7 +167,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// HEADER // HEADER
let (directory, file) = split_path(&base_file_entry.path); 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::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&base_file_entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (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 // MEAT
for entry in vector { for entry in vector {
let (directory, file) = split_path(&entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
@ -224,7 +226,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// HEADER // HEADER
let (directory, file) = split_path(&base_file_entry.path); 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::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&base_file_entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (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 { for entry in vector {
let (directory, file) = split_path(&entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (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 // HEADER
let (directory, file) = split_path(&base_file_entry.path); 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::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&base_file_entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (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); list_store.set(&list_store.append(), &values);
for entry in vector { for entry in vector {
let (directory, file) = split_path(&entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); 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() vector.clone()
}; };
let values: [(u32, &dyn ToValue); 9] = [ let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false), (ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&"".to_string())), (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::Modification as u32, (&"".to_string())), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, (&(0))), // Not used here (ColumnsDuplicates::ModificationAsSecs as u32, (&(0))), // Not used here
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
for entry in vector { for entry in vector {
let (directory, file) = split_path(&entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); 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() vector.clone()
}; };
let values: [(u32, &dyn ToValue); 9] = [ let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false), (ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&"".to_string())), (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::Modification as u32, &"".to_string()), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, &(0)), (ColumnsDuplicates::ModificationAsSecs as u32, &(0)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (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 { for entry in vector {
let (directory, file) = split_path(&entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (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 { } else {
vector.clone() vector.clone()
}; };
let values: [(u32, &dyn ToValue); 9] = [ let values: [(u32, &dyn ToValue); 10] = [
(ColumnsDuplicates::ActivatableSelectButton as u32, &false), (ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&"".to_string())), (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::Modification as u32, &"".to_string()), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, &(0)), // Not used here (ColumnsDuplicates::ModificationAsSecs as u32, &(0)), // Not used here
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &true),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
for entry in vector { for entry in vector {
let (directory, file) = split_path(&entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false), (ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Size as u32, (&entry.size.file_size(options::BINARY).unwrap())), (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::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::IsHeader as u32, &false),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); 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")); entry_info.set_text(&flg!("compute_stopped_by_user"));
} else { } else {
if sf.get_use_reference() { 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 { } else {
tree_view_similar_images_finder tree_view_similar_images_finder.selection().set_select_function(select_function_similar_images);
.selection()
.set_select_function(Some(Box::new(select_function_similar_images)));
} }
let information = sf.get_information(); let information = sf.get_information();
let text_messages = sf.get_text_messages(); 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); let list_store = get_list_store(&tree_view_similar_images_finder);
if sf.get_use_reference() { if sf.get_use_reference() {
let vec_struct_similar: &Vec<(czkawka_core::similar_images::FileEntry, Vec<czkawka_core::similar_images::FileEntry>)> = let vec_struct_similar: &Vec<(similar_images::FileEntry, Vec<similar_images::FileEntry>)> = sf.get_similar_images_referenced();
sf.get_similar_images_referenced();
for (base_file_entry, vec_file_entry) in vec_struct_similar.iter() { for (base_file_entry, vec_file_entry) in vec_struct_similar.iter() {
// Sort // Sort
let vec_file_entry = if vec_file_entry.len() >= 2 { 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 // Header
let (directory, file) = split_path(&base_file_entry.path); 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::ActivatableSelectButton as u32, &false),
(ColumnsSimilarImages::SelectionButton as u32, &false), (ColumnsSimilarImages::SelectionButton as u32, &false),
(ColumnsSimilarImages::Similarity as u32, &"".to_string()), (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::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsSimilarImages::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsSimilarImages::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarImages::IsHeader as u32, &true),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
@ -848,7 +858,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Meat // Meat
for file_entry in vec_file_entry.iter() { for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsSimilarImages::SelectionButton as u32, &false), (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::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarImages::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsSimilarImages::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarImages::IsHeader as u32, &false),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
@ -887,7 +898,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
}; };
// Header // Header
let values: [(u32, &dyn ToValue); 12] = [ let values: [(u32, &dyn ToValue); 13] = [
(ColumnsSimilarImages::ActivatableSelectButton as u32, &false), (ColumnsSimilarImages::ActivatableSelectButton as u32, &false),
(ColumnsSimilarImages::SelectionButton as u32, &false), (ColumnsSimilarImages::SelectionButton as u32, &false),
(ColumnsSimilarImages::Similarity as u32, &"".to_string()), (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::Modification as u32, &"".to_string()),
(ColumnsSimilarImages::ModificationAsSecs as u32, &(0)), (ColumnsSimilarImages::ModificationAsSecs as u32, &(0)),
(ColumnsSimilarImages::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsSimilarImages::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarImages::IsHeader as u32, &true),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
@ -906,7 +918,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Meat // Meat
for file_entry in vec_file_entry.iter() { for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsSimilarImages::SelectionButton as u32, &false), (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::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarImages::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsSimilarImages::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarImages::IsHeader as u32, &false),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); 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")); entry_info.set_text(&flg!("compute_stopped_by_user"));
} else { } else {
if ff.get_use_reference() { 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 { } else {
tree_view_similar_videos_finder tree_view_similar_videos_finder.selection().set_select_function(select_function_similar_videos);
.selection()
.set_select_function(Some(Box::new(select_function_similar_videos)));
} }
let information = ff.get_information(); let information = ff.get_information();
let text_messages = ff.get_text_messages(); let text_messages = ff.get_text_messages();
@ -1009,7 +1020,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Header // Header
let (directory, file) = split_path(&base_file_entry.path); 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::ActivatableSelectButton as u32, &false),
(ColumnsSimilarVideos::SelectionButton as u32, &false), (ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &base_file_entry.size.file_size(options::BINARY).unwrap()), (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::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsSimilarVideos::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsSimilarVideos::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarVideos::IsHeader as u32, &true),
(ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
@ -1029,7 +1041,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Meat // Meat
for file_entry in vec_file_entry.iter() { for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsSimilarVideos::SelectionButton as u32, &false), (ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()), (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::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarVideos::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsSimilarVideos::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarVideos::IsHeader as u32, &false),
(ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
@ -1064,7 +1077,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
}; };
// Header // Header
let values: [(u32, &dyn ToValue); 10] = [ let values: [(u32, &dyn ToValue); 11] = [
(ColumnsSimilarVideos::ActivatableSelectButton as u32, &false), (ColumnsSimilarVideos::ActivatableSelectButton as u32, &false),
(ColumnsSimilarVideos::SelectionButton as u32, &false), (ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &"".to_string()), (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::Modification as u32, &"".to_string()),
(ColumnsSimilarVideos::ModificationAsSecs as u32, &(0)), (ColumnsSimilarVideos::ModificationAsSecs as u32, &(0)),
(ColumnsSimilarVideos::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsSimilarVideos::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarVideos::IsHeader as u32, &true),
(ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
@ -1081,7 +1095,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Meat // Meat
for file_entry in vec_file_entry.iter() { for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsSimilarVideos::SelectionButton as u32, &false), (ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()), (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::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarVideos::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsSimilarVideos::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarVideos::IsHeader as u32, &false),
(ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSimilarVideos::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); 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")); entry_info.set_text(&flg!("compute_stopped_by_user"));
} else { } else {
if mf.get_use_reference() { 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 { } 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(); 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 (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::ActivatableSelectButton as u32, &false),
(ColumnsSameMusic::SelectionButton as u32, &false), (ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &base_file_entry.size.file_size(options::BINARY).unwrap()), (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::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
(ColumnsSameMusic::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsSameMusic::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSameMusic::IsHeader as u32, &true),
(ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
for file_entry in vec_file_entry { for file_entry in vec_file_entry {
let (directory, file) = split_path(&file_entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsSameMusic::SelectionButton as u32, &false), (ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()), (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::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSameMusic::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsSameMusic::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSameMusic::IsHeader as u32, &false),
(ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); 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() vec_file_entry.clone()
}; };
let values: [(u32, &dyn ToValue); 17] = [ let values: [(u32, &dyn ToValue); 18] = [
(ColumnsSameMusic::ActivatableSelectButton as u32, &false), (ColumnsSameMusic::ActivatableSelectButton as u32, &false),
(ColumnsSameMusic::SelectionButton as u32, &false), (ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &"".to_string()), (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::Modification as u32, &"".to_string()),
(ColumnsSameMusic::ModificationAsSecs as u32, &(0)), (ColumnsSameMusic::ModificationAsSecs as u32, &(0)),
(ColumnsSameMusic::Color as u32, &(HEADER_ROW_COLOR.to_string())), (ColumnsSameMusic::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSameMusic::IsHeader as u32, &true),
(ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); list_store.set(&list_store.append(), &values);
for file_entry in vec_file_entry { for file_entry in vec_file_entry {
let (directory, file) = split_path(&file_entry.path); 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::ActivatableSelectButton as u32, &true),
(ColumnsSameMusic::SelectionButton as u32, &false), (ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()), (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::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSameMusic::Color as u32, &(MAIN_ROW_COLOR.to_string())), (ColumnsSameMusic::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSameMusic::IsHeader as u32, &false),
(ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())), (ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())),
]; ];
list_store.set(&list_store.append(), &values); 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; use crate::gui_structs::gui_data::GuiData;

View file

@ -1,12 +1,12 @@
use crate::flg; use crate::flg;
use gdk::gdk_pixbuf::{InterpType, Pixbuf}; use gdk4::gdk_pixbuf::{InterpType, Pixbuf};
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{CheckButton, Image, ListStore, Orientation, ScrolledWindow, TreeIter, TreeModel, TreePath, TreeSelection}; use gtk4::{CheckButton, Image, ListStore, Orientation, ScrolledWindow, TreeIter, TreeModel, TreePath, TreeSelection, Widget};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use crate::gui_structs::gui_data::GuiData; 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; use crate::localizer_core::generate_translation_hashmap;
const BIG_PREVIEW_SIZE: i32 = 600; 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_left = gui_data.compare_images.image_compare_left.clone();
let image_compare_right = gui_data.compare_images.image_compare_right.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 |_| { button_compare.connect_clicked(move |_| {
let nb_number = notebook_main.current_page().unwrap(); let nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize]; let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
let model = tree_view.model().unwrap(); 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 { if group_number == 0 {
return; return;
} }
// Check selected items // 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_current_of_groups.borrow_mut() = current_group;
*shared_numbers_of_groups.borrow_mut() = group_number; *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 window_compare = gui_data.compare_images.window_compare.clone();
let image_compare_left = gui_data.compare_images.image_compare_left.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(); 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(); window_compare.hide();
*shared_image_cache.borrow_mut() = Vec::new(); *shared_image_cache.borrow_mut() = Vec::new();
*shared_current_path.borrow_mut() = None; *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); *shared_using_for_preview.borrow_mut() = (None, None);
image_compare_left.set_from_pixbuf(None); image_compare_left.set_from_pixbuf(None);
image_compare_right.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(); 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 current_group = *shared_current_of_groups.borrow();
let group_number = *shared_numbers_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( populate_groups_at_start(
nb_object, nb_object,
@ -178,7 +181,7 @@ pub fn connect_button_compare(gui_data: &GuiData) {
let current_group = *shared_current_of_groups.borrow(); let current_group = *shared_current_of_groups.borrow();
let group_number = *shared_numbers_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( populate_groups_at_start(
nb_object, 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 notebook_main = gui_data.main_notebook.notebook_main.clone();
let shared_current_path = gui_data.compare_images.shared_current_path.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(); 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 nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize]; let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[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 shared_current_path = gui_data.compare_images.shared_current_path.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone();
let main_tree_views = gui_data.main_notebook.get_main_tree_views(); 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 nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize]; let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize]; let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
@ -251,18 +255,18 @@ fn populate_groups_at_start(
model: &TreeModel, model: &TreeModel,
shared_current_path: Rc<RefCell<Option<TreePath>>>, shared_current_path: Rc<RefCell<Option<TreePath>>>,
tree_path: TreePath, tree_path: TreePath,
image_compare_left: &gtk::Image, image_compare_left: &gtk4::Image,
image_compare_right: &gtk::Image, image_compare_right: &gtk4::Image,
current_group: u32, current_group: u32,
group_number: u32, group_number: u32,
check_button_left_preview_text: &gtk::CheckButton, check_button_left_preview_text: &gtk4::CheckButton,
check_button_right_preview_text: &gtk::CheckButton, check_button_right_preview_text: &gtk4::CheckButton,
scrolled_window_compare_choose_images: &gtk::ScrolledWindow, scrolled_window_compare_choose_images: &gtk4::ScrolledWindow,
label_group_info: &gtk::Label, label_group_info: &gtk4::Label,
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)>>>,
shared_using_for_preview: Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>, shared_using_for_preview: Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>,
button_go_previous_compare_group: &gtk::Button, button_go_previous_compare_group: &gtk4::Button,
button_go_next_compare_group: &gtk::Button, button_go_next_compare_group: &gtk4::Button,
) { ) {
if current_group == 1 { if current_group == 1 {
button_go_previous_compare_group.set_sensitive(false); 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); 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); *shared_current_path.borrow_mut() = Some(tree_path);
let cache_all_images = generate_cache_for_results(all_vec); let cache_all_images = generate_cache_for_results(all_vec);
// This is safe, because cache have at least 2 results // 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_left.set_paintable(cache_all_images[0].2.paintable().as_ref());
image_compare_right.set_from_pixbuf(cache_all_images[1].2.pixbuf().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())); *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_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(&format!("2. {}", get_max_file_name(&cache_all_images[1].0, 70))); 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( label_group_info.set_text(
flg!( flg!(
@ -317,9 +321,9 @@ fn populate_groups_at_start(
*shared_image_cache.borrow_mut() = cache_all_images.clone(); *shared_image_cache.borrow_mut() = cache_all_images.clone();
let mut found = false; 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" { 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); update_bottom_buttons(&gtk_box, shared_using_for_preview, shared_image_cache);
found = true; found = true;
break; break;
@ -327,20 +331,20 @@ fn populate_groups_at_start(
} }
assert!(found); 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); 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); 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 /// 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, // TODO use here threads,
// For now threads cannot be used because Image and TreeIter cannot be used in threads // For now threads cannot be used because Image and TreeIter cannot be used in threads
let mut cache_all_images = Vec::new(); let mut cache_all_images = Vec::new();
for (full_path, name, tree_path) in vector_with_path { for (full_path, name, tree_path) in vector_with_path {
let small_img = gtk::Image::new(); let small_img = gtk4::Image::new();
let big_img = gtk::Image::new(); let big_img = gtk4::Image::new();
match Pixbuf::from_file(&full_path) { match Pixbuf::from_file(&full_path) {
Ok(pixbuf) => Ok(pixbuf) =>
@ -362,8 +366,8 @@ fn generate_cache_for_results(vector_with_path: Vec<(String, String, gtk::TreePa
Some(pixbuf) => pixbuf, Some(pixbuf) => pixbuf,
}; };
big_img.set_pixbuf(Some(&pixbuf_big)); big_img.set_from_pixbuf(Some(&pixbuf_big));
small_img.set_pixbuf(Some(&pixbuf_small)); small_img.set_from_pixbuf(Some(&pixbuf_small));
break; 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 /// 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(); let used_iter = model.iter(current_path).unwrap();
assert_eq!(model.value(&used_iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR); assert!(model.get::<bool>(&used_iter, column_header));
let using_reference = !model.value(&used_iter, column_path).get::<String>().unwrap().is_empty(); let using_reference = !model.get::<String>(&used_iter, column_path).is_empty();
let mut returned_vector = Vec::new(); let mut returned_vector = Vec::new();
if using_reference { if using_reference {
let name = model.value(&used_iter, column_name).get::<String>().unwrap(); let name = model.get::<String>(&used_iter, column_name);
let path = model.value(&used_iter, column_path).get::<String>().unwrap(); let path = model.get::<String>(&used_iter, column_path);
let full_name = get_full_name_from_path_name(&path, &name); 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) { if !model.iter_next(&used_iter) {
@ -400,20 +404,18 @@ fn get_all_path(model: &TreeModel, current_path: &TreePath, column_color: i32, c
} }
loop { loop {
let name = model.value(&used_iter, column_name).get::<String>().unwrap(); let name = model.get::<String>(&used_iter, column_name);
let path = model.value(&used_iter, column_path).get::<String>().unwrap(); let path = model.get::<String>(&used_iter, column_path);
let full_name = get_full_name_from_path_name(&path, &name); 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) { if !model.iter_next(&used_iter) {
break; break;
} }
let color = model.value(&used_iter, column_color).get::<String>().unwrap(); if model.get::<bool>(&used_iter, column_header) {
if color == HEADER_ROW_COLOR {
break; break;
} }
} }
@ -424,10 +426,10 @@ fn get_all_path(model: &TreeModel, current_path: &TreePath, column_color: i32, c
} }
/// Moves iterator to previous/next header /// 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(); 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 go_next {
if !model.iter_next(&tree_iter) { 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 model.get::<bool>(&tree_iter, column_header) {
if color == HEADER_ROW_COLOR {
break; break;
} }
} }
model.path(&tree_iter).unwrap() model.path(&tree_iter)
} }
/// Populate bottom Scrolled View with small thumbnails /// Populate bottom Scrolled View with small thumbnails
@ -466,28 +466,26 @@ fn populate_similar_scrolled_view(
image_compare_left: &Image, image_compare_left: &Image,
image_compare_right: &Image, image_compare_right: &Image,
shared_using_for_preview: Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>, 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_left_preview_text: &CheckButton,
check_button_right_preview_text: &CheckButton, check_button_right_preview_text: &CheckButton,
model: &TreeModel, model: &TreeModel,
column_selection: i32, column_selection: i32,
) { ) {
if let Some(child) = scrolled_window.child() { scrolled_window.set_child(None::<&Widget>);
scrolled_window.remove(&child);
};
scrolled_window.set_propagate_natural_height(true); 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"); all_gtk_box.set_widget_name("all_box");
for (number, (path, _name, big_thumbnail, small_thumbnail, tree_path)) in image_cache.iter().enumerate() { 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 button_left = gtk4::Button::builder().label(&flg!("compare_move_left_button")).build();
let label = gtk::Label::builder().label(&(number + 1).to_string()).build(); let label = gtk4::Label::builder().label(&(number + 1).to_string()).build();
let button_right = gtk::Button::builder().label(&flg!("compare_move_right_button")).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_left = image_compare_left.clone();
let image_compare_right = image_compare_right.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| { button_left.connect_clicked(move |_button_left| {
shared_using_for_preview_clone.borrow_mut().0 = Some(tree_path_clone.clone()); 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()); 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_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(); let big_thumbnail_clone = big_thumbnail.clone();
@ -523,51 +521,51 @@ fn populate_similar_scrolled_view(
button_right.connect_clicked(move |_button_right| { button_right.connect_clicked(move |_button_right| {
shared_using_for_preview_clone.borrow_mut().1 = Some(tree_path_clone.clone()); 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()); 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_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.append(&button_left);
smaller_box.add(&label); smaller_box.append(&label);
smaller_box.add(&button_right); smaller_box.append(&button_right);
small_box.add(&smaller_box); small_box.append(&smaller_box);
small_box.add(small_thumbnail); small_box.append(small_thumbnail);
all_gtk_box.add(&small_box); all_gtk_box.append(&small_box);
} }
all_gtk_box.show_all(); all_gtk_box.show();
scrolled_window.add(&all_gtk_box); scrolled_window.set_child(Some(&all_gtk_box));
} }
/// Disables/Enables L/R buttons at the bottom scrolled view /// Disables/Enables L/R buttons at the bottom scrolled view
fn update_bottom_buttons( fn update_bottom_buttons(
all_gtk_box: &gtk::Box, all_gtk_box: &gtk4::Box,
shared_using_for_preview: Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>, shared_using_for_preview: Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>,
image_cache: Rc<RefCell<Vec<(String, String, Image, Image, TreePath)>>>, image_cache: Rc<RefCell<Vec<(String, String, Image, Image, TreePath)>>>,
) { ) {
let left_tree_view = (*shared_using_for_preview.borrow()).0.clone().unwrap(); let left_tree_view = (*shared_using_for_preview.borrow()).0.clone().unwrap();
let right_tree_view = (*shared_using_for_preview.borrow()).1.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 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 is_chosen = cache_tree_path != right_tree_view && cache_tree_path != left_tree_view;
let bx = i.downcast::<gtk::Box>().unwrap(); let bx = i.downcast::<gtk4::Box>().unwrap();
let smaller_bx = bx.children()[0].clone().downcast::<gtk::Box>().unwrap(); let smaller_bx = get_all_children(&bx)[0].clone().downcast::<gtk4::Box>().unwrap();
for items in smaller_bx.children() { for items in get_all_children(&smaller_bx) {
if let Ok(btn) = items.downcast::<gtk::Button>() { if let Ok(btn) = items.downcast::<gtk4::Button>() {
btn.set_sensitive(is_chosen); 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 current_group = 1;
let mut possible_group = 1; let mut possible_group = 1;
let mut header_clone: TreeIter; 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 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 header_clone = iter; // if nothing selected, use first group
possible_header = 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() { if !selected_records.is_empty() {
let first_selected_record = selected_records[0].clone(); 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; break;
} }
if model.value(&iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR { if model.get::<bool>(&iter, column_header) {
possible_group += 1; possible_group += 1;
possible_header = iter; possible_header = iter;
} }
if model.path(&iter).unwrap() == first_selected_record { if model.path(&iter) == first_selected_record {
header_clone = possible_header; header_clone = possible_header;
current_group = possible_group; 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;
use std::fs::Metadata; use std::fs::Metadata;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{Align, CheckButton, Dialog, ResponseType, TextView}; use gtk4::{Align, CheckButton, Dialog, Orientation, ResponseType, TextView};
use crate::flg; 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 tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[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 // Nothing is selected
if number_of_selected_items == 0 { if number_of_selected_items == 0 {
@ -57,11 +57,11 @@ pub async fn delete_things(gui_data: GuiData) {
return; 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() if !check_button_settings_confirm_group_deletion.is_active()
|| !check_if_deleting_all_files_in_group( || !check_if_deleting_all_files_in_group(
tree_view, tree_view,
column_color, column_header,
nb_object.column_selection, nb_object.column_selection,
nb_object.column_path, nb_object.column_path,
&window_main, &window_main,
@ -73,7 +73,7 @@ pub async fn delete_things(gui_data: GuiData) {
tree_view, tree_view,
nb_object.column_name, nb_object.column_name,
nb_object.column_path, nb_object.column_path,
column_color, column_header,
nb_object.column_selection, nb_object.column_selection,
&check_button_settings_use_trash, &check_button_settings_use_trash,
&text_view_errors, &text_view_errors,
@ -115,8 +115,8 @@ pub async fn delete_things(gui_data: GuiData) {
} }
pub async fn check_if_can_delete_files( pub async fn check_if_can_delete_files(
check_button_settings_confirm_deletion: &gtk::CheckButton, check_button_settings_confirm_deletion: &gtk4::CheckButton,
window_main: &gtk::Window, window_main: &gtk4::Window,
number_of_selected_items: u64, number_of_selected_items: u64,
number_of_selected_groups: u64, number_of_selected_groups: u64,
) -> bool { ) -> 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 (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; 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() { if !check_button.is_active() {
check_button_settings_confirm_deletion.set_active(false); check_button_settings_confirm_deletion.set_active(false);
} }
@ -139,41 +139,45 @@ pub async fn check_if_can_delete_files(
true true
} }
fn create_dialog_ask_for_deletion(window_main: &gtk::Window, number_of_selected_items: u64, number_of_selected_groups: u64) -> (Dialog, CheckButton) { fn create_dialog_ask_for_deletion(window_main: &gtk4::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(); 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); let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel); dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
let label: gtk::Label = gtk::Label::new(Some(&flg!("delete_question_label"))); dialog.set_default_size(300, 0);
let label2: gtk::Label = match number_of_selected_groups {
0 => gtk::Label::new(Some(&flg!( 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", "delete_items_label",
generate_translation_hashmap(vec![("items", number_of_selected_items.to_string())]) 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", "delete_items_groups_label",
generate_translation_hashmap(vec![("items", number_of_selected_items.to_string()), ("groups", number_of_selected_groups.to_string())]) 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_active(true);
check_button.set_halign(Align::Center); check_button.set_halign(Align::Center);
button_ok.grab_focus(); button_ok.grab_focus();
let internal_box = get_dialog_box_child(&dialog); let parent = button_ok.parent().unwrap().parent().unwrap().downcast::<gtk4::Box>().unwrap(); // TODO Hack, but not so ugly as before
internal_box.add(&label); parent.set_orientation(Orientation::Vertical);
internal_box.add(&label2); parent.insert_child_after(&label, None::<&gtk4::Widget>);
internal_box.add(&check_button); parent.insert_child_after(&label2, Some(&label));
internal_box.set_margin(5); parent.insert_child_after(&check_button, Some(&label2));
// parent.set_margin(5); // TODO
check_button.set_margin_top(5); check_button.set_margin_top(5);
dialog.show_all(); dialog.show();
(dialog, check_button) (dialog, check_button)
} }
fn create_dialog_group_deletion(window_main: &gtk::Window) -> (Dialog, CheckButton) { fn create_dialog_group_deletion(window_main: &gtk4::Window) -> (Dialog, CheckButton) {
let dialog = gtk::Dialog::builder() let dialog = gtk4::Dialog::builder()
.title(&flg!("delete_all_files_in_group_title")) .title(&flg!("delete_all_files_in_group_title"))
.transient_for(window_main) .transient_for(window_main)
.modal(true) .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); let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel); 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 label: gtk4::Label = gtk4::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 label2: gtk4::Label = gtk4::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 check_button: gtk4::CheckButton = gtk4::CheckButton::with_label(&flg!("dialogs_ask_next_time"));
check_button.set_active(true); check_button.set_active(true);
check_button.set_halign(Align::Center); check_button.set_halign(Align::Center);
button_ok.grab_focus(); button_ok.grab_focus();
let internal_box = get_dialog_box_child(&dialog); let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label); internal_box.append(&label);
internal_box.add(&label2); internal_box.append(&label2);
internal_box.add(&check_button); internal_box.append(&check_button);
dialog.show_all(); dialog.show();
(dialog, check_button) (dialog, check_button)
} }
pub async fn check_if_deleting_all_files_in_group( pub async fn check_if_deleting_all_files_in_group(
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_color: i32, column_header: i32,
column_selection: i32, column_selection: i32,
column_path: i32, column_path: i32,
window_main: &gtk::Window, window_main: &gtk4::Window,
check_button_settings_confirm_group_deletion: &gtk::CheckButton, check_button_settings_confirm_group_deletion: &gtk4::CheckButton,
) -> bool { ) -> bool {
let model = get_list_store(tree_view); let model = get_list_store(tree_view);
let mut selected_all_records: bool = true; let mut selected_all_records: bool = true;
if let Some(iter) = model.iter_first() { 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 // 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; return false;
} }
@ -223,13 +227,13 @@ pub async fn check_if_deleting_all_files_in_group(
break; break;
} }
if model.value(&iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR { if model.get::<bool>(&iter, column_header) {
if selected_all_records { if selected_all_records {
break; break;
} }
selected_all_records = true; selected_all_records = true;
} else { } else {
if !model.value(&iter, column_selection).get::<bool>().unwrap() { if !model.get::<bool>(&iter, column_selection) {
selected_all_records = false; 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 (confirmation_dialog_group_delete, check_button) = create_dialog_group_deletion(window_main);
let response_type = confirmation_dialog_group_delete.run_future().await; 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() { if !check_button.is_active() {
check_button_settings_confirm_group_deletion.set_active(false); 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( pub fn empty_folder_remover(
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_file_name: i32, column_file_name: i32,
column_path: i32, column_path: i32,
column_selection: i32, column_selection: i32,
@ -276,8 +280,8 @@ pub fn empty_folder_remover(
if let Some(iter) = model.iter_first() { if let Some(iter) = model.iter_first() {
loop { loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() { if model.get::<bool>(&iter, column_selection) {
selected_rows.push(model.path(&iter).unwrap()); selected_rows.push(model.path(&iter));
} }
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
break; break;
@ -292,12 +296,11 @@ pub fn empty_folder_remover(
let mut messages: String = "".to_string(); 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 // 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() { for tree_path in selected_rows.iter().rev() {
handle_gtk_pending_event_counter(counter);
let iter = model.iter(tree_path).unwrap(); let iter = model.iter(tree_path).unwrap();
let name = model.value(&iter, column_file_name).get::<String>().unwrap(); let name = model.get::<String>(&iter, column_file_name);
let path = model.value(&iter, column_path).get::<String>().unwrap(); let path = model.get::<String>(&iter, column_path);
// We must check if folder is really empty or contains only other empty folders // We must check if folder is really empty or contains only other empty folders
let mut error_happened = false; 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( pub fn basic_remove(
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_file_name: i32, column_file_name: i32,
column_path: i32, column_path: i32,
column_selection: i32, column_selection: i32,
@ -394,8 +397,8 @@ pub fn basic_remove(
if let Some(iter) = model.iter_first() { if let Some(iter) = model.iter_first() {
loop { loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() { if model.get::<bool>(&iter, column_selection) {
selected_rows.push(model.path(&iter).unwrap()); selected_rows.push(model.path(&iter));
} }
if !model.iter_next(&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 // 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() { for tree_path in selected_rows.iter().rev() {
handle_gtk_pending_event_counter(counter);
let iter = model.iter(tree_path).unwrap(); let iter = model.iter(tree_path).unwrap();
let name = model.value(&iter, column_file_name).get::<String>().unwrap(); let name = model.get::<String>(&iter, column_file_name);
let path = model.value(&iter, column_path).get::<String>().unwrap(); let path = model.get::<String>(&iter, column_path);
if !use_trash { if !use_trash {
match fs::remove_file(get_full_name_from_path_name(&path, &name)) { 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 // Remove all occurrences - remove every element which have same path and name as even non selected ones
pub fn tree_remove( pub fn tree_remove(
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_file_name: i32, column_file_name: i32,
column_path: i32, column_path: i32,
column_color: i32, column_header: i32,
column_selection: i32, column_selection: i32,
check_button_settings_use_trash: &CheckButton, check_button_settings_use_trash: &CheckButton,
text_view_errors: &TextView, text_view_errors: &TextView,
@ -474,9 +476,9 @@ pub fn tree_remove(
if let Some(iter) = model.iter_first() { if let Some(iter) = model.iter_first() {
loop { loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() { if model.get::<bool>(&iter, column_selection) {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR { if !model.get::<bool>(&iter, column_header) {
selected_rows.push(model.path(&iter).unwrap()); selected_rows.push(model.path(&iter));
} else { } else {
panic!("Header row shouldn't be selected, please report bug."); 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() { for tree_path in selected_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap(); let iter = model.iter(tree_path).unwrap();
let file_name = model.value(&iter, column_file_name).get::<String>().unwrap(); let file_name = model.get::<String>(&iter, column_file_name);
let path = model.value(&iter, column_path).get::<String>().unwrap(); let path = model.get::<String>(&iter, column_path);
model.remove(&iter); model.remove(&iter);
@ -506,13 +508,10 @@ pub fn tree_remove(
} }
// Delete duplicated entries, and remove real files // Delete duplicated entries, and remove real files
let mut counter = 0_usize;
for (path, mut vec_file_name) in map_with_path_to_delete { for (path, mut vec_file_name) in map_with_path_to_delete {
vec_file_name.sort(); vec_file_name.sort();
vec_file_name.dedup(); vec_file_name.dedup();
for file_name in vec_file_name { for file_name in vec_file_name {
handle_gtk_pending_event_counter(counter);
counter += 1;
if !use_trash { if !use_trash {
if let Err(e) = fs::remove_file(get_full_name_from_path_name(&path, &file_name)) { if let Err(e) = fs::remove_file(get_full_name_from_path_name(&path, &file_name)) {
messages += flg!( 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::fs;
use std::path::PathBuf; use std::path::PathBuf;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{Align, CheckButton, Dialog, ResponseType, TextView, TreeIter, TreePath}; use gtk4::{Align, CheckButton, Dialog, ResponseType, TextView, TreeIter, TreePath};
use crate::flg; use crate::flg;
use czkawka_core::duplicate::make_hard_link; 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 tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[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(); 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; return;
} }
@ -69,7 +69,7 @@ async fn sym_hard_link_things(gui_data: GuiData, hardlinking: TypeOfTool) {
return; 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; return;
} }
@ -77,7 +77,7 @@ async fn sym_hard_link_things(gui_data: GuiData, hardlinking: TypeOfTool) {
tree_view, tree_view,
nb_object.column_name, nb_object.column_name,
nb_object.column_path, nb_object.column_path,
column_color, column_header,
nb_object.column_selection, nb_object.column_selection,
hardlinking, hardlinking,
&text_view_errors, &text_view_errors,
@ -97,10 +97,10 @@ async fn sym_hard_link_things(gui_data: GuiData, hardlinking: TypeOfTool) {
} }
fn hardlink_symlink( fn hardlink_symlink(
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_file_name: i32, column_file_name: i32,
column_path: i32, column_path: i32,
column_color: i32, column_header: i32,
column_selection: i32, column_selection: i32,
hardlinking: TypeOfTool, hardlinking: TypeOfTool,
text_view_errors: &TextView, text_view_errors: &TextView,
@ -125,9 +125,9 @@ fn hardlink_symlink(
let mut selected_rows = Vec::new(); let mut selected_rows = Vec::new();
if let Some(iter) = model.iter_first() { if let Some(iter) = model.iter_first() {
loop { loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() { if model.get::<bool>(&iter, column_selection) {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR { if !model.get::<bool>(&iter, column_header) {
selected_rows.push(model.path(&iter).unwrap()); selected_rows.push(model.path(&iter));
} else { } else {
panic!("Header row shouldn't be selected, please report bug."); 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_symhardlink_data: Option<SymHardlinkData> = None;
let mut current_selected_index = 0; let mut current_selected_index = 0;
loop { 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 let Some(current_symhardlink_data) = current_symhardlink_data {
if !current_symhardlink_data.files_to_symhardlink.is_empty() { if !current_symhardlink_data.files_to_symhardlink.is_empty() {
vec_symhardlink_data.push(current_symhardlink_data); vec_symhardlink_data.push(current_symhardlink_data);
@ -159,13 +159,13 @@ fn hardlink_symlink(
continue; continue;
} }
if model.path(&current_iter).unwrap() == selected_rows[current_selected_index] { if model.path(&current_iter) == selected_rows[current_selected_index] {
let file_name = model.value(&current_iter, column_file_name).get::<String>().unwrap(); let file_name = model.get::<String>(&current_iter, column_file_name);
let path = model.value(&current_iter, column_path).get::<String>().unwrap(); let path = model.get::<String>(&current_iter, column_path);
let full_file_path = get_full_name_from_path_name(&path, &file_name); let full_file_path = get_full_name_from_path_name(&path, &file_name);
if current_symhardlink_data.is_some() { 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(); let mut temp_data = current_symhardlink_data.unwrap();
temp_data.files_to_symhardlink.push(full_file_path); temp_data.files_to_symhardlink.push(full_file_path);
current_symhardlink_data = Some(temp_data); current_symhardlink_data = Some(temp_data);
@ -200,8 +200,7 @@ fn hardlink_symlink(
} }
if hardlinking == TypeOfTool::Hardlinking { if hardlinking == TypeOfTool::Hardlinking {
for symhardlink_data in vec_symhardlink_data { for symhardlink_data in vec_symhardlink_data {
for (counter, file_to_hardlink) in symhardlink_data.files_to_symhardlink.into_iter().enumerate() { for file_to_hardlink in symhardlink_data.files_to_symhardlink.into_iter() {
handle_gtk_pending_event_counter(counter);
if let Err(e) = make_hard_link(&PathBuf::from(&symhardlink_data.original_data), &PathBuf::from(&file_to_hardlink)) { 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()); add_text_to_text_view(text_view_errors, format!("{} {}, reason {}", flg!("hardlink_failed"), file_to_hardlink, e).as_str());
continue; continue;
@ -210,8 +209,7 @@ fn hardlink_symlink(
} }
} else { } else {
for symhardlink_data in vec_symhardlink_data { for symhardlink_data in vec_symhardlink_data {
for (counter, file_to_symlink) in symhardlink_data.files_to_symhardlink.into_iter().enumerate() { for file_to_symlink in symhardlink_data.files_to_symhardlink.into_iter() {
handle_gtk_pending_event_counter(counter);
if let Err(e) = fs::remove_file(&file_to_symlink) { if let Err(e) = fs::remove_file(&file_to_symlink) {
add_text_to_text_view( add_text_to_text_view(
text_view_errors, text_view_errors,
@ -259,11 +257,11 @@ fn hardlink_symlink(
model.remove(&model.iter(tree_path).unwrap()); 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 { fn create_dialog_non_group(window_main: &gtk4::Window) -> Dialog {
let dialog = gtk::Dialog::builder() let dialog = gtk4::Dialog::builder()
.title(&flg!("hard_sym_invalid_selection_title_dialog")) .title(&flg!("hard_sym_invalid_selection_title_dialog"))
.transient_for(window_main) .transient_for(window_main)
.modal(true) .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); let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel); 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 label: gtk4::Label = gtk4::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 label2: gtk4::Label = gtk4::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 label3: gtk4::Label = gtk4::Label::new(Some(&flg!("hard_sym_invalid_selection_label_3")));
button_ok.grab_focus(); button_ok.grab_focus();
let internal_box = get_dialog_box_child(&dialog); let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label); internal_box.append(&label);
internal_box.add(&label2); internal_box.append(&label2);
internal_box.add(&label3); internal_box.append(&label3);
dialog.show_all(); dialog.show();
dialog 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 model = get_list_store(tree_view);
let mut selected_values_in_group = 0; let mut selected_values_in_group = 0;
if let Some(iter) = model.iter_first() { 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 { loop {
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
break; 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 { if selected_values_in_group == 1 {
break; break;
} }
selected_values_in_group = 0; selected_values_in_group = 0;
} else { } else {
if model.value(&iter, column_selection).get::<bool>().unwrap() { if model.get::<bool>(&iter, column_selection) {
selected_values_in_group += 1; 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 confirmation_dialog = create_dialog_non_group(window_main);
let response_type = confirmation_dialog.run_future().await; 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.hide();
confirmation_dialog.close(); confirmation_dialog.close();
return false; return false;
@ -330,18 +328,18 @@ pub async fn check_if_changing_one_item_in_group_and_continue(tree_view: &gtk::T
true 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); let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() { 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 { loop {
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
break; 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; return true;
} }
} }
@ -350,12 +348,12 @@ pub async fn check_if_anything_is_selected_async(tree_view: &gtk::TreeView, colu
false 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() { if check_button_settings_confirm_link.is_active() {
let (confirmation_dialog_link, check_button) = create_dialog_ask_for_linking(window_main); let (confirmation_dialog_link, check_button) = create_dialog_ask_for_linking(window_main);
let response_type = confirmation_dialog_link.run_future().await; 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() { if !check_button.is_active() {
check_button_settings_confirm_link.set_active(false); 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 true
} }
fn create_dialog_ask_for_linking(window_main: &gtk::Window) -> (Dialog, CheckButton) { fn create_dialog_ask_for_linking(window_main: &gtk4::Window) -> (Dialog, CheckButton) {
let dialog = gtk::Dialog::builder() let dialog = gtk4::Dialog::builder()
.title(&flg!("hard_sym_link_title_dialog")) .title(&flg!("hard_sym_link_title_dialog"))
.transient_for(window_main) .transient_for(window_main)
.modal(true) .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); let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel); dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
let label: gtk::Label = gtk::Label::new(Some(&flg!("hard_sym_link_label"))); let label: gtk4::Label = gtk4::Label::new(Some(&flg!("hard_sym_link_label")));
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_active(true);
check_button.set_halign(Align::Center); check_button.set_halign(Align::Center);
button_ok.grab_focus(); button_ok.grab_focus();
let internal_box = get_dialog_box_child(&dialog); let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label); internal_box.append(&label);
internal_box.add(&check_button); internal_box.append(&check_button);
dialog.show_all(); dialog.show();
(dialog, check_button) (dialog, check_button)
} }

View file

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

View file

@ -3,7 +3,7 @@ use std::sync::Arc;
use std::thread; use std::thread;
use glib::Sender; use glib::Sender;
use gtk::prelude::*; use gtk4::prelude::*;
use czkawka_core::bad_extensions::BadExtensions; use czkawka_core::bad_extensions::BadExtensions;
use czkawka_core::big_file::BigFile; 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_names = gui_data.bottom_buttons.buttons_names;
let buttons_search_clone = gui_data.bottom_buttons.buttons_search.clone(); 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_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_duplicate_case_sensitive_name: gtk4::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_artist: gtk4::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_title: gtk4::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_year: gtk4::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_genre: gtk4::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_length: gtk4::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_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_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_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(); 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)); let show_dialog = Arc::new(AtomicBool::new(true));
window_progress.set_title(Some(&flg!("window_progress_title")));
hide_all_buttons(&buttons_array); hide_all_buttons(&buttons_array);
notebook_main.set_sensitive(false); notebook_main.set_sensitive(false);
@ -168,8 +170,8 @@ pub fn connect_button_search(
image_preview_duplicates.hide(); image_preview_duplicates.hide();
label_stage.show(); label_stage.show();
grid_progress_stages.show_all(); grid_progress_stages.show();
window_progress.resize(1, 1); window_progress.set_default_size(1, 1);
get_list_store(&tree_view_duplicate_finder).clear(); get_list_store(&tree_view_duplicate_finder).clear();
@ -214,7 +216,7 @@ pub fn connect_button_search(
NotebookMainEnum::EmptyFiles => { NotebookMainEnum::EmptyFiles => {
label_stage.show(); label_stage.show();
grid_progress_stages.hide(); 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(); get_list_store(&tree_view_empty_files_finder).clear();
@ -235,7 +237,7 @@ pub fn connect_button_search(
NotebookMainEnum::EmptyDirectories => { NotebookMainEnum::EmptyDirectories => {
label_stage.show(); label_stage.show();
grid_progress_stages.hide(); 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(); get_list_store(&tree_view_empty_folder_finder).clear();
@ -253,7 +255,7 @@ pub fn connect_button_search(
NotebookMainEnum::BigFiles => { NotebookMainEnum::BigFiles => {
label_stage.show(); label_stage.show();
grid_progress_stages.hide(); 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(); get_list_store(&tree_view_big_files_finder).clear();
@ -277,7 +279,7 @@ pub fn connect_button_search(
NotebookMainEnum::Temporary => { NotebookMainEnum::Temporary => {
label_stage.show(); label_stage.show();
grid_progress_stages.hide(); 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(); get_list_store(&tree_view_temporary_files_finder).clear();
@ -298,8 +300,8 @@ pub fn connect_button_search(
image_preview_similar_images.hide(); image_preview_similar_images.hide();
label_stage.show(); label_stage.show();
grid_progress_stages.show_all(); grid_progress_stages.show();
window_progress.resize(1, 1); window_progress.set_default_size(1, 1);
get_list_store(&tree_view_similar_images_finder).clear(); get_list_store(&tree_view_similar_images_finder).clear();
@ -348,8 +350,8 @@ pub fn connect_button_search(
} }
NotebookMainEnum::SimilarVideos => { NotebookMainEnum::SimilarVideos => {
label_stage.show(); label_stage.show();
grid_progress_stages.show_all(); grid_progress_stages.show();
window_progress.resize(1, 1); window_progress.set_default_size(1, 1);
get_list_store(&tree_view_similar_videos_finder).clear(); get_list_store(&tree_view_similar_videos_finder).clear();
@ -383,8 +385,8 @@ pub fn connect_button_search(
} }
NotebookMainEnum::SameMusic => { NotebookMainEnum::SameMusic => {
label_stage.show(); label_stage.show();
grid_progress_stages.show_all(); grid_progress_stages.show();
window_progress.resize(1, 1); window_progress.set_default_size(1, 1);
get_list_store(&tree_view_same_music_finder).clear(); get_list_store(&tree_view_same_music_finder).clear();
@ -444,7 +446,7 @@ pub fn connect_button_search(
NotebookMainEnum::Symlinks => { NotebookMainEnum::Symlinks => {
label_stage.show(); label_stage.show();
grid_progress_stages.hide(); grid_progress_stages.hide();
window_progress.resize(1, 1); window_progress.set_default_size(1, 1);
get_list_store(&tree_view_invalid_symlinks).clear(); get_list_store(&tree_view_invalid_symlinks).clear();
@ -465,7 +467,7 @@ pub fn connect_button_search(
NotebookMainEnum::BrokenFiles => { NotebookMainEnum::BrokenFiles => {
label_stage.show(); label_stage.show();
grid_progress_stages.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(); get_list_store(&tree_view_broken_files).clear();
@ -487,8 +489,8 @@ pub fn connect_button_search(
} }
NotebookMainEnum::BadExtensions => { NotebookMainEnum::BadExtensions => {
label_stage.show(); label_stage.show();
grid_progress_stages.show_all(); grid_progress_stages.show();
window_progress.resize(1, 1); window_progress.set_default_size(1, 1);
get_list_store(&tree_view_bad_extensions).clear(); 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_data::GuiData;
use crate::gui_structs::gui_popovers::GuiPopovers; use crate::gui_structs::gui_popovers::GuiPopovers;
@ -8,12 +8,10 @@ use crate::notebook_enums::*;
pub fn connect_button_select(gui_data: &GuiData) { pub fn connect_button_select(gui_data: &GuiData) {
let popovers = gui_data.popovers.clone(); let popovers = gui_data.popovers.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone(); let notebook_main = gui_data.main_notebook.notebook_main.clone();
let popover_select = gui_data.popovers.popover_select.clone(); let gc_buttons_select = gui_data.bottom_buttons.gc_buttons_select.clone();
let buttons_select = gui_data.bottom_buttons.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())); 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 crossbeam_channel::{Sender, TrySendError};
use gtk::prelude::*;
use crate::flg;
use crate::gui_structs::gui_data::GuiData; use crate::gui_structs::gui_data::GuiData;
use crate::help_functions::KEY_ENTER; use crate::help_functions::KEY_ENTER;
use gtk4::prelude::*;
fn send_stop_message(stop_sender: &Sender<()>) { fn send_stop_message(stop_sender: &Sender<()>) {
stop_sender stop_sender
@ -13,25 +14,22 @@ fn send_stop_message(stop_sender: &Sender<()>) {
pub fn connect_button_stop(gui_data: &GuiData) { 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 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(); let stop_sender = gui_data.stop_sender.clone();
evk_button_stop_in_dialog.connect_key_released(move |_, _, key_code, _| { evk_button_stop_in_dialog.connect_key_released(move |_, _, key_code, _| {
if key_code == KEY_ENTER { 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); send_stop_message(&stop_sender);
} }
}); });
let button_stop_in_dialog = gui_data.progress_window.button_stop_in_dialog.clone(); 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(); let stop_sender = gui_data.stop_sender.clone();
button_stop_in_dialog.connect_button_release_event(move |_, _e| { // TODO GTK 4 change this to connect released, not sure why not works here
send_stop_message(&stop_sender);
gtk::Inhibit(false)
});
// let gc_button_stop_in_dialog = gui_data.progress_window.gc_button_stop_in_dialog.clone(); button_stop_in_dialog.connect_clicked(move |_a| {
// let stop_sender = gui_data.stop_sender.clone(); stop_dialog.set_title(Some(&format!("{} ({})", flg!("window_progress_title"), flg!("progress_stop_additional_message"))));
// gc_button_stop_in_dialog.connect_button_release_event(move |_, _e| { send_stop_message(&stop_sender);
// stop_sender.send(()).unwrap(); });
// gtk::Inhibit(false)
// });
} }

View file

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

View file

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

View file

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

View file

@ -1,5 +1,5 @@
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{ResponseType, TreeIter, Window}; use gtk4::{ResponseType, TreeIter, Window};
use regex::Regex; use regex::Regex;
use czkawka_core::common::Common; 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 // 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. // 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); let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() { if let Some(iter) = model.iter_first() {
if let Some(column_color) = column_color { if let Some(column_header) = column_header {
loop { 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()); model.set_value(&iter, column_button_selection, &true.to_value());
} }
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
@ -37,7 +37,7 @@ fn popover_select_all(popover: &gtk::Popover, tree_view: &gtk::TreeView, column_
popover.popdown(); 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); let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() { 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(); 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); let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() { if let Some(iter) = model.iter_first() {
if let Some(column_color) = column_color { if let Some(column_header) = column_header {
loop { loop {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR { if !model.get::<bool>(&iter, column_header) {
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()); model.set_value(&iter, column_button_selection, &(!current_value).to_value());
} }
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
@ -68,7 +68,7 @@ fn popover_reverse(popover: &gtk::Popover, tree_view: &gtk::TreeView, column_but
} }
} else { } else {
loop { 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()); model.set_value(&iter, column_button_selection, &(!current_value).to_value());
if !model.iter_next(&iter) { 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( fn popover_all_except_oldest_newest(
popover: &gtk::Popover, popover: &gtk4::Popover,
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_color: i32, column_header: i32,
column_modification_as_secs: i32, column_modification_as_secs: i32,
column_file_name: i32, column_file_name: i32,
column_button_selection: u32, column_button_selection: u32,
@ -105,16 +105,15 @@ fn popover_all_except_oldest_newest(
let mut file_length: usize = 0; let mut file_length: usize = 0;
loop { loop {
let color = model.value(&iter, column_color).get::<String>().unwrap(); if model.get::<bool>(&iter, column_header) {
if color == HEADER_ROW_COLOR {
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
end = true; end = true;
} }
break; break;
} }
tree_iter_array.push(iter); tree_iter_array.push(iter);
let modification = model.value(&iter, column_modification_as_secs).get::<u64>().unwrap(); let modification = model.get::<u64>(&iter, column_modification_as_secs);
let current_file_length = model.value(&iter, column_file_name).get::<String>().unwrap().len(); let current_file_length = model.get::<String>(&iter, column_file_name).len();
if except_oldest { if except_oldest {
if modification < modification_time_min_max || (modification == modification_time_min_max && current_file_length < file_length) { if modification < modification_time_min_max || (modification == modification_time_min_max && current_file_length < file_length) {
file_length = current_file_length; file_length = current_file_length;
@ -156,9 +155,9 @@ fn popover_all_except_oldest_newest(
} }
fn popover_one_oldest_newest( fn popover_one_oldest_newest(
popover: &gtk::Popover, popover: &gtk4::Popover,
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_color: i32, column_header: i32,
column_modification_as_secs: i32, column_modification_as_secs: i32,
column_file_name: i32, column_file_name: i32,
column_button_selection: u32, column_button_selection: u32,
@ -180,16 +179,15 @@ fn popover_one_oldest_newest(
let mut file_length: usize = 0; let mut file_length: usize = 0;
loop { loop {
let color = model.value(&iter, column_color).get::<String>().unwrap(); if model.get::<bool>(&iter, column_header) {
if color == HEADER_ROW_COLOR {
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
end = true; end = true;
} }
break; break;
} }
tree_iter_array.push(iter); tree_iter_array.push(iter);
let modification = model.value(&iter, column_modification_as_secs).get::<u64>().unwrap(); let modification = model.get::<u64>(&iter, column_modification_as_secs);
let current_file_length = model.value(&iter, column_file_name).get::<String>().unwrap().len(); let current_file_length = model.get::<String>(&iter, column_file_name).len();
if check_oldest { if check_oldest {
if modification < modification_time_min_max || (modification == modification_time_min_max && current_file_length > file_length) { if modification < modification_time_min_max || (modification == modification_time_min_max && current_file_length > file_length) {
file_length = current_file_length; file_length = current_file_length;
@ -232,10 +230,10 @@ fn popover_one_oldest_newest(
} }
fn popover_custom_select_unselect( fn popover_custom_select_unselect(
popover: &gtk::Popover, popover: &gtk4::Popover,
window_main: &Window, window_main: &Window,
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_color: Option<i32>, column_header: Option<i32>,
column_file_name: i32, column_file_name: i32,
column_path: i32, column_path: i32,
column_button_selection: u32, column_button_selection: u32,
@ -250,26 +248,26 @@ fn popover_custom_select_unselect(
// Dialog for select/unselect items // 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_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel); 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_path = gtk4::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_name = gtk4::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_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); 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); check_button_select_not_all_results.set_active(true);
let entry_path = gtk::Entry::new(); let entry_path = gtk4::Entry::new();
let entry_name = gtk::Entry::new(); let entry_name = gtk4::Entry::new();
let entry_rust_regex = gtk::Entry::new(); let entry_rust_regex = gtk4::Entry::new();
entry_rust_regex.set_sensitive(false); // By default check button regex is disabled 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 // Tooltips
{ {
@ -337,7 +335,7 @@ fn popover_custom_select_unselect(
// Configure look of things // Configure look of things
{ {
// TODO Label should have const width, and rest should fill entry, but for now is 50%-50% // 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_row_homogeneous(true);
grid.set_column_homogeneous(true); grid.set_column_homogeneous(true);
@ -358,9 +356,9 @@ fn popover_custom_select_unselect(
} }
let box_widget = get_dialog_box_child(&dialog); 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(); let tree_view = tree_view.clone();
@ -374,7 +372,7 @@ fn popover_custom_select_unselect(
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
let path_wildcard = path_wildcard.replace("/", "\\"); 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_path = check_button_path.is_active();
let check_name = check_button_name.is_active(); let check_name = check_button_name.is_active();
let check_regex = check_button_rust_regex.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 number_of_already_selected_things = 0;
let mut vec_of_iters: Vec<TreeIter> = Vec::new(); let mut vec_of_iters: Vec<TreeIter> = Vec::new();
loop { loop {
if let Some(column_color) = column_color { if let Some(column_header) = column_header {
let color = model.value(&iter, column_color).get::<String>().unwrap(); if model.get::<bool>(&iter, column_header) {
if color == HEADER_ROW_COLOR {
if select_things { if select_things {
if check_all_selected && (number_of_all_things - number_of_already_selected_things == vec_of_iters.len()) { if check_all_selected && (number_of_all_things - number_of_already_selected_things == vec_of_iters.len()) {
vec_of_iters.pop(); 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 is_selected = model.get::<bool>(&iter, column_button_selection as i32);
let path = model.value(&iter, column_path).get::<String>().unwrap(); let path = model.get::<String>(&iter, column_path);
let name = model.value(&iter, column_file_name).get::<String>().unwrap(); let name = model.get::<String>(&iter, column_file_name);
let path_and_name = get_full_name_from_path_name(&path, &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( fn popover_all_except_biggest_smallest(
popover: &gtk::Popover, popover: &gtk4::Popover,
tree_view: &gtk::TreeView, tree_view: &gtk4::TreeView,
column_color: i32, column_header: i32,
column_size_as_bytes: i32, column_size_as_bytes: i32,
column_dimensions: Option<i32>, column_dimensions: Option<i32>,
column_button_selection: u32, column_button_selection: u32,
@ -536,19 +533,18 @@ fn popover_all_except_biggest_smallest(
}; };
loop { loop {
let color = model.value(&iter, column_color).get::<String>().unwrap(); if model.get::<bool>(&iter, column_header) {
if color == HEADER_ROW_COLOR {
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
end = true; end = true;
} }
break; break;
} }
tree_iter_array.push(iter); 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 dimension exists, then needs to be checked images
if let Some(column_dimensions) = column_dimensions { 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 dimensions = change_dimension_to_krotka(dimensions_string);
let number_of_pixels = dimensions.0 * dimensions.1; 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 tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[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(); 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 tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[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(); 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_all_except_oldest_newest(
&popover_select, &popover_select,
tree_view, 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_modification_as_secs.expect("AEO needs modification as secs column"),
nb_object.column_name, nb_object.column_name,
nb_object.column_selection as u32, nb_object.column_selection as u32,
@ -677,7 +673,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_all_except_oldest_newest( popover_all_except_oldest_newest(
&popover_select, &popover_select,
tree_view, 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_modification_as_secs.expect("AEN needs modification as secs column"),
nb_object.column_name, nb_object.column_name,
nb_object.column_selection as u32, nb_object.column_selection as u32,
@ -697,7 +693,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_one_oldest_newest( popover_one_oldest_newest(
&popover_select, &popover_select,
tree_view, 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_modification_as_secs.expect("OO needs modification as secs column"),
nb_object.column_name, nb_object.column_name,
nb_object.column_selection as u32, nb_object.column_selection as u32,
@ -717,7 +713,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_one_oldest_newest( popover_one_oldest_newest(
&popover_select, &popover_select,
tree_view, 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_modification_as_secs.expect("ON needs modification as secs column"),
nb_object.column_name, nb_object.column_name,
nb_object.column_selection as u32, nb_object.column_selection as u32,
@ -739,7 +735,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
&popover_select, &popover_select,
&window_main, &window_main,
tree_view, tree_view,
nb_object.column_color, nb_object.column_header,
nb_object.column_name, nb_object.column_name,
nb_object.column_path, nb_object.column_path,
nb_object.column_selection as u32, nb_object.column_selection as u32,
@ -761,7 +757,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
&popover_select, &popover_select,
&window_main, &window_main,
tree_view, tree_view,
nb_object.column_color, nb_object.column_header,
nb_object.column_name, nb_object.column_name,
nb_object.column_path, nb_object.column_path,
nb_object.column_selection as u32, nb_object.column_selection as u32,
@ -781,7 +777,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_all_except_biggest_smallest( popover_all_except_biggest_smallest(
&popover_select, &popover_select,
tree_view, 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_size_as_bytes.expect("AEB needs size as bytes column"),
nb_object.column_dimensions, nb_object.column_dimensions,
nb_object.column_selection as u32, nb_object.column_selection as u32,
@ -801,7 +797,7 @@ pub fn connect_popovers(gui_data: &GuiData) {
popover_all_except_biggest_smallest( popover_all_except_biggest_smallest(
&popover_select, &popover_select,
tree_view, 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_size_as_bytes.expect("AES needs size as bytes column"),
nb_object.column_dimensions, nb_object.column_dimensions,
nb_object.column_selection as u32, nb_object.column_selection as u32,

View file

@ -1,6 +1,6 @@
use futures::channel::mpsc::UnboundedReceiver; use futures::channel::mpsc::UnboundedReceiver;
use futures::StreamExt; use futures::StreamExt;
use gtk::prelude::*; use gtk4::prelude::*;
use czkawka_core::common_dir_traversal::ProgressData; use czkawka_core::common_dir_traversal::ProgressData;
use czkawka_core::{big_file, broken_files, common_dir_traversal, similar_images, similar_videos, temporary}; 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 std::path::PathBuf;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{ResponseType, TreeView, Window}; use gtk4::{Orientation, ResponseType, TreeView, Window};
use crate::flg; use crate::flg;
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
use czkawka_core::common::Common; use czkawka_core::common::Common;
use crate::gui_structs::gui_data::GuiData; 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) { pub fn connect_selection_of_directories(gui_data: &GuiData) {
// Add manually directory // Add manually directory
@ -86,9 +86,9 @@ fn add_chosen_directories(window_main: &Window, tree_view: &TreeView, excluded_i
flg!("include_folders_dialog_title") flg!("include_folders_dialog_title")
}; };
let file_chooser = gtk::FileChooserDialog::builder() let file_chooser = gtk4::FileChooserDialog::builder()
.title(&folders_to) .title(&folders_to)
.action(gtk::FileChooserAction::SelectFolder) .action(gtk4::FileChooserAction::SelectFolder)
.transient_for(window_main) .transient_for(window_main)
.modal(true) .modal(true)
.build(); .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.add_button(&flg!("general_close_button"), ResponseType::Cancel);
file_chooser.set_select_multiple(true); file_chooser.set_select_multiple(true);
file_chooser.show_all(); file_chooser.show();
let tree_view = tree_view.clone(); let tree_view = tree_view.clone();
file_chooser.connect_response(move |file_chooser, response_type| { file_chooser.connect_response(move |file_chooser, response_type| {
if response_type == gtk::ResponseType::Ok { if response_type == gtk4::ResponseType::Ok {
let folders: Vec<PathBuf> = file_chooser.filenames(); let mut folders: Vec<PathBuf> = Vec::new();
// GTK 4 let g_files = file_chooser.files();
// folders = Vec::new(); for index in 0..g_files.n_items() {
// if let Some(g_files) = file_chooser.files() { let file = &g_files.item(index);
// for index in 0..g_files.n_items() { if let Some(file) = file {
// let file = &g_files.item(index); let ss = file.clone().downcast::<gtk4::gio::File>().unwrap();
// if let Some(file) = file { if let Some(path_buf) = ss.path() {
// println!("{:?}", file); folders.push(path_buf);
// 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); 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) { 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")) .title(&flg!("include_manually_directories_dialog_title"))
.transient_for(window_main) .transient_for(window_main)
.modal(true) .modal(true)
.build(); .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); 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();
dialog.show_all();
let tree_view = tree_view.clone(); let tree_view = tree_view.clone();
dialog.connect_response(move |dialog, response_type| { 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(); let text = entry.text().to_string().trim().to_string();
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]

View file

@ -2,9 +2,9 @@ use std::collections::BTreeMap;
use std::default::Default; use std::default::Default;
use directories_next::ProjectDirs; use directories_next::ProjectDirs;
use gtk::builders::LabelBuilder; use gtk4::builders::LabelBuilder;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{ResponseType, Window}; use gtk4::{ResponseType, Window};
use image::imageops::FilterType; use image::imageops::FilterType;
use image_hasher::HashAlg; use image_hasher::HashAlg;
@ -27,9 +27,9 @@ pub fn connect_settings(gui_data: &GuiData) {
let window_settings = gui_data.settings.window_settings.clone(); 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(); 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 |_| { button_settings_duplicates_clear_cache.connect_clicked(move |_| {
let dialog = create_clear_cache_dialog(flg!("cache_clear_duplicates_title"), &settings_window); 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 text_view_errors = text_view_errors.clone();
let entry_settings_cache_file_minimal_size = entry_settings_cache_file_minimal_size.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")); 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(); dialog.close();
@ -139,7 +139,7 @@ pub fn connect_settings(gui_data: &GuiData) {
button_settings_similar_images_clear_cache.connect_clicked(move |_| { button_settings_similar_images_clear_cache.connect_clicked(move |_| {
let dialog = create_clear_cache_dialog(flg!("cache_clear_similar_images_title"), &settings_window); 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(); 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")); 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(); dialog.close();
}); });
@ -178,7 +178,7 @@ pub fn connect_settings(gui_data: &GuiData) {
button_settings_similar_videos_clear_cache.connect_clicked(move |_| { button_settings_similar_videos_clear_cache.connect_clicked(move |_| {
let dialog = create_clear_cache_dialog(flg!("cache_clear_similar_videos_title"), &settings_window); 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(); 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")); 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(); 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 { fn create_clear_cache_dialog(title_str: String, window_settings: &Window) -> gtk4::Dialog {
let dialog = gtk::Dialog::builder().title(&title_str).modal(true).transient_for(window_settings).build(); 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_ok_button"), ResponseType::Ok);
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel); 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 label4 = LabelBuilder::new().label(&flg!("cache_clear_message_label_4")).build();
let internal_box = get_dialog_box_child(&dialog); let internal_box = get_dialog_box_child(&dialog);
internal_box.add(&label); internal_box.append(&label);
internal_box.add(&label2); internal_box.append(&label2);
internal_box.add(&label3); internal_box.append(&label3);
internal_box.add(&label4); internal_box.append(&label4);
dialog dialog
} }

View file

@ -1,4 +1,4 @@
use gtk::prelude::*; use gtk4::prelude::*;
use crate::gui_structs::gui_data::GuiData; 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}; use czkawka_core::similar_images::{get_string_from_similarity, Similarity, SIMILAR_VALUES};

View file

@ -1,41 +1,38 @@
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::TreeViewColumn; use gtk4::TreeViewColumn;
use crate::help_functions::*; use crate::help_functions::*;
// When adding new column do not forget to update translations // 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.set_title("Folders to check"); column.set_title("Folders to check");
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.add_attribute(&renderer, "text", ColumnsIncludedDirectory::Path as i32); column.add_attribute(&renderer, "text", ColumnsIncludedDirectory::Path as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsIncludedDirectory::ReferenceButton as i32);
.value(&iter, ColumnsIncludedDirectory::ReferenceButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsIncludedDirectory::ReferenceButton as u32, &fixed.to_value()); model.set_value(&iter, ColumnsIncludedDirectory::ReferenceButton as u32, &fixed.to_value());
}); });
renderer.set_activatable(true); renderer.set_activatable(true);
let column = gtk::TreeViewColumn::new(); let column = gtk4::TreeViewColumn::new();
column.set_title("Reference folder"); column.set_title("Reference folder");
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.add_attribute(&renderer, "active", ColumnsIncludedDirectory::ReferenceButton as i32); column.add_attribute(&renderer, "active", ColumnsIncludedDirectory::ReferenceButton as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
} }
pub fn create_tree_view_excluded_directories(tree_view: &gtk::TreeView) { pub fn create_tree_view_excluded_directories(tree_view: &gtk4::TreeView) {
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.add_attribute(&renderer, "text", ColumnsExcludedDirectory::Path as i32); column.add_attribute(&renderer, "text", ColumnsExcludedDirectory::Path as i32);
tree_view.append_column(&column); 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); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsDuplicates::SelectionButton as i32);
.value(&iter, ColumnsDuplicates::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsDuplicates::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); 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); column.add_attribute(&renderer, "cell-background", ColumnsDuplicates::Color as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Size"); column.set_title("Size");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsDuplicates::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("File Name"); column.set_title("File Name");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsDuplicates::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsDuplicates::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -112,28 +106,25 @@ pub fn create_tree_view_duplicates(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsEmptyFolders::SelectionButton as i32);
.value(&iter, ColumnsEmptyFolders::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsEmptyFolders::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsEmptyFolders::SelectionButton as i32); column.add_attribute(&renderer, "active", ColumnsEmptyFolders::SelectionButton as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Folder Name"); column.set_title("Folder Name");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsEmptyFolders::Name as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsEmptyFolders::Path as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -165,28 +156,25 @@ pub fn create_tree_view_empty_folders(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsBigFiles::SelectionButton as i32);
.value(&iter, ColumnsBigFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsBigFiles::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsBigFiles::SelectionButton as i32); column.add_attribute(&renderer, "active", ColumnsBigFiles::SelectionButton as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Size"); column.set_title("Size");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsBigFiles::SizeAsBytes as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("File Name"); column.set_title("File Name");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsBigFiles::Name as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsBigFiles::Path as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -228,28 +216,25 @@ pub fn create_tree_view_big_files(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsTemporaryFiles::SelectionButton as i32);
.value(&iter, ColumnsTemporaryFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsTemporaryFiles::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsTemporaryFiles::SelectionButton as i32); column.add_attribute(&renderer, "active", ColumnsTemporaryFiles::SelectionButton as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("File Name"); column.set_title("File Name");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsTemporaryFiles::Name as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsTemporaryFiles::Path as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -281,28 +266,25 @@ pub fn create_tree_view_temporary_files(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsEmptyFiles::SelectionButton as i32);
.value(&iter, ColumnsEmptyFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsEmptyFiles::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsEmptyFiles::SelectionButton as i32); column.add_attribute(&renderer, "active", ColumnsEmptyFiles::SelectionButton as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("File Name"); column.set_title("File Name");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsEmptyFiles::Name as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsEmptyFiles::Path as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -334,20 +316,17 @@ pub fn create_tree_view_empty_files(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsSimilarImages::SelectionButton as i32);
.value(&iter, ColumnsSimilarImages::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsSimilarImages::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); 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); column.add_attribute(&renderer, "cell-background", ColumnsSimilarImages::Color as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Similarity"); column.set_title("Similarity");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Size"); column.set_title("Size");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Dimensions"); column.set_title("Dimensions");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("File Name"); column.set_title("File Name");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSimilarImages::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -425,20 +404,17 @@ pub fn create_tree_view_similar_images(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsSimilarVideos::SelectionButton as i32);
.value(&iter, ColumnsSimilarVideos::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsSimilarVideos::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); 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); column.add_attribute(&renderer, "cell-background", ColumnsSimilarVideos::Color as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Size"); column.set_title("Size");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSimilarVideos::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("File Name"); column.set_title("File Name");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSimilarVideos::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSimilarVideos::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -494,20 +470,17 @@ pub fn create_tree_view_similar_videos(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsSameMusic::SelectionButton as i32);
.value(&iter, ColumnsSameMusic::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsSameMusic::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); 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); column.add_attribute(&renderer, "cell-background", ColumnsSameMusic::Color as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Size"); column.set_title("Size");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("File Name"); column.set_title("File Name");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Title"); column.set_title("Title");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Artist"); column.set_title("Artist");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Year"); column.set_title("Year");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Bitrate"); column.set_title("Bitrate");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Length"); column.set_title("Length");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Genre"); column.set_title("Genre");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.add_attribute(&renderer, "foreground", ColumnsSameMusic::TextColor as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -629,28 +602,25 @@ pub fn create_tree_view_same_music(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsInvalidSymlinks::SelectionButton as i32);
.value(&iter, ColumnsInvalidSymlinks::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsInvalidSymlinks::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsInvalidSymlinks::SelectionButton as i32); column.add_attribute(&renderer, "active", ColumnsInvalidSymlinks::SelectionButton as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Symlink File Name"); column.set_title("Symlink File Name");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsInvalidSymlinks::Name as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Symlink Folder"); column.set_title("Symlink Folder");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsInvalidSymlinks::Path as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Destination Path"); column.set_title("Destination Path");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsInvalidSymlinks::DestinationPath as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Type of Error"); column.set_title("Type of Error");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsInvalidSymlinks::TypeOfError as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);
@ -702,28 +672,25 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &gtk::TreeView) {
tree_view.set_vexpand(true); 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 model = get_list_store(tree_view);
let renderer = gtk::CellRendererToggle::new(); let renderer = gtk4::CellRendererToggle::new();
renderer.connect_toggled(move |_r, path| { renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap(); let iter = model.iter(&path).unwrap();
let mut fixed = model let mut fixed = model.get::<bool>(&iter, ColumnsBrokenFiles::SelectionButton as i32);
.value(&iter, ColumnsBrokenFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
fixed = !fixed; fixed = !fixed;
model.set_value(&iter, ColumnsBrokenFiles::SelectionButton as u32, &fixed.to_value()); 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.pack_start(&renderer, true);
column.set_resizable(false); column.set_resizable(false);
column.set_fixed_width(30); column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsBrokenFiles::SelectionButton as i32); column.add_attribute(&renderer, "active", ColumnsBrokenFiles::SelectionButton as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Name"); column.set_title("Name");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsBrokenFiles::Name as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Path"); column.set_title("Path");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsBrokenFiles::Path as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("ErrorType"); column.set_title("ErrorType");
column.set_resizable(true); 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); column.set_sort_column_id(ColumnsBrokenFiles::ErrorType as i32);
tree_view.append_column(&column); tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new(); let renderer = gtk4::CellRendererText::new();
let column: gtk::TreeViewColumn = TreeViewColumn::new(); let column: gtk4::TreeViewColumn = TreeViewColumn::new();
column.pack_start(&renderer, true); column.pack_start(&renderer, true);
column.set_title("Modification Date"); column.set_title("Modification Date");
column.set_resizable(true); column.set_resizable(true);

View file

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

View file

@ -1,7 +1,7 @@
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{Bin, Widget}; 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::{ 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, 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, CZK_ICON_TRASH,
@ -9,36 +9,43 @@ use crate::{
#[derive(Clone)] #[derive(Clone)]
pub struct GuiBottomButtons { pub struct GuiBottomButtons {
pub buttons_search: gtk::Button, pub buttons_search: gtk4::Button,
pub buttons_select: gtk::MenuButton, pub buttons_select: gtk4::MenuButton,
pub buttons_delete: gtk::Button, pub buttons_delete: gtk4::Button,
pub buttons_save: gtk::Button, pub buttons_save: gtk4::Button,
pub buttons_symlink: gtk::Button, pub buttons_symlink: gtk4::Button,
pub buttons_hardlink: gtk::Button, pub buttons_hardlink: gtk4::Button,
pub buttons_move: gtk::Button, pub buttons_move: gtk4::Button,
pub buttons_compare: gtk::Button, pub buttons_compare: gtk4::Button,
pub buttons_show_errors: gtk::Button, pub buttons_show_errors: gtk4::Button,
pub buttons_show_upper_notebook: gtk::Button, pub buttons_show_upper_notebook: gtk4::Button,
pub buttons_names: [BottomButtonsEnum; 8], pub buttons_names: [BottomButtonsEnum; 8],
pub buttons_array: [Widget; 8], pub buttons_array: [Widget; 8],
pub gc_buttons_select: gtk4::GestureClick,
} }
impl GuiBottomButtons { impl GuiBottomButtons {
pub fn create_from_builder(builder: &gtk::Builder, popover_select: &gtk::Popover) -> Self { pub fn create_from_builder(builder: &gtk4::Builder, popover_select: &gtk4::Popover) -> Self {
let buttons_search: gtk::Button = builder.object("buttons_search").unwrap(); let buttons_search: gtk4::Button = builder.object("buttons_search").unwrap();
let buttons_select: gtk::MenuButton = builder.object("buttons_select").unwrap(); let buttons_select: gtk4::MenuButton = builder.object("buttons_select").unwrap();
let buttons_delete: gtk::Button = builder.object("buttons_delete").unwrap(); let buttons_delete: gtk4::Button = builder.object("buttons_delete").unwrap();
let buttons_save: gtk::Button = builder.object("buttons_save").unwrap(); let buttons_save: gtk4::Button = builder.object("buttons_save").unwrap();
let buttons_symlink: gtk::Button = builder.object("buttons_symlink").unwrap(); let buttons_symlink: gtk4::Button = builder.object("buttons_symlink").unwrap();
let buttons_hardlink: gtk::Button = builder.object("buttons_hardlink").unwrap(); let buttons_hardlink: gtk4::Button = builder.object("buttons_hardlink").unwrap();
let buttons_move: gtk::Button = builder.object("buttons_move").unwrap(); let buttons_move: gtk4::Button = builder.object("buttons_move").unwrap();
let buttons_compare: gtk::Button = builder.object("buttons_compare").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_errors: gtk4::Button = builder.object("buttons_show_errors").unwrap();
let buttons_show_upper_notebook: gtk::Button = builder.object("buttons_show_upper_notebook").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_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_delete, CZK_ICON_TRASH);
set_icon_of_button(&buttons_save, CZK_ICON_SAVE); set_icon_of_button(&buttons_save, CZK_ICON_SAVE);
set_icon_of_button(&buttons_symlink, CZK_ICON_SYMLINK); set_icon_of_button(&buttons_symlink, CZK_ICON_SYMLINK);
@ -84,24 +91,17 @@ impl GuiBottomButtons {
buttons_show_upper_notebook, buttons_show_upper_notebook,
buttons_names, buttons_names,
buttons_array, buttons_array,
gc_buttons_select,
} }
} }
pub fn update_language(&self) { 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_widget(&self.buttons_search.clone()).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_widget(&self.buttons_select.clone()).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_widget(&self.buttons_delete.clone()).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_widget(&self.buttons_save.clone()).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_widget(&self.buttons_symlink.clone()).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_widget(&self.buttons_hardlink.clone()).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_widget(&self.buttons_move.clone()).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"));
self.buttons_search.set_tooltip_text(Some(&flg!("bottom_search_button_tooltip"))); self.buttons_search.set_tooltip_text(Some(&flg!("bottom_search_button_tooltip")));
self.buttons_select.set_tooltip_text(Some(&flg!("bottom_select_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::help_functions::set_icon_of_button;
use crate::{flg, CZK_ICON_LEFT, CZK_ICON_RIGHT}; use crate::{flg, CZK_ICON_LEFT, CZK_ICON_RIGHT};
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{Builder, TreePath}; use gtk4::{Builder, TreePath};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
#[derive(Clone)] #[derive(Clone)]
pub struct GuiCompareImages { 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_previous_compare_group: gtk4::Button,
pub button_go_next_compare_group: gtk::Button, pub button_go_next_compare_group: gtk4::Button,
pub check_button_left_preview_text: gtk::CheckButton, pub check_button_left_preview_text: gtk4::CheckButton,
pub check_button_right_preview_text: gtk::CheckButton, pub check_button_right_preview_text: gtk4::CheckButton,
pub image_compare_left: gtk::Image, pub image_compare_left: gtk4::Image,
pub image_compare_right: gtk::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_numbers_of_groups: Rc<RefCell<u32>>,
pub shared_current_of_groups: Rc<RefCell<u32>>, pub shared_current_of_groups: Rc<RefCell<u32>>,
pub shared_current_path: Rc<RefCell<Option<TreePath>>>, 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_image_cache: Rc<RefCell<Vec<(String, String, gtk4::Image, gtk4::Image, gtk4::TreePath)>>>,
pub shared_using_for_preview: Rc<RefCell<(Option<gtk::TreePath>, Option<gtk::TreePath>)>>, pub shared_using_for_preview: Rc<RefCell<(Option<gtk4::TreePath>, Option<gtk4::TreePath>)>>,
} }
impl GuiCompareImages { 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 glade_src = include_str!("../../ui/compare_images.ui").to_string();
let builder = Builder::from_string(glade_src.as_str()); let builder = Builder::from_string(glade_src.as_str());
let window_compare: gtk::Window = builder.object("window_compare").unwrap(); let window_compare: gtk4::Window = builder.object("window_compare").unwrap();
window_compare.set_title(&flg!("window_compare_images")); window_compare.set_title(Some(&flg!("window_compare_images")));
window_compare.set_modal(true); window_compare.set_modal(true);
window_compare.set_transient_for(Some(window_main)); 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_previous_compare_group: gtk4::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_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_left_preview_text: gtk4::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_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_left: gtk4::Image = builder.object("image_compare_left").unwrap();
let image_compare_right: gtk::Image = builder.object("image_compare_right").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_numbers_of_groups = Rc::new(RefCell::new(0));
let shared_current_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) { 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 crossbeam_channel::bounded;
use czkawka_core::bad_extensions::BadExtensions; use czkawka_core::bad_extensions::BadExtensions;
use gdk::gdk_pixbuf::Pixbuf; use gdk4::gdk_pixbuf::Pixbuf;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::Builder; use gtk4::Builder;
use crate::flg; use crate::flg;
use czkawka_core::big_file::BigFile; use czkawka_core::big_file::BigFile;
@ -60,7 +60,7 @@ pub struct GuiData {
pub builder: Builder, pub builder: Builder,
// Windows // Windows
pub window_main: gtk::Window, pub window_main: gtk4::Window,
pub main_notebook: GuiMainNotebook, pub main_notebook: GuiMainNotebook,
pub upper_notebook: GuiUpperNotebook, pub upper_notebook: GuiUpperNotebook,
@ -94,11 +94,11 @@ pub struct GuiData {
pub preview_path: Rc<RefCell<String>>, pub preview_path: Rc<RefCell<String>>,
//// Entry //// Entry
pub entry_info: gtk::Entry, pub entry_info: gtk4::Entry,
//// Bottom //// Bottom
pub text_view_errors: gtk::TextView, pub text_view_errors: gtk4::TextView,
pub scrolled_window_errors: gtk::ScrolledWindow, pub scrolled_window_errors: gtk4::ScrolledWindow,
// Used for sending stop signal to thread // Used for sending stop signal to thread
pub stop_sender: crossbeam_channel::Sender<()>, pub stop_sender: crossbeam_channel::Sender<()>,
@ -106,18 +106,18 @@ pub struct GuiData {
} }
impl 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 //// Loading glade file content and build with it help UI
let glade_src = include_str!("../../ui/main_window.ui").to_string(); let glade_src = include_str!("../../ui/main_window.ui").to_string();
let builder = Builder::from_string(glade_src.as_str()); let builder = Builder::from_string(glade_src.as_str());
//// Windows //// Windows
let window_main: gtk::Window = builder.object("window_main").unwrap(); let window_main: gtk4::Window = builder.object("window_main").unwrap();
window_main.set_title(&flg!("window_main_title")); window_main.set_title(Some(&flg!("window_main_title")));
window_main.show_all(); window_main.show();
let pixbuf = Pixbuf::from_read(std::io::BufReader::new(&ICON_ABOUT[..])).unwrap(); 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)); window_main.set_application(Some(application));
@ -169,12 +169,12 @@ impl GuiData {
let preview_path: Rc<RefCell<_>> = Rc::new(RefCell::new("".to_string())); let preview_path: Rc<RefCell<_>> = Rc::new(RefCell::new("".to_string()));
//// Entry //// Entry
let entry_info: gtk::Entry = builder.object("entry_info").unwrap(); let entry_info: gtk4::Entry = builder.object("entry_info").unwrap();
//// Bottom //// Bottom
let text_view_errors: gtk::TextView = builder.object("text_view_errors").unwrap(); let text_view_errors: gtk4::TextView = builder.object("text_view_errors").unwrap();
let scrolled_window_errors: gtk::ScrolledWindow = builder.object("scrolled_window_errors").unwrap(); let scrolled_window_errors: gtk4::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 scrolled_window_errors.show(); // Not sure why needed, but without it text view errors sometimes hide itself
// Used for sending stop signal to thread // Used for sending stop signal to thread
let (stop_sender, stop_receiver): (crossbeam_channel::Sender<()>, crossbeam_channel::Receiver<()>) = bounded(1); let (stop_sender, stop_receiver): (crossbeam_channel::Sender<()>, crossbeam_channel::Receiver<()>) = bounded(1);
@ -215,7 +215,7 @@ impl GuiData {
} }
pub fn update_language(&self) { 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.main_notebook.update_language();
self.upper_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::help_functions::set_icon_of_button;
use crate::{flg, CZK_ICON_INFO, CZK_ICON_SETTINGS}; use crate::{flg, CZK_ICON_INFO, CZK_ICON_SETTINGS};
#[derive(Clone)] #[derive(Clone)]
pub struct GuiHeader { pub struct GuiHeader {
pub button_settings: gtk::Button, pub button_settings: gtk4::Button,
pub button_app_info: gtk::Button, pub button_app_info: gtk4::Button,
} }
impl GuiHeader { impl GuiHeader {
pub fn create_from_builder(builder: &gtk::Builder) -> Self { pub fn create_from_builder(builder: &gtk4::Builder) -> Self {
let button_settings: gtk::Button = builder.object("button_settings").unwrap(); let button_settings: gtk4::Button = builder.object("button_settings").unwrap();
let button_app_info: gtk::Button = builder.object("button_app_info").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_settings, CZK_ICON_SETTINGS);
set_icon_of_button(&button_app_info, CZK_ICON_INFO); 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::common_dir_traversal::CheckingMethod;
use czkawka_core::localizer_core::{fnc_get_similarity_minimal, fnc_get_similarity_very_high}; use czkawka_core::localizer_core::{fnc_get_similarity_minimal, fnc_get_similarity_very_high};
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{EventControllerKey, TreeView}; use gtk4::{EventControllerKey, GestureClick, TreeView};
use czkawka_core::similar_images::{get_string_from_similarity, Similarity, SIMILAR_VALUES}; use czkawka_core::similar_images::{get_string_from_similarity, Similarity, SIMILAR_VALUES};
use crate::flg; use crate::flg;
use crate::help_combo_box::{DUPLICATES_CHECK_METHOD_COMBO_BOX, IMAGES_HASH_SIZE_COMBO_BOX}; 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}; use crate::notebook_enums::{NotebookMainEnum, NUMBER_OF_NOTEBOOK_MAIN_TABS};
#[derive(Clone)] #[derive(Clone)]
pub struct GuiMainNotebook { pub struct GuiMainNotebook {
pub notebook_main: gtk::Notebook, pub notebook_main: gtk4::Notebook,
pub scrolled_window_duplicate_finder: gtk::ScrolledWindow, pub scrolled_window_duplicate_finder: gtk4::ScrolledWindow,
pub scrolled_window_empty_folder_finder: gtk::ScrolledWindow, pub scrolled_window_empty_folder_finder: gtk4::ScrolledWindow,
pub scrolled_window_empty_files_finder: gtk::ScrolledWindow, pub scrolled_window_empty_files_finder: gtk4::ScrolledWindow,
pub scrolled_window_temporary_files_finder: gtk::ScrolledWindow, pub scrolled_window_temporary_files_finder: gtk4::ScrolledWindow,
pub scrolled_window_big_files_finder: gtk::ScrolledWindow, pub scrolled_window_big_files_finder: gtk4::ScrolledWindow,
pub scrolled_window_similar_images_finder: gtk::ScrolledWindow, pub scrolled_window_similar_images_finder: gtk4::ScrolledWindow,
pub scrolled_window_similar_videos_finder: gtk::ScrolledWindow, pub scrolled_window_similar_videos_finder: gtk4::ScrolledWindow,
pub scrolled_window_same_music_finder: gtk::ScrolledWindow, pub scrolled_window_same_music_finder: gtk4::ScrolledWindow,
pub scrolled_window_invalid_symlinks: gtk::ScrolledWindow, pub scrolled_window_invalid_symlinks: gtk4::ScrolledWindow,
pub scrolled_window_broken_files: gtk::ScrolledWindow, pub scrolled_window_broken_files: gtk4::ScrolledWindow,
pub scrolled_window_bad_extensions: gtk::ScrolledWindow, pub scrolled_window_bad_extensions: gtk4::ScrolledWindow,
pub tree_view_duplicate_finder: gtk::TreeView, pub tree_view_duplicate_finder: gtk4::TreeView,
pub tree_view_empty_folder_finder: gtk::TreeView, pub tree_view_empty_folder_finder: gtk4::TreeView,
pub tree_view_empty_files_finder: gtk::TreeView, pub tree_view_empty_files_finder: gtk4::TreeView,
pub tree_view_temporary_files_finder: gtk::TreeView, pub tree_view_temporary_files_finder: gtk4::TreeView,
pub tree_view_big_files_finder: gtk::TreeView, pub tree_view_big_files_finder: gtk4::TreeView,
pub tree_view_similar_images_finder: gtk::TreeView, pub tree_view_similar_images_finder: gtk4::TreeView,
pub tree_view_similar_videos_finder: gtk::TreeView, pub tree_view_similar_videos_finder: gtk4::TreeView,
pub tree_view_same_music_finder: gtk::TreeView, pub tree_view_same_music_finder: gtk4::TreeView,
pub tree_view_invalid_symlinks: gtk::TreeView, pub tree_view_invalid_symlinks: gtk4::TreeView,
pub tree_view_broken_files: gtk::TreeView, pub tree_view_broken_files: gtk4::TreeView,
pub tree_view_bad_extensions: gtk::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: gtk4::EventControllerKey,
pub evk_tree_view_duplicate_finder: gtk::EventControllerKey, pub evk_tree_view_empty_folder_finder: gtk4::EventControllerKey,
pub evk_tree_view_empty_folder_finder: gtk::EventControllerKey, pub evk_tree_view_empty_files_finder: gtk4::EventControllerKey,
pub evk_tree_view_empty_files_finder: gtk::EventControllerKey, pub evk_tree_view_temporary_files_finder: gtk4::EventControllerKey,
pub evk_tree_view_temporary_files_finder: gtk::EventControllerKey, pub evk_tree_view_big_files_finder: gtk4::EventControllerKey,
pub evk_tree_view_big_files_finder: gtk::EventControllerKey, pub evk_tree_view_similar_images_finder: gtk4::EventControllerKey,
pub evk_tree_view_similar_images_finder: gtk::EventControllerKey, pub evk_tree_view_similar_videos_finder: gtk4::EventControllerKey,
pub evk_tree_view_similar_videos_finder: gtk::EventControllerKey, pub evk_tree_view_same_music_finder: gtk4::EventControllerKey,
pub evk_tree_view_same_music_finder: gtk::EventControllerKey, pub evk_tree_view_invalid_symlinks: gtk4::EventControllerKey,
pub evk_tree_view_invalid_symlinks: gtk::EventControllerKey, pub evk_tree_view_broken_files: gtk4::EventControllerKey,
pub evk_tree_view_broken_files: gtk::EventControllerKey, pub evk_tree_view_bad_extensions: gtk4::EventControllerKey,
pub evk_tree_view_bad_extensions: gtk::EventControllerKey,
// pub gc_tree_view_duplicate_finder: gtk4::GestureClick, pub gc_tree_view_duplicate_finder: gtk4::GestureClick,
// pub gc_tree_view_empty_folder_finder: gtk::GestureClick, pub gc_tree_view_empty_folder_finder: gtk4::GestureClick,
// pub gc_tree_view_empty_files_finder: gtk::GestureClick, pub gc_tree_view_empty_files_finder: gtk4::GestureClick,
// pub gc_tree_view_temporary_files_finder: gtk::GestureClick, pub gc_tree_view_temporary_files_finder: gtk4::GestureClick,
// pub gc_tree_view_big_files_finder: gtk::GestureClick, pub gc_tree_view_big_files_finder: gtk4::GestureClick,
// pub gc_tree_view_similar_images_finder: gtk::GestureClick, pub gc_tree_view_similar_images_finder: gtk4::GestureClick,
// pub gc_tree_view_similar_videos_finder: gtk::GestureClick, pub gc_tree_view_similar_videos_finder: gtk4::GestureClick,
// pub gc_tree_view_same_music_finder: gtk::GestureClick, pub gc_tree_view_same_music_finder: gtk4::GestureClick,
// pub gc_tree_view_invalid_symlinks: gtk::GestureClick, pub gc_tree_view_invalid_symlinks: gtk4::GestureClick,
// pub gc_tree_view_broken_files: gtk::GestureClick, pub gc_tree_view_broken_files: gtk4::GestureClick,
// pub gc_tree_view_bad_extensions: gtk::GestureClick, pub gc_tree_view_bad_extensions: gtk4::GestureClick,
// General // General
// Duplicate // Duplicate
pub combo_box_duplicate_check_method: gtk::ComboBoxText, pub combo_box_duplicate_check_method: gtk4::ComboBoxText,
pub combo_box_duplicate_hash_type: gtk::ComboBoxText, pub combo_box_duplicate_hash_type: gtk4::ComboBoxText,
pub label_duplicate_check_method: gtk::Label, pub label_duplicate_check_method: gtk4::Label,
pub label_duplicate_hash_type: gtk::Label, pub label_duplicate_hash_type: gtk4::Label,
pub check_button_duplicate_case_sensitive_name: gtk::CheckButton, pub check_button_duplicate_case_sensitive_name: gtk4::CheckButton,
pub image_preview_duplicates: gtk::Image, pub image_preview_duplicates: gtk4::Image,
// Big file // Big file
pub label_big_shown_files: gtk::Label, pub label_big_shown_files: gtk4::Label,
pub entry_big_files_number: gtk::Entry, pub entry_big_files_number: gtk4::Entry,
// Similar Images // 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_resize_algorithm: gtk4::Label,
pub label_image_hash_type: gtk::Label, pub label_image_hash_type: gtk4::Label,
pub label_image_hash_size: gtk::Label, pub label_image_hash_size: gtk4::Label,
pub combo_box_image_resize_algorithm: gtk::ComboBoxText, pub combo_box_image_resize_algorithm: gtk4::ComboBoxText,
pub combo_box_image_hash_algorithm: gtk::ComboBoxText, pub combo_box_image_hash_algorithm: gtk4::ComboBoxText,
pub combo_box_image_hash_size: gtk::ComboBoxText, pub combo_box_image_hash_size: gtk4::ComboBoxText,
pub check_button_image_ignore_same_size: gtk::CheckButton, pub check_button_image_ignore_same_size: gtk4::CheckButton,
pub check_button_video_ignore_same_size: gtk::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: gtk4::Label,
pub label_image_similarity_max: gtk::Label, pub label_image_similarity_max: gtk4::Label,
pub image_preview_similar_images: gtk::Image, pub image_preview_similar_images: gtk4::Image,
pub label_similar_images_minimal_similarity: gtk::Label, pub label_similar_images_minimal_similarity: gtk4::Label,
// Video // Video
pub label_video_similarity: gtk::Label, pub label_video_similarity: gtk4::Label,
pub label_video_similarity_min: gtk::Label, pub label_video_similarity_min: gtk4::Label,
pub label_video_similarity_max: gtk::Label, pub label_video_similarity_max: gtk4::Label,
pub scale_similarity_similar_videos: gtk::Scale, pub scale_similarity_similar_videos: gtk4::Scale,
// Music // Music
pub check_button_music_title: gtk::CheckButton, pub check_button_music_title: gtk4::CheckButton,
pub check_button_music_artist: gtk::CheckButton, pub check_button_music_artist: gtk4::CheckButton,
pub check_button_music_year: gtk::CheckButton, pub check_button_music_year: gtk4::CheckButton,
pub check_button_music_bitrate: gtk::CheckButton, pub check_button_music_bitrate: gtk4::CheckButton,
pub check_button_music_genre: gtk::CheckButton, pub check_button_music_genre: gtk4::CheckButton,
pub check_button_music_length: gtk::CheckButton, pub check_button_music_length: gtk4::CheckButton,
pub check_button_music_approximate_comparison: gtk::CheckButton, pub check_button_music_approximate_comparison: gtk4::CheckButton,
} }
impl GuiMainNotebook { impl GuiMainNotebook {
pub fn create_from_builder(builder: &gtk::Builder) -> Self { pub fn create_from_builder(builder: &gtk4::Builder) -> Self {
let notebook_main: gtk::Notebook = builder.object("notebook_main").unwrap(); 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_duplicate_finder: gtk4::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_folder_finder: gtk4::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_empty_files_finder: gtk4::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_temporary_files_finder: gtk4::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_big_files_finder: gtk4::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_images_finder: gtk4::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_similar_videos_finder: gtk4::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_same_music_finder: gtk4::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_invalid_symlinks: gtk4::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_broken_files: gtk4::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_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"); tree_view_duplicate_finder.set_widget_name("PIERD");
let tree_view_empty_folder_finder: gtk::TreeView = TreeView::new(); let tree_view_empty_folder_finder: gtk4::TreeView = TreeView::new();
let tree_view_empty_files_finder: gtk::TreeView = TreeView::new(); let tree_view_empty_files_finder: gtk4::TreeView = TreeView::new();
let tree_view_temporary_files_finder: gtk::TreeView = TreeView::new(); let tree_view_temporary_files_finder: gtk4::TreeView = TreeView::new();
let tree_view_big_files_finder: gtk::TreeView = TreeView::new(); let tree_view_big_files_finder: gtk4::TreeView = TreeView::new();
let tree_view_similar_images_finder: gtk::TreeView = TreeView::new(); let tree_view_similar_images_finder: gtk4::TreeView = TreeView::new();
let tree_view_similar_videos_finder: gtk::TreeView = TreeView::new(); let tree_view_similar_videos_finder: gtk4::TreeView = TreeView::new();
let tree_view_same_music_finder: gtk::TreeView = TreeView::new(); let tree_view_same_music_finder: gtk4::TreeView = TreeView::new();
let tree_view_invalid_symlinks: gtk::TreeView = TreeView::new(); let tree_view_invalid_symlinks: gtk4::TreeView = TreeView::new();
let tree_view_broken_files: gtk::TreeView = TreeView::new(); let tree_view_broken_files: gtk4::TreeView = TreeView::new();
let tree_view_bad_extensions: gtk::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_duplicate_finder: gtk4::EventControllerKey = EventControllerKey::new();
let evk_tree_view_empty_folder_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_empty_folder_finder); tree_view_duplicate_finder.add_controller(&evk_tree_view_duplicate_finder);
let evk_tree_view_empty_files_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_empty_files_finder); let evk_tree_view_empty_folder_finder: gtk4::EventControllerKey = EventControllerKey::new();
let evk_tree_view_temporary_files_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_temporary_files_finder); tree_view_empty_folder_finder.add_controller(&evk_tree_view_empty_folder_finder);
let evk_tree_view_big_files_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_big_files_finder); let evk_tree_view_empty_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
let evk_tree_view_similar_images_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_similar_images_finder); tree_view_empty_files_finder.add_controller(&evk_tree_view_empty_files_finder);
let evk_tree_view_similar_videos_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_similar_videos_finder); let evk_tree_view_temporary_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
let evk_tree_view_same_music_finder: gtk::EventControllerKey = EventControllerKey::new(&tree_view_same_music_finder); tree_view_temporary_files_finder.add_controller(&evk_tree_view_temporary_files_finder);
let evk_tree_view_invalid_symlinks: gtk::EventControllerKey = EventControllerKey::new(&tree_view_invalid_symlinks); let evk_tree_view_big_files_finder: gtk4::EventControllerKey = EventControllerKey::new();
let evk_tree_view_broken_files: gtk::EventControllerKey = EventControllerKey::new(&tree_view_broken_files); tree_view_big_files_finder.add_controller(&evk_tree_view_big_files_finder);
let evk_tree_view_bad_extensions: gtk::EventControllerKey = EventControllerKey::new(&tree_view_bad_extensions); 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 gc_tree_view_duplicate_finder: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_duplicate_finder: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_duplicate_finder.add_controller(&gc_tree_view_duplicate_finder);
// tree_view_duplicate_finder.add_controller(&evk_tree_view_duplicate_finder); let gc_tree_view_empty_folder_finder: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_empty_folder_finder: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_empty_folder_finder.add_controller(&gc_tree_view_empty_folder_finder);
// tree_view_empty_folder_finder.add_controller(&evk_tree_view_empty_folder_finder); let gc_tree_view_empty_files_finder: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_empty_files_finder: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_empty_files_finder.add_controller(&gc_tree_view_empty_files_finder);
// tree_view_empty_files_finder.add_controller(&evk_tree_view_empty_files_finder); let gc_tree_view_temporary_files_finder: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_temporary_files_finder: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_temporary_files_finder.add_controller(&gc_tree_view_temporary_files_finder);
// tree_view_temporary_files_finder.add_controller(&evk_tree_view_temporary_files_finder); let gc_tree_view_big_files_finder: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_big_files_finder: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_big_files_finder.add_controller(&gc_tree_view_big_files_finder);
// tree_view_big_files_finder.add_controller(&evk_tree_view_big_files_finder); let gc_tree_view_similar_images_finder: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_similar_images_finder: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_similar_images_finder.add_controller(&gc_tree_view_similar_images_finder);
// tree_view_similar_images_finder.add_controller(&evk_tree_view_similar_images_finder); let gc_tree_view_similar_videos_finder: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_similar_videos_finder: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_similar_videos_finder.add_controller(&gc_tree_view_similar_videos_finder);
// tree_view_similar_videos_finder.add_controller(&evk_tree_view_similar_videos_finder); let gc_tree_view_same_music_finder: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_same_music_finder: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_same_music_finder.add_controller(&gc_tree_view_same_music_finder);
// tree_view_same_music_finder.add_controller(&evk_tree_view_same_music_finder); let gc_tree_view_invalid_symlinks: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_invalid_symlinks: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_invalid_symlinks.add_controller(&gc_tree_view_invalid_symlinks);
// tree_view_invalid_symlinks.add_controller(&evk_tree_view_invalid_symlinks); let gc_tree_view_broken_files: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_broken_files: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_broken_files.add_controller(&gc_tree_view_broken_files);
// tree_view_broken_files.add_controller(&evk_tree_view_broken_files); let gc_tree_view_bad_extensions: gtk4::GestureClick = GestureClick::new();
// let evk_tree_view_bad_extensions: gtk4::EventControllerKey = EventControllerKey::new(); tree_view_bad_extensions.add_controller(&gc_tree_view_bad_extensions);
// tree_view_bad_extensions.add_controller(&evk_tree_view_bad_extensions);
// let gc_tree_view_duplicate_finder: gtk4::GestureClick = GestureClick::new(); let combo_box_duplicate_check_method: gtk4::ComboBoxText = builder.object("combo_box_duplicate_check_method").unwrap();
// tree_view_duplicate_finder.add_controller(&gc_tree_view_duplicate_finder); let combo_box_duplicate_hash_type: gtk4::ComboBoxText = builder.object("combo_box_duplicate_hash_type").unwrap();
// 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: gtk::ComboBoxText = builder.object("combo_box_duplicate_check_method").unwrap(); let entry_big_files_number: gtk4::Entry = builder.object("entry_big_files_number").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();
//// Check Buttons //// Check Buttons
let check_button_duplicate_case_sensitive_name: gtk::CheckButton = builder.object("check_button_duplicate_case_sensitive_name").unwrap(); let check_button_duplicate_case_sensitive_name: gtk4::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_title: gtk4::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_artist: gtk4::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_year: gtk4::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_bitrate: gtk4::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_genre: gtk4::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_length: gtk4::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_music_approximate_comparison: gtk4::CheckButton = builder.object("check_button_music_approximate_comparison").unwrap();
//// Radio Buttons //// Radio Buttons
let scale_similarity_similar_images: gtk::Scale = builder.object("scale_similarity_similar_images").unwrap(); let scale_similarity_similar_images: gtk4::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_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_resize_algorithm: gtk4::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_algorithm: gtk4::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_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_image_ignore_same_size: gtk4::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_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_check_method: gtk4::Label = builder.object("label_duplicate_check_method").unwrap();
let label_duplicate_hash_type: gtk::Label = builder.object("label_duplicate_hash_type").unwrap(); let label_duplicate_hash_type: gtk4::Label = builder.object("label_duplicate_hash_type").unwrap();
let label_big_shown_files: gtk::Label = builder.object("label_big_shown_files").unwrap(); let label_big_shown_files: gtk4::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_resize_algorithm: gtk4::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_type: gtk4::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_hash_size: gtk4::Label = builder.object("label_image_hash_size").unwrap();
let label_image_similarity: gtk::Label = builder.object("label_image_similarity").unwrap(); let label_image_similarity: gtk4::Label = builder.object("label_image_similarity").unwrap();
let label_image_similarity_max: gtk::Label = builder.object("label_image_similarity_max").unwrap(); let label_image_similarity_max: gtk4::Label = builder.object("label_image_similarity_max").unwrap();
let label_video_similarity: gtk::Label = builder.object("label_video_similarity").unwrap(); let label_video_similarity: gtk4::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_min: gtk4::Label = builder.object("label_video_similarity_min").unwrap();
let label_video_similarity_max: gtk::Label = builder.object("label_video_similarity_max").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_similar_images: gtk4::Image = builder.object("image_preview_similar_images").unwrap();
let image_preview_duplicates: gtk::Image = builder.object("image_preview_duplicates").unwrap(); let image_preview_duplicates: gtk4::Image = builder.object("image_preview_duplicates").unwrap();
Self { Self {
notebook_main, notebook_main,
@ -318,6 +305,17 @@ impl GuiMainNotebook {
check_button_image_fast_compare, check_button_image_fast_compare,
check_button_duplicate_case_sensitive_name, check_button_duplicate_case_sensitive_name,
evk_tree_view_bad_extensions, 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) { pub fn update_language(&self) {
self.check_button_duplicate_case_sensitive_name.set_label(&flg!("duplicate_case_sensitive_name")); self.check_button_duplicate_case_sensitive_name.set_label(Some(&flg!("duplicate_case_sensitive_name")));
self.check_button_music_title.set_label(&flg!("music_title_checkbox")); self.check_button_music_title.set_label(Some(&flg!("music_title_checkbox")));
self.check_button_music_artist.set_label(&flg!("music_artist_checkbox")); self.check_button_music_artist.set_label(Some(&flg!("music_artist_checkbox")));
self.check_button_music_year.set_label(&flg!("music_year_checkbox")); self.check_button_music_year.set_label(Some(&flg!("music_year_checkbox")));
self.check_button_music_bitrate.set_label(&flg!("music_bitrate_checkbox")); self.check_button_music_bitrate.set_label(Some(&flg!("music_bitrate_checkbox")));
self.check_button_music_genre.set_label(&flg!("music_genre_checkbox")); self.check_button_music_genre.set_label(Some(&flg!("music_genre_checkbox")));
self.check_button_music_length.set_label(&flg!("music_length_checkbox")); self.check_button_music_length.set_label(Some(&flg!("music_length_checkbox")));
self.check_button_music_approximate_comparison.set_label(&flg!("music_comparison_checkbox")); self.check_button_music_approximate_comparison.set_label(Some(&flg!("music_comparison_checkbox")));
self.check_button_music_approximate_comparison self.check_button_music_approximate_comparison
.set_tooltip_text(Some(&flg!("music_comparison_checkbox_tooltip"))); .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"))); .set_tooltip_text(Some(&flg!("check_button_general_same_size_tooltip")));
self.check_button_video_ignore_same_size self.check_button_video_ignore_same_size
.set_tooltip_text(Some(&flg!("check_button_general_same_size_tooltip"))); .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_image_ignore_same_size.set_label(Some(&flg!("check_button_general_same_size")));
self.check_button_video_ignore_same_size.set_label(&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 self.check_button_image_fast_compare
.set_tooltip_text(Some(&flg!("main_notebook_image_fast_compare_tooltip"))); .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<gtk4::Widget> = get_all_children(&self.notebook_main);
let vec_children: Vec<gtk4::Widget> = get_all_children(&vec_children[1]);
// let vec_children: Vec<gtk::Widget> = get_all_children(&self.notebook_main);
// let vec_children: Vec<gtk::Widget> = get_all_children(&vec_children[1]);
// Change name of main notebook tabs // Change name of main notebook tabs
for (main_enum, fl_thing) in [ for (main_enum, fl_thing) in [
@ -435,7 +431,7 @@ impl GuiMainNotebook {
self.notebook_main self.notebook_main
.tab_label(&vec_children[main_enum]) .tab_label(&vec_children[main_enum])
.unwrap() .unwrap()
.downcast::<gtk::Label>() .downcast::<gtk4::Label>()
.unwrap() .unwrap()
.set_text(&fl_thing); .set_text(&fl_thing);
} }

View file

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

View file

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

View file

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

View file

@ -1,78 +1,88 @@
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{Bin, EventControllerKey, TreeView}; 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::notebook_enums::NotebookUpperEnum;
use crate::{flg, CZK_ICON_ADD, CZK_ICON_DELETE, CZK_ICON_MANUAL_ADD}; use crate::{flg, CZK_ICON_ADD, CZK_ICON_DELETE, CZK_ICON_MANUAL_ADD};
#[derive(Clone)] #[derive(Clone)]
pub struct GuiUpperNotebook { pub struct GuiUpperNotebook {
pub notebook_upper: gtk::Notebook, pub notebook_upper: gtk4::Notebook,
pub scrolled_window_included_directories: gtk::ScrolledWindow, pub scrolled_window_included_directories: gtk4::ScrolledWindow,
pub scrolled_window_excluded_directories: gtk::ScrolledWindow, pub scrolled_window_excluded_directories: gtk4::ScrolledWindow,
pub tree_view_included_directories: gtk::TreeView, pub tree_view_included_directories: gtk4::TreeView,
pub tree_view_excluded_directories: gtk::TreeView, pub tree_view_excluded_directories: gtk4::TreeView,
pub evk_tree_view_included_directories: gtk::EventControllerKey, pub evk_tree_view_included_directories: gtk4::EventControllerKey,
pub evk_tree_view_excluded_directories: gtk::EventControllerKey, pub evk_tree_view_excluded_directories: gtk4::EventControllerKey,
pub entry_excluded_items: gtk::Entry, pub gc_tree_view_included_directories: gtk4::GestureClick,
pub entry_allowed_extensions: gtk::Entry, 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 check_button_recursive: gtk4::CheckButton,
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 label_excluded_items: gtk::Label, pub buttons_manual_add_included_directory: gtk4::Button,
pub label_allowed_extensions: gtk::Label, 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 label_excluded_items: gtk4::Label,
pub entry_general_maximal_size: gtk::Entry, pub label_allowed_extensions: gtk4::Label,
pub label_general_size_bytes: gtk::Label,
pub label_general_min_size: gtk::Label, pub entry_general_minimal_size: gtk4::Entry,
pub label_general_max_size: gtk::Label, 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 { impl GuiUpperNotebook {
pub fn create_from_builder(builder: &gtk::Builder) -> Self { pub fn create_from_builder(builder: &gtk4::Builder) -> Self {
let notebook_upper: gtk::Notebook = builder.object("notebook_upper").unwrap(); 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_included_directories: gtk4::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_excluded_directories: gtk4::ScrolledWindow = builder.object("scrolled_window_excluded_directories").unwrap();
let tree_view_included_directories: gtk::TreeView = TreeView::new(); let tree_view_included_directories: gtk4::TreeView = TreeView::new();
let tree_view_excluded_directories: gtk::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_included_directories: gtk4::EventControllerKey = EventControllerKey::new();
let evk_tree_view_excluded_directories: gtk::EventControllerKey = EventControllerKey::new(&tree_view_excluded_directories); 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 gc_tree_view_included_directories: gtk4::GestureClick = GestureClick::new();
let entry_excluded_items: gtk::Entry = builder.object("entry_excluded_items").unwrap(); 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 check_button_recursive: gtk4::CheckButton = builder.object("check_button_recursive").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 label_excluded_items: gtk::Label = builder.object("label_excluded_items").unwrap(); let buttons_manual_add_included_directory: gtk4::Button = builder.object("buttons_manual_add_included_directory").unwrap();
let label_allowed_extensions: gtk::Label = builder.object("label_allowed_extensions").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 label_excluded_items: gtk4::Label = builder.object("label_excluded_items").unwrap();
let entry_general_maximal_size: gtk::Entry = builder.object("entry_general_maximal_size").unwrap(); let label_allowed_extensions: gtk4::Label = builder.object("label_allowed_extensions").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 entry_general_minimal_size: gtk4::Entry = builder.object("entry_general_minimal_size").unwrap();
let label_general_max_size: gtk::Label = builder.object("label_general_max_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_add_included_directory, CZK_ICON_ADD);
set_icon_of_button(&buttons_manual_add_included_directory, CZK_ICON_MANUAL_ADD); set_icon_of_button(&buttons_manual_add_included_directory, CZK_ICON_MANUAL_ADD);
@ -89,6 +99,8 @@ impl GuiUpperNotebook {
tree_view_excluded_directories, tree_view_excluded_directories,
evk_tree_view_included_directories, evk_tree_view_included_directories,
evk_tree_view_excluded_directories, evk_tree_view_excluded_directories,
gc_tree_view_included_directories,
gc_tree_view_excluded_directories,
entry_excluded_items, entry_excluded_items,
entry_allowed_extensions, entry_allowed_extensions,
check_button_recursive, check_button_recursive,
@ -108,23 +120,15 @@ impl GuiUpperNotebook {
} }
} }
pub fn update_language(&self) { 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"))); 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_widget(&self.buttons_manual_add_included_directory.clone()).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_widget(&self.buttons_add_included_directory.clone()).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_widget(&self.buttons_remove_included_directory.clone()).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_widget(&self.buttons_manual_add_excluded_directory.clone()).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_widget(&self.buttons_add_excluded_directory.clone()).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")); get_custom_label_from_widget(&self.buttons_remove_excluded_directory.clone()).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"));
self.buttons_manual_add_included_directory self.buttons_manual_add_included_directory
.set_tooltip_text(Some(&flg!("upper_manual_add_included_button_tooltip"))); .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_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"))); 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<gtk4::Widget> = get_all_children(&self.notebook_upper);
let vec_children: Vec<gtk4::Widget> = get_all_children(&vec_children[1]);
// let vec_children: Vec<gtk::Widget> = get_all_children(&self.notebook_upper);
// let vec_children: Vec<gtk::Widget> = get_all_children(&vec_children[1]);
// Change name of upper notebook tabs // Change name of upper notebook tabs
for (upper_enum, fl_thing) in [ for (upper_enum, fl_thing) in [
@ -167,7 +169,7 @@ impl GuiUpperNotebook {
self.notebook_upper self.notebook_upper
.tab_label(&vec_children[upper_enum]) .tab_label(&vec_children[upper_enum])
.unwrap() .unwrap()
.downcast::<gtk::Label>() .downcast::<gtk4::Label>()
.unwrap() .unwrap()
.set_text(&fl_thing); .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::cmp::Ordering;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use czkawka_core::bad_extensions::BadExtensions; use czkawka_core::bad_extensions::BadExtensions;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{Bin, ListStore, TextView, TreeView, Widget}; use gtk4::{ListStore, TextView, TreeView, Widget};
use crate::flg; use crate::flg;
use czkawka_core::big_file::BigFile; 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_HOME: u32 = 115;
// pub const KEY_END: u32 = 110; // pub const KEY_END: u32 = 110;
pub const CHECK_GTK_EVENTS_INTERVAL: usize = 100;
#[derive(Eq, PartialEq)] #[derive(Eq, PartialEq)]
pub enum PopoverTypes { pub enum PopoverTypes {
All, All,
@ -70,7 +68,7 @@ pub struct NotebookObject {
pub column_path: i32, pub column_path: i32,
pub column_name: i32, pub column_name: i32,
pub column_selection: i32, pub column_selection: i32,
pub column_color: Option<i32>, pub column_header: Option<i32>,
pub column_dimensions: Option<i32>, pub column_dimensions: Option<i32>,
pub column_size: Option<i32>, pub column_size: Option<i32>,
pub column_size_as_bytes: 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_path: ColumnsDuplicates::Path as i32,
column_name: ColumnsDuplicates::Name as i32, column_name: ColumnsDuplicates::Name as i32,
column_selection: ColumnsDuplicates::SelectionButton 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_dimensions: None,
column_size: None, // Do not add, useless in hash and size mode 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 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_path: ColumnsEmptyFolders::Path as i32,
column_name: ColumnsEmptyFolders::Name as i32, column_name: ColumnsEmptyFolders::Name as i32,
column_selection: ColumnsEmptyFolders::SelectionButton as i32, column_selection: ColumnsEmptyFolders::SelectionButton as i32,
column_color: None, column_header: None,
column_dimensions: None, column_dimensions: None,
column_size: None, column_size: None,
column_size_as_bytes: 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_path: ColumnsBigFiles::Path as i32,
column_name: ColumnsBigFiles::Name as i32, column_name: ColumnsBigFiles::Name as i32,
column_selection: ColumnsBigFiles::SelectionButton as i32, column_selection: ColumnsBigFiles::SelectionButton as i32,
column_color: None, column_header: None,
column_dimensions: None, column_dimensions: None,
column_size: None, column_size: None,
column_size_as_bytes: 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_path: ColumnsEmptyFiles::Path as i32,
column_name: ColumnsEmptyFiles::Name as i32, column_name: ColumnsEmptyFiles::Name as i32,
column_selection: ColumnsEmptyFiles::SelectionButton as i32, column_selection: ColumnsEmptyFiles::SelectionButton as i32,
column_color: None, column_header: None,
column_dimensions: None, column_dimensions: None,
column_size: None, column_size: None,
column_size_as_bytes: 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_path: ColumnsTemporaryFiles::Path as i32,
column_name: ColumnsTemporaryFiles::Name as i32, column_name: ColumnsTemporaryFiles::Name as i32,
column_selection: ColumnsTemporaryFiles::SelectionButton as i32, column_selection: ColumnsTemporaryFiles::SelectionButton as i32,
column_color: None, column_header: None,
column_dimensions: None, column_dimensions: None,
column_size: None, column_size: None,
column_size_as_bytes: 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_path: ColumnsSimilarImages::Path as i32,
column_name: ColumnsSimilarImages::Name as i32, column_name: ColumnsSimilarImages::Name as i32,
column_selection: ColumnsSimilarImages::SelectionButton 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_dimensions: Some(ColumnsSimilarImages::Dimensions as i32),
column_size: Some(ColumnsSimilarImages::Size as i32), column_size: Some(ColumnsSimilarImages::Size as i32),
column_size_as_bytes: Some(ColumnsSimilarImages::SizeAsBytes 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_path: ColumnsSimilarVideos::Path as i32,
column_name: ColumnsSimilarVideos::Name as i32, column_name: ColumnsSimilarVideos::Name as i32,
column_selection: ColumnsSimilarVideos::SelectionButton 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_dimensions: None,
column_size: Some(ColumnsSimilarVideos::Size as i32), column_size: Some(ColumnsSimilarVideos::Size as i32),
column_size_as_bytes: Some(ColumnsSimilarVideos::SizeAsBytes 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_path: ColumnsSameMusic::Path as i32,
column_name: ColumnsSameMusic::Name as i32, column_name: ColumnsSameMusic::Name as i32,
column_selection: ColumnsSameMusic::SelectionButton 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_dimensions: None,
column_size: None, column_size: None,
column_size_as_bytes: Some(ColumnsSameMusic::SizeAsBytes as i32), 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_path: ColumnsInvalidSymlinks::Path as i32,
column_name: ColumnsInvalidSymlinks::Name as i32, column_name: ColumnsInvalidSymlinks::Name as i32,
column_selection: ColumnsInvalidSymlinks::SelectionButton as i32, column_selection: ColumnsInvalidSymlinks::SelectionButton as i32,
column_color: None, column_header: None,
column_dimensions: None, column_dimensions: None,
column_size: None, column_size: None,
column_size_as_bytes: 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_path: ColumnsBrokenFiles::Path as i32,
column_name: ColumnsBrokenFiles::Name as i32, column_name: ColumnsBrokenFiles::Name as i32,
column_selection: ColumnsBrokenFiles::SelectionButton as i32, column_selection: ColumnsBrokenFiles::SelectionButton as i32,
column_color: None, column_header: None,
column_dimensions: None, column_dimensions: None,
column_size: None, column_size: None,
column_size_as_bytes: 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_path: ColumnsBadExtensions::Path as i32,
column_name: ColumnsBadExtensions::Name as i32, column_name: ColumnsBadExtensions::Name as i32,
column_selection: ColumnsBadExtensions::SelectionButton as i32, column_selection: ColumnsBadExtensions::SelectionButton as i32,
column_color: None, column_header: None,
column_dimensions: None, column_dimensions: None,
column_size: None, column_size: None,
column_size_as_bytes: None, column_size_as_bytes: None,
@ -247,6 +245,7 @@ pub enum ColumnsDuplicates {
Modification, Modification,
ModificationAsSecs, ModificationAsSecs,
Color, Color,
IsHeader,
TextColor, TextColor,
} }
@ -307,6 +306,7 @@ pub enum ColumnsSimilarImages {
Modification, Modification,
ModificationAsSecs, ModificationAsSecs,
Color, Color,
IsHeader,
TextColor, TextColor,
} }
@ -320,6 +320,7 @@ pub enum ColumnsSimilarVideos {
Modification, Modification,
ModificationAsSecs, ModificationAsSecs,
Color, Color,
IsHeader,
TextColor, TextColor,
} }
@ -340,6 +341,7 @@ pub enum ColumnsSameMusic {
Modification, Modification,
ModificationAsSecs, ModificationAsSecs,
Color, Color,
IsHeader,
TextColor, TextColor,
} }
@ -372,14 +374,12 @@ pub enum ColumnsBadExtensions {
ModificationAsSecs, ModificationAsSecs,
} }
pub const MAIN_ROW_COLOR: &str = "#222222";
pub const HEADER_ROW_COLOR: &str = "#111111";
pub const TEXT_COLOR: &str = "#ffffff"; 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> { pub fn get_string_from_list_store(tree_view: &gtk4::TreeView, column_full_path: i32, column_selection: Option<i32>) -> Vec<String> {
let list_store: gtk::ListStore = get_list_store(tree_view); let list_store: gtk4::ListStore = get_list_store(tree_view);
let mut string_vector: Vec<String> = Vec::new(); 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 { match column_selection {
Some(column_selection) => loop { Some(column_selection) => loop {
if list_store.value(&tree_iter, column_selection).get::<bool>().unwrap() { if list_store.get::<bool>(&tree_iter, column_selection) {
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) { if !list_store.iter_next(&tree_iter) {
return string_vector; return string_vector;
} }
}, },
None => loop { 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) { if !list_store.iter_next(&tree_iter) {
return string_vector; 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(""); let mut messages: String = String::from("");
if !text_messages.messages.is_empty() { if !text_messages.messages.is_empty() {
messages += format!("############### {}({}) ###############\n", flg!("text_view_messages"), text_messages.messages.len()).as_str(); 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"; // 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) { 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) { pub fn add_text_to_text_view(text_view: &TextView, string_to_append: &str) {
let buffer = text_view.buffer().unwrap(); let buffer = text_view.buffer();
let current_text = match buffer.text(&buffer.start_iter(), &buffer.end_iter(), true) { let current_text = buffer.text(&buffer.start_iter(), &buffer.end_iter(), true).to_string();
Some(t) => t.to_string(),
None => "".to_string(),
};
if current_text.is_empty() { if current_text.is_empty() {
buffer.set_text(string_to_append); buffer.set_text(string_to_append);
} else { } 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() { for (index, button) in buttons_array.iter().enumerate() {
if *hashmap.get_mut(&button_names[index]).unwrap() { if *hashmap.get_mut(&button_names[index]).unwrap() {
button.show(); 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 { pub fn get_list_store(tree_view: &gtk4::TreeView) -> ListStore {
tree_view.model().unwrap().downcast::<gtk::ListStore>().unwrap() tree_view.model().unwrap().downcast::<gtk4::ListStore>().unwrap()
} }
pub fn get_dialog_box_child(dialog: &gtk::Dialog) -> gtk::Box { pub fn get_dialog_box_child(dialog: &gtk4::Dialog) -> gtk4::Box {
dialog.child().unwrap().downcast::<gtk::Box>().unwrap() dialog.child().unwrap().downcast::<gtk4::Box>().unwrap()
} }
pub fn change_dimension_to_krotka(dimensions: String) -> (u64, u64) { 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) (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() { match (*tree_view).widget_name().to_string().as_str() {
"tree_view_duplicate_finder" => NotebookMainEnum::Duplicate, "tree_view_duplicate_finder" => NotebookMainEnum::Duplicate,
"tree_view_empty_folder_finder" => NotebookMainEnum::EmptyDirectories, "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() { match (*tree_view).widget_name().to_string().as_str() {
"tree_view_upper_included_directories" => NotebookUpperEnum::IncludedDirectories, "tree_view_upper_included_directories" => NotebookUpperEnum::IncludedDirectories,
"tree_view_upper_excluded_directories" => NotebookUpperEnum::ExcludedDirectories, "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); let nb_enum = get_notebook_enum_from_tree_view(tree_view);
&NOTEBOOKS_INFOS[nb_enum as usize] &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 // 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 // Remove only child from header
if let Some(first_iter) = model.iter_first() { 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; 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 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; let mut next_next_iter;
// Empty means default check type // 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 { '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 panic!("First deleted element, should be a header"); // First element should be header
}; };
next_iter = current_iter; next_iter = current_iter;
if !model.iter_next(&next_iter) { if !model.iter_next(&next_iter) {
// There is only single header left (H1 -> END) -> (NOTHING) // 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; 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) // 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; current_iter = next_iter;
continue 'main; continue 'main;
} }
@ -591,15 +588,15 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
next_next_iter = next_iter; next_next_iter = next_iter;
if !model.iter_next(&next_next_iter) { if !model.iter_next(&next_next_iter) {
// There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING) // 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(&current_iter));
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); vec_tree_path_to_delete.push(model.path(&next_iter));
break 'main; 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) // 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(&current_iter));
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap()); vec_tree_path_to_delete.push(model.path(&next_iter));
current_iter = next_next_iter; current_iter = next_next_iter;
continue 'main; continue 'main;
} }
@ -610,7 +607,7 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
break 'main; break 'main;
} }
// Move to next header // 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; current_iter = next_next_iter;
continue 'main; 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 // Non empty means that header points at reference folder
else { else {
'reference: loop { '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 panic!("First deleted element, should be a header"); // First element should be header
}; };
next_iter = current_iter; next_iter = current_iter;
if !model.iter_next(&next_iter) { if !model.iter_next(&next_iter) {
// There is only single header left (H1 -> END) -> (NOTHING) // 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; 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) // 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; current_iter = next_iter;
continue 'reference; continue 'reference;
} }
@ -647,7 +644,7 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
break 'reference; 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) // One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
current_iter = next_next_iter; current_iter = next_next_iter;
continue 'reference; continue 'reference;
@ -659,7 +656,7 @@ pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32, column_p
break 'reference; break 'reference;
} }
// Move to next header // 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; current_iter = next_next_iter;
continue 'reference; 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_items: u64 = 0;
let mut number_of_selected_groups: 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 // First iter
if let Some(iter) = model.iter_first() { if let Some(iter) = model.iter_first() {
if let Some(column_color) = column_color { if let Some(column_header) = column_header {
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 { loop {
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
break; 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; is_item_currently_selected_in_group = false;
} else { } else {
if model.value(&iter, column_selection).get::<bool>().unwrap() { if model.get::<bool>(&iter, column_selection) {
number_of_selected_items += 1; number_of_selected_items += 1;
if !is_item_currently_selected_in_group { 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 { } else {
if model.get::<bool>(&iter, column_selection) {
number_of_selected_items += 1;
}
loop { loop {
if !model.iter_next(&iter) { if !model.iter_next(&iter) {
break; break;
} }
if model.value(&iter, column_selection).get::<bool>().unwrap() { if model.get::<bool>(&iter, column_selection) {
number_of_selected_items += 1; 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 /// 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 mut number_of_selected_groups = 0;
let model = get_list_store(tree_view); let model = get_list_store(tree_view);
if let Some(iter) = model.iter_first() { 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; number_of_selected_groups += 1;
loop { loop {
@ -740,7 +740,7 @@ pub fn count_number_of_groups(tree_view: &TreeView, column_color: i32) -> u32 {
break; 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; 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 { pub fn get_custom_label_from_widget<P: IsA<gtk4::Widget>>(item: &P) -> gtk4::Label {
let internal_box = button.child().unwrap().downcast::<gtk::Box>().unwrap(); let mut widgets_to_check = vec![item.clone().upcast::<gtk4::Widget>()];
for child in internal_box.children() {
if let Ok(t) = child.downcast::<gtk::Label>() { while let Some(widget) = widgets_to_check.pop() {
return t; 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"); panic!("Button doesn't have proper custom label child");
} }
pub fn get_custom_image_from_button_with_image(button: &gtk::Bin) -> gtk::Image { pub fn get_custom_image_from_widget<P: IsA<gtk4::Widget>>(item: &P) -> gtk4::Image {
let internal_box = match button.child().unwrap().downcast::<gtk::Box>() { let mut widgets_to_check = vec![item.clone().upcast::<gtk4::Widget>()];
Ok(t) => t,
Err(wid) => { while let Some(widget) = widgets_to_check.pop() {
return wid.downcast::<gtk::Image>().unwrap(); if let Ok(image) = widget.clone().downcast::<gtk4::Image>() {
} return image;
}; } else {
for child in internal_box.children() { widgets_to_check.extend(get_all_children(&widget));
if let Ok(t) = child.downcast::<gtk::Image>() {
return t;
} }
} }
panic!("Button doesn't have proper custom label child"); panic!("Button doesn't have proper custom label child");
} }
pub fn handle_gtk_pending_event() -> bool { #[allow(dead_code)]
let have_pending = gtk::events_pending(); pub fn debug_print_widget<P: IsA<gtk4::Widget>>(item: &P) {
if have_pending { let mut widgets_to_check = vec![(0, 0, item.clone().upcast::<gtk4::Widget>())];
gtk::main_iteration();
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 { pub fn get_all_children<P: IsA<gtk4::Widget>>(wid: &P) -> Vec<gtk4::Widget> {
if counter > 0 && (counter % CHECK_GTK_EVENTS_INTERVAL) == 0 { let mut vector = vec![];
return handle_gtk_pending_event(); 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 SIZE_OF_ICON: i32 = 18;
const TYPE_OF_INTERPOLATION: InterpType = InterpType::Tiles; const TYPE_OF_INTERPOLATION: InterpType = InterpType::Tiles;
pub fn set_icon_of_button(button: &gtk::Button, data: &'static [u8]) { pub fn set_icon_of_button<P: IsA<gtk4::Widget>>(button: &P, data: &'static [u8]) {
let image = get_custom_image_from_button_with_image(&button.clone().upcast::<Bin>()); let image = get_custom_image_from_widget(&button.clone());
let pixbuf = Pixbuf::from_read(std::io::BufReader::new(data)).unwrap(); 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(); 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));
}
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));
} }

View file

@ -3,10 +3,10 @@ use std::ops::Deref;
use std::path::Path; use std::path::Path;
use std::rc::Rc; use std::rc::Rc;
use gdk::gdk_pixbuf::Pixbuf; use gdk4::gdk_pixbuf::Pixbuf;
use gtk::gdk_pixbuf::InterpType; use gtk4::gdk_pixbuf::InterpType;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{CheckButton, Image, SelectionMode, TextView, TreeView}; use gtk4::{CheckButton, Image, SelectionMode, TextView, TreeView};
use crate::flg; use crate::flg;
use czkawka_core::common::{IMAGE_RS_EXTENSIONS, RAW_IMAGE_EXTENSIONS}; 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(); let image_preview = gui_data.main_notebook.image_preview_duplicates.clone();
image_preview.hide(); 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, // ActivatableSelectButton
glib::types::Type::BOOL, // SelectionButton glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Size 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::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs glib::types::Type::U64, // ModificationAsSecs
glib::types::Type::STRING, // Color glib::types::Type::STRING, // Color
glib::types::Type::BOOL, // IsHeader
glib::types::Type::STRING, // TextColor 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_duplicates(&tree_view);
tree_view.set_widget_name("tree_view_duplicate_finder"); tree_view.set_widget_name("tree_view_duplicate_finder");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Empty Folders // Empty Folders
{ {
@ -159,7 +160,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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"); tree_view.set_widget_name("tree_view_empty_folder_finder");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Empty Files // Empty Files
{ {
@ -182,7 +183,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_empty_files(&tree_view);
tree_view.set_widget_name("tree_view_empty_files_finder"); tree_view.set_widget_name("tree_view_empty_files_finder");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Temporary Files // Temporary Files
{ {
@ -205,7 +206,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_temporary_files(&tree_view);
tree_view.set_widget_name("tree_view_temporary_files_finder"); tree_view.set_widget_name("tree_view_temporary_files_finder");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Big Files // Big Files
{ {
@ -230,7 +231,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::U64, // SizeAsBytes glib::types::Type::U64, // SizeAsBytes
glib::types::Type::U64, // ModificationAsSecs 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_big_files(&tree_view);
tree_view.set_widget_name("tree_view_big_files_finder"); tree_view.set_widget_name("tree_view_big_files_finder");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Similar Images // 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(); let image_preview = gui_data.main_notebook.image_preview_similar_images.clone();
image_preview.hide(); 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, // ActivatableSelectButton
glib::types::Type::BOOL, // SelectionButton glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Similarity 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::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs glib::types::Type::U64, // ModificationAsSecs
glib::types::Type::STRING, // Color glib::types::Type::STRING, // Color
glib::types::Type::BOOL, // IsHeader
glib::types::Type::STRING, // TextColor 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_similar_images(&tree_view);
tree_view.set_widget_name("tree_view_similar_images_finder"); tree_view.set_widget_name("tree_view_similar_images_finder");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Similar Videos // Similar Videos
{ {
let scrolled_window = gui_data.main_notebook.scrolled_window_similar_videos_finder.clone(); 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 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, // ActivatableSelectButton
glib::types::Type::BOOL, // SelectionButton glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Size 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::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs glib::types::Type::U64, // ModificationAsSecs
glib::types::Type::STRING, // Color glib::types::Type::STRING, // Color
glib::types::Type::BOOL, // IsHeader
glib::types::Type::STRING, // TextColor 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_similar_videos(&tree_view);
tree_view.set_widget_name("tree_view_similar_videos_finder"); tree_view.set_widget_name("tree_view_similar_videos_finder");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Same Music // Same Music
{ {
let scrolled_window = gui_data.main_notebook.scrolled_window_same_music_finder.clone(); 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 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, // ActivatableSelectButton
glib::types::Type::BOOL, // SelectionButton glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Size 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::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs glib::types::Type::U64, // ModificationAsSecs
glib::types::Type::STRING, // Color glib::types::Type::STRING, // Color
glib::types::Type::BOOL, // IsHeader
glib::types::Type::STRING, // TextColor 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_same_music(&tree_view);
tree_view.set_widget_name("tree_view_same_music_finder"); tree_view.set_widget_name("tree_view_same_music_finder");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Invalid Symlinks // Invalid Symlinks
{ {
@ -354,7 +358,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_invalid_symlinks(&tree_view);
tree_view.set_widget_name("tree_view_invalid_symlinks"); tree_view.set_widget_name("tree_view_invalid_symlinks");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Broken Files // Broken Files
{ {
@ -378,7 +382,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_broken_files(&tree_view);
tree_view.set_widget_name("tree_view_broken_files"); tree_view.set_widget_name("tree_view_broken_files");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); scrolled_window.show();
} }
// Bad Extensions // Bad Extensions
{ {
@ -403,7 +407,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
glib::types::Type::STRING, // Modification glib::types::Type::STRING, // Modification
glib::types::Type::U64, // ModificationAsSecs 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_broken_files(&tree_view);
tree_view.set_widget_name("tree_view_bad_extensions"); tree_view.set_widget_name("tree_view_bad_extensions");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); 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 scrolled_window = gui_data.upper_notebook.scrolled_window_included_directories.clone();
let tree_view = gui_data.upper_notebook.tree_view_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 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] = [ let col_types: [glib::types::Type; 2] = [
glib::types::Type::STRING, // Path glib::types::Type::STRING, // Path
glib::types::Type::BOOL, // ReferenceButton 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_included_directories(&tree_view);
tree_view.set_widget_name("tree_view_upper_included_directories"); tree_view.set_widget_name("tree_view_upper_included_directories");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); 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_pressed(opening_enter_function_ported_upper_directories);
evk.connect_key_released(move |_event_controller_key, _key_value, key_code, _modifier_type| { evk.connect_key_released(move |_event_controller_key, _key_value, key_code, _modifier_type| {
if key_code == KEY_DELETE { 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 scrolled_window = gui_data.upper_notebook.scrolled_window_excluded_directories.clone();
let tree_view = gui_data.upper_notebook.tree_view_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 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 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.set_model(Some(&list_store));
tree_view.selection().set_mode(SelectionMode::Multiple); 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); create_tree_view_excluded_directories(&tree_view);
tree_view.set_widget_name("tree_view_upper_excluded_directories"); tree_view.set_widget_name("tree_view_upper_excluded_directories");
scrolled_window.add(&tree_view); scrolled_window.set_child(Some(&tree_view));
scrolled_window.show_all(); 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_pressed(opening_enter_function_ported_upper_directories);
evk.connect_key_released(move |_event_controller_key, _key_value, key_code, _modifier_type| { evk.connect_key_released(move |_event_controller_key, _key_value, key_code, _modifier_type| {
if key_code == KEY_DELETE { 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 window_progress = gui_data.progress_window.window_progress.clone();
let stop_sender = gui_data.stop_sender.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(); 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) { fn connect_event_mouse(gui_data: &GuiData) {
for tree_view in gui_data.main_notebook.get_main_tree_views() { // GTK 4
tree_view.connect_button_press_event(opening_double_click_function); for gc in [
tree_view.connect_button_release_event(opening_middle_mouse_function); &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 // 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 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 image_preview = gui_data.main_notebook.image_preview_duplicates.clone();
let preview_path = gui_data.preview_path.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 nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
let preview_path = preview_path.clone(); let preview_path = preview_path.clone();
show_preview( show_preview(
tree_view, &tree_view,
&text_view_errors, &text_view_errors,
&check_button_settings_show_preview, &check_button_settings_show_preview,
&image_preview, &image_preview,
@ -532,23 +555,24 @@ fn connect_event_mouse(gui_data: &GuiData) {
nb_object.column_path, nb_object.column_path,
nb_object.column_name, nb_object.column_name,
); );
gtk::Inhibit(false)
}); });
} }
// Similar Images // Similar Images
{ {
let text_view_errors = gui_data.text_view_errors.clone(); 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 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 preview_path = gui_data.preview_path.clone();
let image_preview = gui_data.main_notebook.image_preview_similar_images.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 nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
let preview_path = preview_path.clone(); let preview_path = preview_path.clone();
show_preview( show_preview(
tree_view, &tree_view,
&text_view_errors, &text_view_errors,
&check_button_settings_show_preview, &check_button_settings_show_preview,
&image_preview, &image_preview,
@ -556,60 +580,8 @@ fn connect_event_mouse(gui_data: &GuiData) {
nb_object.column_path, nb_object.column_path,
nb_object.column_name, 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) { fn connect_event_buttons(gui_data: &GuiData) {
for evk in [ for evk in [
@ -652,7 +624,7 @@ fn connect_event_buttons(gui_data: &GuiData) {
let preview_path = preview_path.clone(); let preview_path = preview_path.clone();
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize]; let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
show_preview( show_preview(
&event_controller_key.widget().unwrap().downcast::<gtk::TreeView>().unwrap(), &event_controller_key.widget().downcast::<gtk4::TreeView>().unwrap(),
&text_view_errors, &text_view_errors,
&check_button_settings_show_preview, &check_button_settings_show_preview,
&image_preview, &image_preview,
@ -680,7 +652,7 @@ fn connect_event_buttons(gui_data: &GuiData) {
let preview_path = preview_path.clone(); let preview_path = preview_path.clone();
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize]; let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
show_preview( show_preview(
&event_controller_key.widget().unwrap().downcast::<gtk::TreeView>().unwrap(), &event_controller_key.widget().downcast::<gtk4::TreeView>().unwrap(),
&text_view_errors, &text_view_errors,
&check_button_settings_show_preview_similar_images, &check_button_settings_show_preview_similar_images,
&image_preview, &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 // 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)] #[allow(clippy::never_loop)]
'dir: loop { 'dir: loop {
let path = tree_model.value(&tree_model.iter(&tree_path).unwrap(), column_path).get::<String>().unwrap(); let path = tree_model.get::<String>(&tree_model.iter(&tree_path).unwrap(), column_path);
let name = tree_model.value(&tree_model.iter(&tree_path).unwrap(), column_name).get::<String>().unwrap(); 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 = get_full_name_from_path_name(&path, &name);
let file_name = file_name.as_str(); 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 => { None => {
add_text_to_text_view( add_text_to_text_view(
text_view_errors, text_view_errors,
@ -760,7 +732,7 @@ fn show_preview(
Some(pixbuf) => pixbuf, Some(pixbuf) => pixbuf,
}; };
image_preview.set_pixbuf(Some(&pixbuf)); image_preview.set_from_pixbuf(Some(&pixbuf));
{ {
let mut preview_path = preview_path.borrow_mut(); let mut preview_path = preview_path.borrow_mut();
*preview_path = file_name.to_string(); *preview_path = file_name.to_string();

View file

@ -5,9 +5,10 @@
#![allow(clippy::type_complexity)] #![allow(clippy::type_complexity)]
#![allow(clippy::needless_late_init)] #![allow(clippy::needless_late_init)]
use gtk::gio::ApplicationFlags; use gtk4::gio::ApplicationFlags;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::Application; use gtk4::Application;
use gtk4::Inhibit;
use std::env; use std::env;
use std::ffi::OsString; use std::ffi::OsString;
@ -59,7 +60,7 @@ mod taskbar_progress_win;
mod tests; mod tests;
fn main() { 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| { application.connect_command_line(move |app, cmdline| {
build_ui(app, cmdline.arguments()); build_ui(app, cmdline.arguments());
0 0
@ -186,7 +187,7 @@ fn build_ui(application: &Application, arguments: Vec<OsString>) {
let window_main = gui_data.window_main.clone(); let window_main = gui_data.window_main.clone();
let taskbar_state = gui_data.taskbar_state.clone(); let taskbar_state = gui_data.taskbar_state.clone();
let used_additional_arguments = arguments.len() > 1; 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 // Not save configuration when using non default arguments
if !used_additional_arguments { if !used_additional_arguments {
save_configuration(false, &gui_data.upper_notebook, &gui_data.main_notebook, &gui_data.settings, &gui_data.text_view_errors); 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 gdk4::{Key, ModifierType};
use gtk::prelude::*; use glib::signal::Inhibit;
use gtk4::prelude::*;
use gtk4::GestureClick;
use crate::help_functions::*; use crate::help_functions::*;
use crate::notebook_enums::NotebookUpperEnum; use crate::notebook_enums::NotebookUpperEnum;
// TODO add option to open files and folders from context menu activated by pressing ONCE with right mouse button // 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 { 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().unwrap().downcast::<gtk::TreeView>().unwrap(); 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_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();
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
println!("key_code {}", key_code); println!("key_code {}", key_code);
@ -48,101 +31,101 @@ pub fn opening_enter_function_ported_upper_directories(event_controller: &gtk::E
panic!() 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 { pub fn opening_middle_mouse_function(gesture_click: &GestureClick, _number_of_clicks: i32, _b: f64, _c: f64) {
let nt_object = get_notebook_object_from_tree_view(tree_view); println!("MIDDLE MOUSE BUTTON CLICKED");
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 { let tree_view = gesture_click.widget().downcast::<gtk4::TreeView>().unwrap();
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(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { let nt_object = get_notebook_object_from_tree_view(&tree_view);
let nt_object = get_notebook_object_from_tree_view(tree_view); if let Some(column_header) = nt_object.column_header {
if let Some(column_color) = nt_object.column_color { if gesture_click.current_button() == 2 {
if event.button() == 2 { reverse_selection(&tree_view, column_header, nt_object.column_selection);
reverse_selection(tree_view, column_color, nt_object.column_selection);
} }
} }
gtk::Inhibit(false)
} }
pub fn opening_double_click_function_directories(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit { pub fn opening_double_click_function_directories(gesture_click: &GestureClick, number_of_clicks: i32, _b: f64, _c: f64) {
if event.event_type() == gdk::EventType::DoubleButtonPress && (event.button() == 1 || event.button() == 3) { let tree_view = gesture_click.widget().downcast::<gtk4::TreeView>().unwrap();
match get_notebook_upper_enum_from_tree_view(tree_view) {
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 => { 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 => { 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!() panic!()
} }
} }
} }
gtk::Inhibit(false)
} }
// // GTK 4 pub fn opening_enter_function_ported(event_controller: &gtk4::EventControllerKey, _key: gdk4::Key, key_code: u32, _modifier_type: ModifierType) -> gtk4::Inhibit {
// 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().downcast::<gtk4::TreeView>().unwrap();
// let tree_view = event_controller.widget().unwrap().downcast::<gtk4::TreeView>().unwrap(); #[cfg(debug_assertions)]
// #[cfg(debug_assertions)] {
// { println!("key_code {}", key_code);
// println!("key_code {}", key_code); }
// }
// let nt_object = get_notebook_object_from_tree_view(&tree_view);
// let nt_object = get_notebook_object_from_tree_view(&tree_view); handle_tree_keypress(
// handle_tree_keypress(&tree_view, key_code, nt_object.column_name, nt_object.column_path, nt_object.column_selection); &tree_view,
// Inhibit(false) // True catches signal, and don't send it to function, e.g. up button is catched and don't move selection key_code,
// } nt_object.column_name,
// nt_object.column_path,
// pub fn opening_double_click_function(gesture_click: &GestureClick, number_of_clicks: i32, _b: f64, _c: f64) { nt_object.column_selection,
// let tree_view = gesture_click.widget().unwrap().downcast::<gtk4::TreeView>().unwrap(); nt_object.column_header,
// );
// let nt_object = get_notebook_object_from_tree_view(&tree_view); Inhibit(false) // True catches signal, and don't send it to function, e.g. up button is catched and don't move selection
// 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); pub fn opening_double_click_function(gesture_click: &GestureClick, number_of_clicks: i32, _b: f64, _c: f64) {
// } else if gesture_click.current_button() == 3 { let tree_view = gesture_click.widget().downcast::<gtk4::TreeView>().unwrap();
// common_open_function(&tree_view, nt_object.column_name, nt_object.column_path, OpenMode::OnlyPath);
// } 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 { enum OpenMode {
OnlyPath, OnlyPath,
PathAndName, 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 selection = tree_view.selection();
let (selected_rows, tree_model) = selection.selected_rows(); let (selected_rows, tree_model) = selection.selected_rows();
let model = get_list_store(tree_view); let model = get_list_store(tree_view);
for tree_path in selected_rows.iter().rev() { for tree_path in selected_rows.iter().rev() {
if let Some(column_color) = column_color { if let Some(column_header) = column_header {
if model.value(&model.iter(tree_path).unwrap(), column_color).get::<String>().unwrap() == HEADER_ROW_COLOR { if model.get::<bool>(&model.iter(tree_path).unwrap(), column_header) {
continue; 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()); 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 selection = tree_view.selection();
let (selected_rows, tree_model) = selection.selected_rows(); let (selected_rows, tree_model) = selection.selected_rows();
for tree_path in selected_rows.iter().rev() { 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 name = tree_model.get::<String>(&tree_model.iter(tree_path).unwrap(), column_name);
let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::<String>().unwrap(); let path = tree_model.get::<String>(&tree_model.iter(tree_path).unwrap(), column_path);
let end_path = match opening_mode { let end_path = match opening_mode {
OpenMode::OnlyPath => path, 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 (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 { if selected_rows.len() != 1 {
return; // Multiple selection is not supported because it is a lot of harder to do it properly 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 tree_path = selected_rows[0].clone();
let current_iter = model.iter(&tree_path).unwrap(); 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) 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 // 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()); // model.set_value(&current_iter, column_selection as u32, &(!current_value).to_value());
let to_upper_iter = current_iter; 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) { if !model.iter_previous(&to_upper_iter) {
break; 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; 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()); 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) { if !model.iter_next(&to_lower_iter) {
break; 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; 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()); 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 selection = tree_view.selection();
let (selected_rows, tree_model) = selection.selected_rows(); let (selected_rows, tree_model) = selection.selected_rows();
for tree_path in selected_rows.iter().rev() { 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); 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 { match key_code {
KEY_ENTER => { KEY_ENTER => {
common_open_function_upper_directories(tree_view, full_path_column); 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 { match key_code {
KEY_ENTER => { KEY_ENTER => {
common_open_function(tree_view, name_column, path_column, OpenMode::PathAndName); common_open_function(tree_view, name_column, path_column, OpenMode::PathAndName);
} }
KEY_SPACE => { 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 { pub fn select_function_duplicates(_tree_selection: &gtk4::TreeSelection, tree_model: &gtk4::TreeModel, tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model !tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::IsHeader as i32)
.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_same_music(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool { pub fn select_function_same_music(_tree_selection: &gtk4::TreeSelection, tree_model: &gtk4::TreeModel, tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model !tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), ColumnsSameMusic::IsHeader as i32)
.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_similar_images(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool { pub fn select_function_similar_images(_tree_selection: &gtk4::TreeSelection, tree_model: &gtk4::TreeModel, tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model !tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarImages::IsHeader as i32)
.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_videos(_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 {
let color = tree_model !tree_model.get::<bool>(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarVideos::IsHeader as i32)
.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarVideos::Color as i32) }
.get::<String>() pub fn select_function_always_true(_tree_selection: &gtk4::TreeSelection, _tree_model: &gtk4::TreeModel, _tree_path: &gtk4::TreePath, _is_path_currently_selected: bool) -> bool {
.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 {
true true
} }

View file

@ -7,8 +7,8 @@ use std::{env, fs};
use czkawka_core::common_dir_traversal::CheckingMethod; use czkawka_core::common_dir_traversal::CheckingMethod;
use directories_next::ProjectDirs; use directories_next::ProjectDirs;
use gtk::prelude::*; use gtk4::prelude::*;
use gtk::{ComboBoxText, ScrolledWindow, TextView}; use gtk4::{ComboBoxText, ScrolledWindow, TextView};
use crate::flg; use crate::flg;
use crate::gui_structs::gui_main_notebook::GuiMainNotebook; use crate::gui_structs::gui_main_notebook::GuiMainNotebook;
@ -64,11 +64,11 @@ const DEFAULT_EXCLUDED_DIRECTORIES: &[&str] = &["C:\\Windows"];
struct LoadSaveStruct { struct LoadSaveStruct {
loaded_items: HashMap<String, Vec<String>>, loaded_items: HashMap<String, Vec<String>>,
text_view: gtk::TextView, text_view: gtk4::TextView,
} }
impl LoadSaveStruct { impl LoadSaveStruct {
pub fn with_text_view(text_view: gtk::TextView) -> Self { pub fn with_text_view(text_view: gtk4::TextView) -> Self {
Self { Self {
loaded_items: Default::default(), loaded_items: Default::default(),
text_view, text_view,
@ -193,13 +193,13 @@ impl LoadSaveStruct {
self.loaded_items.insert(key, vec![value.to_string()]); 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 mut vec_string = vec![];
let list_store = get_list_store(tree_view); let list_store = get_list_store(tree_view);
if let Some(iter) = list_store.iter_first() { if let Some(iter) = list_store.iter_first() {
loop { loop {
// TODO maybe save also here reference directories? // 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) { if !list_store.iter_next(&iter) {
break; 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"?> <?xml version='1.0' encoding='UTF-8'?>
<!-- Generated with glade 3.39.0 <!-- Created with Cambalache 0.9.1 -->
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>
<requires lib="gtk+" version="3.24"/> <!-- interface-name about_dialog.ui -->
<!-- interface-license-type mit --> <requires lib="gtk" version="4.0"/>
<!-- 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 -->
<object class="GtkAboutDialog" id="about_dialog"> <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) <property name="comments" translatable="yes">2020 - 2022 Rafał Mikrut(qarmin)
This program is free to use and will always be. This program is free to use and will always be.
</property> </property>
<property name="authors">Rafał Mikrut(qarmin)</property>
<property name="logo-icon-name">help-about</property>
<property name="license-type">mit-x11</property> <property name="license-type">mit-x11</property>
<child internal-child="vbox"> <property name="logo-icon-name">help-about-symbolic</property>
<object class="GtkBox"> <property name="program-name">Czkawka</property>
<property name="can-focus">False</property> <property name="version">4.1.0</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>
</object> </object>
</interface> </interface>

View file

@ -1,190 +1,79 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 --> <!-- Created with Cambalache 0.9.1 -->
<!-- Generated with glade 3.39.0 -->
<interface> <interface>
<!-- interface-name compare_images.ui --> <!-- interface-name compare_images.ui -->
<requires lib="gtk+" version="3.24"/> <requires lib="gtk" version="4.0"/>
<object class="GtkDialog" id="window_compare"> <object class="GtkDialog" id="window_compare">
<property name="can-focus">False</property> <child>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">2</property> <property name="vexpand">1</property>
<child internal-child="action_area"> <child>
<object class="GtkButtonBox"> <object class="GtkBox">
<property name="can-focus">False</property> <child>
<property name="layout-style">end</property> <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> </object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property> <property name="homogeneous">1</property>
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkBox"> <object class="GtkCheckButton" id="check_button_left_preview_text">
<property name="can-focus">False</property> <property name="focusable">1</property>
<property name="visible">True</property> <property name="label" translatable="yes">First Game</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> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkBox"> <object class="GtkCheckButton" id="check_button_right_preview_text">
<property name="can-focus">False</property> <property name="focusable">1</property>
<property name="homogeneous">True</property> <property name="label" translatable="yes">Second Game</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> </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> </child>
</object> </object>
<packing> </child>
<property name="expand">True</property> <child>
<property name="fill">True</property> <object class="GtkBox">
<property name="position">0</property> <property name="homogeneous">1</property>
</packing> <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> </child>
</object> </object>
</child> </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'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 --> <!-- Created with Cambalache 0.9.1 -->
<!-- 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
-->
<interface> <interface>
<!-- interface-name Czkawka --> <!-- interface-name popover_right_click.ui -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. --> <requires lib="gtk" version="4.0"/>
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<object class="GtkPopover" id="popover_right_click"> <object class="GtkPopover" id="popover_right_click">
<property name="can-focus">False</property> <property name="child">
<property name="position">left</property>
<child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkButton" id="buttons_popover_right_click_open_file"> <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="label" translatable="yes">Open File</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_right_click_open_folder"> <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="label" translatable="yes">Open Folder</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
</object> </object>
</child> </property>
<property name="position">left</property>
</object> </object>
</interface> </interface>

View file

@ -1,233 +1,102 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 --> <!-- Created with Cambalache 0.9.1 -->
<!-- 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
-->
<interface> <interface>
<!-- interface-name Czkawka --> <!-- interface-name popover_select.ui -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. --> <requires lib="gtk" version="4.0"/>
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<object class="GtkPopover" id="popover_select"> <object class="GtkPopover" id="popover_select">
<property name="can-focus">False</property> <property name="child">
<child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkButton" id="buttons_popover_select_custom"> <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="label" translatable="yes">Select custom</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_unselect_custom"> <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="label" translatable="yes">Unselect custom</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkSeparator" id="separator_select_custom"> <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>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_select_all_images_except_biggest"> <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="label" translatable="yes">Select all except biggest</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_select_all_images_except_smallest"> <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="label" translatable="yes">Select all except smallest</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkSeparator" id="separator_select_image_size"> <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>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_select_all_except_oldest"> <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="label" translatable="yes">Select all except oldest</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_select_all_except_newest"> <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="label" translatable="yes">Select all except newest</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_select_one_oldest"> <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="label" translatable="yes">Select one oldest</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">8</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_select_one_newest"> <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="label" translatable="yes">Select one newest</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">9</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkSeparator" id="separator_select_date"> <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>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_reverse"> <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="label" translatable="yes">Reverse Selection</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">11</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkSeparator" id="separator_select_reverse"> <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>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_select_all"> <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="label" translatable="yes">Select All</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">13</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="buttons_popover_unselect_all"> <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="label" translatable="yes">Unselect All</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">14</property>
</packing>
</child> </child>
</object> </object>
</child> </property>
</object> </object>
</interface> </interface>

View file

@ -1,195 +1,94 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 --> <!-- Created with Cambalache 0.9.1 -->
<!-- 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>
<!-- interface-name Czkawka --> <!-- interface-name progress.ui -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. --> <requires lib="gtk" version="4.0"/>
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<object class="GtkDialog" id="window_progress"> <object class="GtkDialog" id="window_progress">
<property name="can-focus">False</property> <child>
<property name="gravity">center</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox"> <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="orientation">vertical</property>
<property name="spacing">2</property> <property name="spacing">10</property>
<child internal-child="action_area"> <child>
<object class="GtkButtonBox"> <object class="GtkGrid" id="grid_progress_stages">
<property name="can-focus">False</property> <property name="margin-end">2</property>
<property name="layout-style">end</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> </object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkBox"> <object class="GtkLabel" id="label_stage">
<property name="can-focus">False</property> <property name="label" translatable="yes">Stage 1/2</property>
<property name="margin-bottom">10</property> </object>
<property name="margin-end">10</property> </child>
<property name="margin-start">10</property> <child>
<property name="margin-top">10</property> <object class="GtkButton" id="button_stop_in_dialog">
<property name="orientation">vertical</property> <property name="focusable">1</property>
<property name="spacing">10</property> <property name="halign">end</property>
<property name="visible">True</property> <property name="margin-end">2</property>
<property name="receives-default">1</property>
<property name="valign">center</property>
<child> <child>
<!-- n-columns=2 n-rows=2 --> <object class="GtkBox">
<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>
<child> <child>
<object class="GtkLabel" id="label_progress_all_stages"> <object class="GtkImage">
<property name="can-focus">False</property> <property name="icon-name">image-missing</property>
<property name="label" translatable="yes">All stages: </property>
<property name="name">label_progress_all_stages</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkProgressBar" id="progress_bar_all_stages"> <object class="GtkLabel">
<property name="can-focus">False</property> <property name="hexpand">1</property>
<property name="hexpand">True</property> <property name="label" translatable="yes">Stop</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> </object>
</child> </child>
</object> </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> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
</object> </object>
</child> </child>

View file

@ -1,689 +1,343 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.9.0 --> <!-- Created with Cambalache 0.9.1 -->
<!-- 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>
<!-- interface-name Czkawka --> <!-- interface-name settings.ui -->
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders, similar images etc. --> <requires lib="gtk" version="4.0"/>
<!-- interface-authors Rafa\305\202 Mikrut -->
<!-- interface-license-id mit_x11 -->
<requires lib="gtk+" version="3.24"/>
<object class="GtkDialog" id="window_settings"> <object class="GtkDialog" id="window_settings">
<property name="can-focus">False</property> <property name="modal">1</property>
<property name="modal">True</property>
<property name="title" translatable="yes">Czkawka Options</property> <property name="title" translatable="yes">Czkawka Options</property>
<property name="type-hint">dialog</property> <child>
<child internal-child="vbox"> <object class="GtkBox" id="potatoo">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">2</property> <property name="vexpand">1</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> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkBox"> <object class="GtkComboBoxText">
<property name="can-focus">False</property> <property name="valign">center</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> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </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> <child>
<object class="GtkNotebook" id="notebook_settings"> <object class="GtkNotebookPage">
<property name="can-focus">True</property> <property name="child">
<property name="tab-pos">left</property>
<property name="visible">True</property>
<child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property> <property name="margin-bottom">5</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="visible">True</property> <property name="valign">center</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkLabel" id="label_settings_general_language"> <object class="GtkLabel" id="label_settings_general_language">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Language</property> <property name="label" translatable="yes">Language</property>
<property name="margin-end">10</property> <property name="margin-end">10</property>
<property name="margin-start">5</property> <property name="margin-start">5</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText" id="combo_box_settings_language"> <object class="GtkComboBoxText" id="combo_box_settings_language">
<property name="can-focus">False</property> <property name="hexpand">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_load_at_start"> <object class="GtkCheckButton" id="check_button_settings_load_at_start">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Load configuration at start</property> <property name="label" translatable="yes">Load configuration at start</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_save_at_exit"> <object class="GtkCheckButton" id="check_button_settings_save_at_exit">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Save configuration at exit</property> <property name="label" translatable="yes">Save configuration at exit</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_confirm_deletion"> <object class="GtkCheckButton" id="check_button_settings_confirm_deletion">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Show confirm dialog when deleting any files</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> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_confirm_link"> <object class="GtkCheckButton" id="check_button_settings_confirm_link">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Show confirm dialog when hard/symlinks any files</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> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_confirm_group_deletion"> <object class="GtkCheckButton" id="check_button_settings_confirm_group_deletion">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Show confirm dialog when deleting all files in group</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> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_show_text_view"> <object class="GtkCheckButton" id="check_button_settings_show_text_view">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Show bottom text panel</property> <property name="label" translatable="yes">Show bottom text panel</property>
<property name="receives-default">False</property> <property name="valign">center</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">6</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_use_cache"> <object class="GtkCheckButton" id="check_button_settings_use_cache">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Use cache</property> <property name="label" translatable="yes">Use cache</property>
<property name="receives-default">False</property> <property name="vexpand">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_save_also_json"> <object class="GtkCheckButton" id="check_button_settings_save_also_json">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Save cache also to JSON file</property> <property name="label" translatable="yes">Save cache also to JSON file</property>
<property name="receives-default">False</property> <property name="vexpand">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">8</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_use_trash"> <object class="GtkCheckButton" id="check_button_settings_use_trash">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Move deleted files to trash</property> <property name="label" translatable="yes">Move deleted files to trash</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">9</property>
</packing>
</child> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property> <property name="valign">center</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkButton" id="button_settings_open_cache_folder"> <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="label" translatable="yes">Open cache folder</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="button_settings_open_settings_folder"> <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="label" translatable="yes">Open settings folder</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property>
</object> </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> </child>
</object> </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> </child>
</object> </object>
</child> </property>
<child type="tab"> <property name="tab">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">General</property> <property name="label" translatable="yes">General</property>
<property name="visible">True</property>
</object> </object>
<packing> </property>
<property name="tab-fill">False</property> </object>
</packing> </child>
</child> <child>
<child> <object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_hide_hard_links"> <object class="GtkCheckButton" id="check_button_settings_hide_hard_links">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Hide hard links(only Linux and MacOS)</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> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_show_preview_duplicates"> <object class="GtkCheckButton" id="check_button_settings_show_preview_duplicates">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Show image preview</property> <property name="label" translatable="yes">Show image preview</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_duplicates_delete_outdated_cache"> <object class="GtkCheckButton" id="check_button_settings_duplicates_delete_outdated_cache">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Delete outdated cache entries automatically</property> <property name="label" translatable="yes">Delete outdated cache entries automatically</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-end">4</property> <property name="margin-end">4</property>
<property name="margin-start">4</property> <property name="margin-start">4</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkLabel" id="label_settings_duplicate_minimal_size_cache"> <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="label" translatable="yes">Minimal size of files in bytes saved to cache</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkEntry" id="entry_settings_cache_file_minimal_size"> <object class="GtkEntry" id="entry_settings_cache_file_minimal_size">
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="caps-lock-warning">False</property> <property name="halign">center</property>
<property name="input-purpose">number</property> <property name="input-purpose">number</property>
<property name="max-length">15</property> <property name="max-length">15</property>
<property name="text" translatable="yes">257144</property> <property name="text" translatable="yes">257144</property>
<property name="visible">True</property>
</object> </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> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_duplicates_use_prehash_cache"> <object class="GtkCheckButton" id="check_button_duplicates_use_prehash_cache">
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Use prehash cache</property> <property name="label" translatable="yes">Use prehash cache</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="button_settings_duplicates_clear_cache"> <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="label" translatable="yes">Remove outdated results from duplicates cache</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property> <property name="valign">center</property>
</object> </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>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="margin-end">4</property> <property name="margin-end">4</property>
<property name="margin-start">4</property> <property name="margin-start">4</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkLabel" id="label_settings_duplicate_minimal_size_cache_prehash"> <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="label" translatable="yes">Minimal size of files in bytes saved to prehash cache</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkEntry" id="entry_settings_prehash_cache_file_minimal_size"> <object class="GtkEntry" id="entry_settings_prehash_cache_file_minimal_size">
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="caps-lock-warning">False</property> <property name="halign">center</property>
<property name="input-purpose">number</property> <property name="input-purpose">number</property>
<property name="max-length">15</property> <property name="max-length">15</property>
<property name="text" translatable="yes">1</property> <property name="text" translatable="yes">1</property>
<property name="visible">True</property>
</object> </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> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child> </child>
</object> </object>
<packing> </property>
<property name="position">1</property> <property name="position">1</property>
</packing> <property name="tab">
</child>
<child type="tab">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Duplicate Finder</property> <property name="label" translatable="yes">Duplicate Finder</property>
<property name="visible">True</property>
</object> </object>
<packing> </property>
<property name="position">1</property> </object>
<property name="tab-fill">False</property> </child>
</packing> <child>
</child> <object class="GtkNotebookPage">
<child> <property name="child">
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_show_preview_similar_images"> <object class="GtkCheckButton" id="check_button_settings_show_preview_similar_images">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Show image preview</property> <property name="label" translatable="yes">Show image preview</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_similar_images_delete_outdated_cache"> <object class="GtkCheckButton" id="check_button_settings_similar_images_delete_outdated_cache">
<property name="active">True</property> <property name="active">1</property>
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Delete outdated cache entries automatically</property> <property name="label" translatable="yes">Delete outdated cache entries automatically</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="button_settings_similar_images_clear_cache"> <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="label" translatable="yes">Remove outdated results from images cache</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property> <property name="valign">center</property>
</object> </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> </child>
</object> </object>
<packing> </property>
<property name="position">2</property> <property name="position">2</property>
</packing> <property name="tab">
</child>
<child type="tab">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Similar Images</property> <property name="label" translatable="yes">Similar Images</property>
<property name="visible">True</property>
</object> </object>
<packing> </property>
<property name="position">2</property> </object>
<property name="tab-fill">False</property> </child>
</packing> <child>
</child> <object class="GtkNotebookPage">
<child> <property name="child">
<object class="GtkBox"> <object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="visible">True</property>
<child> <child>
<object class="GtkButton" id="button_settings_similar_videos_clear_cache"> <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="label" translatable="yes">Remove outdated results from videos cache</property>
<property name="receives-default">True</property> <property name="receives-default">1</property>
<property name="visible">True</property> <property name="valign">center</property>
</object> </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>
<child> <child>
<object class="GtkCheckButton" id="check_button_settings_similar_videos_delete_outdated_cache"> <object class="GtkCheckButton" id="check_button_settings_similar_videos_delete_outdated_cache">
<property name="can-focus">True</property> <property name="focusable">1</property>
<property name="draw-indicator">True</property>
<property name="label" translatable="yes">Delete outdated cache entries automatically</property> <property name="label" translatable="yes">Delete outdated cache entries automatically</property>
<property name="receives-default">False</property>
<property name="visible">True</property>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
</object> </object>
<packing> </property>
<property name="position">3</property> <property name="position">3</property>
</packing> <property name="tab">
</child>
<child type="tab">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Similar Videos</property> <property name="label" translatable="yes">Similar Videos</property>
<property name="visible">True</property>
</object> </object>
<packing> </property>
<property name="position">3</property> </object>
<property name="tab-fill">False</property> </child>
</packing> </object>
</child> </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> </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> </child>
</object> </object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child> </child>
</object> </object>
</child> </child>

View file

@ -16,7 +16,7 @@ FFmpeg is not included here because it is not needed to build - it is dynamicall
```shell ```shell
sudo apt install -y curl git build-essential # Needed by Rust update tool 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 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 #### 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/ <!-- 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/ 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 ### 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 #### Ubuntu/Debian/Linux Mint
``` ```
sudo apt install libgtk-3-dev ffmpeg sudo apt install libgtk-4-dev ffmpeg
``` ```
#### Fedora/Rocky Linux #### Fedora/Rocky Linux
``` ```
@ -24,7 +24,7 @@ sudo xbps-install gcc pkg-config ffmpeg
``` ```
### macOS ### 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/). One very straight-forward way to do this is by using [Homebrew](https://brew.sh/).
Installation in the terminal: Installation in the terminal:
```shell ```shell
@ -47,7 +47,7 @@ arch -x86_64 /usr/local/bin/brew install gtk+3 adwaita-icon-theme ffmpeg librsvg
``` ```
### Windows ### 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). 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/). 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 # curl is needed by Rust update tool
RUN apt-get update \ 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/* && 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 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 summary: Czkawka - fast data cleaner written in Rust # 79 char long summary
description: | 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. 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 grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots confinement: strict # use 'strict' once you have the right plugs and slots
compression: lzo compression: lzo