├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── linux.yml │ ├── mac.yml │ ├── quality.yml │ └── windows.yml ├── .gitignore ├── .mailmap ├── .rustfmt.toml ├── Cargo.lock ├── Cargo.toml ├── Changelog.md ├── LICENSE_CC_BY_4_ICONS ├── README.md ├── ci_tester ├── Cargo.toml └── src │ └── main.rs ├── clippy.toml ├── czkawka_cli ├── Cargo.toml ├── LICENSE_MIT ├── README.md ├── data └── src │ ├── commands.rs │ ├── main.rs │ └── progress.rs ├── czkawka_core ├── Cargo.toml ├── LICENSE_MIT ├── README.md ├── benches │ └── hash_calculation_benchmark.rs ├── build.rs ├── data ├── i18n.toml ├── i18n │ ├── ar │ │ └── czkawka_core.ftl │ ├── bg │ │ └── czkawka_core.ftl │ ├── cs │ │ └── czkawka_core.ftl │ ├── de │ │ └── czkawka_core.ftl │ ├── el │ │ └── czkawka_core.ftl │ ├── en │ │ └── czkawka_core.ftl │ ├── es-ES │ │ └── czkawka_core.ftl │ ├── fr │ │ └── czkawka_core.ftl │ ├── it │ │ └── czkawka_core.ftl │ ├── ja │ │ └── czkawka_core.ftl │ ├── ko │ │ └── czkawka_core.ftl │ ├── nl │ │ └── czkawka_core.ftl │ ├── no │ │ └── czkawka_core.ftl │ ├── pl │ │ └── czkawka_core.ftl │ ├── pt-BR │ │ └── czkawka_core.ftl │ ├── pt-PT │ │ └── czkawka_core.ftl │ ├── ro │ │ └── czkawka_core.ftl │ ├── ru │ │ └── czkawka_core.ftl │ ├── sv-SE │ │ └── czkawka_core.ftl │ ├── tr │ │ └── czkawka_core.ftl │ ├── uk │ │ └── czkawka_core.ftl │ ├── zh-CN │ │ └── czkawka_core.ftl │ └── zh-TW │ │ └── czkawka_core.ftl └── src │ ├── common.rs │ ├── common_cache.rs │ ├── common_dir_traversal.rs │ ├── common_directory.rs │ ├── common_extensions.rs │ ├── common_image.rs │ ├── common_items.rs │ ├── common_messages.rs │ ├── common_tool.rs │ ├── common_traits.rs │ ├── lib.rs │ ├── localizer_core.rs │ ├── progress_data.rs │ └── tools │ ├── bad_extensions.rs │ ├── big_file.rs │ ├── broken_files.rs │ ├── duplicate.rs │ ├── empty_files.rs │ ├── empty_folder.rs │ ├── invalid_symlinks.rs │ ├── mod.rs │ ├── same_music.rs │ ├── similar_images.rs │ ├── similar_videos.rs │ └── temporary.rs ├── czkawka_gui ├── Cargo.toml ├── LICENSE_CC_BY_4_ICONS ├── LICENSE_MIT_APP_CODE ├── LICENSE_MIT_WINDOWS_THEME ├── README.md ├── data ├── i18n.toml ├── i18n │ ├── ar │ │ └── czkawka_gui.ftl │ ├── bg │ │ └── czkawka_gui.ftl │ ├── cs │ │ └── czkawka_gui.ftl │ ├── de │ │ └── czkawka_gui.ftl │ ├── el │ │ └── czkawka_gui.ftl │ ├── en │ │ └── czkawka_gui.ftl │ ├── es-ES │ │ └── czkawka_gui.ftl │ ├── fr │ │ └── czkawka_gui.ftl │ ├── it │ │ └── czkawka_gui.ftl │ ├── ja │ │ └── czkawka_gui.ftl │ ├── ko │ │ └── czkawka_gui.ftl │ ├── nl │ │ └── czkawka_gui.ftl │ ├── no │ │ └── czkawka_gui.ftl │ ├── pl │ │ └── czkawka_gui.ftl │ ├── pt-BR │ │ └── czkawka_gui.ftl │ ├── pt-PT │ │ └── czkawka_gui.ftl │ ├── ro │ │ └── czkawka_gui.ftl │ ├── ru │ │ └── czkawka_gui.ftl │ ├── sv-SE │ │ └── czkawka_gui.ftl │ ├── tr │ │ └── czkawka_gui.ftl │ ├── uk │ │ └── czkawka_gui.ftl │ ├── zh-CN │ │ └── czkawka_gui.ftl │ └── zh-TW │ │ └── czkawka_gui.ftl ├── icons │ ├── czk_add.svg │ ├── czk_compare.svg │ ├── czk_delete.svg │ ├── czk_hardlink.svg │ ├── czk_hide_down.svg │ ├── czk_hide_up.svg │ ├── czk_info.svg │ ├── czk_left.svg │ ├── czk_manual_add.svg │ ├── czk_move.svg │ ├── czk_right.svg │ ├── czk_save.svg │ ├── czk_search.svg │ ├── czk_select.svg │ ├── czk_settings.svg │ ├── czk_sort.svg │ ├── czk_stop.svg │ ├── czk_symlink.svg │ ├── czk_trash.svg │ └── icon_about.png ├── src │ ├── compute_results.rs │ ├── connect_things │ │ ├── connect_about_buttons.rs │ │ ├── connect_button_compare.rs │ │ ├── connect_button_delete.rs │ │ ├── connect_button_hardlink.rs │ │ ├── connect_button_move.rs │ │ ├── connect_button_save.rs │ │ ├── connect_button_search.rs │ │ ├── connect_button_select.rs │ │ ├── connect_button_sort.rs │ │ ├── connect_button_stop.rs │ │ ├── connect_change_language.rs │ │ ├── connect_duplicate_buttons.rs │ │ ├── connect_header_buttons.rs │ │ ├── connect_notebook_tabs.rs │ │ ├── connect_popovers_select.rs │ │ ├── connect_popovers_sort.rs │ │ ├── connect_progress_window.rs │ │ ├── connect_same_music_mode_changed.rs │ │ ├── connect_selection_of_directories.rs │ │ ├── connect_settings.rs │ │ ├── connect_show_hide_ui.rs │ │ ├── connect_similar_image_size_change.rs │ │ └── mod.rs │ ├── create_tree_view.rs │ ├── gui_structs │ │ ├── gui_about.rs │ │ ├── gui_bottom_buttons.rs │ │ ├── gui_compare_images.rs │ │ ├── gui_data.rs │ │ ├── gui_header.rs │ │ ├── gui_main_notebook.rs │ │ ├── gui_popovers_select.rs │ │ ├── gui_popovers_sort.rs │ │ ├── gui_progress_dialog.rs │ │ ├── gui_settings.rs │ │ ├── gui_upper_notebook.rs │ │ └── mod.rs │ ├── help_combo_box.rs │ ├── help_functions.rs │ ├── initialize_gui.rs │ ├── language_functions.rs │ ├── localizer_gui.rs │ ├── main.rs │ ├── notebook_enums.rs │ ├── notebook_info.rs │ ├── opening_selecting_records.rs │ ├── saving_loading.rs │ ├── taskbar_progress.rs │ ├── taskbar_progress_dummy.rs │ ├── taskbar_progress_win.rs │ └── tests.rs └── ui │ ├── about_dialog.ui │ ├── compare_images.ui │ ├── czkawka.cmb │ ├── main_window.ui │ ├── popover_right_click.ui │ ├── popover_select.ui │ ├── popover_sort.ui │ ├── progress.ui │ └── settings.ui ├── data ├── com.github.qarmin.czkawka.desktop ├── com.github.qarmin.czkawka.metainfo.xml └── icons │ ├── com.github.qarmin.czkawka-symbolic.svg │ ├── com.github.qarmin.czkawka.Devel.svg │ └── com.github.qarmin.czkawka.svg ├── instructions ├── Instruction.md └── Translations.md ├── justfile ├── krokiet ├── .clippy.toml ├── Cargo.toml ├── LICENSE_CC_BY_4_ICONS ├── LICENSE_GPL_APP ├── LICENSE_MIT_CODE ├── README.md ├── build.rs ├── i18n.toml ├── i18n │ ├── ar │ │ └── krokiet.ftl │ ├── bg │ │ └── krokiet.ftl │ ├── cs │ │ └── krokiet.ftl │ ├── de │ │ └── krokiet.ftl │ ├── el │ │ └── krokiet.ftl │ ├── en │ │ └── krokiet.ftl │ ├── es-ES │ │ └── krokiet.ftl │ ├── fr │ │ └── krokiet.ftl │ ├── it │ │ └── krokiet.ftl │ ├── ja │ │ └── krokiet.ftl │ ├── ko │ │ └── krokiet.ftl │ ├── nl │ │ └── krokiet.ftl │ ├── no │ │ └── krokiet.ftl │ ├── pl │ │ └── krokiet.ftl │ ├── pt-BR │ │ └── krokiet.ftl │ ├── pt-PT │ │ └── krokiet.ftl │ ├── ro │ │ └── krokiet.ftl │ ├── ru │ │ └── krokiet.ftl │ ├── sv-SE │ │ └── krokiet.ftl │ ├── tr │ │ └── krokiet.ftl │ ├── uk │ │ └── krokiet.ftl │ ├── zh-CN │ │ └── krokiet.ftl │ └── zh-TW │ │ └── krokiet.ftl ├── icons │ ├── krokiet_add.svg │ ├── krokiet_delete.svg │ ├── krokiet_dir.svg │ ├── krokiet_info.svg │ ├── krokiet_logo.png │ ├── krokiet_logo_small.png │ ├── krokiet_manual_add.svg │ ├── krokiet_move.svg │ ├── krokiet_remove.svg │ ├── krokiet_rename.svg │ ├── krokiet_save.svg │ ├── krokiet_search.svg │ ├── krokiet_select.svg │ ├── krokiet_settings.svg │ ├── krokiet_sort.svg │ ├── krokiet_stop.svg │ └── krokiet_subsettings.svg ├── src │ ├── common.rs │ ├── connect_delete.rs │ ├── connect_directories_changes.rs │ ├── connect_move.rs │ ├── connect_open.rs │ ├── connect_progress_receiver.rs │ ├── connect_rename.rs │ ├── connect_row_selection.rs │ ├── connect_save.rs │ ├── connect_scan.rs │ ├── connect_select.rs │ ├── connect_show_preview.rs │ ├── connect_sort.rs │ ├── connect_stop.rs │ ├── connect_translation.rs │ ├── localizer_krokiet.rs │ ├── main.rs │ ├── model_operations.rs │ ├── set_initial_gui_info.rs │ ├── settings.rs │ ├── shared_models.rs │ └── test_common.rs └── ui │ ├── about.slint │ ├── action_buttons.slint │ ├── bottom_panel.slint │ ├── callabler.slint │ ├── color_palette.slint │ ├── common.slint │ ├── gui_state.slint │ ├── included_directories.slint │ ├── left_side_panel.slint │ ├── main_lists.slint │ ├── main_window.slint │ ├── popup_base.slint │ ├── popup_centered_text.slint │ ├── popup_delete.slint │ ├── popup_move_folders.slint │ ├── popup_new_directories.slint │ ├── popup_rename_files.slint │ ├── popup_save.slint │ ├── popup_select_results.slint │ ├── popup_sort.slint │ ├── preview.slint │ ├── progress.slint │ ├── selectable_tree_view.slint │ ├── settings.slint │ ├── settings_list.slint │ ├── tool_settings.slint │ └── translations.slint └── misc ├── .idea ├── czkawka.iml ├── modules.xml ├── vcs.xml └── workspace.xml ├── cargo ├── PublishCore.sh └── PublishOther.sh ├── czkawka-appimage-recipe.yml ├── delete_unused_krokiet_slint_imports.py ├── docker └── Dockerfile ├── flathub.sh ├── generate_krokiet_translations.py ├── test_image_perf ├── Cargo.toml └── src │ └── main.rs └── test_read_perf ├── Cargo.toml └── src └── main.rs /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: qarmin # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve app 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Bug Description** 11 | 12 | **Steps to reproduce:** 13 | <!-- Please describe what you expected to see and what you saw instead. Also include screenshots or screencasts if needed. --> 14 | 15 | **Terminal output** (optional): 16 | 17 | ``` 18 | <!-- 19 | Add terminal output only if needed - if there are some errors or warnings or you have performance/freeze issues. 20 | Very helpful in this situation will be logs from czkawka run with RUST_LOG environment variable set e.g. 21 | `RUST_LOG=debug ./czkawka` or `flatpak run --env=RUST_LOG=debug com.github.qarmin.czkawka` if you use flatpak, which will print more detailed info about executed function. 22 | --> 23 | 24 | <details> 25 | <summary>Debug log</summary> 26 | 27 | # UNCOMMENT DETAILS AND PUT LOGS HERE 28 | 29 | </details> 30 | ``` 31 | 32 | **System** 33 | <!-- OS and Czkawka/Krokiet version, you can just copy from logs, if you run app from terminal or find it in logs file. --> 34 | <!-- Example of logs: --> 35 | <!-- Czkawka gtk version: 9.0.0, debug mode, rust 1.85.0 (2025-02-17), os Ubuntu 24.10.0 [x86_64 64-bit], 24 cpu/threads, features(1): [fast_image_resize], app cpu version: [x86-64-v3 (AVX2) or x86-64-v4 (AVX-512)], os cpu version: [x86-64-v4 (AVX-512)] !--> 36 | <!-- Please do not report feature request for Gtk Czkawka gui, because it is in maintenance mode. --> 37 | 38 | - Czkawka/Krokiet version: <!-- e.g. 9.0.0 cli/gui --> 39 | - OS version: <!-- e.g Ubuntu 22.04, Windows 11, Mac 15.1 ARM --> 40 | - Installation method: <!-- e.g. github binaries, snap, flatpak, msys2 --> 41 | 42 | <!-- If you use flatpak, please include the result of `flatpak info com.github.qarmin.czkawka`. --> 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Feature Description** 11 | ... 12 | -------------------------------------------------------------------------------- /.github/workflows/quality.yml: -------------------------------------------------------------------------------- 1 | name: Quality 2 | on: 3 | push: 4 | pull_request: 5 | schedule: 6 | - cron: '0 0 * * 2' 7 | 8 | env: 9 | CARGO_TERM_COLOR: always 10 | 11 | jobs: 12 | quality: 13 | runs-on: ubuntu-24.04 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Install Gtk 4 18 | run: sudo apt update || true; sudo apt install -y libgtk-4-dev libraw-dev libheif-dev libavif-dev libdav1d-dev -y 19 | 20 | - name: Setup rust version 21 | run: | 22 | rustup default 1.85.0 23 | rustup component add rustfmt 24 | rustup component add clippy 25 | 26 | - name: Disable optimizations 27 | run: | 28 | sed -i 's/^\(\[profile\.dev\.package.*\)/#\1/' Cargo.toml 29 | sed -i 's|^opt-level = 3 # OPT PACKAGES|#opt-level = 3 # OPT PACKAGES|' Cargo.toml 30 | 31 | - name: Check the format 32 | run: cargo fmt --all -- --check 33 | 34 | - name: Run clippy 35 | run: cargo clippy --all-targets --all-features -- -D warnings 36 | 37 | - name: Run clippy 38 | run: cargo clippy -- -D warnings 39 | 40 | - name: Check tools 41 | run: | 42 | cd misc/test_image_perf 43 | cargo check 44 | cd ../../ 45 | 46 | cd misc/test_read_perf 47 | cargo check 48 | cd ../../ 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .idea/ 3 | *.iml 4 | *~ 5 | *# 6 | results*.txt 7 | TestSuite* 8 | *.snap 9 | flatpak/ 10 | *.zip 11 | *.zst 12 | *.profraw 13 | *.profdata 14 | /lcov_report* 15 | /report 16 | ci_tester/target 17 | ci_tester/Cargo.lock 18 | krokiet/Cargo.lock 19 | krokiet/target 20 | *.json 21 | *.mm_profdata 22 | perf.data 23 | perf.data.old 24 | krokiet/ui/test.slint 25 | *.html 26 | misc/*/*.lock 27 | misc/*/target/ 28 | misc/*/.idea 29 | benchmarks -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | TheEvilSkeleton <theevilskeleton@riseup.net> Proprietary Chrome-chan <theevilskeleton@riseup.net> 2 | Rafał Mikrut <mikrutrafal@protonmail.com> <mikrutrafal54@gmail.com> <41945903+qarmin@users.noreply.github.com> 3 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | newline_style = "Unix" 2 | max_width = 180 3 | 4 | # Enable only with nightly channel via - cargo +nightly fmt 5 | imports_granularity = "Module" 6 | group_imports = "StdExternalCrate" -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "czkawka_core", 4 | "czkawka_cli", 5 | "czkawka_gui", 6 | "krokiet" 7 | ] 8 | exclude = [ 9 | "misc/test_read_perf", 10 | "misc/test_image_perf", 11 | "ci_tester", 12 | ] 13 | resolver = "3" 14 | 15 | [profile.release] 16 | # panic = "unwind" in opposite to "abort", allows to catch panic!() 17 | # Since Czkawka parse different types of files with few libraries, it is possible 18 | # that some files will cause crash, so at this moment I don't recommend to use "abort" 19 | # until you are ready to occasional crashes 20 | panic = "unwind" 21 | 22 | # Should find more panics, that now are hidden from user - in long term it should decrease bugs in app 23 | # There is one big disadvantage - in case of overflow/underflow entire app crashes and not everywhere I catch this panic so app aborts 24 | # So feel free to disable it, if you want 25 | overflow-checks = true 26 | 27 | # LTO setting is disabled by default, because release mode is usually needed to develop app and compilation with LTO would take a lot of time 28 | # But it is used to optimize release builds(and probably also in CI, where time is not so important as in local development) 29 | #lto = "thin" 30 | 31 | # Optimize all dependencies except application/workspaces, even in debug builds to get reasonable performance e.g. when opening images 32 | [profile.dev.package."*"] # OPT PACKAGES 33 | opt-level = 3 # OPT PACKAGES 34 | 35 | [profile.test] 36 | debug-assertions = true # Forces to crash when there is duplicated item in cli 37 | overflow-checks = true 38 | opt-level = 3 39 | 40 | # Unsafe profile, just to check, how fast and small app could be 41 | [profile.fastest] 42 | inherits = "release" 43 | panic = "abort" 44 | lto = "thin" 45 | strip = "symbols" 46 | codegen-units = 1 47 | opt-level = 3 48 | debug = false -------------------------------------------------------------------------------- /ci_tester/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ci_tester" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | 9 | [profile.release] 10 | debug-assertions = true 11 | overflow-checks = true 12 | 13 | [dependencies] 14 | state = "0.6.0" 15 | handsome_logger = "0.8.0" 16 | log = "0.4.20" -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | allow-indexing-slicing-in-tests = true -------------------------------------------------------------------------------- /czkawka_cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "czkawka_cli" 3 | version = "9.0.0" 4 | authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"] 5 | edition = "2024" 6 | rust-version = "1.85.0" 7 | description = "CLI frontend of Czkawka" 8 | license = "MIT" 9 | homepage = "https://github.com/qarmin/czkawka" 10 | repository = "https://github.com/qarmin/czkawka" 11 | 12 | [dependencies] 13 | clap = { version = "4.5", features = ["derive"] } 14 | 15 | # For enum types 16 | image_hasher = "3.0" 17 | 18 | log = "0.4.22" 19 | czkawka_core = { path = "../czkawka_core", version = "9.0.0", features = [] } 20 | indicatif = "0.17" 21 | crossbeam-channel = { version = "0.5", features = [] } 22 | ctrlc = { version = "3.4", features = ["termination"] } 23 | humansize = "2.1" 24 | 25 | [features] 26 | default = ["fast_image_resize"] 27 | heif = ["czkawka_core/heif"] 28 | libraw = ["czkawka_core/libraw"] 29 | libavif = ["czkawka_core/libavif"] 30 | fast_image_resize = ["czkawka_core/fast_image_resize"] 31 | -------------------------------------------------------------------------------- /czkawka_cli/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2025 Rafał Mikrut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /czkawka_cli/README.md: -------------------------------------------------------------------------------- 1 | # Czkawka CLI 2 | 3 | CLI frontend, allows to use Czkawka from terminal. 4 | 5 | ## Requirements 6 | 7 | Precompiled binaries should work without any additional dependencies with Linux(Ubuntu 20.04+), Windows(10+) and macOS( 8 | 10.15+). 9 | 10 | If you decide to compile the app, you probably will be able to run it on even older versions of OS, like Ubuntu 16.04 or 11 | Windows 7. 12 | 13 | On linux it is even possible with eyra to avoid entirely libc and using fully static rust binary. 14 | 15 | If you want to use similar videos tool, you need to install ffmpeg(runtime dependency). 16 | If you want to use heif/libraw/libavif(build/runtime dependency) you need to install required packages(may require 17 | bigger os version than czkawka). 18 | 19 | - mac - `brew install ffmpeg libraw libheif libavif` - https://formulae.brew.sh/formula/ffmpeg 20 | - linux - `sudo apt install ffmpeg libraw-dev libheif-dev libavif-dev libdav1d-dev` 21 | - windows - `choco install ffmpeg` - or if not working, download from https://ffmpeg.org/download.html#build-windows and 22 | unpack to location with `czkawka_cli.exe`, heif and libraw are not supported on windows 23 | 24 | ## Compilation 25 | 26 | For compilation, you need to have installed Rust via rustup - https://rustup.rs/ and compile it e.g. via 27 | 28 | ```shell 29 | cargo run --release --bin czkawka_cli 30 | ``` 31 | 32 | you can enable additional features via 33 | 34 | ```shell 35 | cargo run --release --bin czkawka_cli --features "heif,libraw,libavif" 36 | ``` 37 | 38 | on linux to build fully static binary with eyra you need to use (this is only for crazy people, so just use command 39 | above if you don't know what you are doing) 40 | 41 | ```shell 42 | rustup default nightly-2025-01-01 # or any newer nightly that works fine with eyra 43 | cd czkawka_cli 44 | cargo add eyra --rename=std 45 | echo 'fn main() { println!("cargo:rustc-link-arg=-nostartfiles"); }' > build.rs 46 | cd .. 47 | cargo build --release --bin czkawka_cli 48 | ``` 49 | 50 | ## LICENSE 51 | 52 | MIT -------------------------------------------------------------------------------- /czkawka_cli/data: -------------------------------------------------------------------------------- 1 | ../data/ -------------------------------------------------------------------------------- /czkawka_core/LICENSE_MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2025 Rafał Mikrut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /czkawka_core/README.md: -------------------------------------------------------------------------------- 1 | # Czkawka Core 2 | 3 | Core of Czkawka GUI/CLI and Krokiet projects. 4 | -------------------------------------------------------------------------------- /czkawka_core/benches/hash_calculation_benchmark.rs: -------------------------------------------------------------------------------- 1 | use std::env::temp_dir; 2 | use std::fs::File; 3 | use std::io::Write; 4 | use std::path::PathBuf; 5 | use std::sync::Arc; 6 | 7 | use criterion::{Criterion, black_box, criterion_group, criterion_main}; 8 | use czkawka_core::tools::duplicate::{DuplicateEntry, HashType, hash_calculation}; 9 | 10 | fn setup_test_file(size: u64) -> PathBuf { 11 | let mut path = temp_dir(); 12 | path.push("test_file"); 13 | let mut file = File::create(&path).expect("Failed to create test file"); 14 | file.write_all(&vec![0u8; size as usize]).expect("Failed to write to test file"); 15 | path 16 | } 17 | 18 | fn get_file_entry(size: u64) -> DuplicateEntry { 19 | let path = setup_test_file(size); 20 | DuplicateEntry { 21 | path, 22 | modified_date: 0, 23 | size, 24 | hash: String::new(), 25 | } 26 | } 27 | 28 | fn benchmark_hash_calculation_vec<const FILE_SIZE: u64, const BUFFER_SIZE: usize>(c: &mut Criterion) { 29 | let file_entry = get_file_entry(FILE_SIZE); 30 | let function_name = format!("hash_calculation_vec_file_{FILE_SIZE}_buffer_{BUFFER_SIZE}"); 31 | 32 | c.bench_function(&function_name, |b| { 33 | b.iter(|| { 34 | let mut buffer = vec![0u8; BUFFER_SIZE]; 35 | hash_calculation(black_box(&mut buffer), black_box(&file_entry), black_box(HashType::Blake3), &Arc::default(), None).expect("Failed to calculate hash"); 36 | }); 37 | }); 38 | } 39 | 40 | fn benchmark_hash_calculation_arr<const FILE_SIZE: u64, const BUFFER_SIZE: usize>(c: &mut Criterion) { 41 | let file_entry = get_file_entry(FILE_SIZE); 42 | let function_name = format!("hash_calculation_arr_file_{FILE_SIZE}_buffer_{BUFFER_SIZE}"); 43 | 44 | c.bench_function(&function_name, |b| { 45 | b.iter(|| { 46 | let mut buffer = [0u8; BUFFER_SIZE]; 47 | hash_calculation(black_box(&mut buffer), black_box(&file_entry), black_box(HashType::Blake3), &Arc::default(), None).expect("Failed to calculate hash"); 48 | }); 49 | }); 50 | } 51 | 52 | criterion_group!(benches, 53 | benchmark_hash_calculation_vec<{16 * 1024 * 1024}, {16 * 1024}>, 54 | benchmark_hash_calculation_vec<{16 * 1024 * 1024}, {1024 * 1024}>, 55 | benchmark_hash_calculation_arr<{16 * 1024 * 1024}, {16 * 1024}>, 56 | benchmark_hash_calculation_arr<{16 * 1024 * 1024}, {1024 * 1024}>, 57 | ); 58 | criterion_main!(benches); 59 | -------------------------------------------------------------------------------- /czkawka_core/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let rust_version = match rustc_version::version_meta() { 3 | Ok(meta) => { 4 | let rust_v = meta.semver.to_string(); 5 | let rust_date = meta.commit_date.unwrap_or_default(); 6 | format!("{rust_v} ({rust_date})") 7 | } 8 | Err(_) => "<unknown>".to_string(), 9 | }; 10 | println!("cargo:rustc-env=RUST_VERSION_INTERNAL={rust_version}"); 11 | 12 | if let Ok(encoded) = std::env::var("CARGO_ENCODED_RUSTFLAGS") { 13 | println!("cargo:rustc-env=UUSED_RUSTFLAGS={encoded}"); 14 | } 15 | 16 | let using_cranelift = 17 | std::env::var("CARGO_PROFILE_RELEASE_CODEGEN_UNITS") == Ok("1".to_string()) || std::env::var("CARGO_PROFILE_DEV_CODEGEN_BACKEND") == Ok("cranelift".to_string()); 18 | 19 | if using_cranelift { 20 | println!("cargo:rustc-env=USING_CRANELIFT=1"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /czkawka_core/data: -------------------------------------------------------------------------------- 1 | ../data/ -------------------------------------------------------------------------------- /czkawka_core/i18n.toml: -------------------------------------------------------------------------------- 1 | # (Required) The language identifier of the language used in the 2 | # source code for gettext system, and the primary fallback language 3 | # (for which all strings must be present) when using the fluent 4 | # system. 5 | fallback_language = "en" 6 | 7 | # Use the fluent localization system. 8 | [fluent] 9 | # (Required) The path to the assets directory. 10 | # The paths inside the assets directory should be structured like so: 11 | # `assets_dir/{language}/{domain}.ftl` 12 | assets_dir = "i18n" 13 | 14 | -------------------------------------------------------------------------------- /czkawka_core/i18n/ar/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = الأصل 3 | core_similarity_very_high = عالية جدا 4 | core_similarity_high = مرتفع 5 | core_similarity_medium = متوسط 6 | core_similarity_small = صغير 7 | core_similarity_very_small = صغير جدا 8 | core_similarity_minimal = الحد الأدنى 9 | core_cannot_open_dir = لا يمكن فتح dir { $dir }، السبب { $reason } 10 | core_cannot_read_entry_dir = لا يمكن قراءة الإدخال في dir { $dir }، السبب { $reason } 11 | core_cannot_read_metadata_dir = لا يمكن قراءة البيانات الوصفية في dir { $dir }، السبب { $reason } 12 | core_file_not_utf8_name = الملف { $name } ليس لديه اسم UTF-8 صالح (قد لا تظهر بعض الأحرف) 13 | core_file_modified_before_epoch = يبدو أن الملف { $name } قد تم تعديله قبل يونكس Epoch 14 | core_folder_modified_before_epoch = يبدو أن المجلد { $name } قد تم تعديله قبل يونكس Epoch 15 | core_file_no_modification_date = غير قادر على الحصول على تاريخ التعديل من الملف { $name }، السبب { $reason } 16 | core_folder_no_modification_date = غير قادر على الحصول على تاريخ التعديل من المجلد { $name }، السبب { $reason } 17 | core_missing_no_chosen_included_directory = يجب توفير دليل واحد على الأقل 18 | core_directory_wildcard_no_supported = الأدلة: البطاقات البرية في المسار غير مدعومة، تجاهل { $path } 19 | core_directory_must_exists = الأدلة: يجب أن يكون مسار المجلد المتوفر موجودا، تجاهل { $path } 20 | core_directory_must_be_directory = الأدلة: المسار المقدم يجب أن يشير إلى الدليل، تجاهل { $path } 21 | core_included_directory_zero_valid_directories = خطأ في الدليل المضمن: لا يوجد حتى مسار واحد صحيح للإدراج المطلوب 22 | core_excluded_directory_pointless_slash = الأدلة: استبعاد / لا معنى له، لأنه يعني أنه لن يتم مسح أي ملفات 23 | core_directory_overlap = الأدلة: جميع الدلائل للبحث عن التداخل مع الدلائل المستبعدة 24 | core_directory_unable_to_get_device_id = الأدلة: غير قادر على الحصول على معرف الجهاز من المجلد { $path } 25 | core_ffmpeg_not_found = لا يمكن العثور على التثبيت الصحيح لFFmpeg 26 | core_ffmpeg_not_found_windows = تأكد من أن ffmpeg.exe و ffprobe.exe متاحان في PATH أو يتم وضعهما مباشرة لنفس المجلد حيث التطبيق قابل للتنفيذ 27 | core_ffmpeg_missing_in_snap = مقاطع فيديو مشابهة لا تعمل حاليا مع السعادة، إذا كنت تريد المساعدة في النظر - { $url } 28 | core_saving_to_cache = تم الحفظ في الملف { $number } إدخالات ذاكرة التخزين المؤقت 29 | core_loading_from_cache = تحميل من ذاكرة التخزين المؤقت { $number } إدخالات 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/bg/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Оригинален 3 | core_similarity_very_high = Много висок 4 | core_similarity_high = Висок 5 | core_similarity_medium = Среден 6 | core_similarity_small = Малък 7 | core_similarity_very_small = Много малък 8 | core_similarity_minimal = Минимален 9 | core_cannot_open_dir = Не може да се отвори папка { $dir }, причината е { $reason } 10 | core_cannot_read_entry_dir = Не може да се прочете папка { $dir }, причината е { $reason } 11 | core_cannot_read_metadata_dir = Не могат да се прочетат мета-данните в папка { $dir }, причината е { $reason } 12 | core_file_not_utf8_name = Файлът { $name } няма валидно UTF-8 име (някои от символите може да не се визуализират) 13 | core_file_modified_before_epoch = Файлът { $name } изглежда да е променен преди Unix Epoc 14 | core_folder_modified_before_epoch = Папка { $name } изглежда да е променена преди Unix Epoc 15 | core_file_no_modification_date = Невъзможно е да се получи променената дата от файл { $name }, причината е { $reason } 16 | core_folder_no_modification_date = Невъзможно е да се извлече променената дата от файл { $name }, причината е { $reason } 17 | core_missing_no_chosen_included_directory = Трябва да се предостави поне една директория 18 | core_directory_wildcard_no_supported = Директории: Не се поддържат заместващи знаци в пътя, игнорирайки { $path } 19 | core_directory_must_exists = Директории: Предоставеният път до папката трябва да съществува, като се игнорира { $path } 20 | core_directory_must_be_directory = Директории: Предоставеният път трябва да сочи към директорията, като не се взема под внимание { $path } 21 | core_included_directory_zero_valid_directories = Включена директория ГРЕШКА: Не е намерен дори един правилен път към включената директория, която се изисква 22 | core_excluded_directory_pointless_slash = Директории: Изключването на / е безсмислено, защото означава, че няма да бъдат сканирани никакви файлове 23 | core_directory_overlap = Директории: Всички директории за търсене се припокриват с изключените директории 24 | core_directory_unable_to_get_device_id = Директории: Невъзможно е да се получи идентификатор на устройството от папка { $path } 25 | core_ffmpeg_not_found = Не мога да намеря правилната инсталация на FFmpeg 26 | core_ffmpeg_not_found_windows = Уверете се, че ffmpeg.exe и ffprobe.exe са налични в PATH или са поставени директно в същата папка, където е изпълнимото приложение 27 | core_ffmpeg_missing_in_snap = Подобни видеоклипове не работят в момента със snap, ако искате помощ, погледнете - { $url } 28 | core_saving_to_cache = Запазени във файл {$number } записи в кеша 29 | core_loading_from_cache = Заредени от кеш { $number } вписвания 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/cs/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Originál 3 | core_similarity_very_high = Velmi vysoká 4 | core_similarity_high = Vysoká 5 | core_similarity_medium = Střední 6 | core_similarity_small = Malá 7 | core_similarity_very_small = Velmi malá 8 | core_similarity_minimal = Minimální 9 | core_cannot_open_dir = Nelze otevřít adresář { $dir }, důvod { $reason } 10 | core_cannot_read_entry_dir = Nelze načíst záznam v adresáři { $dir }, důvod { $reason } 11 | core_cannot_read_metadata_dir = Nelze načíst metadata v adresáři { $dir }, důvod { $reason } 12 | core_file_not_utf8_name = Soubor { $name } nemá platný název UTF-8 (některé znaky nemusí být zobrazeny) 13 | core_file_modified_before_epoch = Soubor { $name } se zdá být upraven před unixovým Epochem (1.1.1970) 14 | core_folder_modified_before_epoch = Složka { $name } se zdá být upravena před unixovým Epochem (1.1.1970) 15 | core_file_no_modification_date = Nelze získat datum úpravy ze souboru { $name }, důvod { $reason } 16 | core_folder_no_modification_date = Nelze získat datum úpravy ze složky { $name }, důvod { $reason } 17 | core_missing_no_chosen_included_directory = Musí být uveden alespoň jeden adresář 18 | core_directory_wildcard_no_supported = Adresáře: Zástupné znaky v cestě nejsou podporovány, ignoruji { $path } 19 | core_directory_must_exists = Adresáře: Poskytnutá cesta ke složce musí existovat, ignoruji { $path } 20 | core_directory_must_be_directory = Adresáře: Poskytnutá cesta musí směřovat do adresáře, ignoruji { $path } 21 | core_included_directory_zero_valid_directories = CHYBA zahrnutí adresáře: Nenalezena ani jedna správná cesta k zahrnutí, která je vyžadována 22 | core_excluded_directory_pointless_slash = Adresáře: Vyloučení / je bezúčelné, protože to znamená, že žádné soubory nebudou naskenovány 23 | core_directory_overlap = Adresáře: Všechny adresáře pro vyhledávání se překrývají s vyloučením adresářů 24 | core_directory_unable_to_get_device_id = Adresáře: Nelze získat ID zařízení ze složky { $path } 25 | core_ffmpeg_not_found = Nelze najít správnou instalaci FFmpeg 26 | core_ffmpeg_not_found_windows = Ujistěte se, že ffmpeg.exe a ffprobe.exe jsou k dispozici v PATH nebo jsou umístěny přímo do stejné složky, kde lze spustit aplikaci 27 | core_ffmpeg_missing_in_snap = Podobná videa v současné době nefungují se snapem, pokud chcete nápovědu sledovat - { $url } 28 | core_saving_to_cache = Uloženo do souboru { $number } položek mezipaměti 29 | core_loading_from_cache = Načteno z { $number } položek keše 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/de/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Original 3 | core_similarity_very_high = Sehr Hoch 4 | core_similarity_high = Hoch 5 | core_similarity_medium = Mittel 6 | core_similarity_small = Klein 7 | core_similarity_very_small = Sehr klein 8 | core_similarity_minimal = Minimal 9 | core_cannot_open_dir = Verzeichnis { $dir } kann nicht geöffnet werden, Grund { $reason } 10 | core_cannot_read_entry_dir = Kann Eintrag in Verzeichnis { $dir } nicht lesen, Grund { $reason } 11 | core_cannot_read_metadata_dir = Metadaten können in Verzeichnis { $dir } nicht gelesen werden, Grund { $reason } 12 | core_file_not_utf8_name = Datei { $name } hat keinen gültigen UTF-8-Namen (einige Zeichen könnten nicht angezeigt werden) 13 | core_file_modified_before_epoch = Datei { $name } scheint vor dieser Unix-Epoche geändert worden zu sein 14 | core_folder_modified_before_epoch = Ordner { $name } scheint vor dieser Unix-Epoche geändert worden zu sein 15 | core_file_no_modification_date = Konnte das Änderungsdatum von Datei { $name } nicht abrufen, Grund { $reason } 16 | core_folder_no_modification_date = Konnte das Änderungsdatum aus dem Ordner { $name } nicht abrufen, Grund { $reason } 17 | core_missing_no_chosen_included_directory = Mindestens ein Verzeichnis muss angegeben werden 18 | core_directory_wildcard_no_supported = Verzeichnisse: Wildcards im Pfad werden nicht unterstützt, { $path } wird ignoriert 19 | core_directory_must_exists = Verzeichnisse: Der angegebene Ordnerpfad muss existieren, { $path } wird ignoriert 20 | core_directory_must_be_directory = Verzeichnisse: Der angegebene Pfad muss auf das Verzeichnis zeigen, { $path } wird ignoriert 21 | core_included_directory_zero_valid_directories = Einbezogenes Verzeichnis-FEHLER: Kein korrekter Pfad gefunden, welcher einbezogen werden soll, was erforderlich ist 22 | core_excluded_directory_pointless_slash = Verzeichnisse: / auszuschließen ist sinnlos, weil somit keine Dateien gescannt werden 23 | core_directory_overlap = Verzeichnisse: Alle zu durchsuchende Verzeichnisse überlappen mit den ausgeschlossenen Verzeichnissen 24 | core_directory_unable_to_get_device_id = Verzeichnisse: Geräte-ID kann nicht aus dem Ordner { $path } geholt werden 25 | core_ffmpeg_not_found = Keine richtige Installation von FFmpeg gefunden 26 | core_ffmpeg_not_found_windows = Stellen Sie sicher, dass ffmpeg.exe und ffprobe.exe in PATH verfügbar sind oder direkt in den gleichen Ordner gelegt werden, in dem die App ausführbar ist 27 | core_ffmpeg_missing_in_snap = Ähnliche Videos funktionieren derzeit nicht mit Snap, wenn du Hilfe möchtest, besuche - { $url } 28 | core_saving_to_cache = { $number } Cache-Einträge in der Datei gespeichert 29 | core_loading_from_cache = { $number } Einträge aus dem Cache geladen 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/el/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Αρχικό 3 | core_similarity_very_high = Πολύ Υψηλή 4 | core_similarity_high = Υψηλή 5 | core_similarity_medium = Μεσαίο 6 | core_similarity_small = Μικρό 7 | core_similarity_very_small = Πολύ Μικρό 8 | core_similarity_minimal = Ελάχιστα 9 | core_cannot_open_dir = Αδυναμία ανοίγματος dir { $dir }, λόγος { $reason } 10 | core_cannot_read_entry_dir = Αδυναμία ανάγνωσης καταχώρησης στον κατάλογο { $dir }, λόγος { $reason } 11 | core_cannot_read_metadata_dir = Αδύνατη η ανάγνωση μεταδεδομένων στον κατάλογο { $dir }, λόγος { $reason } 12 | core_file_not_utf8_name = Το αρχείο { $name } δεν έχει ένα έγκυρο όνομα UTF-8 (ορισμένοι χαρακτήρες μπορεί να μην εμφανίζονται) 13 | core_file_modified_before_epoch = Το { $name } φαίνεται να τροποποιείται πριν το Unix Epoch 14 | core_folder_modified_before_epoch = Ο φάκελος { $name } φαίνεται να τροποποιείται πριν το Unix Epoch 15 | core_file_no_modification_date = Δεν είναι δυνατή η λήψη ημερομηνίας τροποποίησης από το αρχείο { $name }, λόγος { $reason } 16 | core_folder_no_modification_date = Δεν είναι δυνατή η λήψη ημερομηνίας τροποποίησης από το φάκελο { $name }, λόγος { $reason } 17 | core_missing_no_chosen_included_directory = Πρέπει να παρέχεται τουλάχιστον ένας κατάλογος 18 | core_directory_wildcard_no_supported = Κατάλογοι: Δεν υποστηρίζονται μπαλαντέρ στο μονοπάτι, αγνοώντας { $path } 19 | core_directory_must_exists = Κατάλογοι: Η παρεχόμενη διαδρομή φακέλου πρέπει να υπάρχει, αγνοώντας { $path } 20 | core_directory_must_be_directory = Κατάλογοι: Παρέχεται διαδρομή πρέπει να δείχνει στον κατάλογο, αγνοώντας { $path } 21 | core_included_directory_zero_valid_directories = Συμπεριλαμβανόμενος κατάλογος ΣΦΑΛΜΑ: Δεν βρέθηκε ούτε μια σωστή διαδρομή για να συμπεριληφθεί η οποία απαιτείται 22 | core_excluded_directory_pointless_slash = Κατάλογοι: Εξαιρούνται / είναι άσκοπες, επειδή σημαίνει ότι δεν θα σαρωθούν αρχεία 23 | core_directory_overlap = Κατάλογοι: Όλοι οι κατάλογοι για αναζήτηση επικαλύψεων με αποκλεισμένους καταλόγους 24 | core_directory_unable_to_get_device_id = Κατάλογοι: Αδυναμία λήψης id συσκευής από το φάκελο { $path } 25 | core_ffmpeg_not_found = Αδυναμία εύρεσης σωστής εγκατάστασης του FFmpeg 26 | core_ffmpeg_not_found_windows = Να είστε βέβαιος ότι ffmpeg.exe και ffprobe.exe είναι διαθέσιμα σε PATH ή τίθενται απευθείας στον ίδιο φάκελο όπου είναι εκτελέσιμο app 27 | core_ffmpeg_missing_in_snap = Παρόμοια βίντεο δεν λειτουργούν αυτή τη στιγμή με συμπληρωματικό πρόγραμμα, αν θέλετε να δείτε βοήθεια - { $url } 28 | core_saving_to_cache = Αποθηκεύτηκε στο αρχείο καταχωρήσεις { $number } cache 29 | core_loading_from_cache = Φορτώθηκε από καταχωρήσεις της λανθάνουσας μνήμης { $number } 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/en/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Original 3 | core_similarity_very_high = Very High 4 | core_similarity_high = High 5 | core_similarity_medium = Medium 6 | core_similarity_small = Small 7 | core_similarity_very_small = Very Small 8 | core_similarity_minimal = Minimal 9 | 10 | core_cannot_open_dir = Cannot open dir {$dir}, reason {$reason} 11 | core_cannot_read_entry_dir = Cannot read entry in dir {$dir}, reason {$reason} 12 | core_cannot_read_metadata_dir = Cannot read metadata in dir {$dir}, reason {$reason} 13 | core_file_not_utf8_name = File {$name} does not have a valid UTF-8 name (some characters may not be shown) 14 | core_file_modified_before_epoch = File {$name} seems to be modified before Unix Epoch 15 | core_folder_modified_before_epoch = Folder {$name} seems to be modified before Unix Epoch 16 | core_file_no_modification_date = Unable to get modification date from file {$name}, reason {$reason} 17 | core_folder_no_modification_date = Unable to get modification date from folder {$name}, reason {$reason} 18 | 19 | core_missing_no_chosen_included_directory = At least one directory must be provided 20 | core_directory_wildcard_no_supported = Directories: Wildcards in path are not supported, ignoring { $path } 21 | core_directory_must_exists = Directories: Provided folder path must exist, ignoring { $path } 22 | core_directory_must_be_directory = Directories: Provided path must point at the directory, ignoring { $path } 23 | core_included_directory_zero_valid_directories = Included Directory ERROR: Not found even one correct path to included which is required 24 | core_excluded_directory_pointless_slash = Directories: Excluding / is pointless, because it means that no files will be scanned 25 | core_directory_overlap = Directories: All directories to search overlaps with excluded directories 26 | core_directory_unable_to_get_device_id = Directories: Unable to get device id from folder { $path } 27 | 28 | core_ffmpeg_not_found = Cannot find proper installation of FFmpeg 29 | core_ffmpeg_not_found_windows = Be sure that ffmpeg.exe and ffprobe.exe are available in PATH or are put directly to same folder where is app executable 30 | 31 | core_saving_to_cache = Saved to file { $number } cache entries 32 | core_loading_from_cache = Loaded from cache { $number } entries 33 | -------------------------------------------------------------------------------- /czkawka_core/i18n/es-ES/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Original 3 | core_similarity_very_high = Muy alta 4 | core_similarity_high = Alta 5 | core_similarity_medium = Medio 6 | core_similarity_small = Pequeño 7 | core_similarity_very_small = Muy pequeño 8 | core_similarity_minimal = Mínimo 9 | core_cannot_open_dir = No se puede abrir el directorio { $dir }, razón { $reason } 10 | core_cannot_read_entry_dir = No se puede leer la entrada en directorio { $dir }, razón { $reason } 11 | core_cannot_read_metadata_dir = No se pueden leer metadatos en el directorio { $dir }, razón { $reason } 12 | core_file_not_utf8_name = El archivo { $name } no tiene un nombre UTF-8 válido (algunos caracteres pueden no mostrarse) 13 | core_file_modified_before_epoch = El archivo { $name } parece ser modificado antes de Unix Epoch 14 | core_folder_modified_before_epoch = La carpeta { $name } parece ser modificada antes del Epoch Unix 15 | core_file_no_modification_date = No se puede obtener la fecha de modificación del archivo { $name }, razón { $reason } 16 | core_folder_no_modification_date = No se puede obtener la fecha de modificación de la carpeta { $name }, razón { $reason } 17 | core_missing_no_chosen_included_directory = Debe proporcionarse al menos un directorio 18 | core_directory_wildcard_no_supported = Directorios: Los comodines en la ruta no son compatibles, ignorando { $path } 19 | core_directory_must_exists = Directorios: La ruta de la carpeta debe salir, ignorando { $path } 20 | core_directory_must_be_directory = Directorios: La ruta proporcionada debe apuntar al directorio, ignorando { $path } 21 | core_included_directory_zero_valid_directories = ERROR del directorio incluido: No se ha encontrado ni una ruta correcta a incluida que es necesaria 22 | core_excluded_directory_pointless_slash = Directorios: Excluyendo / es inútil, ya que no se analizarán archivos 23 | core_directory_overlap = Directorios: Todos los directorios para buscar superposiciones con directorios excluidos 24 | core_directory_unable_to_get_device_id = Directorios: No se puede obtener el id del dispositivo de la carpeta { $path } 25 | core_ffmpeg_not_found = No se puede encontrar la instalación correcta de FFmpeg 26 | core_ffmpeg_not_found_windows = Asegúrese de que ffmpeg.exe y ffprobe.exe están disponibles en PATH o se colocan directamente en la misma carpeta donde es ejecutable la aplicación 27 | core_ffmpeg_missing_in_snap = Los Videos Similares no funcionan actualmente con el snap, si quieres ayuda mira - { $url } 28 | core_saving_to_cache = Guardado en el archivo { $number } entradas de caché 29 | core_loading_from_cache = Cargado desde { $number } entradas de caché 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/fr/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Originale 3 | core_similarity_very_high = Très haute 4 | core_similarity_high = Haute 5 | core_similarity_medium = Moyenne 6 | core_similarity_small = Basse 7 | core_similarity_very_small = Très basse 8 | core_similarity_minimal = Minimale 9 | core_cannot_open_dir = Impossible d’ouvrir le répertoire { $dir }. Raison : { $reason } 10 | core_cannot_read_entry_dir = Impossible de lire l'entrée dans le répertoire { $dir }. Raison : { $reason } 11 | core_cannot_read_metadata_dir = Impossible de lire les métadonnées dans le répertoire { $dir }. Raison : { $reason } 12 | core_file_not_utf8_name = Le fichier { $name } n'a pas de nom UTF-8 valide (certains caractères peuvent ne pas être affichés) 13 | core_file_modified_before_epoch = Le fichier { $name } semble avoir été modifié avant l'epoch Unix 14 | core_folder_modified_before_epoch = Le dossier { $name } semble avoir été modifié avant l'epoch Unix 15 | core_file_no_modification_date = Impossible d'obtenir la date de modification du fichier { $name }. Raison : { $reason } 16 | core_folder_no_modification_date = Impossible d'obtenir la date de modification du dossier { $name }. Raison : { $reason } 17 | core_missing_no_chosen_included_directory = Au moins un répertoire doit être fourni 18 | core_directory_wildcard_no_supported = Répertoires : les jokers dans le chemin ne sont pas pris en charge. { $path } est ignoré 19 | core_directory_must_exists = Répertoires : le chemin du dossier fourni doit exister. { $path } est ignoré 20 | core_directory_must_be_directory = Répertoires : le chemin fourni doit pointer vers le répertoire, { $path } est ignoré 21 | core_included_directory_zero_valid_directories = ERREUR de répertoire inclus : aucun chemin correct n'a été trouvé alors qu'au moins un est nécessaire 22 | core_excluded_directory_pointless_slash = Répertoires: exclure « / » est inutile car cela signifie qu'aucun fichier ne sera scanné 23 | core_directory_overlap = Répertoires : tous les répertoires dans lesquels rechercher des chevauchements avec des répertoires exclus 24 | core_directory_unable_to_get_device_id = Répertoires : impossible d'obtenir l'ID de l'appareil depuis le dossier { $path } 25 | core_ffmpeg_not_found = Impossible de trouver une installation correcte de FFmpeg 26 | core_ffmpeg_not_found_windows = Assurez-vous que ffmpeg.exe et ffprobe.exe sont disponibles dans PATH ou sont présents dans le même dossier que l'exécutable de l'application 27 | core_ffmpeg_missing_in_snap = Les vidéos similaires ne fonctionnent pas actuellement avec snap. Si vous voulez de l'aide référez vous à - { $url } 28 | core_saving_to_cache = { $number } entrées du cache enregistres dans un fichier 29 | core_loading_from_cache = { $number } entrées chargées depuis le cache 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/it/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Originali 3 | core_similarity_very_high = Altissima 4 | core_similarity_high = Alta 5 | core_similarity_medium = Media 6 | core_similarity_small = Piccola 7 | core_similarity_very_small = Piccolissima 8 | core_similarity_minimal = Minima 9 | core_cannot_open_dir = Impossibile aprire cartella { $dir }, motivo { $reason } 10 | core_cannot_read_entry_dir = Impossibile leggere elemento nella cartella { $dir }, ragione { $reason } 11 | core_cannot_read_metadata_dir = Impossibile leggere metadati nella cartella { $dir }, ragione { $reason } 12 | core_file_not_utf8_name = Il file { $name } non ha un nome UTF-8 valido (alcuni caratteri potrebbero non essere mostrati) 13 | core_file_modified_before_epoch = Il file { $name } sembra essere stato modificato prima dell'Epoca Unix 14 | core_folder_modified_before_epoch = La cartella { $name } sembra essere stato modificata prima dell'Epoca Unix 15 | core_file_no_modification_date = Impossibile recuperare data di modifica dal file { $name }, ragione { $reason } 16 | core_folder_no_modification_date = Impossibile recuperare data di modifica dalla cartella { $name }, ragione { $reason } 17 | core_missing_no_chosen_included_directory = Almeno una directory deve essere fornita 18 | core_directory_wildcard_no_supported = Cartelle: i caratteri jolly nel percorso non sono supportati, ignorando { $path } 19 | core_directory_must_exists = Directories: Il percorso della cartella fornito deve uscire, ignorando { $path } 20 | core_directory_must_be_directory = Directories: Il percorso fornito deve puntare alla directory, ignorando { $path } 21 | core_included_directory_zero_valid_directories = ERRORE Directory incluso: Non trovato nemmeno un percorso corretto incluso che è richiesto 22 | core_excluded_directory_pointless_slash = Cartelle: Escludere / è inutile, perché significa che nessun file verrà scansionato 23 | core_directory_overlap = Directories: Tutte le directory per cercare sovrapposizioni con directory escluse 24 | core_directory_unable_to_get_device_id = Directory: non è possibile ottenere l'id del dispositivo dalla cartella { $path } 25 | core_ffmpeg_not_found = Impossibile trovare la corretta installazione di FFmpeg 26 | core_ffmpeg_not_found_windows = Quando si utilizza Windows essere sicuri che ffmpeg.exe e ffprobe.exe sono disponibili in PATH o sono messi direttamente nella stessa cartella dove è eseguibile l'applicazione 27 | core_ffmpeg_missing_in_snap = Video simili non funzionano attualmente con snap, se si desidera aiutare a guardare - { $url } 28 | core_saving_to_cache = Salvato nel file { $number } voci cache 29 | core_loading_from_cache = Caricato dalla cache { $number } voci 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/ja/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = 新規に作成 3 | core_similarity_very_high = 非常に高い 4 | core_similarity_high = 高い 5 | core_similarity_medium = ミディアム 6 | core_similarity_small = 小 7 | core_similarity_very_small = 非常に小さい 8 | core_similarity_minimal = 最小 9 | core_cannot_open_dir = ディレクトリを開くことができません { $dir }、理由 { $reason } 10 | core_cannot_read_entry_dir = Dir { $dir } でエントリを読み込めません、理由 { $reason } 11 | core_cannot_read_metadata_dir = Dir { $dir } でメタデータを読み込めません、理由 { $reason } 12 | core_file_not_utf8_name = ファイル { $name } に有効な UTF-8 名がありません (一部の文字は表示されない可能性があります) 13 | core_file_modified_before_epoch = ファイル { $name } は Unix Epoch より前に変更されているようです 14 | core_folder_modified_before_epoch = フォルダ { $name } は、Unix Epoch の前に変更されているようです 15 | core_file_no_modification_date = ファイル { $name } から変更日を取得できません、理由 { $reason } 16 | core_folder_no_modification_date = フォルダ { $name } から変更日を取得できません、理由 { $reason } 17 | core_missing_no_chosen_included_directory = 少なくとも 1 つのディレクトリを指定する必要があります。 18 | core_directory_wildcard_no_supported = ディレクトリ: パス内のワイルドカードはサポートされていません。 { $path } を無視してください 19 | core_directory_must_exists = ディレクトリ: 指定されたフォルダパスは、 { $path } を無視して終了する必要があります 20 | core_directory_must_be_directory = ディレクトリ: 指定されたパスはディレクトリを指す必要があります。 { $path } を無視します 21 | core_included_directory_zero_valid_directories = 含まれるディレクトリエラー: 必須の正しいパスが1つも見つかりません 22 | core_excluded_directory_pointless_slash = ディレクトリ: ファイルがスキャンされないことを意味するため、除外/無意味です 23 | core_directory_overlap = ディレクトリ: 除外されたディレクトリとオーバーラップを検索するすべてのディレクトリ 24 | core_directory_unable_to_get_device_id = ディレクトリ: フォルダ { $path } からデバイス ID を取得できません 25 | core_ffmpeg_not_found = 適切なFFmpegのインストールが見つかりません 26 | core_ffmpeg_not_found_windows = ffmpeg.exeとffprobe.exeがPATHで使用できることを確認するか、アプリ実行ファイルのある同じフォルダに直接配置してください。 27 | core_ffmpeg_missing_in_snap = ヘルプを見たい場合は、現在同様のビデオはスナップでは動作しません - { $url } 28 | core_saving_to_cache = { $number } 個のキャッシュエントリをファイルに保存しました 29 | core_loading_from_cache = キャッシュから { $number } 個のエントリが読み込まれました 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/ko/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = 원본 3 | core_similarity_very_high = 매우 높음 4 | core_similarity_high = 높음 5 | core_similarity_medium = 보통 6 | core_similarity_small = 낮음 7 | core_similarity_very_small = 매우 낮음 8 | core_similarity_minimal = 최소 9 | core_cannot_open_dir = { $dir } 디렉터리를 열 수 없습니다. 이유: { $reason } 10 | core_cannot_read_entry_dir = { $dir } 디렉터리를 열 수 없습니다. 이유: { $reason } 11 | core_cannot_read_metadata_dir = { $dir } 디렉터리의 메타데이터를 열 수 없습니다. 이유: { $reason } 12 | core_file_not_utf8_name = 파일 이름 "{ $name }"은 유효한 UTF-8 이름이 아닙니다. 일부 글자가 보이지 않을 수 있습니다. 13 | core_file_modified_before_epoch = { $name } 파일이 Unix 시간 이전에 수정된 것 같습니다. 14 | core_folder_modified_before_epoch = { $name } 폴더가 Unix 시간 이전에 수정된 것 같습니다. 15 | core_file_no_modification_date = { $name } 파일의 수정된 시각을 읽을 수 없습니다. 이유: { $reason } 16 | core_folder_no_modification_date = { $name } 폴더의 수정된 시각을 읽을 수 없습니다. 이유: { $reason } 17 | core_missing_no_chosen_included_directory = 적어도 1개 이상의 디렉터리가 주어져야 합니다. 18 | core_directory_wildcard_no_supported = 디렉터리: 경로에는 와일드 카드가 지원되지 않습니다. "{ $path }"는 무시됩니다. 19 | core_directory_must_exists = 디렉터리: 주어진 폴더 경로는 반드시 존재해야 합니다. "{ $path }"는 무시됩니다. 20 | core_directory_must_be_directory = 디렉터리: 주어진 경로는 디렉터리를 가리켜야 합니다. "{ $path }"는 무시됩니다. 21 | core_included_directory_zero_valid_directories = 검색 대상 디렉터리 오류: 적어도 1개 이상의 유효한 경로가 주어져야 합니다. 유효한 경로가 하나도 없습니다. 22 | core_excluded_directory_pointless_slash = 디렉터리: "/"를 제외하는 것은 아무런 파일도 스캔하지 않는다는 것이므로, 의미가 없습니다. 23 | core_directory_overlap = 디렉터리: 모든 주어진 경로가 검색 제외 경로와 겹칩니다. 24 | core_directory_unable_to_get_device_id = 디렉터리: { $path }의 장치 ID를 가져올 수 없습니다. 25 | core_ffmpeg_not_found = 유효한 FFmpeg 설치를 발견하지 못했습니다. 26 | core_ffmpeg_not_found_windows = ffmpeg.exe와 ffprobe.exe가 시스템 변수 PATH에서 사용 가능하거나, 이 프로그램의 경로와 같은 곳에 위치하는지 확인하세요. 27 | core_ffmpeg_missing_in_snap = 현재 ffmpeg snap에서는 유사한 영상 검색이 지원되지 않습니다. 더 많은 정보는 { $url }에서 확인하세요. 28 | core_saving_to_cache = { $number }개의 파일을 캐시에 저장했습니다. 29 | core_loading_from_cache = { $number }개의 파일을 캐시에서 불러왔습니다. 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/nl/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Origineel 3 | core_similarity_very_high = Zeer hoog 4 | core_similarity_high = hoog 5 | core_similarity_medium = Middelgroot 6 | core_similarity_small = Klein 7 | core_similarity_very_small = Zeer Klein 8 | core_similarity_minimal = Minimaal 9 | core_cannot_open_dir = Kan dir { $dir }niet openen, reden { $reason } 10 | core_cannot_read_entry_dir = Kan invoer niet lezen in map { $dir }, reden { $reason } 11 | core_cannot_read_metadata_dir = Kan metadata niet lezen in map { $dir }, reden { $reason } 12 | core_file_not_utf8_name = Bestand { $name } heeft geen geldige UTF-8-naam (sommige tekens kunnen niet worden getoond) 13 | core_file_modified_before_epoch = Het bestand { $name } lijkt aangepast te zijn voor Unix Epoch 14 | core_folder_modified_before_epoch = Map { $name } lijkt aangepast te zijn voor Unix Epoch 15 | core_file_no_modification_date = Niet in staat om de datum van bestand { $name }te krijgen, reden { $reason } 16 | core_folder_no_modification_date = Niet in staat om wijzigingsdatum van map { $name }te krijgen, reden { $reason } 17 | core_missing_no_chosen_included_directory = Ten minste één map moet worden opgegeven 18 | core_directory_wildcard_no_supported = Maps: Wildcards op pad worden niet ondersteund, negeer { $path } 19 | core_directory_must_exists = Maps: Opgegeven mappad moet bestaan, afwijzend { $path } 20 | core_directory_must_be_directory = Directories: Het opgegeven pad moet naar de map wijzen, { $path } wordt genegeerd 21 | core_included_directory_zero_valid_directories = Inclusief map FOUT: Er is niet één juist pad gevonden naar de map die vereist is 22 | core_excluded_directory_pointless_slash = Maps: Uitsluiten/is zinloos, omdat er geen bestanden worden gescand 23 | core_directory_overlap = Maps: alle mappen om overlappingen te zoeken met uitgesloten mappen 24 | core_directory_unable_to_get_device_id = Maps: Kan apparaat-id niet ophalen uit map { $path } 25 | core_ffmpeg_not_found = Kan de juiste installatie van FFmpeg niet vinden 26 | core_ffmpeg_not_found_windows = Zorg ervoor dat ffmpeg.exe en ffprobe.exe beschikbaar zijn in PATH of direct in dezelfde map geplaatst zijn waar de app uitvoerbaar is 27 | core_ffmpeg_missing_in_snap = Vergelijkbare video's werken momenteel niet met snap, als je wilt helpen kijken naar - { $url } 28 | core_saving_to_cache = Opgeslagen in bestand { $number } cache items 29 | core_loading_from_cache = Geladen uit cache { $number } items 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/no/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Opprinnelig 3 | core_similarity_very_high = Veldig høy 4 | core_similarity_high = Høy 5 | core_similarity_medium = Middels 6 | core_similarity_small = Liten 7 | core_similarity_very_small = Veldig liten 8 | core_similarity_minimal = Minimal 9 | core_cannot_open_dir = Kan ikke åpne dir { $dir }, årsak { $reason } 10 | core_cannot_read_entry_dir = Kan ikke lese oppføringen i dir { $dir }, årsak { $reason } 11 | core_cannot_read_metadata_dir = Kan ikke lese metadata i dir { $dir }, årsak { $reason } 12 | core_file_not_utf8_name = Filen { $name } har ikke et gyldig UTF-8-navn (noen tegn kan ikke vises) 13 | core_file_modified_before_epoch = Filen { $name } ser ut til å bli endret før Unix Epoch 14 | core_folder_modified_before_epoch = Mappen { $name } ser ut til å bli endret før Unix Epoch 15 | core_file_no_modification_date = Klarte ikke å hente endringsdato fra filen { $name }. Årsak { $reason } 16 | core_folder_no_modification_date = Klarte ikke å hente endringsdato fra mappen { $name }. Årsak { $reason } 17 | core_missing_no_chosen_included_directory = Minst en katalog må angis 18 | core_directory_wildcard_no_supported = Kataloger: Jokertegn i stien støttes ikke, ignorerer { $path } 19 | core_directory_must_exists = Kataloger: Angitt sti for mappe må eksistere. Ignorerer { $path } 20 | core_directory_must_be_directory = Kataloger: Angitt sti må peke på mappen. Ignorerer { $path } 21 | core_included_directory_zero_valid_directories = Feil med inkludert katalog: Fant ikke én eneste sti til den inkluderte mappen, noe som er påkrevd 22 | core_excluded_directory_pointless_slash = Kataloger: Ekskludere / er poengløst, fordi det betyr at ingen filer vil bli skannet 23 | core_directory_overlap = Kataloger: Alle kataloger å søke overlapper med ekskluderte mapper 24 | core_directory_unable_to_get_device_id = Mapper: Kan ikke hente enhets id fra mappen { $path } 25 | core_ffmpeg_not_found = Klarte ikke å finne riktig installasjon av FFmpeg 26 | core_ffmpeg_not_found_windows = Pass på at ffmpeg.exe og ffprobe.exe er tilgjengelig i PATH eller plasseres direkte i samme mappe som appen kan kjøres 27 | core_ffmpeg_missing_in_snap = Lignende videoer fungerer ikke for øyeblikket med snap. Hvis du vil ha hjelp kan du se her - { $url } 28 | core_saving_to_cache = Lagret i filen { $number } cache-oppføringer 29 | core_loading_from_cache = Lastet fra hurtigbuffer { $number } oppføringer 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/pl/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Oryginalny 3 | core_similarity_very_high = Bardzo Duże 4 | core_similarity_high = Duże 5 | core_similarity_medium = Średnie 6 | core_similarity_small = Małe 7 | core_similarity_very_small = Bardzo Małe 8 | core_similarity_minimal = Minimalne 9 | core_cannot_open_dir = Nie można otworzyć folderu { $dir }, powód { $reason } 10 | core_cannot_read_entry_dir = Nie można odczytać danych z folderu { $dir }, powód { $reason } 11 | core_cannot_read_metadata_dir = Nie można odczytać metadanych folderu { $dir }, powód { $reason } 12 | core_file_not_utf8_name = Plik { $name } nie posiada nazwy zakodowanej za pomocą UTF-8(niektóre znaki mogą się nie wyświetlać) 13 | core_file_modified_before_epoch = Plik { $name } ma datę modyfikacji sprzed epoki unixa 14 | core_folder_modified_before_epoch = Folder { $name } ma datę modyfikacji sprzed epoki unixa 15 | core_file_no_modification_date = Nie udało się pobrać daty modyfikacji z pliku { $name }, powód { $reason } 16 | core_folder_no_modification_date = Nie udało się pobrać daty modyfikacji z folderu { $name }, powód { $reason } 17 | core_missing_no_chosen_included_directory = Należy podać co najmniej jeden katalog 18 | core_directory_wildcard_no_supported = Katalogi: Wildcard na ścieżce nie są obsługiwane, ignorowanie { $path } 19 | core_directory_must_exists = Katalogi: Podana ścieżka do folderu musi istnieć, ignorowanie { $path } 20 | core_directory_must_be_directory = Katalogi: Podana ścieżka musi wskazywać na katalog, ignorowanie { $path } 21 | core_included_directory_zero_valid_directories = Błąd katalogów do przeszukiwania: Nie znaleziono nawet jednej poprawnej ścieżki do przeszukania 22 | core_excluded_directory_pointless_slash = Katalogi: Wykluczanie folderu / jest bezcelowe, ponieważ oznacza to, że żadne pliki nie zostaną sprawdzone 23 | core_directory_overlap = Katalogi: Wszystkie katalogi do wyszukiwania pokrywają się z wykluczonymi 24 | core_directory_unable_to_get_device_id = Katalogi: Nie można uzyskać identyfikatora urządzenia z folderu { $path } 25 | core_ffmpeg_not_found = Nie można odnaleźć poprawnej instalacji FFmpeg 26 | core_ffmpeg_not_found_windows = Upewnij się, że ffmpeg.exe i ffprobe.exe są dostępne w PATH lub są umieszczone bezpośrednio w tym samym folderze, w którym aplikacja jest uruchamiana. 27 | core_ffmpeg_missing_in_snap = Wyszukiwanie podobnych filmów nie działa obecnie w snapach, jeśli chcesz pomóc spójrz na - { $url } 28 | core_saving_to_cache = Zapisano do pliku { $number } obiektów 29 | core_loading_from_cache = Załadowano z pamięci podręcznej { $number } obiektów 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/pt-BR/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Original 3 | core_similarity_very_high = Muito alto 4 | core_similarity_high = alta 5 | core_similarity_medium = Média 6 | core_similarity_small = Pequeno 7 | core_similarity_very_small = Muito Pequeno 8 | core_similarity_minimal = Mínimo 9 | core_cannot_open_dir = Não é possível abrir o dir { $dir }, razão { $reason } 10 | core_cannot_read_entry_dir = Não é possível ler a entrada no diretório { $dir }, razão { $reason } 11 | core_cannot_read_metadata_dir = Não é possível ler os metadados no diretório { $dir }, razão { $reason } 12 | core_file_not_utf8_name = O arquivo { $name } não possui um nome UTF-8 válido (alguns caracteres não podem ser exibidos) 13 | core_file_modified_before_epoch = O arquivo { $name } parece ser modificado antes do Epoch Unix 14 | core_folder_modified_before_epoch = Pasta { $name } parece ser modificada antes do Epoch Unix 15 | core_file_no_modification_date = Não é possível obter a data de modificação do arquivo { $name }, motivo { $reason } 16 | core_folder_no_modification_date = Não é possível obter a data de modificação da pasta { $name }, motivo { $reason } 17 | core_missing_no_chosen_included_directory = Pelo menos um diretório deve ser fornecido 18 | core_directory_wildcard_no_supported = Directorias: Caracteres curinga no caminho não são suportados, ignorando { $path } 19 | core_directory_must_exists = Diretórios: Caminho da pasta fornecida deve existir, ignorando { $path } 20 | core_directory_must_be_directory = Directorias: Caminho fornecido deve apontar para o diretório, ignorando { $path } 21 | core_included_directory_zero_valid_directories = ERRO do Diretório incluído: Não foi encontrado nenhum caminho correto que é necessário incluir 22 | core_excluded_directory_pointless_slash = Directorias: Excluir / não faz sentido, porque significa que nenhum arquivo será escaneado 23 | core_directory_overlap = Diretórios: Todos os diretórios para pesquisar sobreposições com diretórios excluídos 24 | core_directory_unable_to_get_device_id = Directorias: Não foi possível obter o dispositivo de ajuda da pasta { $path } 25 | core_ffmpeg_not_found = Instalação adequada do FFmpeg não encontrada 26 | core_ffmpeg_not_found_windows = Certifique-se de que o ffmpeg.exe e ffprobe.exe estão disponíveis no PATH ou são colocados diretamente na mesma pasta onde o aplicativo é executável 27 | core_ffmpeg_missing_in_snap = Vídeos similares não funcionam atualmente com o snap, se você quiser ajudar a olhar - { $url } 28 | core_saving_to_cache = Salvo no arquivo { $number } entradas de cache 29 | core_loading_from_cache = Foram carregados "{ $number }" dados do arquivo de ‘cache’ 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/pt-PT/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Original 3 | core_similarity_very_high = Muito alto 4 | core_similarity_high = Alto 5 | core_similarity_medium = Média 6 | core_similarity_small = Pequeno 7 | core_similarity_very_small = Muito Pequeno 8 | core_similarity_minimal = Mínimo 9 | core_cannot_open_dir = Não é possível abrir o diretório { $dir }, razão { $reason } 10 | core_cannot_read_entry_dir = Não é possível ler a entrada no diretório { $dir }, razão { $reason } 11 | core_cannot_read_metadata_dir = Não é possível ler os metadados no diretório { $dir }, razão { $reason } 12 | core_file_not_utf8_name = Arquivo { $name } não tem nome UTF-8 válido (alguns caracteres não podem ser exibidos) 13 | core_file_modified_before_epoch = Arquivo { $name } parece ser modificado antes do Epoch Unix 14 | core_folder_modified_before_epoch = A pasta { $name } parece ser modificada antes do Epoch Unix 15 | core_file_no_modification_date = Não foi possível obter a data de modificação do arquivo { $name }, motivo { $reason } 16 | core_folder_no_modification_date = Não foi possível obter a data de modificação da pasta { $name }, motivo { $reason } 17 | core_missing_no_chosen_included_directory = Pelo menos um diretório deve ser fornecido 18 | core_directory_wildcard_no_supported = Directorias: Caracteres curinga no caminho não são suportados, ignorando { $path } 19 | core_directory_must_exists = Directórios: Caminho da pasta fornecida deve sair, ignorando { $path } 20 | core_directory_must_be_directory = Diretórios: Caminho fornecido deve apontar para o diretório, ignorando { $path } 21 | core_included_directory_zero_valid_directories = ERRO do Diretório incluído: Não foi encontrado nenhum caminho correto que é necessário incluir 22 | core_excluded_directory_pointless_slash = Directorias: Excluir / não faz sentido, porque significa que nenhum arquivo será escaneado 23 | core_directory_overlap = Diretórios: Todos os diretórios para pesquisar sobreposições com diretórios excluídos 24 | core_directory_unable_to_get_device_id = Directorias: Não foi possível obter o dispositivo id da pasta { $path } 25 | core_ffmpeg_not_found = Instalação adequada do FFmpeg não encontrada 26 | core_ffmpeg_not_found_windows = Certifique-se de que o ffmpeg.exe e ffprobe.exe estão disponíveis no PATH ou são colocados diretamente na mesma pasta onde o aplicativo é executável 27 | core_ffmpeg_missing_in_snap = Vídeos similares não funcionam atualmente com o snap, se você quiser ajudar a olhar - { $url } 28 | core_saving_to_cache = Salvo no arquivo { $number } entradas de cache 29 | core_loading_from_cache = Carregado do cache { $number } entradas 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/ro/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Originală 3 | core_similarity_very_high = Foarte Mare 4 | core_similarity_high = Ridicat 5 | core_similarity_medium = Medie 6 | core_similarity_small = Mică 7 | core_similarity_very_small = Foarte mic 8 | core_similarity_minimal = Minimă 9 | core_cannot_open_dir = Nu se poate deschide dir { $dir }, motiv { $reason } 10 | core_cannot_read_entry_dir = Nu se poate citi intrarea în dir { $dir }, motivul { $reason } 11 | core_cannot_read_metadata_dir = Metadatele nu pot fi citite în dir { $dir }, motivul { $reason } 12 | core_file_not_utf8_name = Fișierul { $name } nu are un nume valid UTF-8 (este posibil ca unele caractere să nu fie afișate) 13 | core_file_modified_before_epoch = Fișierul { $name } pare să fie modificat înainte de Epoch Unix 14 | core_folder_modified_before_epoch = Dosarul { $name } pare să fie modificat înainte de Epoc Unix 15 | core_file_no_modification_date = Imposibil de obținut data modificării din fișierul { $name }, motivul { $reason } 16 | core_folder_no_modification_date = Imposibil de obținut data modificării din dosarul { $name }, motivul { $reason } 17 | core_missing_no_chosen_included_directory = Trebuie furnizat cel puțin un director 18 | core_directory_wildcard_no_supported = Directoare: Wildcards pe cale nu sunt acceptate, ignorând { $path } 19 | core_directory_must_exists = Directoare: Calea dosarului furnizat trebuie să existe, ignorând { $path } 20 | core_directory_must_be_directory = Directoare: Calea specificată trebuie să indice în director, ignorând { $path } 21 | core_included_directory_zero_valid_directories = EROARE din Director inclusă: Nici măcar o cale corectă de inclus, care este necesară 22 | core_excluded_directory_pointless_slash = Directoare: Excludere / este inutilă, deoarece înseamnă că niciun fișier nu va fi scanat 23 | core_directory_overlap = Directoare: Toate directoarele pentru a căuta suprapuneri cu directoarele excluse 24 | core_directory_unable_to_get_device_id = Directoare: Imposibil de obținut ID-ul dispozitivului din folderul { $path } 25 | core_ffmpeg_not_found = Nu se poate găsi instalarea corectă a FFmpeg 26 | core_ffmpeg_not_found_windows = Asigurați-vă că ffmpeg.exe și ffprobe.exe sunt disponibile în PATH sau sunt puse direct în același folder unde este executabilă aplicația 27 | core_ffmpeg_missing_in_snap = Videoclipuri similare nu funcționează în prezent cu ancorare, dacă doriți să vă uitați - { $url } 28 | core_saving_to_cache = Intrări cache salvate în fişierul { $number } 29 | core_loading_from_cache = Încărcat din geocutia { $number } 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/ru/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Оригинальное 3 | core_similarity_very_high = Очень высокое 4 | core_similarity_high = Высокое 5 | core_similarity_medium = Среднее 6 | core_similarity_small = Низкое 7 | core_similarity_very_small = Очень низкое 8 | core_similarity_minimal = Минимальное 9 | core_cannot_open_dir = Невозможно открыть каталог { $dir }, причина: { $reason } 10 | core_cannot_read_entry_dir = Невозможно прочитать запись в директории { $dir }, причина: { $reason } 11 | core_cannot_read_metadata_dir = Невозможно прочитать метаданные в директории { $dir }, причина: { $reason } 12 | core_file_not_utf8_name = У файла { $name } неверное имя UTF-8 (некоторые символы могут не отображаться) 13 | core_file_modified_before_epoch = Файл { $name }, кажется, изменён до начала эпохи Unix 14 | core_folder_modified_before_epoch = Папка { $name }, кажется, изменена до начала эпохи Unix 15 | core_file_no_modification_date = Не удаётся получить дату изменения из файла { $name }, причина: { $reason } 16 | core_folder_no_modification_date = Не удаётся получить дату изменения из папки { $name }, причина: { $reason } 17 | core_missing_no_chosen_included_directory = Должен быть указан хотя бы один каталог 18 | core_directory_wildcard_no_supported = Директории: Не поддерживаются маски в путях, будет проигнорирован { $path } 19 | core_directory_must_exists = Директории: Указанный путь к папке должен существовать, будет проигнорирован{ $path } 20 | core_directory_must_be_directory = Директории: Указанный путь должен указывать на директорию, будет проигнорирован { $path } 21 | core_included_directory_zero_valid_directories = Включённый каталог, ОШИБКА: Не найдено ни одного корректного пути для включения в список поиска — обязательно добавить хотя бы один 22 | core_excluded_directory_pointless_slash = Директории: Исключение корневой папки «/» бессмысленно, потому что в таком случае ни один файл не будет просканирован 23 | core_directory_overlap = Каталоги: Все директории для поиска также присутствуют в списке исключённых каталогов 24 | core_directory_unable_to_get_device_id = Каталоги: Не удалось получить идентификатор устройства из папки { $path } 25 | core_ffmpeg_not_found = Не удалось найти путь, содержащий корректную инсталляцию FFmpeg 26 | core_ffmpeg_not_found_windows = Убедитесь, что ffmpeg.exe и ffprobe.exe доступны в PATH или находятся в той же папке, где это исполняемый файл 27 | core_ffmpeg_missing_in_snap = Функция поиска похожих видео пока не работает — если хотите помочь проекту, см. { $url } 28 | core_saving_to_cache = Сохранено в файл записей кэша: { $number } 29 | core_loading_from_cache = Загружено записей из кэша: { $number } 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/sv-SE/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Ursprunglig 3 | core_similarity_very_high = Mycket Hög 4 | core_similarity_high = Hög 5 | core_similarity_medium = Mellan 6 | core_similarity_small = Litet 7 | core_similarity_very_small = Väldigt Liten 8 | core_similarity_minimal = Minimalt 9 | core_cannot_open_dir = Kan inte öppna dir { $dir }anledning { $reason } 10 | core_cannot_read_entry_dir = Kan inte läsa post i dir { $dir }, anledning { $reason } 11 | core_cannot_read_metadata_dir = Kan inte läsa metadata i dir { $dir }, anledning { $reason } 12 | core_file_not_utf8_name = Filen { $name } har inte ett giltigt UTF-8-namn (vissa tecken kan inte visas) 13 | core_file_modified_before_epoch = Filen { $name } verkar ändras innan Unix Epoch 14 | core_folder_modified_before_epoch = Mappen { $name } verkar ändras innan Unix Epoch 15 | core_file_no_modification_date = Det går inte att hämta ändringsdatum från filen { $name }, anledning { $reason } 16 | core_folder_no_modification_date = Det går inte att hämta ändringsdatum från mappen { $name }, anledning { $reason } 17 | core_missing_no_chosen_included_directory = Minst en katalog måste tillhandahållas 18 | core_directory_wildcard_no_supported = Kataloger: Wildcards i sökvägen stöds inte, ignorerar { $path } 19 | core_directory_must_exists = Kataloger: Tillhandahållen mappsökväg måste finnas, ignorerar { $path } 20 | core_directory_must_be_directory = Kataloger: Tillhandahållen sökväg måste peka på katalogen, ignorerar { $path } 21 | core_included_directory_zero_valid_directories = Inkluderad katalog FEL: Hittas inte ens en korrekt sökväg till inkluderad som krävs 22 | core_excluded_directory_pointless_slash = Kataloger: Exklusive / är meningslös, eftersom det innebär att inga filer kommer att skannas 23 | core_directory_overlap = Kataloger: Alla kataloger att söka överlappar med uteslutna kataloger 24 | core_directory_unable_to_get_device_id = Kataloger: Det går inte att hämta enhets-id från mappen { $path } 25 | core_ffmpeg_not_found = Kan inte hitta rätt installation av FFmpeg 26 | core_ffmpeg_not_found_windows = Se till att ffmpeg.exe och ffprobe.exe är tillgängliga i PATH eller sätts direkt till samma mapp där är app körbar 27 | core_ffmpeg_missing_in_snap = Liknande videor fungerar inte just nu med snap, om du vill ha hjälp att titta på - { $url } 28 | core_saving_to_cache = Sparad i filen { $number } cacheposter 29 | core_loading_from_cache = Laddad från cache { $number } poster 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/tr/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Asıl 3 | core_similarity_very_high = Çok Yüksek 4 | core_similarity_high = Yüksek 5 | core_similarity_medium = Orta 6 | core_similarity_small = Düşük 7 | core_similarity_very_small = Çok Düşük 8 | core_similarity_minimal = Aşırı Düşük 9 | core_cannot_open_dir = { $dir } dizini açılamıyor, nedeni: { $reason } 10 | core_cannot_read_entry_dir = { $dir } dizinindeki girdi okunamıyor, nedeni: { $reason } 11 | core_cannot_read_metadata_dir = { $dir } dizinindeki metaveri okunamıyor, nedei: { $reason } 12 | core_file_not_utf8_name = { $name } dosyasının geçerli bir UTF-8 adı yok (kimi karakterler gösterilemeyebilir) 13 | core_file_modified_before_epoch = { $name } dosyası Unix Epoch'tan önce değiştirilmiş gibi görünüyor. 14 | core_folder_modified_before_epoch = { $name } klasörü Unix Epoch'tan önce değiştirilmiş gibi görünüyor. 15 | core_file_no_modification_date = { $name } dosyasının değişiklik tarihine erişilemiyor, nedeni: { $reason } 16 | core_folder_no_modification_date = { $name } klasörünün değişiklik tarihine erişilemiyor, nedeni: { $reason } 17 | core_missing_no_chosen_included_directory = "Aranacak Dizinler" listesinde en az bir dizin yer almalıdır. 18 | core_directory_wildcard_no_supported = Dizinler: Yol adında joker karakterler desteklenmez, { $path } yok sayıldı. 19 | core_directory_must_exists = Dizinler: Girilen klasör yolu var olmalı, { $path } yok sayıldı. 20 | core_directory_must_be_directory = Dizinler: Girilen yol bir dizini göstermelidir, { $path } yok sayıldı. 21 | core_included_directory_zero_valid_directories = "Aranacak Dizinler" listesinde HATA: Tarama yapılması için gerekli olan tek bir doğru yol bile bulunamadı. 22 | core_excluded_directory_pointless_slash = Dizinler: "/" kök dizinini hariç tutmak anlamsızdır, çünkü bu hiçbir dosyanın taranmayacağı anlamına gelir. 23 | core_directory_overlap = Dizinler: Aranacak tüm dizinler, hariç tutulan dizinlerle çakışıyor. 24 | core_directory_unable_to_get_device_id = Dizinler: { $path } klasörünün aygıt kimliği bilgisine erişilemiyor. 25 | core_ffmpeg_not_found = FFmpeg'in uygun kurulumu bulunamıyor. 26 | core_ffmpeg_not_found_windows = "ffmpeg(.exe)" ve "ffprobe(.exe)" uygulamalarının PATH dizininde ya da uygulamanın doğrudan yürütüldüğü dizinde yer aldığından ve 'yürütülebilir' olarak işaretlendiğinden emin olun. 27 | core_ffmpeg_missing_in_snap = Benzer Videolar şu anda snap ile çalışmıyor, eğer yardım istiyorsanız - { $url } 28 | core_saving_to_cache = { $number } adet önbellek kaydı dosyaya kaydedildi 29 | core_loading_from_cache = Önbellekten { $number } adet kayıt yüklendi 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/uk/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = Оригінал 3 | core_similarity_very_high = Дуже висока 4 | core_similarity_high = Висока 5 | core_similarity_medium = Середня 6 | core_similarity_small = Низька 7 | core_similarity_very_small = Дуже низька 8 | core_similarity_minimal = Мінімальна 9 | core_cannot_open_dir = Не вдалося відкрити каталог { $dir }, причина: { $reason } 10 | core_cannot_read_entry_dir = Не вдалося прочитати запис в каталозі { $dir }, причина: { $reason } 11 | core_cannot_read_metadata_dir = Не вдалося прочитати метадані в каталозі { $dir }, причина: { $reason } 12 | core_file_not_utf8_name = Файл { $name } не має припустимого імені UTF-8 (деякі символи не можуть бути показані) 13 | core_file_modified_before_epoch = Файл { $name }, здається, змінено до початку епохи Unix 14 | core_folder_modified_before_epoch = Папка { $name }, здається, змінена до початку епохи Unix 15 | core_file_no_modification_date = Не вдалося отримати дату модифікації з файлу { $name }, причина: { $reason } 16 | core_folder_no_modification_date = Не вдалося отримати дату модифікації з каталогу { $name }, причина: { $reason } 17 | core_missing_no_chosen_included_directory = Необхідно вказати принаймні один каталог 18 | core_directory_wildcard_no_supported = Директорії: Не підтримуються маски у шляхах, буде проігнорован { $path } 19 | core_directory_must_exists = Директорії: Вказаний шлях до папки має існувати, буде проігнорован { $path } 20 | core_directory_must_be_directory = Директорії: Вказаний шлях повинен вказувати на директорію, буде проігнорован { $path } 21 | core_included_directory_zero_valid_directories = Включений каталог, ПОМИЛКА: Не знайдено жодного коректного шляху для включення до списку пошуку — обов'язково додати хоча б один 22 | core_excluded_directory_pointless_slash = Директорії: Виключення кореневого каталогу «/» не має сенсу, тому що в такому разі жоден файл не буде просканований 23 | core_directory_overlap = Каталоги: Усі директорії для пошуку також присутні у списку виключених каталогів 24 | core_directory_unable_to_get_device_id = Каталоги: Не вдалося отримати ідентифікатор пристрою з папки { $path } 25 | core_ffmpeg_not_found = Неможливо знайти шлях, що містить коректну інсталяцію FFmpeg 26 | core_ffmpeg_not_found_windows = Будьте впевнені, що ffmpeg.exe і ffprobe.exe доступні в PATH або прямо в тій же папці, де є виконуваний додаток 27 | core_ffmpeg_missing_in_snap = Функція пошуку схожих відео поки не працює — якщо хочете допомогти проекту, див. {$url} 28 | core_saving_to_cache = Збережено записів кешу у файл: { $number } 29 | core_loading_from_cache = Завантажено записів з кешу: { $number } 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/zh-CN/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = 原版 3 | core_similarity_very_high = 非常高 4 | core_similarity_high = 高 5 | core_similarity_medium = 中 6 | core_similarity_small = 小的 7 | core_similarity_very_small = 非常小 8 | core_similarity_minimal = 最小化 9 | core_cannot_open_dir = 无法打开目录 { $dir },因为 { $reason } 10 | core_cannot_read_entry_dir = 无法在目录 { $dir } 中读取条目,因为 { $reason } 11 | core_cannot_read_metadata_dir = 无法读取目录 { $dir } 中的元数据,因为 { $reason } 12 | core_file_not_utf8_name = 文件 { $name } 没有有效的 UTF-8 名称 (可能无法显示一些字符) 13 | core_file_modified_before_epoch = 文件 { $name } 似乎在 Unix Epoch 之前被修改过 14 | core_folder_modified_before_epoch = 文件夹 { $name } 似乎在 Unix Epoch 之前被修改过 15 | core_file_no_modification_date = 无法从文件 { $name } 获取修改日期,因为 { $reason } 16 | core_folder_no_modification_date = 无法从文件夹 { $name } 获取修改日期,因为 { $reason } 17 | core_missing_no_chosen_included_directory = 必须至少提供一个目录 18 | core_directory_wildcard_no_supported = 目录:不支持路径中的通配符,忽略 { $path } 19 | core_directory_must_exists = 目录:提供的文件夹路径必须退出,忽略 { $path } 20 | core_directory_must_be_directory = 目录:提供的路径必须指向目录,忽略 { $path } 21 | core_included_directory_zero_valid_directories = 包括目录错误:即使找不到一个需要包含的正确路径 22 | core_excluded_directory_pointless_slash = 目录:不包括 / 无意义,因为它意味着没有文件将被扫描 23 | core_directory_overlap = 目录:所有要搜索与排除目录重叠的目录 24 | core_directory_unable_to_get_device_id = 目录:无法从文件夹 { $path } 获取设备 id 25 | core_ffmpeg_not_found = FFmpeg未被正确安装 26 | core_ffmpeg_not_found_windows = 请确保 ffmpeg.exe 和 ffprobe.exe 在 PATH 中可用,或者直接放入应用可执行文件的同一文件夹中 27 | core_ffmpeg_missing_in_snap = 类似的视频目前不适用于快照,如果您想要帮助查看- { $url } 28 | core_saving_to_cache = 保存到文件 { $number } 个缓存条目 29 | core_loading_from_cache = 从缓存加载 { $number } 个条目 30 | -------------------------------------------------------------------------------- /czkawka_core/i18n/zh-TW/czkawka_core.ftl: -------------------------------------------------------------------------------- 1 | # Core 2 | core_similarity_original = 原始 3 | core_similarity_very_high = 極高 4 | core_similarity_high = 高 5 | core_similarity_medium = 中等 6 | core_similarity_small = 小 7 | core_similarity_very_small = 非常小 8 | core_similarity_minimal = 最小 9 | core_cannot_open_dir = 無法開啟目錄 { $dir },原因是 { $reason } 10 | core_cannot_read_entry_dir = 無法讀取目錄 { $dir } 中的項目,原因是 { $reason } 11 | core_cannot_read_metadata_dir = 無法讀取目錄 { $dir } 的中繼資料,原因是 { $reason } 12 | core_file_not_utf8_name = 檔案 { $name } 名稱非有效的 UTF-8 格式(部分字元可能無法顯示) 13 | core_file_modified_before_epoch = 檔案 { $name } 似乎在 Unix Epoch 之前就已被修改 14 | core_folder_modified_before_epoch = 資料夾 { $name } 似乎在 Unix Epoch 之前就已被修改 15 | core_file_no_modification_date = 無法取得檔案 { $name } 的修改日期,原因是 { $reason } 16 | core_folder_no_modification_date = 無法取得資料夾 { $name } 的修改日期,原因是 { $reason } 17 | core_missing_no_chosen_included_directory = 必須至少選擇一個目錄 18 | core_directory_wildcard_no_supported = 目錄:不支援路徑中的萬用字元,已忽略 { $path } 19 | core_directory_must_exists = 目錄:所提供的資料夾路徑必須存在,已忽略 { $path } 20 | core_directory_must_be_directory = 目錄:所提供的路徑必須為目錄,已忽略 { $path } 21 | core_included_directory_zero_valid_directories = 包含目錄錯誤:未找到任何有效的包含路徑 22 | core_excluded_directory_pointless_slash = 目錄:排除 / 是無意義的,因為這意味著不會有任何檔案被掃描 23 | core_directory_overlap = 目錄:所有搜尋目錄與排除目錄均有重疊 24 | core_directory_unable_to_get_device_id = 目錄:無法從資料夾 { $path } 取得裝置 ID 25 | core_ffmpeg_not_found = 找不到已正確安裝的 FFmpeg 26 | core_ffmpeg_not_found_windows = 請確保 ffmpeg.exe 和 ffprobe.exe 在 PATH 中可用,或者直接將它們放在與可執行應用程式的同一個資料夾中 27 | core_ffmpeg_missing_in_snap = 快照中目前無法使用相似影片功能,如需協助,請參考 { $url } 28 | core_saving_to_cache = 已將 { $number } 個項目儲存至快取 29 | core_loading_from_cache = 已從快取載入 { $number } 個項目 30 | -------------------------------------------------------------------------------- /czkawka_core/src/common_messages.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, Default, Clone)] 2 | pub struct Messages { 3 | pub messages: Vec<String>, 4 | pub warnings: Vec<String>, 5 | pub errors: Vec<String>, 6 | } 7 | 8 | impl Messages { 9 | pub fn new() -> Self { 10 | Default::default() 11 | } 12 | pub fn new_from_errors(errors: Vec<String>) -> Self { 13 | Self { errors, ..Default::default() } 14 | } 15 | pub fn new_from_warnings(warnings: Vec<String>) -> Self { 16 | Self { warnings, ..Default::default() } 17 | } 18 | pub fn new_from_messages(messages: Vec<String>) -> Self { 19 | Self { messages, ..Default::default() } 20 | } 21 | #[allow(clippy::print_stdout)] 22 | pub fn print_messages(&self) { 23 | println!("{}", self.create_messages_text()); 24 | } 25 | 26 | pub fn create_messages_text(&self) -> String { 27 | let mut text_to_return: String = String::new(); 28 | 29 | if !self.messages.is_empty() { 30 | text_to_return += "-------------------------------MESSAGES--------------------------------\n"; 31 | for i in &self.messages { 32 | text_to_return += i; 33 | text_to_return += "\n"; 34 | } 35 | text_to_return += "---------------------------END OF MESSAGES-----------------------------\n"; 36 | } 37 | 38 | if !self.warnings.is_empty() { 39 | text_to_return += "-------------------------------WARNINGS--------------------------------\n"; 40 | 41 | for i in &self.warnings { 42 | text_to_return += i; 43 | text_to_return += "\n"; 44 | } 45 | text_to_return += "---------------------------END OF WARNINGS-----------------------------\n"; 46 | } 47 | 48 | if !self.errors.is_empty() { 49 | text_to_return += "--------------------------------ERRORS---------------------------------\n"; 50 | 51 | for i in &self.errors { 52 | text_to_return += i; 53 | text_to_return += "\n"; 54 | } 55 | text_to_return += "----------------------------END OF ERRORS------------------------------\n"; 56 | } 57 | 58 | text_to_return 59 | } 60 | 61 | pub fn extend_messages_with(&mut self, messages: Vec<String>, warnings: Vec<String>, errors: Vec<String>) { 62 | self.messages.extend(messages); 63 | self.warnings.extend(warnings); 64 | self.errors.extend(errors); 65 | } 66 | 67 | pub fn extend_with_another_messages(&mut self, messages: Self) { 68 | let (messages, warnings, errors) = (messages.messages, messages.warnings, messages.errors); 69 | self.messages.extend(messages); 70 | self.warnings.extend(warnings); 71 | self.errors.extend(errors); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /czkawka_core/src/common_traits.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::{BufWriter, Write}; 3 | use std::path::Path; 4 | 5 | use fun_time::fun_time; 6 | use serde::Serialize; 7 | 8 | pub trait DebugPrint { 9 | fn debug_print(&self); 10 | } 11 | 12 | pub trait PrintResults { 13 | fn write_results<T: Write>(&self, writer: &mut T) -> std::io::Result<()>; 14 | 15 | #[fun_time(message = "print_results_to_output", level = "debug")] 16 | fn print_results_to_output(&self) { 17 | let stdout = std::io::stdout(); 18 | let mut handle = stdout.lock(); 19 | // Panics here are allowed, because it is used only in CLI 20 | self.write_results(&mut handle).expect("Error while writing to stdout"); 21 | handle.flush().expect("Error while flushing stdout"); 22 | } 23 | 24 | #[fun_time(message = "print_results_to_file", level = "debug")] 25 | fn print_results_to_file(&self, file_name: &str) -> std::io::Result<()> { 26 | let file_name: String = match file_name { 27 | "" => "results.txt".to_string(), 28 | k => k.to_string(), 29 | }; 30 | 31 | let file_handler = File::create(file_name)?; 32 | let mut writer = BufWriter::new(file_handler); 33 | self.write_results(&mut writer)?; 34 | writer.flush()?; 35 | Ok(()) 36 | } 37 | 38 | fn save_results_to_file_as_json(&self, file_name: &str, pretty_print: bool) -> std::io::Result<()>; 39 | 40 | fn save_results_to_file_as_json_internal<T: Serialize + std::fmt::Debug>(&self, file_name: &str, item_to_serialize: &T, pretty_print: bool) -> std::io::Result<()> { 41 | if pretty_print { 42 | self.save_results_to_file_as_json_pretty(file_name, item_to_serialize) 43 | } else { 44 | self.save_results_to_file_as_json_compact(file_name, item_to_serialize) 45 | } 46 | } 47 | 48 | #[fun_time(message = "save_results_to_file_as_json_pretty", level = "debug")] 49 | fn save_results_to_file_as_json_pretty<T: Serialize + std::fmt::Debug>(&self, file_name: &str, item_to_serialize: &T) -> std::io::Result<()> { 50 | let file_handler = File::create(file_name)?; 51 | let mut writer = BufWriter::new(file_handler); 52 | serde_json::to_writer_pretty(&mut writer, item_to_serialize)?; 53 | Ok(()) 54 | } 55 | 56 | #[fun_time(message = "save_results_to_file_as_json_compact", level = "debug")] 57 | fn save_results_to_file_as_json_compact<T: Serialize + std::fmt::Debug>(&self, file_name: &str, item_to_serialize: &T) -> std::io::Result<()> { 58 | let file_handler = File::create(file_name)?; 59 | let mut writer = BufWriter::new(file_handler); 60 | serde_json::to_writer(&mut writer, item_to_serialize)?; 61 | Ok(()) 62 | } 63 | 64 | fn save_all_in_one(&self, folder: &str, base_file_name: &str) -> std::io::Result<()> { 65 | let pretty_name = format!("{folder}/{base_file_name}_pretty.json"); 66 | self.save_results_to_file_as_json(&pretty_name, true)?; 67 | let compact_name = format!("{folder}/{base_file_name}_compact.json"); 68 | self.save_results_to_file_as_json(&compact_name, false)?; 69 | let txt_name = format!("{folder}/{base_file_name}.txt"); 70 | self.print_results_to_file(&txt_name)?; 71 | Ok(()) 72 | } 73 | } 74 | 75 | pub trait ResultEntry { 76 | fn get_path(&self) -> &Path; 77 | fn get_modified_date(&self) -> u64; 78 | fn get_size(&self) -> u64; 79 | } 80 | -------------------------------------------------------------------------------- /czkawka_core/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::collapsible_else_if)] 2 | #![allow(clippy::type_complexity)] 3 | #![allow(clippy::needless_late_init)] 4 | #![allow(clippy::too_many_arguments)] 5 | #![warn(clippy::unwrap_used)] 6 | #![warn(clippy::print_stderr)] 7 | #![warn(clippy::print_stdout)] 8 | #![warn(clippy::dbg_macro)] 9 | #![warn(clippy::string_slice)] 10 | 11 | #[macro_use] 12 | extern crate bitflags; 13 | extern crate core; 14 | 15 | pub mod common; 16 | pub mod common_cache; 17 | pub mod common_dir_traversal; 18 | pub mod common_directory; 19 | pub mod common_extensions; 20 | pub mod common_image; 21 | pub mod common_items; 22 | pub mod common_messages; 23 | pub mod common_tool; 24 | pub mod common_traits; 25 | pub mod localizer_core; 26 | pub mod progress_data; 27 | pub mod tools; 28 | 29 | pub const CZKAWKA_VERSION: &str = env!("CARGO_PKG_VERSION"); 30 | pub const TOOLS_NUMBER: usize = 11; 31 | -------------------------------------------------------------------------------- /czkawka_core/src/localizer_core.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use i18n_embed::fluent::{FluentLanguageLoader, fluent_language_loader}; 4 | use i18n_embed::{DefaultLocalizer, LanguageLoader, Localizer}; 5 | use once_cell::sync::Lazy; 6 | use rust_embed::RustEmbed; 7 | 8 | #[derive(RustEmbed)] 9 | #[folder = "i18n/"] 10 | struct Localizations; 11 | 12 | pub static LANGUAGE_LOADER_CORE: Lazy<FluentLanguageLoader> = Lazy::new(|| { 13 | let loader: FluentLanguageLoader = fluent_language_loader!(); 14 | 15 | loader.load_fallback_language(&Localizations).expect("Error while loading fallback language"); 16 | 17 | loader 18 | }); 19 | 20 | #[macro_export] 21 | macro_rules! flc { 22 | ($message_id:literal) => {{ 23 | i18n_embed_fl::fl!($crate::localizer_core::LANGUAGE_LOADER_CORE, $message_id) 24 | }}; 25 | 26 | ($message_id:literal, $($args:expr),*) => {{ 27 | i18n_embed_fl::fl!($crate::localizer_core::LANGUAGE_LOADER_CORE, $message_id, $($args), *) 28 | }}; 29 | } 30 | 31 | // Get the `Localizer` to be used for localizing this library. 32 | 33 | pub fn localizer_core() -> Box<dyn Localizer> { 34 | Box::from(DefaultLocalizer::new(&*LANGUAGE_LOADER_CORE, &Localizations)) 35 | } 36 | 37 | pub fn generate_translation_hashmap(vec: Vec<(&'static str, String)>) -> HashMap<&'static str, String> { 38 | let mut hashmap: HashMap<&'static str, String> = Default::default(); 39 | for (key, value) in vec { 40 | hashmap.insert(key, value); 41 | } 42 | hashmap 43 | } 44 | 45 | pub fn fnc_get_similarity_very_high() -> String { 46 | flc!("core_similarity_very_high") 47 | } 48 | 49 | pub fn fnc_get_similarity_minimal() -> String { 50 | flc!("core_similarity_minimal") 51 | } 52 | -------------------------------------------------------------------------------- /czkawka_core/src/tools/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod bad_extensions; 2 | pub mod big_file; 3 | pub mod broken_files; 4 | pub mod duplicate; 5 | pub mod empty_files; 6 | pub mod empty_folder; 7 | pub mod invalid_symlinks; 8 | pub mod same_music; 9 | pub mod similar_images; 10 | pub mod similar_videos; 11 | pub mod temporary; 12 | -------------------------------------------------------------------------------- /czkawka_gui/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "czkawka_gui" 3 | version = "9.0.0" 4 | authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"] 5 | edition = "2024" 6 | rust-version = "1.85.0" 7 | description = "GTK frontend of Czkawka" 8 | license = "MIT" 9 | homepage = "https://github.com/qarmin/czkawka" 10 | repository = "https://github.com/qarmin/czkawka" 11 | 12 | [dependencies] 13 | gdk4 = { version = "0.9", default-features = false, features = ["v4_6"] } 14 | glib = "0.20" 15 | gtk4 = { version = "0.9", default-features = false, features = ["v4_6"] } 16 | 17 | humansize = "2.1" 18 | chrono = "0.4.38" 19 | crossbeam-channel = "0.5" 20 | directories-next = "2.0" 21 | open = "5.3" 22 | image = "0.25" 23 | regex = "1.11" 24 | image_hasher = "3.0" 25 | trash = "5.1" 26 | fs_extra = "1.3" 27 | 28 | i18n-embed = { version = "0.15", features = ["fluent-system", "desktop-requester"] } 29 | i18n-embed-fl = "0.9" 30 | rust-embed = { version = "8.5", features = ["debug-embed"] } 31 | once_cell = "1.20" 32 | 33 | log = "0.4.22" 34 | fun_time = { version = "0.3", features = ["log"] } 35 | rayon = "1.10" 36 | 37 | czkawka_core = { path = "../czkawka_core", version = "9.0.0", features = [] } 38 | 39 | [dev-dependencies] 40 | rand = "0.9.0" 41 | 42 | [target.'cfg(windows)'.dependencies] 43 | winapi = { version = "0.3.9", features = ["combaseapi", "objbase", "shobjidl_core", "windef", "winerror", "wtypesbase", "winuser"] } 44 | 45 | [features] 46 | default = ["fast_image_resize"] 47 | heif = ["czkawka_core/heif"] 48 | libraw = ["czkawka_core/libraw"] 49 | libavif = ["czkawka_core/libavif"] 50 | fast_image_resize = ["czkawka_core/fast_image_resize"] 51 | -------------------------------------------------------------------------------- /czkawka_gui/LICENSE_MIT_APP_CODE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2025 Rafał Mikrut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /czkawka_gui/LICENSE_MIT_WINDOWS_THEME: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2020 Nick Rhodes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /czkawka_gui/data: -------------------------------------------------------------------------------- 1 | ../data/ -------------------------------------------------------------------------------- /czkawka_gui/i18n.toml: -------------------------------------------------------------------------------- 1 | # (Required) The language identifier of the language used in the 2 | # source code for gettext system, and the primary fallback language 3 | # (for which all strings must be present) when using the fluent 4 | # system. 5 | fallback_language = "en" 6 | 7 | # Use the fluent localization system. 8 | [fluent] 9 | # (Required) The path to the assets directory. 10 | # The paths inside the assets directory should be structured like so: 11 | # `assets_dir/{language}/{domain}.ftl` 12 | assets_dir = "i18n" 13 | 14 | -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_add.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><circle cx="255.998" cy="255.998" fill="#008000" r="245.419"/><path d="m256.001 512c-141.16 0-256.001-114.841-256.001-256.001 0-141.158 114.841-255.999 256.001-255.999s255.999 114.841 255.999 255.999c0 141.16-114.841 256.001-255.999 256.001zm0-490.842c-129.493 0-234.843 105.35-234.843 234.841 0 129.493 105.35 234.841 234.843 234.841s234.841-105.35 234.841-234.841-105.35-234.841-234.841-234.841z"/><g fill="#f2f2f2"><path d="m93.920837 228.48424h327.86569v55.947498h-327.86569z"/><path d="m94.802574-283.03333h327.86569v55.947498h-327.86569z" transform="rotate(90)"/></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_delete.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><circle cx="256" cy="256" fill="#f00" r="245.42"/><path d="m256 512c-141.16 0-256-114.84-256-256s114.84-256 256-256 256 114.84 256 256-114.84 256-256 256zm0-490.84c-129.49 0-234.84 105.35-234.84 234.84s105.35 234.84 234.84 234.84 234.84-105.35 234.84-234.84-105.35-234.84-234.84-234.84z"/><path d="m402.81358 218.58h-290.78716v78.662h290.78716z" fill="#f2f2f2" stroke-width="1.23426"/></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_hide_down.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><g fill="#f2f2f2"><g fill-rule="evenodd"><path d="m35.979671 12.962944h446.01709v77.321869h-446.01709z" fill="#666" stroke-width="1.0905"/><path d="m45.104263 22.958824h426.74094v57.075775h-426.74094z" fill="#ccc" stroke-width=".916437"/><path d="m35.747097 107.06576h446.01709v77.321869h-446.01709z" fill="#666" stroke-width="1.0905"/><path d="m44.87167 117.06164h426.74094v57.075775h-426.74094z" fill="#ccc" stroke-width=".916437"/><path d="m37.098015 198.83862h446.01709v77.321869h-446.01709z" fill="#666" stroke-width="1.0905"/><path d="m46.22261 208.8345h426.74094v57.075775h-426.74094z" fill="#ccc" stroke-width=".916437"/></g><path d="m215.91461 286.19522h91.626091v115.46206h-91.626091z" fill="#666" stroke-width="1.2011"/><path d="m224.32861 293.36823h74.477417v98.46283h-74.477417z" fill="#ccc"/><path d="m168.23517 342.06965 94.54786.18875 94.54787.18877-47.4374 81.78647-47.4374 81.78648-47.11046-81.97523z" fill="#666" stroke-linejoin="round" stroke-width="1.43794"/><path d="m184.17275 349.94172 79.03401.15778 79.03401.15779-39.65365 68.36656-39.65365 68.36657-39.38036-68.52435z" fill="#ccc" stroke-linejoin="round" stroke-width="1.202"/></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_hide_up.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><g fill="#f2f2f2"><g transform="scale(-1)"><path d="m-482.88254-506.02011h446.01709v77.321869h-446.01709z" fill="#666" fill-rule="evenodd" stroke-width="1.0905"/><path d="m-473.75793-496.02423h426.74094v57.075775h-426.74094z" fill="#ccc" fill-rule="evenodd" stroke-width=".916437"/><path d="m-483.11511-411.9173h446.01709v77.321869h-446.01709z" fill="#666" fill-rule="evenodd" stroke-width="1.0905"/><path d="m-473.99054-401.92142h426.74094v57.075775h-426.74094z" fill="#ccc" fill-rule="evenodd" stroke-width=".916437"/><path d="m-481.76419-320.14444h446.01709v77.321869h-446.01709z" fill="#666" fill-rule="evenodd" stroke-width="1.0905"/><path d="m-472.63959-310.14856h426.74094v57.075775h-426.74094z" fill="#ccc" fill-rule="evenodd" stroke-width=".916437"/><path d="m-302.9476-232.78784h91.626091v115.46206h-91.626091z" fill="#666" stroke-width="1.2011"/><path d="m-294.5336-225.61484h74.477417v98.46283h-74.477417z" fill="#ccc"/></g><path d="m350.62703 176.91341-94.54786-.18875-94.54787-.18877 47.4374-81.786466 47.4374-81.78648 47.11046 81.97523z" fill="#666" stroke-linejoin="round" stroke-width="1.43794"/><path d="m334.68945 169.04134-79.03401-.15778-79.03401-.15779 39.65365-68.36656 39.65365-68.366566 39.38036 68.524346z" fill="#ccc" stroke-linejoin="round" stroke-width="1.202"/></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_info.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512.001 512.001" viewBox="0 0 512.001 512.001" xmlns="http://www.w3.org/2000/svg"><ellipse cx="256.19809" cy="256.82071" fill="#fff" rx="255.57552" ry="256.19809" stroke-width="1.517"/><g fill="#2ad4ff"><ellipse cx="255.61798" cy="255.90529" rx="242.54349" ry="242.20819" stroke-width="1.72836"/><text stroke-width="1.517"/><text font-family="DejaVu Sans Mono" font-size="400" stroke-width="1.517" transform="matrix(1.5271339 0 0 1.5271339 -269.64919 51.692833)" x="295.4021" y="279.55341"><tspan fill="#000" font-family="Carlito" font-size="400" x="295.4021" y="279.55341">i</tspan></text></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_left.svg: -------------------------------------------------------------------------------- 1 | <svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="m16 32a16 16 0 1 1 16-16 16 16 0 0 1 -16 16zm0-30a14 14 0 1 0 14 14 14 14 0 0 0 -14-14z"/><path d="m18.29 24.71-8-8a1 1 0 0 1 0-1.41l8-8 1.41 1.41-7.29 7.29 7.29 7.29z"/></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_manual_add.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><circle cx="255.998" cy="255.998" fill="#917c6f" r="245.419"/><path d="m256.001 512c-141.16 0-256.001-114.841-256.001-256.001 0-141.158 114.841-255.999 256.001-255.999s255.999 114.841 255.999 255.999c0 141.16-114.841 256.001-255.999 256.001zm0-490.842c-129.493 0-234.843 105.35-234.843 234.841 0 129.493 105.35 234.841 234.843 234.841s234.841-105.35 234.841-234.841-105.35-234.841-234.841-234.841z"/><g fill="#f2f2f2"><path d="m94.377983 224.89618h327.86569v55.947498h-327.86569z"/><path d="m91.214554-283.49048h327.86569v55.947498h-327.86569z" transform="rotate(90)"/></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_move.svg: -------------------------------------------------------------------------------- 1 | <svg height="800" viewBox="0 0 24 24" width="800" xmlns="http://www.w3.org/2000/svg"><path d="m3.033534 6.562339h17.705933v13.021496h-17.705933z" fill="#feaf50" stroke-width=".04551"/><path d="m20 6h-8l-1.234019-2h-6.765981c-1.1 0-1.99.9-1.99 2l-.01 12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-10c0-1.1-.9-2-2-2zm.353272 12.646417-16.9353697-.074836.0407418-11.2095966 16.8454139.0812889z"/><path d="m3.465675 5.336361h6.743204v2.033677h-6.743204z" fill="#b77c38" stroke-width=".011099"/></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_right.svg: -------------------------------------------------------------------------------- 1 | <svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="m16 32a16 16 0 1 1 16-16 16 16 0 0 1 -16 16zm0-30a14 14 0 1 0 14 14 14 14 0 0 0 -14-14z"/><path d="m13.668801 24.68597 8-8a1 1 0 0 0 0-1.41l-8-7.9999999-1.409999 1.41 7.289999 7.2899999-7.289999 7.29z"/></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_save.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m75.92144 262.99274 3.081686-152.54859 27.664994-.44024 25.4638-1.76097-.88048 51.45254 3.08169 31.6417 63.72744 3.08169 61.56132 1.38709-1.79605-37.4312 7.04385-52.33302 35.7099 1.77556 31.74774 1.33533 57.16729 48.83692 53.64536 45.31499-2.20121 107.65929-4.84264 103.69703-178.10626 5.28289-182.948911-3.96216zm187.6699 68.49152c13.10358-2.98743 25.25534-14.46367 29.71153-28.05983 1.63902-5.00078 1.8051-6.29389 1.78756-13.91801-.0179-7.75928-.16542-8.81723-1.92088-13.77039-4.81706-13.59173-15.49715-23.60407-29.18347-27.35886-4.18742-1.1488-6.03431-1.30482-12.42383-1.04953-12.26616.4901-19.77247 3.74833-28.45047 12.34938-9.9941 9.90547-14.28078 24.56943-11.41218 39.03892 4.03383 20.34694 23.33125 35.39851 43.56412 33.97906 2.39699-.16816 6.14442-.713 8.32762-1.21074z" fill="#6e83b7" stroke-width=".944476"/><path d="m136.13074 149.11137 5.72313-39.10746 54.88598 1.76096 54.44573-2.64144 5.72313 34.26481-3.08169 43.95011-54.00548 3.08169-58.84815-2.64145z" fill="#edeff1" stroke-width=".944476"/><g clip-rule="evenodd" fill-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" transform="matrix(.25215706 0 0 .25215706 4.697377 -32.775802)"><path d="m0 0h2048v2048h-2048z" fill="none"/><path d="m236.71658 507.59377h82.08745v1271.91523h-82.08745z" stroke-width=".678476"/><path d="m474.29746 533.31919h82.08745v398.17011h-82.08745z" stroke-width=".379612"/><path d="m1022.7429 849.58334v82.08745h-519.64533v-82.08745z" stroke-width=".43367"/><path d="m966.21052 532.48314h82.08738v398.1701h-82.08738z" stroke-width=".379612"/><path d="m235.65532 1746.6133h1546.04568v85.1226h-1546.04568z" stroke-width=".761729"/><path d="m236.6738 507.31956h1076.3544v85.1226h-1076.3544z" stroke-width=".635575"/><path d="m1311.7633 507.6448 469.3371 399.07317-55.1405 64.84894-469.3371-399.07317z" stroke-width=".480842"/><path d="m1699.1531 904.94712h82.0874v925.90568h-82.0874z" stroke-width=".57888"/><ellipse cx="984.88251" cy="1282.9382" rx="172.11137" ry="174.51003" stroke-width="1.031"/></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_search.svg: -------------------------------------------------------------------------------- 1 | <svg clip-rule="evenodd" fill-rule="evenodd" height="2048" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 2048 2048" width="2048" xmlns="http://www.w3.org/2000/svg"><circle cx="768.67108" cy="766.4572" r="465.17685" style="fill:#b3e5fc;stroke:#373435;stroke-width:2.14421;clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"/><g fill="#01579b" fill-rule="nonzero"><path d="m405 407c100-100 231-150 362-150s262 50 362 150 150 231 150 362-50 262-150 362-231 150-362 150-262-50-362-150-150-231-150-362 50-262 150-362zm362-86c-115 0-229 44-317 131-87 87-131 202-131 317s44 229 131 317c87 87 202 131 317 131s229-44 317-131c87-87 131-202 131-317s-44-229-131-317c-87-87-202-131-317-131z"/><path d="m1161 1066 444 444-92 90-444-444z" stroke-width="2"/></g><path d="m0 0h2048v2048h-2048z" fill="none"/></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_select.svg: -------------------------------------------------------------------------------- 1 | <svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><rect fill="#01579b" height="50.95132228259" ry="12.54524963889" stroke-width="2.14508622439" width="50.95132228259" x="13.07050589161" y=".26568478628"/><rect fill="#fff" height="39.3964833289" ry="9.7002148668" stroke-width="1.65861950757" width="39.3964833289" x="18.71006891524" y="6.27324360751"/><g transform="matrix(1.2071401 0 0 1.2071401 .132098 -12.600551)"><rect fill="#01579b" height="42.07935" ry="10.36079" stroke-width="1.77157" width="42.07935" x=".113693" y="21.757364"/><rect fill="#fff" height="32.536514" ry="8.011151" stroke-width="1.36981" width="32.536514" x="4.771257" y="26.718843"/><text fill="#f00" font-family="Carlito" font-size="48.6995" stroke-width=".184693" x=".820791" y="61.64212"><tspan fill="#f00" stroke-width=".184693" x=".820791" y="61.64212">✔</tspan></text></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_settings.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 256 256" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg"><g fill="#666" stroke="#000" stroke-width="5.587784" transform="matrix(.56677211 0 0 .56677211 -14.277154 -16.497594)"><path d="m259.96 178.63c-116.38.46054-109.81 154.42-4.8963 157.07 110.82 2.7975 108.63-157.48 4.8963-157.07zm-4.5114 238.17-59.661 58.623c-3.663 4.3684-9.9047 5.5348-14.898 2.784l-79.778-46.06c-4.7847-2.888-6.9422-8.6968-5.203-14.008l22.977-56.917c-9.1283-11.972-16.619-25.108-22.274-39.06l-61.08-8.7064c-5.5804-.89998-9.7077-5.679-9.7856-11.331l-.13413-91.888c-.02721-5.6801 4.0661-10.543 9.6676-11.485l61.227-8.6679c2.8571-7.0258 6.169-13.858 9.9147-20.453 3.7735-6.4529 7.9798-12.643 12.59-18.527l-23.107-57.358c-1.985-5.3221.17966-11.298 5.1124-14.115l79.649-45.836c4.933-2.7634 11.138-1.5821 14.711 2.8005l66.966 73.793c-6.8372 161.75-1.2386 214.48-6.8946 306.41z"/><g><path d="m275 50h200v20h-200z"/><path d="m275 85h200v20h-200z"/><path d="m275 120h200v20h-200z"/><path d="m275 155h200v20h-200z"/></g><path d="m335 190h140v20h-140z"/><path d="m345 225h130v20h-130z"/><g transform="scale(1 -1)"><g><path d="m273.16-466.69h199.81v20h-199.81z"/><path d="m273.16-431.69h199.81v20h-199.81z"/><path d="m273.16-396.69h199.81v20h-199.81z"/><path d="m273.16-361.69h199.81v20h-199.81z"/></g><path d="m333.1-326.69h139.87v20h-139.87z"/><path d="m343.09-291.69h129.88v20h-129.88z"/></g></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_sort.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><g stroke="#000"><rect fill="#de8787" height="169.79747" ry="4.218498" stroke-width="4.67244" transform="matrix(-.99999558 -.00297267 .00298205 -.99999555 0 0)" width="76.759132" x="-175.30302" y="-242.6983"/><rect fill="#d35f5f" height="194.57874" ry="4.218498" stroke-width="4.67244" width="88.250015" x="91.748428" y="132.06248"/><rect fill="#a02c2c" height="169.94217" ry="4.222093" stroke-width="4.67245" transform="matrix(.67849982 .73460056 -.7356649 .67734567 0 0)" width="76.693871" x="104.45238" y="-97.039093"/><rect fill="#c83737" height="169.92395" ry="4.221641" stroke-width="4.67245" transform="matrix(-.72694564 .68669501 -.68783746 -.72586475 0 0)" width="76.702095" x="-97.298988" y="-276.05035"/><rect fill="#ff7f2a" height="169.79747" ry="4.218498" stroke-width="4.67244" transform="matrix(-.99999558 -.00297267 .00298205 -.99999555 0 0)" width="76.759132" x="-419.85931" y="-243.06003"/><rect fill="#d45500" height="194.57874" ry="4.218498" stroke-width="4.67244" width="88.250015" x="336.30252" y="133.1512"/><rect fill="#a40" height="169.94217" ry="4.222093" stroke-width="4.67245" transform="matrix(.67849982 .73460056 -.7356649 .67734567 0 0)" width="76.693871" x="270.90118" y="-275.95023"/><rect fill="#803300" height="169.92395" ry="4.221641" stroke-width="4.67245" transform="matrix(-.72694564 .68669501 -.68783746 -.72586475 0 0)" width="76.702095" x="-274.06357" y="-444.77609"/><rect fill="#0fc" height="169.79747" ry="4.218498" stroke-width="4.67244" transform="matrix(.9999993 -.00118262 .00118635 .9999993 0 0)" width="76.759132" x="220.0965" y="268.23785"/><rect fill="#00b3b3" height="194.57874" ry="4.218498" stroke-width="4.67244" transform="matrix(-.99999137 .00415535 -.00416846 -.99999131 0 0)" width="88.250015" x="-302.1257" y="-380.04681"/><g stroke-width="4.67245"><rect fill="#00a2a2" height="169.94106" ry="4.222066" transform="matrix(-.68155158 -.73177007 .73283989 -.68040113 0 0)" width="76.694374" x="-539.08167" y="-155.16403"/><rect fill="#006565" height="169.92506" ry="4.221668" transform="matrix(.72408167 -.68971424 .69085266 .72299557 0 0)" width="76.701591" x="-163.64659" y="366.69989"/></g></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_stop.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><circle cx="256" cy="256" fill="#f00" r="245.42"/><path d="m256 512c-141.16 0-256-114.84-256-256s114.84-256 256-256 256 114.84 256 256-114.84 256-256 256zm0-490.84c-129.49 0-234.84 105.35-234.84 234.84s105.35 234.84 234.84 234.84 234.84-105.35 234.84-234.84-105.35-234.84-234.84-234.84z"/><g fill="#f2f2f2" transform="matrix(.7071438 .70706976 -.70706976 .7071438 261.591021 -107.343357)"><path d="m96.446 234.14h327.87v55.947h-327.87z"/><path d="m98.184-288.35h327.87v55.947h-327.87z" transform="rotate(90)"/></g></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_symlink.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 64 64" height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke-width="4.267" transform="matrix(.01236471 .99992355 -.99992355 .01236471 0 0)"><rect height="34.779018" rx="0" ry="11.501289" stroke="#356200" width="23.002579" x="3.333345" y="-51.239441"/><rect height="34.779018" rx="0" ry="11.501289" stroke="#7d9074" width="23.002579" x="3.272459" y="-48.570278"/><rect height="34.779018" rx="0" ry="11.501289" stroke="#515151" width="23.002579" x="35.87978" y="-50.25383"/><rect height="34.779018" rx="0" ry="11.501289" stroke="#7c7c7c" width="23.002579" x="35.818893" y="-47.584663"/></g><rect fill="#ccc" height="18.405447" ry="4.241425" width="6.965277" x="24.709217" y="21.090387"/><rect fill="#ccc" height="18.405447" ry="4.241425" width="6.965277" x="33.082012" y="21.303345"/></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/czk_trash.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m810.86844 36.649183h419.99996v52h-419.99996z" fill="#edeff1"/><path d="m836.86844 88.649183 20 375.999997h327.99996l20-375.999997z" fill="#edeff1"/><g fill="#d3d3d3" transform="translate(764.86844 -37.350817)"><path d="m438.723 150 1.277-24h-368l1.277 24z"/><path d="m256 457c-13.255 0-24-10.745-24-24v-212c0-13.255 10.745-24 24-24s24 10.745 24 24v212c0 13.255-10.745 24-24 24z"/><path d="m350 457c-13.255 0-24-10.745-24-24v-212c0-13.255 10.745-24 24-24s24 10.745 24 24v212c0 13.255-10.745 24-24 24z"/><path d="m162 457c13.255 0 24-10.745 24-24v-212c0-13.255-10.745-24-24-24s-24 10.745-24 24v212c0 13.255 10.745 24 24 24z"/><path d="m168 10v64h32v-32h112v32h32v-64z"/></g><g fill="#b3b3b3"><rect height="376.51978" ry="109.59763" stroke="#000" stroke-width="8.848" width="300.49173" x="98.400284" y="121.95791"/><rect height="166.5376" ry="36.807224" stroke="#000" stroke-width="7.648" width="299.88834" x="98.400291" y="120.75112"/><rect height="166.5376" ry="36.807224" width="292.19061" x="102.41598" y="198.32443"/><rect height="35.345848" ry="7.811945" stroke="#000" stroke-width="7" width="288.44208" x="104.58985" y="62.868443"/><rect height="73.646797" ry="16.27701" stroke="#000" stroke-width="7.057" width="236.93391" x="131.15132" y="10.045573"/></g><rect fill="#fff" height="35.487885" rx="26.854687" ry="16.459324" stroke-width="3.34055" width="176.19423" x="161.25197" y="29.884533"/><rect fill="#b3b3b3" height="21.648771" ry="4.784693" width="272.56592" x="111.02435" y="66.329552"/><rect fill="#fff" height="35.487904" rx="37.008057" ry="16.459333" stroke-width="3.92154" transform="matrix(-.00080799 -.99999967 .99999882 -.00153448 0 0)" width="242.81071" x="-420.19443" y="150.69518"/><rect fill="#fff" height="35.487904" rx="37.008057" ry="16.459333" stroke-width="3.92154" transform="matrix(-.00080799 -.99999967 .99999882 -.00153448 0 0)" width="242.81071" x="-418.25546" y="233.15419"/><rect fill="#fff" height="35.487904" rx="37.008057" ry="16.459333" stroke-width="3.92154" transform="matrix(-.00080799 -.99999967 .99999882 -.00153448 0 0)" width="242.81071" x="-418.79758" y="311.56973"/></svg> -------------------------------------------------------------------------------- /czkawka_gui/icons/icon_about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qarmin/czkawka/2be42d9478501a90c36e8b1002fa3c7e5cb5ad2d/czkawka_gui/icons/icon_about.png -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_about_buttons.rs: -------------------------------------------------------------------------------- 1 | use gtk4::prelude::*; 2 | use log::error; 3 | 4 | use crate::gui_structs::gui_data::GuiData; 5 | 6 | const SPONSOR_SITE: &str = "https://github.com/sponsors/qarmin"; 7 | const REPOSITORY_SITE: &str = "https://github.com/qarmin/czkawka"; 8 | const INSTRUCTION_SITE: &str = "https://github.com/qarmin/czkawka/blob/master/instructions/Instruction.md"; 9 | const TRANSLATION_SITE: &str = "https://crwd.in/czkawka"; 10 | 11 | pub fn connect_about_buttons(gui_data: &GuiData) { 12 | let button_donation = gui_data.about.button_donation.clone(); 13 | button_donation.connect_clicked(move |_| { 14 | if let Err(e) = open::that(SPONSOR_SITE) { 15 | error!("Failed to open sponsor site: {SPONSOR_SITE}, reason {e}"); 16 | }; 17 | }); 18 | 19 | let button_instruction = gui_data.about.button_instruction.clone(); 20 | button_instruction.connect_clicked(move |_| { 21 | if let Err(e) = open::that(INSTRUCTION_SITE) { 22 | error!("Failed to open instruction site: {INSTRUCTION_SITE}, reason {e}"); 23 | }; 24 | }); 25 | 26 | let button_repository = gui_data.about.button_repository.clone(); 27 | button_repository.connect_clicked(move |_| { 28 | if let Err(e) = open::that(REPOSITORY_SITE) { 29 | error!("Failed to open repository site: {REPOSITORY_SITE}, reason {e}"); 30 | }; 31 | }); 32 | 33 | let button_translation = gui_data.about.button_translation.clone(); 34 | button_translation.connect_clicked(move |_| { 35 | if let Err(e) = open::that(TRANSLATION_SITE) { 36 | error!("Failed to open translation site: {TRANSLATION_SITE}, reason {e}"); 37 | }; 38 | }); 39 | } 40 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_button_sort.rs: -------------------------------------------------------------------------------- 1 | use gtk4::prelude::*; 2 | 3 | use crate::gui_structs::gui_data::GuiData; 4 | use crate::gui_structs::gui_popovers_sort::GuiSortPopovers; 5 | use crate::help_functions::PopoverTypes; 6 | use crate::notebook_enums::{NotebookMainEnum, to_notebook_main_enum}; 7 | use crate::notebook_info::NOTEBOOKS_INFO; 8 | 9 | pub fn connect_button_sort(gui_data: &GuiData) { 10 | let popovers_sort = gui_data.popovers_sort.clone(); 11 | let notebook_main = gui_data.main_notebook.notebook_main.clone(); 12 | let gc_buttons_sort = gui_data.bottom_buttons.gc_buttons_sort.clone(); 13 | 14 | gc_buttons_sort.connect_pressed(move |_, _, _, _| { 15 | show_required_popovers(&popovers_sort, to_notebook_main_enum(notebook_main.current_page().expect("Current page not set"))); 16 | }); 17 | } 18 | 19 | fn show_required_popovers(popovers_sort: &GuiSortPopovers, current_mode: NotebookMainEnum) { 20 | let buttons_popover_sort_file_name = popovers_sort.buttons_popover_sort_file_name.clone(); 21 | let buttons_popover_sort_size = popovers_sort.buttons_popover_sort_size.clone(); 22 | let buttons_popover_sort_folder_name = popovers_sort.buttons_popover_sort_folder_name.clone(); 23 | let buttons_popover_sort_full_name = popovers_sort.buttons_popover_sort_full_name.clone(); 24 | let buttons_popover_sort_selection = popovers_sort.buttons_popover_sort_selection.clone(); 25 | 26 | let arr = &NOTEBOOKS_INFO[current_mode as usize].available_modes; 27 | 28 | buttons_popover_sort_full_name.hide(); 29 | 30 | if arr.contains(&PopoverTypes::All) { 31 | buttons_popover_sort_selection.show(); 32 | buttons_popover_sort_file_name.show(); 33 | buttons_popover_sort_folder_name.show(); 34 | // buttons_popover_sort_full_name.show(); // TODO, this needs to be handled a little different 35 | } else { 36 | buttons_popover_sort_selection.hide(); 37 | buttons_popover_sort_file_name.hide(); 38 | buttons_popover_sort_folder_name.hide(); 39 | // buttons_popover_sort_full_name.hide(); 40 | } 41 | 42 | if arr.contains(&PopoverTypes::Size) { 43 | buttons_popover_sort_size.show(); 44 | } else { 45 | buttons_popover_sort_size.hide(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_button_stop.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | use std::sync::atomic::AtomicBool; 3 | 4 | use gtk4::prelude::*; 5 | 6 | use crate::flg; 7 | use crate::gui_structs::gui_data::GuiData; 8 | use crate::help_functions::KEY_ENTER; 9 | 10 | fn send_stop_message(stop_flag: &Arc<AtomicBool>) { 11 | stop_flag.store(true, std::sync::atomic::Ordering::Relaxed); 12 | } 13 | 14 | pub fn connect_button_stop(gui_data: &GuiData) { 15 | let evk_button_stop_in_dialog = gui_data.progress_window.evk_button_stop_in_dialog.clone(); 16 | let stop_dialog = gui_data.progress_window.window_progress.clone(); 17 | let stop_flag = gui_data.stop_flag.clone(); 18 | evk_button_stop_in_dialog.connect_key_released(move |_, _, key_code, _| { 19 | if key_code == KEY_ENTER { 20 | stop_dialog.set_title(Some(&format!("{} ({})", flg!("window_progress_title"), flg!("progress_stop_additional_message")))); 21 | send_stop_message(&stop_flag); 22 | } 23 | }); 24 | 25 | let button_stop_in_dialog = gui_data.progress_window.button_stop_in_dialog.clone(); 26 | let stop_dialog = gui_data.progress_window.window_progress.clone(); 27 | let stop_flag = gui_data.stop_flag.clone(); 28 | 29 | button_stop_in_dialog.connect_clicked(move |_a| { 30 | stop_dialog.set_title(Some(&format!("{} ({})", flg!("window_progress_title"), flg!("progress_stop_additional_message")))); 31 | send_stop_message(&stop_flag); 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_change_language.rs: -------------------------------------------------------------------------------- 1 | use gtk4::prelude::*; 2 | use i18n_embed::DesktopLanguageRequester; 3 | use i18n_embed::unic_langid::LanguageIdentifier; 4 | use log::error; 5 | 6 | use crate::language_functions::get_language_from_combo_box_text; 7 | use crate::{GuiData, LANGUAGES_ALL, localizer_gui}; 8 | 9 | // use i18n_embed::{DesktopLanguageRequester, Localizer}; 10 | 11 | pub fn connect_change_language(gui_data: &GuiData) { 12 | change_language(gui_data); 13 | 14 | let combo_box_settings_language = gui_data.settings.combo_box_settings_language.clone(); 15 | let gui_data = gui_data.clone(); 16 | combo_box_settings_language.connect_changed(move |_| { 17 | change_language(&gui_data); 18 | }); 19 | } 20 | 21 | fn change_language(gui_data: &GuiData) { 22 | let localizers = vec![ 23 | ("czkawka_core", czkawka_core::localizer_core::localizer_core()), 24 | ("czkawka_gui", localizer_gui::localizer_gui()), 25 | ]; 26 | 27 | let lang_short = get_language_from_combo_box_text(&gui_data.settings.combo_box_settings_language.active_text().expect("No active text")).short_text; 28 | 29 | let lang_identifier = vec![LanguageIdentifier::from_bytes(lang_short.as_bytes()).expect("Failed to create LanguageIdentifier")]; 30 | for (lib, localizer) in localizers { 31 | if let Err(error) = localizer.select(&lang_identifier) { 32 | error!("Error while loadings languages for {lib} {error:?}"); 33 | } 34 | } 35 | gui_data.update_language(); 36 | } 37 | 38 | pub fn load_system_language(gui_data: &GuiData) { 39 | let requested_languages = DesktopLanguageRequester::requested_languages(); 40 | 41 | if let Some(language) = requested_languages.first() { 42 | let old_short_lang = language.to_string(); 43 | let mut short_lang = String::new(); 44 | // removes from e.g. en_zb, ending _zd since Czkawka don't support this(maybe could add this in future, but only when) 45 | for i in old_short_lang.chars() { 46 | if i.is_ascii_alphabetic() { 47 | short_lang.push(i); 48 | } else { 49 | break; 50 | } 51 | } 52 | // let mut found: bool = false; 53 | for (index, lang) in LANGUAGES_ALL.iter().enumerate() { 54 | if lang.short_text == short_lang { 55 | // found = true; 56 | gui_data.settings.combo_box_settings_language.set_active(Some(index as u32)); 57 | break; 58 | } 59 | } 60 | // if found { 61 | // println!("INFO: Default system language {} is available, so choosing them", short_lang); 62 | // } else { 63 | // println!("INFO: Default system language {} is not available, using English(en) instead", short_lang); 64 | // } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_duplicate_buttons.rs: -------------------------------------------------------------------------------- 1 | use czkawka_core::common_dir_traversal::CheckingMethod; 2 | use gtk4::prelude::*; 3 | 4 | use crate::gui_structs::gui_data::GuiData; 5 | use crate::help_combo_box::DUPLICATES_CHECK_METHOD_COMBO_BOX; 6 | 7 | pub fn connect_duplicate_combo_box(gui_data: &GuiData) { 8 | let combo_box_duplicate_check_method = gui_data.main_notebook.combo_box_duplicate_check_method.clone(); 9 | let combo_box_duplicate_hash_type = gui_data.main_notebook.combo_box_duplicate_hash_type.clone(); 10 | let label_duplicate_hash_type = gui_data.main_notebook.label_duplicate_hash_type.clone(); 11 | let check_button_duplicate_case_sensitive_name = gui_data.main_notebook.check_button_duplicate_case_sensitive_name.clone(); 12 | combo_box_duplicate_check_method.connect_changed(move |combo_box_duplicate_check_method| { 13 | // None active can be if when adding elements(this signal is activated when e.g. adding new fields or removing them) 14 | if let Some(chosen_index) = combo_box_duplicate_check_method.active() { 15 | if DUPLICATES_CHECK_METHOD_COMBO_BOX[chosen_index as usize].check_method == CheckingMethod::Hash { 16 | combo_box_duplicate_hash_type.set_visible(true); 17 | label_duplicate_hash_type.set_visible(true); 18 | } else { 19 | combo_box_duplicate_hash_type.set_visible(false); 20 | label_duplicate_hash_type.set_visible(false); 21 | } 22 | 23 | if [CheckingMethod::Name, CheckingMethod::SizeName].contains(&DUPLICATES_CHECK_METHOD_COMBO_BOX[chosen_index as usize].check_method) { 24 | check_button_duplicate_case_sensitive_name.set_visible(true); 25 | } else { 26 | check_button_duplicate_case_sensitive_name.set_visible(false); 27 | } 28 | } 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_header_buttons.rs: -------------------------------------------------------------------------------- 1 | use gtk4::prelude::*; 2 | 3 | use crate::gui_structs::gui_data::GuiData; 4 | 5 | pub fn connect_button_about(gui_data: &GuiData) { 6 | let about_dialog = gui_data.about.about_dialog.clone(); 7 | let button_app_info = gui_data.header.button_app_info.clone(); 8 | button_app_info.connect_clicked(move |_| { 9 | about_dialog.show(); 10 | 11 | // Prevent from deleting dialog after close 12 | about_dialog.connect_close_request(|dialog| { 13 | dialog.hide(); 14 | glib::Propagation::Stop 15 | }); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_notebook_tabs.rs: -------------------------------------------------------------------------------- 1 | use crate::gui_structs::gui_data::GuiData; 2 | use crate::help_functions::*; 3 | use crate::notebook_enums::*; 4 | 5 | pub fn connect_notebook_tabs(gui_data: &GuiData) { 6 | let shared_buttons = gui_data.shared_buttons.clone(); 7 | let buttons_array = gui_data.bottom_buttons.buttons_array.clone(); 8 | let notebook_main_clone = gui_data.main_notebook.notebook_main.clone(); 9 | let buttons_names = gui_data.bottom_buttons.buttons_names; 10 | 11 | notebook_main_clone.connect_switch_page(move |_, _, number| { 12 | let current_tab_in_main_notebook = to_notebook_main_enum(number); 13 | 14 | // Buttons 15 | set_buttons( 16 | &mut *shared_buttons.borrow_mut().get_mut(¤t_tab_in_main_notebook).expect("Failed to get current tab"), 17 | &buttons_array, 18 | &buttons_names, 19 | ); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_show_hide_ui.rs: -------------------------------------------------------------------------------- 1 | use gtk4::prelude::*; 2 | 3 | use crate::gui_structs::gui_data::GuiData; 4 | 5 | pub fn connect_show_hide_ui(gui_data: &GuiData) { 6 | let check_button_settings_show_text_view = gui_data.settings.check_button_settings_show_text_view.clone(); 7 | let buttons_show_errors = gui_data.bottom_buttons.buttons_show_errors.clone(); 8 | let scrolled_window_errors = gui_data.scrolled_window_errors.clone(); 9 | 10 | buttons_show_errors.connect_clicked(move |_| { 11 | if scrolled_window_errors.is_visible() { 12 | scrolled_window_errors.hide(); 13 | check_button_settings_show_text_view.set_active(false); 14 | } else { 15 | scrolled_window_errors.show(); 16 | check_button_settings_show_text_view.set_active(true); 17 | } 18 | }); 19 | 20 | let buttons_show_upper_notebook = gui_data.bottom_buttons.buttons_show_upper_notebook.clone(); 21 | let notebook_upper = gui_data.upper_notebook.notebook_upper.clone(); 22 | 23 | buttons_show_upper_notebook.connect_clicked(move |_| { 24 | if notebook_upper.is_visible() { 25 | notebook_upper.hide(); 26 | } else { 27 | notebook_upper.show(); 28 | } 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/connect_similar_image_size_change.rs: -------------------------------------------------------------------------------- 1 | use czkawka_core::tools::similar_images::{SIMILAR_VALUES, get_string_from_similarity}; 2 | use gtk4::prelude::*; 3 | 4 | use crate::gui_structs::gui_data::GuiData; 5 | use crate::help_combo_box::IMAGES_HASH_SIZE_COMBO_BOX; 6 | 7 | pub fn connect_similar_image_size_change(gui_data: &GuiData) { 8 | let label_similar_images_minimal_similarity = gui_data.main_notebook.label_similar_images_minimal_similarity.clone(); 9 | label_similar_images_minimal_similarity.set_text(&get_string_from_similarity(&SIMILAR_VALUES[0][5], 8)); 10 | 11 | let combo_box_image_hash_size = gui_data.main_notebook.combo_box_image_hash_size.clone(); 12 | let label_similar_images_minimal_similarity = gui_data.main_notebook.label_similar_images_minimal_similarity.clone(); 13 | let scale_similarity_similar_images = gui_data.main_notebook.scale_similarity_similar_images.clone(); 14 | combo_box_image_hash_size.connect_changed(move |combo_box_image_hash_size| { 15 | let hash_size_index = combo_box_image_hash_size.active().expect("Failed to get active item") as usize; 16 | let hash_size = IMAGES_HASH_SIZE_COMBO_BOX[hash_size_index]; 17 | 18 | let index = match hash_size { 19 | 8 => 0, 20 | 16 => 1, 21 | 32 => 2, 22 | 64 => 3, 23 | _ => panic!(), 24 | }; 25 | 26 | scale_similarity_similar_images.set_range(0_f64, SIMILAR_VALUES[index][5] as f64); 27 | scale_similarity_similar_images.set_fill_level(SIMILAR_VALUES[index][5] as f64); 28 | label_similar_images_minimal_similarity.set_text(&get_string_from_similarity(&SIMILAR_VALUES[index][5], hash_size as u8)); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /czkawka_gui/src/connect_things/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod connect_about_buttons; 2 | pub mod connect_button_compare; 3 | pub mod connect_button_delete; 4 | pub mod connect_button_hardlink; 5 | pub mod connect_button_move; 6 | pub mod connect_button_save; 7 | pub mod connect_button_search; 8 | pub mod connect_button_select; 9 | pub mod connect_button_sort; 10 | pub mod connect_button_stop; 11 | pub mod connect_change_language; 12 | pub mod connect_duplicate_buttons; 13 | pub mod connect_header_buttons; 14 | pub mod connect_notebook_tabs; 15 | pub mod connect_popovers_select; 16 | pub mod connect_popovers_sort; 17 | pub mod connect_progress_window; 18 | pub mod connect_same_music_mode_changed; 19 | pub mod connect_selection_of_directories; 20 | pub mod connect_settings; 21 | pub mod connect_show_hide_ui; 22 | pub mod connect_similar_image_size_change; 23 | -------------------------------------------------------------------------------- /czkawka_gui/src/gui_structs/gui_header.rs: -------------------------------------------------------------------------------- 1 | use gtk4::prelude::*; 2 | 3 | use crate::help_functions::set_icon_of_button; 4 | use crate::{CZK_ICON_INFO, CZK_ICON_SETTINGS, flg}; 5 | 6 | #[derive(Clone)] 7 | pub struct GuiHeader { 8 | pub button_settings: gtk4::Button, 9 | pub button_app_info: gtk4::Button, 10 | } 11 | 12 | impl GuiHeader { 13 | pub fn create_from_builder(builder: >k4::Builder) -> Self { 14 | let button_settings: gtk4::Button = builder.object("button_settings").expect("Cambalache"); 15 | let button_app_info: gtk4::Button = builder.object("button_app_info").expect("Cambalache"); 16 | 17 | set_icon_of_button(&button_settings, CZK_ICON_SETTINGS); 18 | set_icon_of_button(&button_app_info, CZK_ICON_INFO); 19 | 20 | Self { button_settings, button_app_info } 21 | } 22 | 23 | pub fn update_language(&self) { 24 | self.button_settings.set_tooltip_text(Some(&flg!("header_setting_button_tooltip"))); 25 | self.button_app_info.set_tooltip_text(Some(&flg!("header_about_button_tooltip"))); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /czkawka_gui/src/gui_structs/gui_popovers_sort.rs: -------------------------------------------------------------------------------- 1 | use gtk4::Builder; 2 | use gtk4::prelude::*; 3 | 4 | use crate::flg; 5 | 6 | #[derive(Clone)] 7 | pub struct GuiSortPopovers { 8 | pub buttons_popover_sort_file_name: gtk4::Button, 9 | pub buttons_popover_sort_folder_name: gtk4::Button, 10 | pub buttons_popover_sort_full_name: gtk4::Button, 11 | pub buttons_popover_sort_size: gtk4::Button, 12 | pub buttons_popover_sort_selection: gtk4::Button, 13 | 14 | pub popover_sort: gtk4::Popover, 15 | } 16 | 17 | impl GuiSortPopovers { 18 | pub fn create_from_builder() -> Self { 19 | let glade_src = include_str!("../../ui/popover_sort.ui").to_string(); 20 | let builder = Builder::from_string(glade_src.as_str()); 21 | 22 | let buttons_popover_sort_file_name: gtk4::Button = builder.object("buttons_popover_sort_file_name").expect("Cambalache"); 23 | let buttons_popover_sort_folder_name: gtk4::Button = builder.object("buttons_popover_sort_folder_name").expect("Cambalache"); 24 | let buttons_popover_sort_full_name: gtk4::Button = builder.object("buttons_popover_sort_full_name").expect("Cambalache"); 25 | let buttons_popover_sort_size: gtk4::Button = builder.object("buttons_popover_sort_size").expect("Cambalache"); 26 | let buttons_popover_sort_selection: gtk4::Button = builder.object("buttons_popover_sort_selection").expect("Cambalache"); 27 | 28 | let popover_sort: gtk4::Popover = builder.object("popover_sort").expect("Cambalache"); 29 | 30 | Self { 31 | buttons_popover_sort_file_name, 32 | buttons_popover_sort_folder_name, 33 | buttons_popover_sort_full_name, 34 | buttons_popover_sort_size, 35 | buttons_popover_sort_selection, 36 | popover_sort, 37 | } 38 | } 39 | pub fn update_language(&self) { 40 | self.buttons_popover_sort_file_name.set_label(&flg!("popover_sort_file_name")); 41 | self.buttons_popover_sort_folder_name.set_label(&flg!("popover_sort_folder_name")); 42 | self.buttons_popover_sort_full_name.set_label(&flg!("popover_sort_full_name")); 43 | self.buttons_popover_sort_size.set_label(&flg!("popover_sort_size")); 44 | self.buttons_popover_sort_selection.set_label(&flg!("popover_sort_selection")); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /czkawka_gui/src/gui_structs/gui_progress_dialog.rs: -------------------------------------------------------------------------------- 1 | use gtk4::prelude::*; 2 | use gtk4::{Builder, EventControllerKey, Window}; 3 | 4 | use crate::help_functions::{get_custom_label_from_widget, set_icon_of_button}; 5 | use crate::{CZK_ICON_STOP, flg}; 6 | 7 | #[derive(Clone)] 8 | pub struct GuiProgressDialog { 9 | pub window_progress: gtk4::Dialog, 10 | 11 | pub progress_bar_current_stage: gtk4::ProgressBar, 12 | pub progress_bar_all_stages: gtk4::ProgressBar, 13 | 14 | pub label_stage: gtk4::Label, 15 | pub label_progress_current_stage: gtk4::Label, 16 | pub label_progress_all_stages: gtk4::Label, 17 | 18 | pub grid_progress: gtk4::Grid, 19 | 20 | pub button_stop_in_dialog: gtk4::Button, 21 | pub evk_button_stop_in_dialog: EventControllerKey, 22 | } 23 | 24 | impl GuiProgressDialog { 25 | pub fn create_from_builder(window_main: &Window) -> Self { 26 | let glade_src = include_str!("../../ui/progress.ui").to_string(); 27 | let builder = Builder::from_string(glade_src.as_str()); 28 | 29 | let window_progress: gtk4::Dialog = builder.object("window_progress").expect("Cambalache"); 30 | window_progress.set_title(Some(&flg!("window_progress_title"))); 31 | window_progress.set_transient_for(Some(window_main)); 32 | window_progress.set_modal(true); 33 | 34 | let progress_bar_current_stage: gtk4::ProgressBar = builder.object("progress_bar_current_stage").expect("Cambalache"); 35 | let progress_bar_all_stages: gtk4::ProgressBar = builder.object("progress_bar_all_stages").expect("Cambalache"); 36 | 37 | let label_stage: gtk4::Label = builder.object("label_stage").expect("Cambalache"); 38 | let label_progress_current_stage: gtk4::Label = builder.object("label_progress_current_stage").expect("Cambalache"); 39 | let label_progress_all_stages: gtk4::Label = builder.object("label_progress_all_stages").expect("Cambalache"); 40 | 41 | let grid_progress: gtk4::Grid = builder.object("grid_progress").expect("Cambalache"); 42 | 43 | let button_stop_in_dialog: gtk4::Button = builder.object("button_stop_in_dialog").expect("Cambalache"); 44 | let evk_button_stop_in_dialog = EventControllerKey::new(); 45 | button_stop_in_dialog.add_controller(evk_button_stop_in_dialog.clone()); 46 | 47 | set_icon_of_button(&button_stop_in_dialog, CZK_ICON_STOP); 48 | 49 | Self { 50 | window_progress, 51 | progress_bar_current_stage, 52 | progress_bar_all_stages, 53 | label_stage, 54 | label_progress_current_stage, 55 | label_progress_all_stages, 56 | grid_progress, 57 | button_stop_in_dialog, 58 | evk_button_stop_in_dialog, 59 | } 60 | } 61 | pub fn update_language(&self) { 62 | self.window_progress.set_title(Some(&flg!("window_progress_title"))); 63 | 64 | get_custom_label_from_widget(&self.button_stop_in_dialog.clone()).set_text(&flg!("progress_stop_button")); 65 | 66 | self.label_progress_current_stage.set_label(&flg!("progress_current_stage")); 67 | self.label_progress_all_stages.set_label(&flg!("progress_all_stages")); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /czkawka_gui/src/gui_structs/mod.rs: -------------------------------------------------------------------------------- 1 | mod gui_about; 2 | mod gui_bottom_buttons; 3 | mod gui_compare_images; 4 | pub mod gui_data; 5 | mod gui_header; 6 | pub mod gui_main_notebook; 7 | pub mod gui_popovers_select; 8 | pub mod gui_popovers_sort; 9 | mod gui_progress_dialog; 10 | pub mod gui_settings; 11 | pub mod gui_upper_notebook; 12 | -------------------------------------------------------------------------------- /czkawka_gui/src/language_functions.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone)] 2 | pub struct Language { 3 | pub combo_box_text: &'static str, 4 | pub short_text: &'static str, 5 | } 6 | 7 | pub const LANGUAGES_ALL: &[Language] = &[ 8 | Language { 9 | combo_box_text: "English", 10 | short_text: "en", 11 | }, 12 | Language { 13 | combo_box_text: "Français (French)", 14 | short_text: "fr", 15 | }, 16 | Language { 17 | combo_box_text: "Italiano (Italian)", 18 | short_text: "it", 19 | }, 20 | Language { 21 | combo_box_text: "Polski (Polish)", 22 | short_text: "pl", 23 | }, 24 | Language { 25 | combo_box_text: "Русский (Russian)", 26 | short_text: "ru", 27 | }, 28 | Language { 29 | combo_box_text: "український (Ukrainian)", 30 | short_text: "uk", 31 | }, 32 | Language { 33 | combo_box_text: "한국인 (Korean)", 34 | short_text: "ko", 35 | }, 36 | Language { 37 | combo_box_text: "Česky (Czech)", 38 | short_text: "cs", 39 | }, 40 | Language { 41 | combo_box_text: "Deutsch (German)", 42 | short_text: "de", 43 | }, 44 | Language { 45 | combo_box_text: "やまと (Japanese)", 46 | short_text: "ja", 47 | }, 48 | Language { 49 | combo_box_text: "Português (Portuguese)", 50 | short_text: "pt-PT", 51 | }, 52 | Language { 53 | combo_box_text: "Português Brasileiro (Brazilian Portuguese)", 54 | short_text: "pt-BR", 55 | }, 56 | Language { 57 | combo_box_text: "简体中文 (Simplified Chinese)", 58 | short_text: "zh-CN", 59 | }, 60 | Language { 61 | combo_box_text: "繁體中文 (Traditional Chinese)", 62 | short_text: "zh-TW", 63 | }, 64 | Language { 65 | combo_box_text: "Español (Spanish)", 66 | short_text: "es-ES", 67 | }, 68 | Language { 69 | combo_box_text: "Norsk (Norwegian)", 70 | short_text: "no", 71 | }, 72 | Language { 73 | combo_box_text: "Swedish (Svenska)", 74 | short_text: "sv-SE", 75 | }, 76 | Language { 77 | combo_box_text: "المملكة العربية السعودية (Saudi Arabia)", 78 | short_text: "ar", 79 | }, 80 | Language { 81 | combo_box_text: "България (Bulgaria)", 82 | short_text: "bg", 83 | }, 84 | Language { 85 | combo_box_text: "Ελλάδα (Greece)", 86 | short_text: "el", 87 | }, 88 | Language { 89 | combo_box_text: "Nederland (Netherlands)", 90 | short_text: "nl", 91 | }, 92 | Language { 93 | combo_box_text: "România (Romania)", 94 | short_text: "ro", 95 | }, 96 | ]; 97 | 98 | pub fn get_language_from_combo_box_text(combo_box_text: &str) -> Language { 99 | for lang in LANGUAGES_ALL { 100 | if lang.combo_box_text == combo_box_text { 101 | return lang.clone(); 102 | } 103 | } 104 | 105 | panic!("Not found proper text"); 106 | } 107 | -------------------------------------------------------------------------------- /czkawka_gui/src/localizer_gui.rs: -------------------------------------------------------------------------------- 1 | use i18n_embed::fluent::{FluentLanguageLoader, fluent_language_loader}; 2 | use i18n_embed::{DefaultLocalizer, LanguageLoader, Localizer}; 3 | use once_cell::sync::Lazy; 4 | use rust_embed::RustEmbed; 5 | 6 | #[derive(RustEmbed)] 7 | #[folder = "i18n/"] 8 | struct Localizations; 9 | 10 | pub static LANGUAGE_LOADER_GUI: Lazy<FluentLanguageLoader> = Lazy::new(|| { 11 | let loader: FluentLanguageLoader = fluent_language_loader!(); 12 | 13 | loader.load_fallback_language(&Localizations).expect("Error while loading fallback language"); 14 | 15 | loader 16 | }); 17 | 18 | #[macro_export] 19 | macro_rules! flg { 20 | ($message_id:literal) => {{ 21 | i18n_embed_fl::fl!($crate::localizer_gui::LANGUAGE_LOADER_GUI, $message_id) 22 | }}; 23 | 24 | ($message_id:literal, $($args:expr),*) => {{ 25 | i18n_embed_fl::fl!($crate::localizer_gui::LANGUAGE_LOADER_GUI, $message_id, $($args), *) 26 | }}; 27 | } 28 | 29 | // Get the `Localizer` to be used for localizing this library. 30 | pub fn localizer_gui() -> Box<dyn Localizer> { 31 | Box::from(DefaultLocalizer::new(&*LANGUAGE_LOADER_GUI, &Localizations)) 32 | } 33 | -------------------------------------------------------------------------------- /czkawka_gui/src/notebook_enums.rs: -------------------------------------------------------------------------------- 1 | use czkawka_core::TOOLS_NUMBER; 2 | 3 | pub const NUMBER_OF_NOTEBOOK_MAIN_TABS: usize = TOOLS_NUMBER; 4 | // pub const NUMBER_OF_NOTEBOOK_UPPER_TABS: usize = 3; 5 | 6 | // Needs to be updated when changed order of notebook tabs 7 | #[derive(Eq, PartialEq, Hash, Clone, Debug, Copy)] 8 | pub enum NotebookMainEnum { 9 | Duplicate = 0, 10 | EmptyDirectories, 11 | BigFiles, 12 | EmptyFiles, 13 | Temporary, 14 | SimilarImages, 15 | SimilarVideos, 16 | SameMusic, 17 | Symlinks, 18 | BrokenFiles, 19 | BadExtensions, 20 | } 21 | 22 | pub fn to_notebook_main_enum(notebook_number: u32) -> NotebookMainEnum { 23 | match notebook_number { 24 | 0 => NotebookMainEnum::Duplicate, 25 | 1 => NotebookMainEnum::EmptyDirectories, 26 | 2 => NotebookMainEnum::BigFiles, 27 | 3 => NotebookMainEnum::EmptyFiles, 28 | 4 => NotebookMainEnum::Temporary, 29 | 5 => NotebookMainEnum::SimilarImages, 30 | 6 => NotebookMainEnum::SimilarVideos, 31 | 7 => NotebookMainEnum::SameMusic, 32 | 8 => NotebookMainEnum::Symlinks, 33 | 9 => NotebookMainEnum::BrokenFiles, 34 | 10 => NotebookMainEnum::BadExtensions, 35 | _ => panic!("Invalid Notebook Tab"), 36 | } 37 | } 38 | 39 | pub fn get_all_main_tabs() -> [NotebookMainEnum; NUMBER_OF_NOTEBOOK_MAIN_TABS] { 40 | [ 41 | to_notebook_main_enum(0), 42 | to_notebook_main_enum(1), 43 | to_notebook_main_enum(2), 44 | to_notebook_main_enum(3), 45 | to_notebook_main_enum(4), 46 | to_notebook_main_enum(5), 47 | to_notebook_main_enum(6), 48 | to_notebook_main_enum(7), 49 | to_notebook_main_enum(8), 50 | to_notebook_main_enum(9), 51 | to_notebook_main_enum(10), 52 | ] 53 | } 54 | 55 | #[derive(Eq, PartialEq, Hash, Clone, Debug, Copy)] 56 | pub enum NotebookUpperEnum { 57 | IncludedDirectories = 0, 58 | ExcludedDirectories, 59 | ItemsConfiguration, 60 | } 61 | 62 | pub fn to_notebook_upper_enum(notebook_number: u32) -> NotebookUpperEnum { 63 | match notebook_number { 64 | 0 => NotebookUpperEnum::IncludedDirectories, 65 | 1 => NotebookUpperEnum::ExcludedDirectories, 66 | 2 => NotebookUpperEnum::ItemsConfiguration, 67 | _ => panic!("Invalid Upper Notebook Tab"), 68 | } 69 | } 70 | 71 | // pub fn get_all_upper_tabs() -> [NotebookUpperEnum; NUMBER_OF_NOTEBOOK_UPPER_TABS] { 72 | // [to_notebook_upper_enum(0), to_notebook_upper_enum(1), to_notebook_upper_enum(2)] 73 | // } 74 | -------------------------------------------------------------------------------- /czkawka_gui/src/taskbar_progress.rs: -------------------------------------------------------------------------------- 1 | #[cfg(not(target_os = "windows"))] 2 | pub use crate::taskbar_progress_dummy::{TaskbarProgress, tbp_flags}; 3 | #[cfg(target_os = "windows")] 4 | pub use crate::taskbar_progress_win::{TaskbarProgress, tbp_flags}; 5 | -------------------------------------------------------------------------------- /czkawka_gui/src/taskbar_progress_dummy.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::upper_case_acronyms)] 2 | #![allow(clippy::needless_pass_by_value)] 3 | #![allow(clippy::pedantic)] 4 | #![cfg(not(target_os = "windows"))] 5 | 6 | use std::convert::From; 7 | 8 | enum HWND__ {} 9 | 10 | type HWND = *mut HWND__; 11 | 12 | #[allow(non_camel_case_types, dead_code)] 13 | pub enum TBPFLAG { 14 | TBPF_NOPROGRESS = 0, 15 | TBPF_INDETERMINATE = 0x1, 16 | TBPF_NORMAL = 0x2, 17 | TBPF_ERROR = 0x4, 18 | TBPF_PAUSED = 0x8, 19 | } 20 | 21 | pub mod tbp_flags { 22 | pub use super::TBPFLAG::*; 23 | } 24 | 25 | pub struct TaskbarProgress {} 26 | 27 | impl TaskbarProgress { 28 | pub fn new() -> Self { 29 | Self {} 30 | } 31 | 32 | pub fn set_progress_state(&self, _tbp_flags: TBPFLAG) {} 33 | 34 | pub fn set_progress_value(&self, _completed: u64, _total: u64) {} 35 | 36 | pub fn hide(&self) {} 37 | 38 | pub fn show(&self) {} 39 | 40 | #[allow(clippy::needless_pass_by_ref_mut)] 41 | pub fn release(&mut self) {} 42 | } 43 | 44 | impl From<HWND> for TaskbarProgress { 45 | fn from(_hwnd: HWND) -> Self { 46 | Self {} 47 | } 48 | } 49 | 50 | impl Drop for TaskbarProgress { 51 | fn drop(&mut self) {} 52 | } 53 | -------------------------------------------------------------------------------- /czkawka_gui/src/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::GuiData; 2 | use crate::help_functions::get_notebook_enum_from_tree_view; 3 | use crate::notebook_enums::to_notebook_main_enum; 4 | use crate::notebook_info::NOTEBOOKS_INFO; 5 | 6 | pub fn validate_notebook_data(gui_data: &GuiData) { 7 | // Test treeviews names, each treeview should have set name same as variable name 8 | 9 | for item in &gui_data.main_notebook.get_main_tree_views() { 10 | // println!("Checking {} element", i); 11 | 12 | get_notebook_enum_from_tree_view(item); 13 | } 14 | 15 | // This test main info about notebooks 16 | // Should have same order as notebook enum types 17 | for (i, item) in NOTEBOOKS_INFO.iter().enumerate() { 18 | let en = to_notebook_main_enum(i as u32); 19 | assert_eq!(item.notebook_type, en); 20 | } 21 | 22 | // Tests if data returned from array get_notebook_enum_from_tree_view are in right 23 | for (i, item) in gui_data.main_notebook.get_main_tree_views().iter().enumerate() { 24 | let nb_en = get_notebook_enum_from_tree_view(item); 25 | assert_eq!(to_notebook_main_enum(i as u32), nb_en); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /czkawka_gui/ui/about_dialog.ui: -------------------------------------------------------------------------------- 1 | <?xml version='1.0' encoding='UTF-8'?> 2 | <!-- Created with Cambalache 0.94.1 --> 3 | <interface> 4 | <!-- interface-name about_dialog.ui --> 5 | <requires lib="gtk" version="4.6"/> 6 | <object class="GtkAboutDialog" id="about_dialog"> 7 | <property name="comments" translatable="yes">2020 - 2025 8 | Rafał Mikrut (qarmin) and contributors 9 | This program is free to use and will always be. 10 | App is now in maintenance mode, so check Krokiet, the sucessor of Czkawka. 11 | </property> 12 | <property name="license-type">mit-x11</property> 13 | <property name="logo-icon-name">help-about-symbolic</property> 14 | <property name="program-name">Czkawka</property> 15 | <property name="version">9.0.0</property> 16 | </object> 17 | </interface> 18 | -------------------------------------------------------------------------------- /czkawka_gui/ui/compare_images.ui: -------------------------------------------------------------------------------- 1 | <?xml version='1.0' encoding='UTF-8'?> 2 | <!-- Created with Cambalache 0.94.1 --> 3 | <interface> 4 | <!-- interface-name compare_images.ui --> 5 | <requires lib="gtk" version="4.6"/> 6 | <object class="GtkDialog" id="window_compare"> 7 | <child> 8 | <object class="GtkBox"> 9 | <property name="orientation">vertical</property> 10 | <property name="vexpand">1</property> 11 | <child> 12 | <object class="GtkBox"> 13 | <child> 14 | <object class="GtkButton" id="button_go_previous_compare_group"> 15 | <property name="focusable">1</property> 16 | <property name="receives-default">1</property> 17 | <child> 18 | <object class="GtkImage"> 19 | <property name="icon-name">image-missing</property> 20 | </object> 21 | </child> 22 | </object> 23 | </child> 24 | <child> 25 | <object class="GtkLabel" id="label_group_info"> 26 | <property name="halign">center</property> 27 | <property name="hexpand">1</property> 28 | <property name="label" translatable="yes">Group XD/PER XD (99 images in current group)</property> 29 | </object> 30 | </child> 31 | <child> 32 | <object class="GtkButton" id="button_go_next_compare_group"> 33 | <property name="focusable">1</property> 34 | <property name="receives-default">1</property> 35 | <child> 36 | <object class="GtkImage"> 37 | <property name="icon-name">image-missing</property> 38 | </object> 39 | </child> 40 | </object> 41 | </child> 42 | </object> 43 | </child> 44 | <child> 45 | <object class="GtkBox"> 46 | <property name="homogeneous">1</property> 47 | <child> 48 | <object class="GtkCheckButton" id="check_button_left_preview_text"> 49 | <property name="focusable">1</property> 50 | <property name="label" translatable="yes">First Game</property> 51 | </object> 52 | </child> 53 | <child> 54 | <object class="GtkCheckButton" id="check_button_right_preview_text"> 55 | <property name="focusable">1</property> 56 | <property name="label" translatable="yes">Second Game</property> 57 | </object> 58 | </child> 59 | </object> 60 | </child> 61 | <child> 62 | <object class="GtkBox"> 63 | <property name="homogeneous">1</property> 64 | <property name="vexpand">1</property> 65 | <child> 66 | <object class="GtkImage" id="image_compare_left"> 67 | <property name="height-request">100</property> 68 | </object> 69 | </child> 70 | <child> 71 | <object class="GtkImage" id="image_compare_right"> 72 | <property name="height-request">100</property> 73 | </object> 74 | </child> 75 | </object> 76 | </child> 77 | <child> 78 | <object class="GtkScrolledWindow" id="scrolled_window_compare_choose_images"> 79 | <property name="focusable">1</property> 80 | <property name="max-content-height">150</property> 81 | <property name="min-content-height">150</property> 82 | </object> 83 | </child> 84 | </object> 85 | </child> 86 | </object> 87 | </interface> 88 | -------------------------------------------------------------------------------- /czkawka_gui/ui/popover_right_click.ui: -------------------------------------------------------------------------------- 1 | <?xml version='1.0' encoding='UTF-8'?> 2 | <!-- Created with Cambalache 0.94.1 --> 3 | <interface> 4 | <!-- interface-name popover_right_click.ui --> 5 | <requires lib="gtk" version="4.6"/> 6 | <object class="GtkPopover" id="popover_right_click"> 7 | <property name="child"> 8 | <object class="GtkBox"> 9 | <property name="orientation">vertical</property> 10 | <child> 11 | <object class="GtkButton" id="buttons_popover_right_click_open_file"> 12 | <property name="focusable">1</property> 13 | <property name="label" translatable="yes">Open File</property> 14 | <property name="receives-default">1</property> 15 | </object> 16 | </child> 17 | <child> 18 | <object class="GtkButton" id="buttons_popover_right_click_open_folder"> 19 | <property name="focusable">1</property> 20 | <property name="label" translatable="yes">Open Folder</property> 21 | <property name="receives-default">1</property> 22 | </object> 23 | </child> 24 | </object> 25 | </property> 26 | <property name="position">left</property> 27 | </object> 28 | </interface> 29 | -------------------------------------------------------------------------------- /czkawka_gui/ui/popover_sort.ui: -------------------------------------------------------------------------------- 1 | <?xml version='1.0' encoding='UTF-8'?> 2 | <!-- Created with Cambalache 0.94.1 --> 3 | <interface> 4 | <!-- interface-name popover_sort.ui --> 5 | <requires lib="gtk" version="4.6"/> 6 | <object class="GtkPopover" id="popover_sort"> 7 | <property name="child"> 8 | <object class="GtkBox"> 9 | <property name="orientation">vertical</property> 10 | <child> 11 | <object class="GtkButton" id="buttons_popover_sort_file_name"> 12 | <property name="focusable">1</property> 13 | <property name="label">File name</property> 14 | <property name="receives-default">1</property> 15 | </object> 16 | </child> 17 | <child> 18 | <object class="GtkButton" id="buttons_popover_sort_folder_name"> 19 | <property name="focusable">1</property> 20 | <property name="label">Folder name</property> 21 | <property name="receives-default">1</property> 22 | </object> 23 | </child> 24 | <child> 25 | <object class="GtkButton" id="buttons_popover_sort_full_name"> 26 | <property name="focusable">1</property> 27 | <property name="label">Full name</property> 28 | <property name="receives-default">1</property> 29 | </object> 30 | </child> 31 | <child> 32 | <object class="GtkButton" id="buttons_popover_sort_size"> 33 | <property name="focusable">1</property> 34 | <property name="label">Size</property> 35 | <property name="receives-default">1</property> 36 | </object> 37 | </child> 38 | <child> 39 | <object class="GtkButton" id="buttons_popover_sort_selection"> 40 | <property name="focusable">1</property> 41 | <property name="label">Selection</property> 42 | <property name="receives-default">1</property> 43 | </object> 44 | </child> 45 | </object> 46 | </property> 47 | <property name="position">top</property> 48 | </object> 49 | </interface> 50 | -------------------------------------------------------------------------------- /data/com.github.qarmin.czkawka.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Terminal=false 4 | Exec=czkawka_gui 5 | Name=Czkawka 6 | Name[it]=Singhiozzo 7 | Comment=Multi functional app to clean OS which allow to find duplicates, empty folders, similar files etc. 8 | Comment[it]=Programma multifunzionale per pulire il sistema, che permette di trovare file duplicati, cartelle vuote, file simili, ecc... 9 | Comment[zh_CN]=可用于清理文件副本、空文件夹、相似文件等的系统清理工具 10 | Comment[zh_TW]=可用於清理重複檔案、空資料夾、相似檔案等的系統清理工具 11 | Icon=com.github.qarmin.czkawka 12 | Categories=System;FileTools 13 | Keywords=Hiccup;duplicate;same;similar;cleaner 14 | StartupWMClass=czkawka_gui 15 | TryExec=czkawka_gui 16 | -------------------------------------------------------------------------------- /data/com.github.qarmin.czkawka.metainfo.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <component type="desktop-application"> 3 | <id>com.github.qarmin.czkawka</id> 4 | <name>Czkawka</name> 5 | <summary>Multi functional app to find duplicates, empty folders, similar images, broken files etc.</summary> 6 | <metadata_license>CC0-1.0</metadata_license> 7 | <project_license>MIT</project_license> 8 | <description> 9 | <p> 10 | Czkawka is simple, fast and easy to use app to remove unnecessary files from your computer. 11 | </p> 12 | </description> 13 | <launchable type="desktop-id">com.github.qarmin.czkawka.desktop</launchable> 14 | <screenshots> 15 | <screenshot type="default"> 16 | <image>https://user-images.githubusercontent.com/41945903/147875238-7f82fa27-c6dd-47e7-87ed-e253fb2cbc3e.png</image> 17 | </screenshot> 18 | <screenshot> 19 | <image>https://user-images.githubusercontent.com/41945903/147875239-bcf9776c-885d-45ac-ba82-5a426d8e1647.png</image> 20 | </screenshot> 21 | <screenshot> 22 | <image>https://user-images.githubusercontent.com/41945903/147875243-e654e683-37f7-46fa-8321-119a4c5775e7.png</image> 23 | </screenshot> 24 | </screenshots> 25 | <releases> 26 | <release version="9.0.0" date="2025-03-16"/> 27 | </releases> 28 | <content_rating type="oars-1.0"/> 29 | <developer_name>Rafał Mikrut</developer_name> 30 | <developer id="com.github.qarmin"> 31 | <name>Rafał Mikrut</name> 32 | </developer> 33 | <url type="homepage">https://github.com/qarmin/czkawka</url> 34 | <url type="bugtracker">https://github.com/qarmin/czkawka/issues</url> 35 | <url type="donation">https://github.com/sponsors/qarmin</url> 36 | <url type="translate">https://crowdin.com/project/czkawka</url> 37 | </component> 38 | -------------------------------------------------------------------------------- /krokiet/.clippy.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qarmin/czkawka/2be42d9478501a90c36e8b1002fa3c7e5cb5ad2d/krokiet/.clippy.toml -------------------------------------------------------------------------------- /krokiet/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "krokiet" 3 | version = "9.0.0" 4 | authors = ["Rafał Mikrut <mikrutrafal@protonmail.com>"] 5 | edition = "2024" 6 | rust-version = "1.85.0" 7 | description = "Slint frontend of Czkawka Core" 8 | license = "GPL-3.0-only" 9 | homepage = "https://github.com/qarmin/czkawka" 10 | repository = "https://github.com/qarmin/czkawka" 11 | build = "build.rs" 12 | 13 | [dependencies] 14 | czkawka_core = { version = "9.0.0", path = "../czkawka_core" } 15 | chrono = "0.4.38" 16 | open = "5.3" 17 | crossbeam-channel = "0.5" 18 | rfd = { version = "0.15", default-features = false, features = ["xdg-portal", "async-std"] } 19 | home = "0.5" 20 | log = "0.4.22" 21 | serde = "1.0" 22 | serde_json = "1.0" 23 | humansize = "2.1" 24 | image = "0.25" 25 | image_hasher = "3.0" 26 | rayon = "1.10" 27 | fs_extra = "1.3" # TODO replace with less buggy library 28 | trash = "5.1" 29 | 30 | # Translations 31 | i18n-embed = { version = "0.15", features = ["fluent-system", "desktop-requester"] } 32 | i18n-embed-fl = "0.9" 33 | rust-embed = { version = "8.5", features = ["debug-embed"] } 34 | once_cell = "1.20" 35 | 36 | # Try to use only needed features from https://github.com/slint-ui/slint/blob/master/api/rs/slint/Cargo.toml#L23-L31 37 | #slint = { path = "/home/rafal/test/slint/api/rs/slint/", default-features = false, features = ["std", 38 | #slint = { git = "https://github.com/slint-ui/slint.git", default-features = false, features = [ 39 | slint = { version = "1.10", default-features = false, features = [ 40 | "std", 41 | "backend-winit", 42 | "compat-1-2" 43 | ] } 44 | [build-dependencies] 45 | #slint-build = { path = "/home/rafal/test/slint/api/rs/build/"} 46 | #slint-build = { git = "https://github.com/slint-ui/slint.git" } 47 | slint-build = "1.8" 48 | 49 | [features] 50 | default = ["winit_femtovg", "winit_software"] 51 | skia_opengl = ["slint/renderer-skia-opengl"] 52 | skia_vulkan = ["slint/renderer-skia-vulkan"] 53 | software = ["slint/renderer-software"] 54 | femtovg = ["slint/renderer-femtovg"] 55 | winit_femtovg = ["slint/renderer-winit-femtovg"] 56 | winit_skia_opengl = ["slint/renderer-winit-skia-opengl"] 57 | winit_skia_vulkan = ["slint/renderer-winit-skia-vulkan"] 58 | winit_software = ["slint/renderer-winit-software"] 59 | 60 | heif = ["czkawka_core/heif"] 61 | libraw = ["czkawka_core/libraw"] 62 | libavif = ["czkawka_core/libavif"] 63 | fast_image_resize = ["czkawka_core/fast_image_resize"] 64 | -------------------------------------------------------------------------------- /krokiet/LICENSE_MIT_CODE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2025 Rafał Mikrut 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /krokiet/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | if env::var("SLINT_STYLE").is_err() || env::var("SLINT_STYLE") == Ok(String::new()) { 5 | slint_build::compile_with_config("ui/main_window.slint", slint_build::CompilerConfiguration::new().with_style("fluent-dark".into())).expect("Unable to compile slint file"); 6 | } else { 7 | slint_build::compile("ui/main_window.slint").expect("Unable to compile slint file"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /krokiet/i18n.toml: -------------------------------------------------------------------------------- 1 | # (Required) The language identifier of the language used in the 2 | # source code for gettext system, and the primary fallback language 3 | # (for which all strings must be present) when using the fluent 4 | # system. 5 | fallback_language = "en" 6 | 7 | # Use the fluent localization system. 8 | [fluent] 9 | # (Required) The path to the assets directory. 10 | # The paths inside the assets directory should be structured like so: 11 | # `assets_dir/{language}/{domain}.ftl` 12 | assets_dir = "i18n" 13 | 14 | -------------------------------------------------------------------------------- /krokiet/icons/krokiet_add.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 | <svg 3 | enable-background="new 0 0 512 512" 4 | viewBox="0 0 512 512" 5 | version="1.1" 6 | id="svg3" 7 | sodipodi:docname="krokiet_remove.svg" 8 | inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 9 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 10 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 11 | xmlns="http://www.w3.org/2000/svg" 12 | xmlns:svg="http://www.w3.org/2000/svg"> 13 | <defs 14 | id="defs3" /> 15 | <sodipodi:namedview 16 | id="namedview3" 17 | pagecolor="#ffffff" 18 | bordercolor="#000000" 19 | borderopacity="0.25" 20 | inkscape:showpageshadow="2" 21 | inkscape:pageopacity="0.0" 22 | inkscape:pagecheckerboard="0" 23 | inkscape:deskcolor="#d1d1d1" 24 | inkscape:zoom="1.1357422" 25 | inkscape:cx="-4.4024076" 26 | inkscape:cy="378.16681" 27 | inkscape:window-width="2560" 28 | inkscape:window-height="1371" 29 | inkscape:window-x="0" 30 | inkscape:window-y="0" 31 | inkscape:window-maximized="1" 32 | inkscape:current-layer="svg3" /> 33 | <path 34 | d="m253.67845 460.24602c-111.34242 0-201.924473-90.58205-201.924473-201.92447s90.582053-201.924472 201.924473-201.924472 201.92447 90.582052 201.92447 201.924472-90.58205 201.92447-201.92447 201.92447zm0-387.158623c-102.1375 0-185.234153 83.096653-185.234153 185.234153s83.096653 185.23415 185.234153 185.23415 185.23415-83.09665 185.23415-185.23415-83.09665-185.234153-185.23415-185.234153z" 35 | stroke-width=".788767" 36 | id="path1" /> 37 | <g 38 | transform="matrix(4.1302107e-5,0.78876747,-0.78876747,4.1302107e-5,463.87368,57.755015)" 39 | id="g3"> 40 | <path 41 | d="m 96.446,234.14 h 327.87 v 55.947 H 96.446 Z" 42 | id="path2" /> 43 | <path 44 | d="m 98.184,-288.35 h 327.87 v 55.947 H 98.184 Z" 45 | transform="rotate(90)" 46 | id="path3" /> 47 | </g> 48 | </svg> 49 | -------------------------------------------------------------------------------- /krokiet/icons/krokiet_delete.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m251.09789 472.84735c-116.86793 0-211.945238-95.07731-211.945238-211.94524s95.077308-211.945239 211.945238-211.945239 211.94524 95.077309 211.94524 211.945239-95.07731 211.94524-211.94524 211.94524zm0-406.371881c-107.20621 0-194.42664 87.220441-194.42664 194.426641 0 107.20621 87.22043 194.42664 194.42664 194.42664 107.2062 0 194.42664-87.22043 194.42664-194.42664 0-107.2062-87.22044-194.426641-194.42664-194.426641z" stroke-width=".827911"/><path d="m372.64648 229.92167h-240.74591v65.12515h240.74591z" stroke-width="1.02186"/></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_dir.svg: -------------------------------------------------------------------------------- 1 | <svg height="800" viewBox="0 0 24 24" width="800" xmlns="http://www.w3.org/2000/svg"><path d="m20 6h-8l-1.234019-2h-6.765981c-1.1 0-1.99.9-1.99 2l-.01 12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2v-10c0-1.1-.9-2-2-2zm.353272 12.646417-16.9353697-.074836.0407418-11.2095966 16.8454139.0812889z"/></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_info.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m24.773302 46.565159h177.47093v34.719147h-177.47093z"/><path d="m24.509338 89.189049h320.15558v34.719147h-320.15558z" stroke-width="1.34313"/><path d="m24.301399 131.74066h258.78989v34.719147h-258.78989z" stroke-width="1.20756"/><path d="m24.437267 174.7984h355.40219v34.719147h-355.40219z" stroke-width="1.41513"/><path d="m24.333075 218.5652h295.98373v34.719147h-295.98373z" stroke-width="1.29143"/><path d="m23.53825 261.53271h230.1015v34.719147h-230.1015z" stroke-width="1.13867"/><path d="m23.328859 306.26999h367.64264v34.719147h-367.64264z" stroke-width="1.43929"/><path d="m23.514387 351.94516h177.47093v34.719147h-177.47093z"/><path d="m23.365833 394.39001h311.79446v34.719147h-311.79446z" stroke-width="1.32547"/><path d="m23.207998 438.19919h425.50278v34.719147h-425.50278z" stroke-width="1.54842"/></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qarmin/czkawka/2be42d9478501a90c36e8b1002fa3c7e5cb5ad2d/krokiet/icons/krokiet_logo.png -------------------------------------------------------------------------------- /krokiet/icons/krokiet_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qarmin/czkawka/2be42d9478501a90c36e8b1002fa3c7e5cb5ad2d/krokiet/icons/krokiet_logo_small.png -------------------------------------------------------------------------------- /krokiet/icons/krokiet_manual_add.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 | <svg 3 | enable-background="new 0 0 512 512" 4 | viewBox="0 0 512 512" 5 | version="1.1" 6 | id="svg2" 7 | sodipodi:docname="krokiet_manual_add.svg" 8 | inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 9 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 10 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 11 | xmlns="http://www.w3.org/2000/svg" 12 | xmlns:svg="http://www.w3.org/2000/svg"> 13 | <defs 14 | id="defs2" /> 15 | <sodipodi:namedview 16 | id="namedview2" 17 | pagecolor="#ffffff" 18 | bordercolor="#000000" 19 | borderopacity="0.25" 20 | inkscape:showpageshadow="2" 21 | inkscape:pageopacity="0.0" 22 | inkscape:pagecheckerboard="0" 23 | inkscape:deskcolor="#d1d1d1" 24 | inkscape:zoom="0.803091" 25 | inkscape:cx="-31.129722" 26 | inkscape:cy="234.71811" 27 | inkscape:window-width="2110" 28 | inkscape:window-height="1371" 29 | inkscape:window-x="20" 30 | inkscape:window-y="20" 31 | inkscape:window-maximized="0" 32 | inkscape:current-layer="svg2" /> 33 | <path 34 | d="m 71.791417,475.05523 -5.480294,21.88756 19.104071,-11.93623 -9.223431,-3.41049 z" 35 | style="fill:#161616;stroke:#356200;stroke-width:0" 36 | id="path6" 37 | sodipodi:nodetypes="ccccc" /> 38 | <path 39 | style="fill:#161616;stroke:#356200;stroke-width:0;stroke-dasharray:none" 40 | d="m 101.90753,415.91461 12.45293,17.04858 19.74694,8.22373 69.9595,-87.38209 -17.25603,-17.42666 -23.93169,-13.50038 z" 41 | id="path7" 42 | sodipodi:nodetypes="ccccccc" /> 43 | <path 44 | style="fill:#161616;stroke:#356200;stroke-width:0;stroke-dasharray:none" 45 | d="m 99.577071,426.08702 -22.290335,41.36898 5.218726,7.48286 8.678331,3.52102 34.536237,-31.61873 -16.51135,-7.24305 z" 46 | id="path8" 47 | sodipodi:nodetypes="ccccccc" /> 48 | <path 49 | style="fill:#161616;stroke:#356200;stroke-width:0;stroke-dasharray:none" 50 | d="m 171.19801,315.74161 22.00422,10.85205 14.95158,15.13577 L 392.93278,96.130388 350.05277,68.143527 Z" 51 | id="path9" 52 | sodipodi:nodetypes="cccccc" /> 53 | <path 54 | style="fill:#161616;stroke:#356200;stroke-width:0;stroke-dasharray:none" 55 | d="m 356.08538,58.706307 14.62872,-19.446043 56.27452,38.035783 10.44854,-13.856213 3.34354,2.644318 -100.933,133.061878 -3.13457,-2.53856 73.76678,-101.753189 z" 56 | id="path10" 57 | sodipodi:nodetypes="ccccccccc" /> 58 | <path 59 | style="fill:#161616;stroke:#356200;stroke-width:0;stroke-dasharray:none" 60 | d="M 381.98339,33.528506 418.75428,58.344397 431.89942,41.800469 414.47756,26.57852 393.35217,16.26528 Z" 61 | id="path11" 62 | sodipodi:nodetypes="cccccc" /> 63 | </svg> 64 | -------------------------------------------------------------------------------- /krokiet/icons/krokiet_move.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m512 164.379v258.695c0 28.231-22.969 51.2-51.2 51.2h-409.6c-28.231 0-51.2-22.969-51.2-51.2v-183.242c0-1.299.049-2.586.144-3.862-.094-.495 3.4314235 78.12995-.144-1.528-12.945347-288.413346 89.381493-161.580916 460.8-121.263 28.06613 3.04661 51.2 22.969 51.2 51.2zm-463.495 24.323c.894-.047 1.79-.07 2.695-.07zm447.327-24.323c0-19.317-15.715-35.032-35.032-35.032l-444.374512 1.52394-.257488 278.72906v13.474c0 19.317 15.715 35.032 35.032 35.032h409.6c19.317 0 35.032-15.715 35.032-35.032z"/></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_remove.svg: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 | <svg 3 | enable-background="new 0 0 512 512" 4 | viewBox="0 0 512 512" 5 | version="1.1" 6 | id="svg3" 7 | sodipodi:docname="krokiet_remove.svg" 8 | inkscape:version="1.4 (e7c3feb100, 2024-10-09)" 9 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" 10 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" 11 | xmlns="http://www.w3.org/2000/svg" 12 | xmlns:svg="http://www.w3.org/2000/svg"> 13 | <defs 14 | id="defs3" /> 15 | <sodipodi:namedview 16 | id="namedview3" 17 | pagecolor="#ffffff" 18 | bordercolor="#000000" 19 | borderopacity="0.25" 20 | inkscape:showpageshadow="2" 21 | inkscape:pageopacity="0.0" 22 | inkscape:pagecheckerboard="0" 23 | inkscape:deskcolor="#d1d1d1" 24 | inkscape:zoom="1.1357422" 25 | inkscape:cx="-4.4024076" 26 | inkscape:cy="378.16681" 27 | inkscape:window-width="2560" 28 | inkscape:window-height="1371" 29 | inkscape:window-x="0" 30 | inkscape:window-y="0" 31 | inkscape:window-maximized="1" 32 | inkscape:current-layer="g3" /> 33 | <path 34 | d="m253.67845 460.24602c-111.34242 0-201.924473-90.58205-201.924473-201.92447s90.582053-201.924472 201.924473-201.924472 201.92447 90.582052 201.92447 201.924472-90.58205 201.92447-201.92447 201.92447zm0-387.158623c-102.1375 0-185.234153 83.096653-185.234153 185.234153s83.096653 185.23415 185.234153 185.23415 185.23415-83.09665 185.23415-185.23415-83.09665-185.234153-185.23415-185.234153z" 35 | stroke-width=".788767" 36 | id="path1" /> 37 | <g 38 | transform="matrix(4.1302107e-5,0.78876747,-0.78876747,4.1302107e-5,463.87368,57.755015)" 39 | id="g3"> 40 | <path 41 | d="m 98.184,-288.35 h 327.87 v 55.947 H 98.184 Z" 42 | transform="rotate(90)" 43 | id="path3" /> 44 | </g> 45 | </svg> 46 | -------------------------------------------------------------------------------- /krokiet/icons/krokiet_rename.svg: -------------------------------------------------------------------------------- 1 | <svg clip-rule="evenodd" fill-rule="evenodd" height="2048" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 2048 2048" width="2048" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h2048v2048h-2048z" fill="none"/><path d="m87.25 611.2605h82.087448v892.82898h-82.087448z" stroke-width=".568446"/><path d="m236.19318 758.95111h866.16052v600.99158h-866.16052z" stroke-width="1.51496"/><path d="m1362.5925 758.12317h203.16624v600.84137h-203.16624z" stroke-width=".733624"/><path d="m87.248306 611.43683h1024.4435v85.122589h-1024.4435z" stroke-width=".62006"/><path d="m917.55438 359.38852h610.18457v85.122589h-610.18457z" stroke-width=".478542"/><path d="m916.36346 1618.0974h610.18457v85.122589h-610.18457z" stroke-width=".478542"/><path d="m87.277161 1418.9902h1024.4435v85.122589h-1024.4435z" stroke-width=".62006"/><path d="m1816.3279 613.24561h82.087448v892.82898h-82.087448z" stroke-width=".568446"/><path d="m1194.8612 430.29568h82.087448v1206.1714h-82.087448z" stroke-width=".660708"/><g stroke-width=".441443"><path d="m1361.6683 613.46094h536.68848v82.355583h-536.68848z"/><path d="m1361.4937 1423.62h536.68848v82.355583h-536.68848z"/></g></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_save.svg: -------------------------------------------------------------------------------- 1 | <svg clip-rule="evenodd" fill-rule="evenodd" height="2048" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 2048 2048" width="2048" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h2048v2048h-2048z" fill="none"/><path d="m236.71658 507.59377h82.08745v1271.91523h-82.08745z" stroke-width=".678476"/><path d="m474.29746 533.31919h82.08745v398.17011h-82.08745z" stroke-width=".379612"/><path d="m1022.7429 849.58334v82.08745h-519.64533v-82.08745z" stroke-width=".43367"/><path d="m966.21052 532.48314h82.08738v398.1701h-82.08738z" stroke-width=".379612"/><path d="m235.65532 1746.6133h1546.04568v85.1226h-1546.04568z" stroke-width=".761729"/><path d="m236.6738 507.31956h1076.3544v85.1226h-1076.3544z" stroke-width=".635575"/><path d="m1311.7633 507.6448 469.3371 399.07317-55.1405 64.84894-469.3371-399.07317z" stroke-width=".480842"/><path d="m1699.1531 904.94712h82.0874v925.90568h-82.0874z" stroke-width=".57888"/><ellipse cx="985.26324" cy="1279.5432" rx="166.93671" ry="169.26324"/></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_search.svg: -------------------------------------------------------------------------------- 1 | <svg clip-rule="evenodd" fill-rule="evenodd" height="2048" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 2048 2048" width="2048" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m405 407c100-100 231-150 362-150s262 50 362 150 150 231 150 362-50 262-150 362-231 150-362 150-262-50-362-150-150-231-150-362 50-262 150-362zm362-86c-115 0-229 44-317 131-87 87-131 202-131 317s44 229 131 317c87 87 202 131 317 131s229-44 317-131c87-87 131-202 131-317s-44-229-131-317c-87-87-202-131-317-131z"/><path d="m1161 1066 444 444-92 90-444-444z" stroke-width="2"/></g><path d="m0 0h2048v2048h-2048z" fill="none"/></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_select.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 256 256" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg"><text/><path d="m88.762429 63.360798s-.422221 3.866804 1.564925 14.586544c.702752 3.791076 1.755116 8.245298 3.305133 12.476376.746597 2.038002 1.623507 4.065074 2.655645 5.960422 1.019612 1.872363 2.214311 3.65987 3.622478 5.21535 1.41229 1.55999 3.06238 2.91163 4.98677 3.86575 1.9601.97182 4.13058 1.49307 6.48306 1.45457 2.39714-.0393 4.86216-.65723 7.35925-1.80738 2.58382-1.1901 5.18603-2.9417 7.79784-5.191517 5.76675-4.967507 11.58647-12.371239 17.35185-21.488295 7.58688-11.997444 14.68709-26.35706 20.48863-39.477373 0 0-5.64097-3.03885-5.64097-3.03885s-5.64096-3.038852-5.64096-3.038852c-5.71885 12.933369-12.19317 26.718281-18.91857 38.402125-5.11472 8.885674-9.85335 15.642247-14.17638 20.178223-1.93003 2.025082-3.68252 3.507311-5.26449 4.54966-1.51207.996293-2.85107 1.579658-4.03668 1.865955-1.15181.278137-2.25333.299771-3.34763.05507-1.09846-.245557-2.22523-.768213-3.3798-1.611286-1.15559-.843802-2.28711-1.971265-3.38107-3.344183-1.103294-1.384656-2.133049-2.974344-3.086024-4.686454-1.985446-3.567097-3.576614-7.554834-4.796996-11.098968-3.437201-9.981995-3.946011-13.826957-3.946011-13.826957z" stroke-width="1.64865"/><g stroke-width="1.52107"><path d="m166.32011 17.387035h12.277943v104.96534h-12.277943z"/><path d="m73.619453 17.351675h12.277943v104.96534h-12.277943z"/><path d="m17.369175-178.59412h12.277943v104.96534h-12.277943z" transform="rotate(90)"/><path d="m110.02438-178.60258h12.277943v104.96534h-12.277943z" transform="rotate(90)"/><path d="m167.52612 131.14308h12.277943v104.96534h-12.277943z"/><path d="m74.82547 131.10773h12.277943v104.96534h-12.277943z"/><g transform="rotate(90)"><path d="m131.12523-179.80013h12.277943v104.96534h-12.277943z"/><path d="m223.78044-179.80859h12.277943v104.96534h-12.277943z"/></g></g></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_settings.svg: -------------------------------------------------------------------------------- 1 | <svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m296 186.72a80 80 0 1 0 29.282 109.28 80.24 80.24 0 0 0 -29.282-109.28zm109.58 155.64a165.53 165.53 0 0 1 -12.59 18.527l23.107 57.358a11.59 11.59 0 0 1 -5.1124 14.115l-79.649 45.836a11.64 11.64 0 0 1 -14.711-2.8005l-38.08-48.544a176.56 176.56 0 0 1 -44.954.2228l-37.803 48.357a11.93 11.93 0 0 1 -14.898 2.784l-79.778-46.06a12 12 0 0 1 -5.203-14.008l22.977-56.917a169.3 169.3 0 0 1 -22.274-39.06l-61.08-8.7064a11.64 11.64 0 0 1 -9.7856-11.331l-.13413-91.888a11.59 11.59 0 0 1 9.6676-11.485l61.227-8.6679a174.58 174.58 0 0 1 9.9147-20.453 165.53 165.53 0 0 1 12.59-18.527l-23.107-57.358a11.59 11.59 0 0 1 5.1124-14.115l79.649-45.836a11.64 11.64 0 0 1 14.711 2.8005l38.08 48.544a176.56 176.56 0 0 1 44.954-.2228l37.803-48.357a11.93 11.93 0 0 1 14.898-2.784l79.778 46.06a12 12 0 0 1 5.203 14.008l-22.977 56.917a169.3 169.3 0 0 1 22.317 39.085l61.037 8.6814a11.64 11.64 0 0 1 9.7856 11.331l.12913 91.896a11.59 11.59 0 0 1 -9.6676 11.485l-61.227 8.6679a174.58 174.58 0 0 1 -9.9097 20.444z"/></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_stop.svg: -------------------------------------------------------------------------------- 1 | <svg enable-background="new 0 0 512 512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m253.67845 460.24602c-111.34242 0-201.924473-90.58205-201.924473-201.92447s90.582053-201.924472 201.924473-201.924472 201.92447 90.582052 201.92447 201.924472-90.58205 201.92447-201.92447 201.92447zm0-387.158623c-102.1375 0-185.234153 83.096653-185.234153 185.234153s83.096653 185.23415 185.234153 185.23415 185.23415-83.09665 185.23415-185.23415-83.09665-185.234153-185.23415-185.234153z" stroke-width=".788767"/><g transform="matrix(.55777203 .55771362 -.55771362 .55777203 258.08847 -28.27187)"><path d="m96.446 234.14h327.87v55.947h-327.87z"/><path d="m98.184-288.35h327.87v55.947h-327.87z" transform="rotate(90)"/></g></svg> -------------------------------------------------------------------------------- /krokiet/icons/krokiet_subsettings.svg: -------------------------------------------------------------------------------- 1 | <svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m259.96 178.63c-116.38.46054-109.81 154.42-4.8963 157.07 110.82 2.7975 108.63-157.48 4.8963-157.07zm-4.5114 238.17-59.661 58.623c-3.663 4.3684-9.9047 5.5348-14.898 2.784l-79.778-46.06c-4.7847-2.888-6.9422-8.6968-5.203-14.008l22.977-56.917c-9.1283-11.972-16.619-25.108-22.274-39.06l-61.08-8.7064c-5.5804-.89998-9.7077-5.679-9.7856-11.331l-.13413-91.888c-.02721-5.6801 4.0661-10.543 9.6676-11.485l61.227-8.6679c2.8571-7.0258 6.169-13.858 9.9147-20.453 3.7735-6.4529 7.9798-12.643 12.59-18.527l-23.107-57.358c-1.985-5.3221.17966-11.298 5.1124-14.115l79.649-45.836c4.933-2.7634 11.138-1.5821 14.711 2.8005l66.966 73.793c-6.8372 161.75-1.2386 214.48-6.8946 306.41z"/><g stroke-width=".8921"><path d="m275 50h200v20h-200z"/><path d="m275 85h200v20h-200z"/><path d="m275 120h200v20h-200z"/><path d="m275 155h200v20h-200z"/></g><path d="m335 190h140v20h-140z" stroke-width=".74638"/><path d="m345 225h130v20h-130z" stroke-width=".71923"/><g transform="scale(1 -1)"><g stroke-width=".89168"><path d="m273.16-466.69h199.81v20h-199.81z"/><path d="m273.16-431.69h199.81v20h-199.81z"/><path d="m273.16-396.69h199.81v20h-199.81z"/><path d="m273.16-361.69h199.81v20h-199.81z"/></g><path d="m333.1-326.69h139.87v20h-139.87z" stroke-width=".74603"/><path d="m343.09-291.69h129.88v20h-129.88z" stroke-width=".71889"/></g></svg> -------------------------------------------------------------------------------- /krokiet/src/connect_open.rs: -------------------------------------------------------------------------------- 1 | use czkawka_core::common::get_config_cache_path; 2 | use log::error; 3 | use slint::ComponentHandle; 4 | 5 | use crate::{Callabler, MainWindow}; 6 | 7 | pub fn connect_open_items(app: &MainWindow) { 8 | app.global::<Callabler>().on_open_config_folder(move || { 9 | let Some(config_cache) = get_config_cache_path() else { 10 | error!("Failed to open config folder"); 11 | return; 12 | }; 13 | if let Err(e) = open::that(&config_cache.config_folder) { 14 | error!("Failed to open config folder \"{}\": {e}", config_cache.config_folder.to_string_lossy()); 15 | } 16 | }); 17 | 18 | app.global::<Callabler>().on_open_cache_folder(move || { 19 | let Some(config_cache) = get_config_cache_path() else { 20 | error!("Failed to open cache folder"); 21 | return; 22 | }; 23 | if let Err(e) = open::that(&config_cache.cache_folder) { 24 | error!("Failed to open cache folder \"{}\": {e}", config_cache.cache_folder.to_string_lossy()); 25 | } 26 | }); 27 | 28 | app.global::<Callabler>().on_open_link(move |link| { 29 | match open::that(link.as_str()) { 30 | Ok(()) => {} 31 | Err(e) => { 32 | error!("Failed to open link: {e}"); 33 | } 34 | }; 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /krokiet/src/connect_rename.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::path::{MAIN_SEPARATOR, Path}; 3 | 4 | use czkawka_core::common_messages::Messages; 5 | use slint::{ComponentHandle, ModelRc, VecModel}; 6 | 7 | use crate::common::{get_is_header_mode, get_tool_model, set_tool_model}; 8 | use crate::connect_row_selection::reset_selection; 9 | use crate::model_operations::{collect_path_name_and_proper_extension_from_model, deselect_all_items, filter_out_checked_items}; 10 | use crate::{Callabler, CurrentTab, GuiState, MainListModel, MainWindow, flk}; 11 | 12 | pub fn connect_rename(app: &MainWindow) { 13 | let a = app.as_weak(); 14 | app.global::<Callabler>().on_rename_files(move || { 15 | let app = a.upgrade().expect("Failed to upgrade app :("); 16 | let active_tab = app.global::<GuiState>().get_active_tab(); 17 | let current_model = get_tool_model(&app, active_tab); 18 | 19 | let (errors, new_model) = rename_operation(¤t_model, active_tab); 20 | if let Some(new_model) = new_model { 21 | set_tool_model(&app, active_tab, new_model); 22 | } 23 | app.global::<GuiState>().set_info_text(Messages::new_from_errors(errors).create_messages_text().into()); 24 | reset_selection(&app, true); 25 | }); 26 | } 27 | 28 | fn rename_operation(items: &ModelRc<MainListModel>, active_tab: CurrentTab) -> (Vec<String>, Option<ModelRc<MainListModel>>) { 29 | assert_eq!(active_tab, CurrentTab::BadExtensions); 30 | let (entries_to_move, mut entries_left) = filter_out_checked_items(items, get_is_header_mode(active_tab)); 31 | 32 | if !entries_to_move.is_empty() { 33 | let vec_items_to_rename = collect_path_name_and_proper_extension_from_model(&entries_to_move, active_tab); 34 | let errors = rename_selected_items(vec_items_to_rename); 35 | deselect_all_items(&mut entries_left); 36 | 37 | let r = ModelRc::new(VecModel::from(entries_left)); 38 | return (errors, Some(r)); 39 | } 40 | (vec![], None) 41 | } 42 | 43 | fn rename_selected_items(files_with_new_extensions: Vec<(String, String, String)>) -> Vec<String> { 44 | let mut errors = vec![]; 45 | for (folder, file_name, new_extension) in files_with_new_extensions { 46 | let file_stem = Path::new(&file_name).file_stem().map(|e| e.to_string_lossy().to_string()).unwrap_or_default(); 47 | let new_full_path = format!("{folder}{MAIN_SEPARATOR}{file_stem}.{new_extension}"); 48 | let old_full_path = format!("{folder}{MAIN_SEPARATOR}{file_name}"); 49 | if let Err(e) = fs::rename(&old_full_path, &new_full_path) { 50 | errors.push(flk!( 51 | "rust_failed_to_rename_file", 52 | old_path = old_full_path, 53 | new_path = new_full_path, 54 | error = e.to_string() 55 | )); 56 | } 57 | } 58 | errors 59 | } 60 | -------------------------------------------------------------------------------- /krokiet/src/connect_save.rs: -------------------------------------------------------------------------------- 1 | use std::sync::{Arc, Mutex}; 2 | 3 | use rfd::FileDialog; 4 | use slint::ComponentHandle; 5 | 6 | use crate::shared_models::SharedModels; 7 | use crate::{Callabler, GuiState, MainWindow}; 8 | 9 | pub fn connect_save(app: &MainWindow, shared_models: Arc<Mutex<SharedModels>>) { 10 | let a = app.as_weak(); 11 | app.global::<Callabler>().on_save_results(move || { 12 | let app = a.upgrade().expect("Failed to upgrade app :("); 13 | let active_tab = app.global::<GuiState>().get_active_tab(); 14 | 15 | let file_dialog = FileDialog::new(); 16 | let Some(folder) = file_dialog.pick_folder() else { 17 | return; 18 | }; 19 | let folder_str = folder.to_string_lossy(); 20 | if let Err(e) = shared_models.lock().unwrap().save_results(active_tab, &folder_str) { 21 | app.global::<GuiState>().set_info_text(e.into()); 22 | } 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /krokiet/src/connect_show_preview.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use std::time::{Duration, Instant}; 3 | 4 | use czkawka_core::common_image::{check_if_can_display_image, get_dynamic_image_from_path}; 5 | use image::DynamicImage; 6 | use log::{debug, error}; 7 | use slint::ComponentHandle; 8 | 9 | use crate::{Callabler, CurrentTab, GuiState, MainWindow, Settings}; 10 | 11 | pub type ImageBufferRgba = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>; 12 | 13 | pub fn connect_show_preview(app: &MainWindow) { 14 | let a = app.as_weak(); 15 | app.global::<Callabler>().on_load_image_preview(move |image_path| { 16 | let app = a.upgrade().expect("Failed to upgrade app :("); 17 | 18 | let settings = app.global::<Settings>(); 19 | let gui_state = app.global::<GuiState>(); 20 | 21 | let active_tab = gui_state.get_active_tab(); 22 | 23 | if !((active_tab == CurrentTab::SimilarImages && settings.get_similar_images_show_image_preview()) 24 | || (active_tab == CurrentTab::DuplicateFiles && settings.get_duplicate_image_preview())) 25 | { 26 | set_preview_visible(&gui_state, None); 27 | return; 28 | } 29 | 30 | if !check_if_can_display_image(&image_path) { 31 | set_preview_visible(&gui_state, None); 32 | return; 33 | } 34 | 35 | // Do not load the same image again 36 | if image_path == gui_state.get_preview_image_path() { 37 | return; 38 | } 39 | 40 | let path = Path::new(image_path.as_str()); 41 | 42 | let res = load_image(path); 43 | if let Some((load_time, img)) = res { 44 | let start_timer_convert_time = Instant::now(); 45 | let slint_image = convert_into_slint_image(&img); 46 | let convert_time = start_timer_convert_time.elapsed(); 47 | 48 | let start_set_time = Instant::now(); 49 | gui_state.set_preview_image(slint_image); 50 | let set_time = start_set_time.elapsed(); 51 | 52 | debug!("Loading image took: {load_time:?}, converting image took: {convert_time:?}, setting image took: {set_time:?}"); 53 | set_preview_visible(&gui_state, Some(image_path.as_str())); 54 | } else { 55 | set_preview_visible(&gui_state, None); 56 | } 57 | }); 58 | } 59 | 60 | fn set_preview_visible(gui_state: &GuiState, preview: Option<&str>) { 61 | if let Some(preview) = preview { 62 | gui_state.set_preview_image_path(preview.into()); 63 | gui_state.set_preview_visible(true); 64 | } else { 65 | gui_state.set_preview_image_path("".into()); 66 | gui_state.set_preview_visible(false); 67 | } 68 | } 69 | 70 | fn convert_into_slint_image(img: &DynamicImage) -> slint::Image { 71 | let image_buffer: ImageBufferRgba = img.to_rgba8(); 72 | let buffer = slint::SharedPixelBuffer::<slint::Rgba8Pixel>::clone_from_slice(image_buffer.as_raw(), image_buffer.width(), image_buffer.height()); 73 | slint::Image::from_rgba8(buffer) 74 | } 75 | 76 | fn load_image(image_path: &Path) -> Option<(Duration, DynamicImage)> { 77 | if !image_path.is_file() { 78 | return None; 79 | } 80 | 81 | let load_img_start_timer = Instant::now(); 82 | 83 | let img = match get_dynamic_image_from_path(&image_path.to_string_lossy()) { 84 | Ok(img) => img, 85 | Err(e) => { 86 | error!("Failed to load image: {e}"); 87 | return None; 88 | } 89 | }; 90 | Some((load_img_start_timer.elapsed(), img)) 91 | } 92 | -------------------------------------------------------------------------------- /krokiet/src/connect_stop.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | use std::sync::atomic::AtomicBool; 3 | 4 | use crate::MainWindow; 5 | 6 | pub fn connect_stop_button(app: &MainWindow, stop_sender: Arc<AtomicBool>) { 7 | app.on_scan_stopping(move || { 8 | stop_sender.store(true, std::sync::atomic::Ordering::Relaxed); 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /krokiet/src/localizer_krokiet.rs: -------------------------------------------------------------------------------- 1 | use i18n_embed::fluent::{FluentLanguageLoader, fluent_language_loader}; 2 | use i18n_embed::{DefaultLocalizer, LanguageLoader, Localizer}; 3 | use once_cell::sync::Lazy; 4 | use rust_embed::RustEmbed; 5 | 6 | #[derive(RustEmbed)] 7 | #[folder = "i18n/"] 8 | struct Localizations; 9 | 10 | pub static LANGUAGE_LOADER_KROKIET: Lazy<FluentLanguageLoader> = Lazy::new(|| { 11 | let loader: FluentLanguageLoader = fluent_language_loader!(); 12 | 13 | loader.load_fallback_language(&Localizations).expect("Error while loading fallback language"); 14 | 15 | loader 16 | }); 17 | 18 | #[macro_export] 19 | macro_rules! flk { 20 | ($message_id:literal) => {{ 21 | i18n_embed_fl::fl!($crate::localizer_krokiet::LANGUAGE_LOADER_KROKIET, $message_id) 22 | }}; 23 | 24 | ($message_id:literal, $($args:expr_2021),*) => {{ 25 | i18n_embed_fl::fl!($crate::localizer_krokiet::LANGUAGE_LOADER_KROKIET, $message_id, $($args), *) 26 | }}; 27 | } 28 | 29 | // Get the `Localizer` to be used for localizing this library. 30 | pub fn localizer_krokiet() -> Box<dyn Localizer> { 31 | Box::from(DefaultLocalizer::new(&*LANGUAGE_LOADER_KROKIET, &Localizations)) 32 | } 33 | -------------------------------------------------------------------------------- /krokiet/src/set_initial_gui_info.rs: -------------------------------------------------------------------------------- 1 | // use czkawka_core::common::get_all_available_threads; 2 | // use slint::{ComponentHandle, VecModel}; 3 | // 4 | // use crate::settings::StringComboBoxItems; 5 | // use crate::{GuiState, MainWindow, Settings}; 6 | // 7 | // // Some info needs to be send to gui at the start like available thread number in OS. 8 | // pub fn set_initial_gui_infos(app: &MainWindow) { 9 | // let threads = get_all_available_threads(); 10 | // let settings = app.global::<Settings>(); 11 | // app.global::<GuiState>().set_maximum_threads(threads as f32); 12 | // 13 | // let collected_items = StringComboBoxItems::get_items(); 14 | // 15 | // settings.set_languages_list(VecModel::from_slice(&StringComboBoxItems::get_display_names(&collected_items.languages))); 16 | // settings.set_similar_images_sub_available_hash_size(VecModel::from_slice(&StringComboBoxItems::get_display_names(&collected_items.hash_size))); 17 | // settings.set_similar_images_sub_available_resize_algorithm(VecModel::from_slice(&StringComboBoxItems::get_display_names(&collected_items.resize_algorithm))); 18 | // settings.set_similar_images_sub_available_hash_type(VecModel::from_slice(&StringComboBoxItems::get_display_names(&collected_items.image_hash_alg))); 19 | // settings.set_biggest_files_sub_method(VecModel::from_slice(&StringComboBoxItems::get_display_names(&collected_items.biggest_files_method))); 20 | // settings.set_duplicates_sub_check_method(VecModel::from_slice(&StringComboBoxItems::get_display_names(&collected_items.duplicates_check_method))); 21 | // settings.set_duplicates_sub_available_hash_type(VecModel::from_slice(&StringComboBoxItems::get_display_names(&collected_items.duplicates_hash_type))); 22 | // } 23 | -------------------------------------------------------------------------------- /krokiet/src/test_common.rs: -------------------------------------------------------------------------------- 1 | use slint::{ModelRc, VecModel}; 2 | 3 | use crate::MainListModel; 4 | 5 | pub fn get_main_list_model() -> MainListModel { 6 | MainListModel { 7 | selected_row: false, 8 | val_int: Default::default(), 9 | checked: false, 10 | filled_header_row: false, 11 | header_row: false, 12 | val_str: Default::default(), 13 | } 14 | } 15 | pub fn get_model_vec(items: usize) -> Vec<MainListModel> { 16 | (0..items).map(|_| get_main_list_model()).collect::<Vec<_>>() 17 | } 18 | pub fn create_model_from_model_vec<T: Clone + 'static>(model_vec: &[T]) -> ModelRc<T> { 19 | ModelRc::new(VecModel::from(model_vec.to_owned())) 20 | } 21 | -------------------------------------------------------------------------------- /krokiet/ui/about.slint: -------------------------------------------------------------------------------- 1 | import { Button } from "std-widgets.slint"; 2 | import { Callabler } from "callabler.slint"; 3 | import { Translations } from "translations.slint"; 4 | 5 | export component About inherits VerticalLayout { 6 | preferred-height: 300px; 7 | preferred-width: 400px; 8 | 9 | img := Image { 10 | source: @image-url("../icons/krokiet_logo.png"); 11 | image-fit: ImageFit.contain; 12 | } 13 | 14 | Text { 15 | text: "9.0.0"; 16 | horizontal-alignment: center; 17 | font-size: max(min(img.width / 20, 17px), 10px); 18 | } 19 | 20 | VerticalLayout { 21 | spacing: 10px; 22 | padding-bottom: 10px; 23 | Text { 24 | text: "2020 - 2025 Rafał Mikrut(qarmin)"; 25 | horizontal-alignment: center; 26 | font-size: 15px; 27 | } 28 | 29 | Text { 30 | text <=> Translations.motto_text; 31 | horizontal-alignment: center; 32 | font-size: 13px; 33 | } 34 | 35 | Text { 36 | text <=> Translations.unicorn_text; 37 | horizontal-alignment: center; 38 | font-size: 13px; 39 | } 40 | } 41 | 42 | HorizontalLayout { 43 | spacing: 5px; 44 | Button { 45 | text <=> Translations.repository_text; 46 | clicked => { 47 | Callabler.open_link("https://github.com/qarmin/czkawka"); 48 | } 49 | } 50 | 51 | Button { 52 | text <=> Translations.instruction_text; 53 | clicked => { 54 | Callabler.open_link("https://github.com/qarmin/czkawka/blob/master/instructions/Instruction.md"); 55 | } 56 | } 57 | 58 | Button { 59 | text <=> Translations.donation_text; 60 | clicked => { 61 | Callabler.open_link("https://github.com/sponsors/qarmin"); 62 | } 63 | } 64 | 65 | Button { 66 | text <=> Translations.translation_text; 67 | clicked => { 68 | Callabler.open_link("https://crwd.in/czkawka"); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /krokiet/ui/callabler.slint: -------------------------------------------------------------------------------- 1 | import { SelectMode, SortMode } from "common.slint"; 2 | import { CurrentTab } from "common.slint"; 3 | import { Palette } from "std-widgets.slint"; 4 | import { Settings } from "settings.slint"; 5 | 6 | export global Callabler { 7 | // Bottom panel operations 8 | callback remove_item_directories(bool); 9 | callback added_manual_directories(bool, string); 10 | 11 | // Row selecting 12 | callback reset_selection(CurrentTab); 13 | 14 | callback row_select_all(); 15 | callback row_reverse_single_unique_item(int); 16 | callback row_reverse_item_selection(int); 17 | callback row_select_items_with_shift(int, int); 18 | 19 | callback row_open_selected_item(); 20 | callback row_open_parent_of_selected_item(); 21 | 22 | callback row_reverse_checked_selection(); 23 | callback row_open_item_with_index(int); 24 | 25 | // Right click or middle click opener 26 | callback open_item(string); 27 | callback open_selected_item(CurrentTab); 28 | 29 | callback delete_selected_items(); 30 | callback select_items(SelectMode); 31 | callback sort_items(SortMode); 32 | 33 | // Preview 34 | callback load_image_preview(string); 35 | 36 | // Settings 37 | callback changed_settings_preset(); 38 | callback save_current_preset(); 39 | callback load_current_preset(); 40 | callback reset_current_preset(); 41 | callback changed_language(); 42 | 43 | callback tab_changed(); 44 | 45 | // Dialogs 46 | callback save_results(); 47 | callback move_items(bool, bool, string); 48 | callback rename_files(); 49 | 50 | // Only Slint 51 | callback open_select_popup(); 52 | 53 | callback open_config_folder(); 54 | callback open_cache_folder(); 55 | 56 | callback open_link(string); 57 | 58 | callback theme_changed(); 59 | theme_changed => { 60 | Palette.color-scheme = Settings.dark_theme ? ColorScheme.dark : ColorScheme.light; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /krokiet/ui/color_palette.slint: -------------------------------------------------------------------------------- 1 | import { Settings } from "settings.slint"; 2 | 3 | export global ColorPalette { 4 | // Tabs at left side 5 | in-out property <color> tab_selected_color: Settings.dark_theme ? #353535 : #5e5e5e; 6 | in-out property <color> tab_hovered_color: Settings.dark_theme ? #49494926 : #80808014; 7 | // ListView 8 | in-out property <color> list_view_item_color: Settings.dark_theme ? #222222 : #dddddd; 9 | in-out property <color> list_view_item_hovered_color: Settings.dark_theme ? #333333 : #d2d2d2; 10 | in-out property <color> list_view_item_selected_color: Settings.dark_theme ? #444444 : #cccccc; 11 | in-out property <color> list_view_item_selected_hovered_color: Settings.dark_theme ? #555555 : #bbbbbb; 12 | 13 | in-out property <color> list_view_header_color: Settings.dark_theme ? #111111 : #888888; 14 | in-out property <color> list_view_clicked_header_color: Settings.dark_theme ? #1a1a1a : #808080; 15 | 16 | // Popup 17 | in-out property <color> popup_background: Settings.dark_theme ? #353535 : #cecece; 18 | in-out property <color> popup_background_border: Settings.dark_theme ? #222222 : #808080; 19 | in-out property <color> popup_background_title_line: Settings.dark_theme ? #252525 : #9e9e9e; 20 | in-out property <color> popup_border_color: Settings.dark_theme ? #000000 : #808080; 21 | 22 | public pure function get_listview_color(selected: bool, hovered: bool) -> color { 23 | if (selected) { 24 | return hovered ? self.list_view_item_selected_hovered_color : self.list_view_item_selected_color; 25 | } else { 26 | return hovered ? self.list_view_item_hovered_color : self.list_view_item_color; 27 | } 28 | } 29 | public pure function get_listview_color_with_header(selected: bool, hovered: bool, header: bool) -> color { 30 | if (header) { 31 | return selected ? self.list_view_clicked_header_color : self.list_view_header_color; 32 | } else { 33 | return self.get_listview_color(selected, hovered); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /krokiet/ui/common.slint: -------------------------------------------------------------------------------- 1 | export enum CurrentTab { 2 | DuplicateFiles, 3 | EmptyFolders, 4 | BigFiles, 5 | EmptyFiles, 6 | TemporaryFiles, 7 | SimilarImages, 8 | SimilarVideos, 9 | SimilarMusic, 10 | InvalidSymlinks, 11 | BrokenFiles, 12 | BadExtensions, 13 | Settings, 14 | About 15 | } 16 | 17 | export enum TypeOfOpenedItem { 18 | CurrentItem, 19 | ParentItem, 20 | } 21 | 22 | export struct ProgressToSend { 23 | current_progress: int, 24 | current_progress_size: int, 25 | all_progress: int, 26 | step_name: string, 27 | } 28 | 29 | export struct MainListModel { 30 | checked: bool, 31 | header_row: bool, 32 | filled_header_row: bool, 33 | selected_row: bool, 34 | val_str: [string], 35 | val_int: [int] 36 | } 37 | 38 | export enum BottomPanelVisibility { 39 | NotVisible, 40 | TextErrors, 41 | Directories 42 | } 43 | 44 | export struct IncludedDirectoriesModel { 45 | path: string, 46 | referenced_folder: bool, 47 | selected_row: bool, 48 | } 49 | 50 | export struct ExcludedDirectoriesModel { 51 | path: string, 52 | selected_row: bool, 53 | } 54 | 55 | export enum SelectMode { 56 | SelectAll, 57 | UnselectAll, 58 | InvertSelection, 59 | SelectTheBiggestSize, 60 | SelectTheBiggestResolution, 61 | SelectTheSmallestSize, 62 | SelectTheSmallestResolution, 63 | SelectNewest, 64 | SelectOldest, 65 | } 66 | 67 | export struct SelectModel { 68 | data: SelectMode, 69 | name: string 70 | } 71 | 72 | export enum SortMode { 73 | ItemName, 74 | ParentName, 75 | FullName, 76 | Size, 77 | ModificationDate, 78 | Selection, 79 | Reverse, 80 | Checked, 81 | } 82 | 83 | export struct SortModel { 84 | data: SortMode, 85 | name: string 86 | } 87 | -------------------------------------------------------------------------------- /krokiet/ui/gui_state.slint: -------------------------------------------------------------------------------- 1 | import { CurrentTab } from "common.slint"; 2 | import { SelectModel, SortModel, SelectMode, SortMode, BottomPanelVisibility } from "common.slint"; 3 | import { Translations } from "translations.slint"; 4 | 5 | // State Gui state that shows the current state of the GUI 6 | // It extends Settings global state with settings that are not saved to the settings file 7 | export global GuiState { 8 | in-out property <length> app_width; 9 | in-out property <length> app_height; 10 | 11 | in-out property <string> info_text: "Nothing to report"; 12 | in-out property <bool> preview_visible; 13 | in-out property <image> preview_image; 14 | in-out property <string> preview_image_path; 15 | 16 | in-out property <length> left_panel_width: 120px; 17 | 18 | in-out property <float> maximum_threads: 40; 19 | 20 | in-out property <bool> choosing_include_directories; 21 | in-out property <bool> visible_tool_settings; 22 | 23 | in-out property <bool> available_subsettings: active_tab == CurrentTab.SimilarImages || active_tab == CurrentTab.DuplicateFiles || active_tab == CurrentTab.SimilarVideos || active_tab == CurrentTab.SimilarMusic || active_tab == CurrentTab.BigFiles || active_tab == CurrentTab.BrokenFiles; 24 | in-out property <CurrentTab> active_tab: CurrentTab.DuplicateFiles; 25 | in-out property <bool> is_tool_tab_active: active_tab != CurrentTab.Settings && active_tab != CurrentTab.About; 26 | 27 | in-out property <[SelectModel]> select_results_list: [ 28 | { data: SelectMode.SelectAll, name: Translations.selection_all_text }, 29 | { data: SelectMode.UnselectAll, name: Translations.selection_deselect_all_text }, 30 | { 31 | data: SelectMode.SelectTheSmallestResolution, 32 | name: Translations.selection_the_smallest_resolution_text 33 | } 34 | ]; 35 | 36 | in-out property <[SortModel]> sort_results_list: [ 37 | { data: SortMode.ItemName, name: Translations.sort_by_item_name_text }, 38 | { data: SortMode.ParentName, name: Translations.sort_by_parent_name_text }, 39 | { data: SortMode.FullName, name: Translations.sort_by_full_name_text }, 40 | { data: SortMode.Size, name: Translations.sort_by_size_text }, 41 | { data: SortMode.ModificationDate, name: Translations.sort_by_modification_date_text }, 42 | { data: SortMode.Selection, name: Translations.sort_by_selection_text }, 43 | { data: SortMode.Reverse, name: Translations.sort_reverse_text } 44 | ]; 45 | 46 | in-out property <[{name: string, tab: CurrentTab}]> tools_model: [ 47 | { name: Translations.tool_duplicate_files_text, tab: CurrentTab.DuplicateFiles }, 48 | { name: Translations.tool_empty_folders_text, tab: CurrentTab.EmptyFolders }, 49 | { name: Translations.tool_big_files_text, tab: CurrentTab.BigFiles }, 50 | { name: Translations.tool_empty_files_text, tab: CurrentTab.EmptyFiles }, 51 | { name: Translations.tool_temporary_files_text, tab: CurrentTab.TemporaryFiles }, 52 | { name: Translations.tool_similar_images_text, tab: CurrentTab.SimilarImages }, 53 | { name: Translations.tool_similar_videos_text, tab: CurrentTab.SimilarVideos }, 54 | { name: Translations.tool_music_duplicates_text, tab: CurrentTab.SimilarMusic }, 55 | { name: Translations.tool_invalid_symlinks_text, tab: CurrentTab.InvalidSymlinks }, 56 | { name: Translations.tool_broken_files_text, tab: CurrentTab.BrokenFiles }, 57 | { name: Translations.tool_bad_extensions_text, tab: CurrentTab.BadExtensions } 58 | ]; 59 | 60 | in-out property <BottomPanelVisibility> bottom_panel_visibility: BottomPanelVisibility.Directories; 61 | } 62 | -------------------------------------------------------------------------------- /krokiet/ui/popup_base.slint: -------------------------------------------------------------------------------- 1 | import { Button } from "std-widgets.slint"; 2 | import { ColorPalette } from "color_palette.slint"; 3 | import { Translations } from "translations.slint"; 4 | 5 | export component PopupBase inherits PopupWindow { 6 | in-out property <string> title_text: "TODO - needs to be changed"; 7 | in-out property <string> ok_text <=> Translations.ok_button_text; 8 | in-out property <string> cancel_text <=> Translations.cancel_button_text; 9 | in-out property <bool> enabled_ok_button: true; 10 | 11 | callback ok_clicked(); 12 | callback cancel_clicked(); 13 | 14 | close-policy: PopupClosePolicy.no-auto-close; 15 | rect := Rectangle { 16 | width: parent.width; 17 | height: parent.height; 18 | border-radius: 10px; 19 | border-color: ColorPalette.popup_border_color; 20 | border-width: 2px; 21 | background: ColorPalette.popup_background; 22 | clip: true; 23 | VerticalLayout { 24 | Rectangle { 25 | width: rect.width; 26 | background: ColorPalette.popup_background_title_line; 27 | 28 | Text { 29 | vertical-stretch: 0.0; 30 | min-height: 30px; 31 | text <=> title_text; 32 | vertical-alignment: center; 33 | horizontal-alignment: center; 34 | font-size: 13px; 35 | } 36 | } 37 | 38 | @children 39 | 40 | HorizontalLayout { 41 | padding: 10px; 42 | Button { 43 | enabled <=> enabled_ok_button; 44 | text <=> ok_text; 45 | clicked => { 46 | root.close(); 47 | ok_clicked(); 48 | } 49 | } 50 | 51 | Rectangle { } 52 | 53 | Button { 54 | text <=> cancel_text; 55 | clicked => { 56 | root.close(); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /krokiet/ui/popup_centered_text.slint: -------------------------------------------------------------------------------- 1 | export component PopupCenteredText inherits Text { 2 | vertical-stretch: 1.0; 3 | vertical-alignment: center; 4 | horizontal-alignment: center; 5 | font-size: 13px; 6 | padding: 10px; 7 | wrap: TextWrap.word-wrap; 8 | } 9 | -------------------------------------------------------------------------------- /krokiet/ui/popup_delete.slint: -------------------------------------------------------------------------------- 1 | import { Callabler } from "callabler.slint"; 2 | import { Translations } from "translations.slint"; 3 | import { PopupBase } from "popup_base.slint"; 4 | import { PopupCenteredText } from "popup_centered_text.slint"; 5 | 6 | export component PopupDelete inherits Rectangle { 7 | out property <length> popup_width: 350px; 8 | out property <length> popup_height: 150px; 9 | callback show_popup(); 10 | 11 | popup_window := PopupBase { 12 | width: popup_width; 13 | height: popup_height; 14 | title_text <=> Translations.delete_text; 15 | 16 | VerticalLayout { 17 | PopupCenteredText { 18 | text <=> Translations.delete_confirmation_text; 19 | } 20 | } 21 | 22 | ok_clicked => { 23 | Callabler.delete_selected_items(); 24 | } 25 | } 26 | 27 | show_popup() => { 28 | popup_window.show(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /krokiet/ui/popup_move_folders.slint: -------------------------------------------------------------------------------- 1 | import { CheckBox } from "std-widgets.slint"; 2 | import { Callabler } from "callabler.slint"; 3 | import { Translations } from "translations.slint"; 4 | import { PopupBase } from "popup_base.slint"; 5 | import { PopupCenteredText } from "popup_centered_text.slint"; 6 | 7 | export component PopupMoveFolders inherits Rectangle { 8 | out property <length> popup_width: 500px; 9 | out property <length> popup_height: 150px; 10 | in-out property <string> folder_name: ""; 11 | callback show_popup(); 12 | 13 | popup_window := PopupBase { 14 | width: popup_width; 15 | height: popup_height; 16 | title_text <=> Translations.popup_move_title_text; 17 | 18 | VerticalLayout { 19 | PopupCenteredText { 20 | text: Translations.popup_move_message_text + "\n" + folder_name; 21 | } 22 | 23 | Rectangle {height: 5px;} 24 | 25 | VerticalLayout { 26 | HorizontalLayout { 27 | alignment: center; 28 | copy_checkbox := CheckBox { 29 | text <=> Translations.popup_move_copy_checkbox_text; 30 | } 31 | } 32 | Rectangle {height: 5px;} 33 | 34 | HorizontalLayout { 35 | alignment: center; 36 | preserve_folder_checkbox := CheckBox { 37 | text <=> Translations.popup_move_preserve_folder_checkbox_text; 38 | } 39 | } 40 | } 41 | Rectangle {height: 20px;} 42 | 43 | PopupCenteredText { 44 | text: Translations.are_you_want_to_continue_text; 45 | } 46 | } 47 | 48 | ok_clicked => { 49 | Callabler.move_items(preserve_folder_checkbox.checked, copy_checkbox.checked, folder_name); 50 | } 51 | } 52 | 53 | show_popup() => { 54 | popup_window.show(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /krokiet/ui/popup_new_directories.slint: -------------------------------------------------------------------------------- 1 | import { TextEdit } from "std-widgets.slint"; 2 | import { Callabler } from "callabler.slint"; 3 | import { Translations } from "translations.slint"; 4 | import { PopupBase } from "popup_base.slint"; 5 | import { GuiState } from "gui_state.slint"; 6 | 7 | export component PopupNewDirectories inherits Rectangle { 8 | out property <length> popup_width: 350px; 9 | out property <length> popup_height: 200px; 10 | callback show_popup(); 11 | 12 | property <bool> included_directories; 13 | private property <string> text_data; 14 | 15 | popup_window := PopupBase { 16 | width: popup_width; 17 | height: popup_height; 18 | title_text <=> Translations.popup_new_directories_title_text; 19 | enabled_ok_button: text_data != ""; 20 | 21 | VerticalLayout { 22 | TextEdit { 23 | vertical-stretch: 1.0; 24 | text <=> text_data; 25 | } 26 | } 27 | 28 | ok_clicked => { 29 | Callabler.added_manual_directories(GuiState.choosing_include_directories, text_data); 30 | } 31 | } 32 | 33 | show_popup() => { 34 | popup_window.show(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /krokiet/ui/popup_rename_files.slint: -------------------------------------------------------------------------------- 1 | import { Callabler } from "callabler.slint"; 2 | import { Translations } from "translations.slint"; 3 | import { PopupBase } from "popup_base.slint"; 4 | import { PopupCenteredText } from "popup_centered_text.slint"; 5 | 6 | export component PopupRenameFiles inherits Rectangle { 7 | out property <length> popup_width: 500px; 8 | out property <length> popup_height: 150px; 9 | callback show_popup(); 10 | 11 | in-out property <string> folder_name: ""; 12 | 13 | popup_window := PopupBase { 14 | width: popup_width; 15 | height: popup_height; 16 | title_text <=> Translations.popup_rename_title_text; 17 | 18 | VerticalLayout { 19 | PopupCenteredText { 20 | text: Translations.popup_rename_message_text + "\n\n" + Translations.are_you_want_to_continue_text; 21 | } 22 | } 23 | 24 | ok_clicked => { 25 | Callabler.rename_files(); 26 | } 27 | } 28 | 29 | show_popup() => { 30 | popup_window.show(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /krokiet/ui/popup_save.slint: -------------------------------------------------------------------------------- 1 | import { Callabler } from "callabler.slint"; 2 | import { Translations } from "translations.slint"; 3 | import { PopupBase } from "popup_base.slint"; 4 | import { PopupCenteredText } from "popup_centered_text.slint"; 5 | 6 | export component PopupSave inherits Rectangle { 7 | out property <length> popup_width: 500px; 8 | out property <length> popup_height: 150px; 9 | callback show_popup(); 10 | 11 | popup_window := PopupBase { 12 | width: popup_width; 13 | height: popup_height; 14 | title_text <=> Translations.popup_save_title_text; 15 | 16 | VerticalLayout { 17 | PopupCenteredText { 18 | text: Translations.popup_save_message_text + "\n\n" + Translations.are_you_want_to_continue_text; 19 | } 20 | } 21 | 22 | ok_clicked => { 23 | Callabler.save_results(); 24 | } 25 | } 26 | 27 | show_popup() => { 28 | popup_window.show(); 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /krokiet/ui/popup_select_results.slint: -------------------------------------------------------------------------------- 1 | import { Button } from "std-widgets.slint"; 2 | import { SelectModel } from "common.slint"; 3 | import { Callabler } from "callabler.slint"; 4 | import { ColorPalette } from "color_palette.slint"; 5 | import { GuiState } from "gui_state.slint"; 6 | 7 | export component PopupSelectResults inherits Rectangle { 8 | callback show_popup(); 9 | property <[SelectModel]> model: GuiState.select_results_list; 10 | property <length> item_height: 30px; 11 | out property <length> item_width: 200px; 12 | out property <length> all_items_height: item_height * model.length; 13 | 14 | popup_window := PopupWindow { 15 | width: item_width; 16 | height: all_items_height; 17 | 18 | close-policy: PopupClosePolicy.close-on-click-outside; 19 | Rectangle { 20 | width: parent.width; 21 | height: parent.height; 22 | border-radius: 5px; 23 | background: ColorPalette.popup_background; 24 | VerticalLayout { 25 | for i in model: Button { 26 | text: i.name; 27 | height: item_height; 28 | width: item_width; 29 | clicked => { 30 | Callabler.select_items(i.data); 31 | popup_window.close(); 32 | } 33 | } 34 | } 35 | } 36 | } 37 | 38 | show_popup() => { 39 | popup_window.show(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /krokiet/ui/popup_sort.slint: -------------------------------------------------------------------------------- 1 | import { Button } from "std-widgets.slint"; 2 | import { SortModel } from "common.slint"; 3 | import { Callabler } from "callabler.slint"; 4 | import { ColorPalette } from "color_palette.slint"; 5 | import { GuiState } from "gui_state.slint"; 6 | 7 | export component PopupSortResults inherits Rectangle { 8 | callback show_popup(); 9 | property <[SortModel]> model: GuiState.sort_results_list; 10 | property <length> item_height: 30px; 11 | out property <length> item_width: 200px; 12 | out property <length> all_items_height: item_height * model.length; 13 | 14 | popup_window := PopupWindow { 15 | width: item_width; 16 | height: all_items_height; 17 | 18 | close-policy: PopupClosePolicy.close-on-click-outside; 19 | Rectangle { 20 | width: parent.width; 21 | height: parent.height; 22 | border-radius: 5px; 23 | background: ColorPalette.popup_background; 24 | VerticalLayout { 25 | for i in model: Button { 26 | text: i.name; 27 | height: item_height; 28 | width: item_width; 29 | clicked => { 30 | Callabler.sort_items(i.data); 31 | popup_window.close(); 32 | } 33 | } 34 | } 35 | } 36 | } 37 | 38 | show_popup() => { 39 | popup_window.show(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /krokiet/ui/preview.slint: -------------------------------------------------------------------------------- 1 | export component Preview inherits Image { 2 | image-rendering: ImageRendering.smooth; 3 | } 4 | -------------------------------------------------------------------------------- /krokiet/ui/progress.slint: -------------------------------------------------------------------------------- 1 | import { ProgressToSend } from "common.slint"; 2 | import { ProgressIndicator } from "std-widgets.slint"; 3 | import { Translations } from "translations.slint"; 4 | 5 | export component Progress { 6 | in-out property <ProgressToSend> progress_datas; 7 | preferred-width: 400px; 8 | preferred-height: 40px; 9 | VerticalLayout { 10 | Text { 11 | text: progress-datas.step_name; 12 | horizontal-alignment: TextHorizontalAlignment.center; 13 | } 14 | 15 | HorizontalLayout { 16 | spacing: 5px; 17 | VerticalLayout { 18 | spacing: 5px; 19 | Text { 20 | vertical-alignment: TextVerticalAlignment.center; 21 | text: Translations.stage_current_text; 22 | } 23 | 24 | Text { 25 | vertical-alignment: TextVerticalAlignment.center; 26 | text: Translations.stage_all_text; 27 | } 28 | } 29 | 30 | VerticalLayout { 31 | spacing: 5px; 32 | VerticalLayout { 33 | alignment: LayoutAlignment.center; 34 | ProgressIndicator { 35 | visible: progress_datas.current_progress >= -0.001; 36 | height: 8px; 37 | progress: progress_datas.current_progress_size == -1 ? progress_datas.current_progress / 100.0 : progress_datas.current_progress_size / 100.0; 38 | } 39 | } 40 | 41 | VerticalLayout { 42 | alignment: LayoutAlignment.center; 43 | ProgressIndicator { 44 | height: 8px; 45 | progress: progress_datas.all_progress / 100.0; 46 | } 47 | } 48 | } 49 | 50 | VerticalLayout { 51 | visible: progress_datas.all_progress > -0.001; 52 | spacing: 5px; 53 | Text { 54 | visible: progress_datas.current_progress >= -0.001; 55 | vertical-alignment: TextVerticalAlignment.center; 56 | text: (progress_datas.current_progress_size == -1 ? progress_datas.current_progress : progress_datas.current_progress_size) + "%"; 57 | } 58 | 59 | Text { 60 | vertical-alignment: TextVerticalAlignment.center; 61 | text: progress_datas.all_progress + "%"; 62 | } 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /misc/.idea/czkawka.iml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <module type="JAVA_MODULE" version="4"> 3 | <component name="NewModuleRootManager" inherit-compiler-output="true"> 4 | <exclude-output /> 5 | <content url="file://$MODULE_DIRquot;> 6 | <sourceFolder url="file://$MODULE_DIR$/czkawka_cli/src" isTestSource="false" /> 7 | <sourceFolder url="file://$MODULE_DIR$/czkawka_core/src" isTestSource="false" /> 8 | <sourceFolder url="file://$MODULE_DIR$/czkawka_gui_orbtk/src" isTestSource="false" /> 9 | <sourceFolder url="file://$MODULE_DIR$/czkawka_gui/src" isTestSource="false" /> 10 | <excludeFolder url="file://$MODULE_DIR$/target" /> 11 | </content> 12 | <orderEntry type="inheritedJdk" /> 13 | <orderEntry type="sourceFolder" forTests="false" /> 14 | </component> 15 | </module> -------------------------------------------------------------------------------- /misc/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <project version="4"> 3 | <component name="ProjectModuleManager"> 4 | <modules> 5 | <module fileurl="file://$PROJECT_DIR$/.idea/czkawka.iml" filepath="$PROJECT_DIR$/.idea/czkawka.iml" /> 6 | </modules> 7 | </component> 8 | </project> -------------------------------------------------------------------------------- /misc/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <project version="4"> 3 | <component name="VcsDirectoryMappings"> 4 | <mapping directory="" vcs="Git" /> 5 | </component> 6 | </project> -------------------------------------------------------------------------------- /misc/cargo/PublishCore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | NUMBER="9.0.0" 3 | CZKAWKA_PATH="/home/rafal" 4 | 5 | cd "$CZKAWKA_PATH" 6 | CZKAWKA_PATH="$CZKAWKA_PATH/czkawka" 7 | rm -rf $CZKAWKA_PATH 8 | git clone https://github.com/qarmin/czkawka.git "$CZKAWKA_PATH" 9 | cd $CZKAWKA_PATH 10 | git checkout "$NUMBER" 11 | 12 | cd "$CZKAWKA_PATH/czkawka_core" 13 | cargo package 14 | if [ $(echo $?) != "0" ] 15 | then 16 | echo "Cargo package failed CORE" 17 | exit 1 18 | fi 19 | git reset --hard 20 | 21 | cd "$CZKAWKA_PATH/czkawka_core" 22 | cargo publish 23 | git reset --hard 24 | 25 | -------------------------------------------------------------------------------- /misc/cargo/PublishOther.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | NUMBER="9.0.0" 3 | CZKAWKA_PATH="/home/rafal" 4 | 5 | cd "$CZKAWKA_PATH" 6 | CZKAWKA_PATH="$CZKAWKA_PATH/czkawka" 7 | rm -rf $CZKAWKA_PATH 8 | git clone https://github.com/qarmin/czkawka.git "$CZKAWKA_PATH" 9 | cd $CZKAWKA_PATH 10 | git checkout "$NUMBER" 11 | 12 | 13 | cd "$CZKAWKA_PATH/czkawka_cli" 14 | cargo package 15 | if [ $(echo $?) != "0" ] 16 | then 17 | echo "Cargo package failed CLI" 18 | exit 1 19 | fi 20 | git reset --hard 21 | 22 | 23 | cd "$CZKAWKA_PATH/czkawka_gui" 24 | cargo package 25 | if [ $(echo $?) != "0" ] 26 | then 27 | echo "Cargo package failed GUI" 28 | exit 1 29 | fi 30 | git reset --hard 31 | 32 | cd "$CZKAWKA_PATH/krokiet" 33 | cargo package 34 | if [ $(echo $?) != "0" ] 35 | then 36 | echo "Cargo package failed krokiet" 37 | exit 1 38 | fi 39 | git reset --hard 40 | 41 | 42 | 43 | 44 | cd "$CZKAWKA_PATH/czkawka_cli" 45 | # sed -i "s/{ path = \"..\/czkawka_core\" }/\"=$NUMBER\"/g" "$CZKAWKA_PATH/czkawka_cli/Cargo.toml" 46 | cargo publish # --allow-dirty 47 | git reset --hard 48 | 49 | cd "$CZKAWKA_PATH/czkawka_gui" 50 | # sed -i "s/{ path = \"..\/czkawka_core\" }/\"=$NUMBER\"/g" "$CZKAWKA_PATH/czkawka_gui/Cargo.toml" 51 | cargo publish # --allow-dirty 52 | git reset --hard 53 | 54 | cd "$CZKAWKA_PATH/krokiet" 55 | # sed -i "s/{ path = \"..\/czkawka_core\" }/\"=$NUMBER\"/g" "$CZKAWKA_PATH/czkawka_gui/Cargo.toml" 56 | cargo publish # --allow-dirty 57 | git reset --hard 58 | -------------------------------------------------------------------------------- /misc/czkawka-appimage-recipe.yml: -------------------------------------------------------------------------------- 1 | app: Czkawka 2 | 3 | ingredients: 4 | script: 5 | - mkdir -p czkawka 6 | 7 | script: 8 | - pwd 9 | - cp ../../czkawka_gui ./usr/bin/czkawka_gui 10 | - cp ../../data/com.github.qarmin.czkawka.desktop . 11 | - cp ../../data/icons/com.github.qarmin.czkawka.svg . 12 | -------------------------------------------------------------------------------- /misc/delete_unused_krokiet_slint_imports.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | 4 | script_path = os.path.dirname(os.path.abspath(__file__)) 5 | ui_path = f"{script_path}/../krokiet/ui" 6 | 7 | collected_files = [ 8 | os.path.join(root, file) 9 | for root, _, files in os.walk(ui_path) 10 | for file in files if file.endswith(".slint") 11 | ] 12 | 13 | for file_path in collected_files: 14 | with open(file_path, "r", encoding="utf-8") as file: 15 | content = file.read() 16 | lines = content.splitlines() 17 | 18 | non_import_lines = [] 19 | imports_to_check = [] 20 | updated_lines = [] 21 | 22 | for line in lines: 23 | if line.startswith("import"): 24 | imports_to_check.append(line) 25 | else: 26 | if len(non_import_lines) == 0 and len(line.strip()) == 0: 27 | continue 28 | non_import_lines.append(line) 29 | 30 | non_imported_content = "\n".join(non_import_lines) 31 | 32 | for import_line in imports_to_check: 33 | imported_items = [i.strip() for i in import_line.split("{")[1].split("}")[0].split(",") if len(i.strip()) > 0] 34 | if not imported_items: 35 | continue 36 | 37 | from_file = import_line.split("from")[1].strip() 38 | 39 | used_items = [] 40 | for item in imported_items: 41 | regex = rf"\b{item}\b" 42 | if len(re.findall(regex, non_imported_content)) >= 1: 43 | used_items.append(item) 44 | 45 | if used_items: 46 | updated_line = f"import {{ {', '.join(used_items)} }} from {from_file}" 47 | updated_line = updated_line.replace(";;", ";") 48 | updated_lines.append(updated_line) 49 | 50 | if len(updated_lines) != 0: 51 | updated_lines.append("") 52 | 53 | updated_lines.extend(non_import_lines) 54 | if len(updated_lines) > 0 and len(updated_lines[-1].strip()) > 0: 55 | updated_lines.append("") 56 | 57 | with open(file_path, "w", encoding="utf-8") as file: 58 | file.write("\n".join(updated_lines)) -------------------------------------------------------------------------------- /misc/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | # curl is needed by Rust update tool 4 | RUN apt-get update \ 5 | && apt-get install -y curl build-essential libgtk-4-dev \ 6 | && apt-get clean ; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* 7 | 8 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y # Download the latest stable Rust 9 | 10 | ENV PATH="/root/.cargo/bin:${PATH}" 11 | 12 | RUN cargo --version 13 | -------------------------------------------------------------------------------- /misc/flathub.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pip3 install aiohttp toml 3 | wget https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/cargo/flatpak-cargo-generator.py 4 | mkdir flatpak 5 | python3 flatpak-cargo-generator.py ./Cargo.lock -o flatpak/cargo-sources.json 6 | rm flatpak-cargo-generator.py 7 | -------------------------------------------------------------------------------- /misc/generate_krokiet_translations.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | script_path = os.path.dirname(os.path.abspath(__file__)) 4 | 5 | translations_slint_path = f"{script_path}/../krokiet/ui/translations.slint" 6 | 7 | start_item = " in-out property <string> " 8 | 9 | rust_items = [] 10 | translation_items = [] 11 | # in-out property <string> scan_button_text: "Scan"; 12 | # translation.set_scan_button_text(flk!("scan_button").into()); 13 | 14 | with open(translations_slint_path, "r", encoding="utf-8") as file: 15 | for line in file: 16 | if line.startswith(start_item): 17 | line = line[len(start_item):] 18 | value = line.split("\"")[1] 19 | line = line.split(":")[0].strip() 20 | assert line.endswith("_text"), line 21 | item = line[:-5] 22 | rust_items.append(f" translation.set_{item}_text(flk!(\"{item}\").into());") 23 | translation_items.append(f"{item} = {value}") 24 | elif "property" in line: 25 | assert False 26 | 27 | for item in rust_items: 28 | print(item) 29 | 30 | print("##############################################################") 31 | 32 | for item in translation_items: 33 | print(item) -------------------------------------------------------------------------------- /misc/test_image_perf/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "test_image_perf" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | walkdir = "2.5.0" 8 | humansize = "2.1.3" 9 | rayon = "1.10.0" 10 | strum = { version = "0.26.3", features = ["strum_macros", "derive"] } 11 | image_hasher = "3.0.0" 12 | image = "0.25.5" 13 | rawloader = "0.37.1" 14 | imagepipe = "0.5.0" 15 | log = "0.4.25" 16 | os_info = "3.10.0" 17 | handsome_logger = "0.8.0" 18 | 19 | [features] 20 | fast_image_resize = ["image_hasher/fast_resize_unstable"] -------------------------------------------------------------------------------- /misc/test_read_perf/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "test_read_perf" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | czkawka_core = { path = "../../czkawka_core", default-features = false } 8 | walkdir = "2.5.0" 9 | humansize = "2.1" 10 | rayon = "1.10.0" 11 | strum = { version = "0.26.3", features = ["strum_macros", "derive"] } --------------------------------------------------------------------------------