Skip to content

Commit

Permalink
Add sort button (#894)
Browse files Browse the repository at this point in the history
* Add sort button

* Update lofty and gtk-rs

* Fix bug with invalid music tags with reference folders

* Remove try at

* Fix loading of certain directories with disabled loading settings at start

* Change FileChooserDialog to FileChooserNative

* Any

* Copy Clone

* Popover sort basic

* Builder using

* Basic sorting

* Fix not working sorting by size

* Changelog
  • Loading branch information
qarmin authored Feb 19, 2023
1 parent 8ea9b4b commit f1c6e6d
Show file tree
Hide file tree
Showing 48 changed files with 1,187 additions and 570 deletions.
369 changes: 204 additions & 165 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ panic = "unwind"
# 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
#lto = "fat"

# Optimize all dependencies except application/workspaces
# Optimize all dependencies except application/workspaces, even in debug builds
[profile.dev.package."*"]
opt-level = 3
14 changes: 14 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## Version 5.1.0 - 19.02.2023r
- Added sort button - [#894](https://github.com/qarmin/czkawka/pull/894)
- Allow to set number of thread used to scan - [#839](https://github.com/qarmin/czkawka/pull/839)
- Faster similar images comparing with reference folders - [#826](https://github.com/qarmin/czkawka/pull/826)
- Update to clap 4 - [#878](https://github.com/qarmin/czkawka/pull/878)
- Use FileChooserNative instead FileChooserDialog - [#894](https://github.com/qarmin/czkawka/pull/894)
- Fix invalid music tags in music files when using reference folders - [#894](https://github.com/qarmin/czkawka/pull/894)
- Updated pdf dependency(a lot of less amount of broken pdf false positives) - [#894](https://github.com/qarmin/czkawka/pull/894)
- Changed strange PDF error message - "Try at" - [#894](https://github.com/qarmin/czkawka/pull/894)
- Treat extensions Mp4 and m4v as identical - [#834](https://github.com/qarmin/czkawka/pull/834)
- Improve thumbnail quality - [#895](https://github.com/qarmin/czkawka/pull/895)
- Verify if hardlinking works, and if not, disable button with proper message - [#881](https://github.com/qarmin/czkawka/pull/881)
- Apply some pydantic clippy lints on project - [#901](https://github.com/qarmin/czkawka/pull/901)

## Version 5.0.2 - 30.08.2022r
- Fixed problem with missing some similar images when using similarity > 0 - [#799](https://github.com/qarmin/czkawka/pull/799)
- Prebuilt Linux binaries are compiled without heif support - [24b](https://github.com/qarmin/czkawka/commit/24b64a32c65904c506b54270f0977ccbe5098cc8)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Icons used inside GUI version
Reshot license
Reshot license - https://www.reshot.com/

czkawka_gui/icons/*

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![com github qarmin czkawka](https://user-images.githubusercontent.com/41945903/102616149-66490400-4137-11eb-9cd6-813b2b070834.png)

**Czkawka** (_tch•kav•ka_ (IPA: [ʈ͡ʂkafka]), "hiccup" in Polish) is a simple, fast and free app to remove unnecessary files from your computer.
**Czkawka** (_tch•kav•ka_ (IPA: [ˈʧ̑kafka]), "hiccup" in Polish) is a simple, fast and free app to remove unnecessary files from your computer.

## Features
- Written in memory-safe Rust
Expand Down
10 changes: 5 additions & 5 deletions czkawka_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ hamming = "0.1.3"

# Needed by same music
bitflags = "1.3.2"
lofty = "0.10.0"
lofty = "0.11.0"

# Futures - needed by async progress sender
futures = "0.3.25"
futures = "0.3.26"

# Needed by broken files
zip = { version = "0.6.3", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
zip = { version = "0.6.4", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
audio_checker = "0.1.0"
pdf = "0.8.0"

Expand All @@ -56,7 +56,7 @@ serde_json = "1.0"
i18n-embed = { version = "0.13.8", features = ["fluent-system", "desktop-requester"] }
i18n-embed-fl = "0.6.5"
rust-embed = "6.4.2"
once_cell = "1.17.0"
once_cell = "1.17.1"

# Raw image files
rawloader = "0.37.1"
Expand All @@ -69,7 +69,7 @@ infer = "0.12.0"
num_cpus = "1.15.0"

# Heif/Heic
libheif-rs = { version = "0.15.1", optional = true }
libheif-rs = { version = "0.16.0", optional = true }
anyhow = { version = "1.0", optional = true }

state="0.5.3"
Expand Down
4 changes: 2 additions & 2 deletions czkawka_core/src/big_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub enum SearchMode {
SmallestFiles,
}

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down Expand Up @@ -394,7 +394,7 @@ impl BigFile {
match self.delete_method {
DeleteMethod::Delete => {
for (_, file_entry) in &self.big_files {
if fs::remove_file(file_entry.path.clone()).is_err() {
if fs::remove_file(&file_entry.path).is_err() {
self.text_messages.warnings.push(file_entry.path.display().to_string());
}
}
Expand Down
62 changes: 31 additions & 31 deletions czkawka_core/src/broken_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::{fs, mem, panic, thread};

use crossbeam_channel::Receiver;
use pdf::object::ParseOptions;
use pdf::PdfError;
use pdf::PdfError::Try;
use rayon::prelude::*;
Expand All @@ -33,7 +34,7 @@ pub struct ProgressData {
pub files_to_check: usize,
}

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down Expand Up @@ -521,41 +522,40 @@ impl BrokenFiles {
Err(_inspected) => Some(None),
},

TypeOfFile::PDF => {
match fs::read(&file_entry.path) {
Ok(content) => {
// Will be available in pdf > 0.7.2
// let parser_options = ParseOptions {
// allow_error_in_option: true,
// allow_xref_error: true,
// allow_invalid_ops: true,
// allow_missing_endobj: true,
// };
// if let Err(e) = pdf::file::File::from_data_with_options(content, parser_options) {

let mut file_entry_clone = file_entry.clone();
let result = panic::catch_unwind(|| {
if let Err(e) = pdf::file::File::from_data(content) {
file_entry.error_string = e.to_string();
let error = unpack_pdf_error(e);
if let PdfError::InvalidPassword = error {
return Some(None);
TypeOfFile::PDF => match fs::read(&file_entry.path) {
Ok(content) => {
let parser_options = ParseOptions::tolerant(); // Only show as broken files with really big bugs

let mut file_entry_clone = file_entry.clone();
let result = panic::catch_unwind(|| {
if let Err(e) = pdf::file::File::from_data_with_options(content, parser_options) {
let mut error_string = e.to_string();
// Workaround for strange error message https://github.com/qarmin/czkawka/issues/898
if error_string.starts_with("Try at") {
if let Some(start_index) = error_string.find("/pdf-") {
error_string = format!("Decoding error in pdf-rs library - {}", &error_string[start_index..]);
}
}
Some(Some(file_entry))
});
if let Ok(pdf_result) = result {
pdf_result
} else {
let message = create_crash_message("PDF-rs", &file_entry_clone.path.to_string_lossy(), "https://github.com/pdf-rs/pdf");
println!("{message}");
file_entry_clone.error_string = message;
Some(Some(file_entry_clone))

file_entry.error_string = error_string;
let error = unpack_pdf_error(e);
if let PdfError::InvalidPassword = error {
return Some(None);
}
}
Some(Some(file_entry))
});
if let Ok(pdf_result) = result {
pdf_result
} else {
let message = create_crash_message("PDF-rs", &file_entry_clone.path.to_string_lossy(), "https://github.com/pdf-rs/pdf");
println!("{message}");
file_entry_clone.error_string = message;
Some(Some(file_entry_clone))
}
Err(_inspected) => Some(None),
}
}
Err(_inspected) => Some(None),
},

// This means that cache read invalid value because maybe cache comes from different czkawka version
TypeOfFile::Unknown => Some(None),
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ pub fn open_cache_folder(cache_file_name: &str, save_to_cache: bool, use_json: b
pub fn get_dynamic_image_from_heic(path: &str) -> Result<DynamicImage> {
let im = HeifContext::read_from_file(path)?;
let handle = im.primary_image_handle()?;
let image = handle.decode(ColorSpace::Rgb(RgbChroma::Rgb), false)?;
let image = handle.decode(ColorSpace::Rgb(RgbChroma::Rgb), None)?;
let width = image.width(Channel::Interleaved).map_err(|e| anyhow::anyhow!("{}", e))?;
let height = image.height(Channel::Interleaved).map_err(|e| anyhow::anyhow!("{}", e))?;
let planes = image.planes();
Expand Down
4 changes: 2 additions & 2 deletions czkawka_core/src/common_dir_traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub struct SymlinkInfo {
pub type_of_error: ErrorType,
}

#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Copy)]
pub enum ErrorType {
InfiniteRecursion,
NonExistentFile,
Expand Down Expand Up @@ -87,7 +87,7 @@ pub enum Collect {
Files,
}

#[derive(Eq, PartialEq)]
#[derive(Eq, PartialEq, Copy, Clone)]
enum EntryType {
File,
Dir,
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/duplicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl HashType {
}
}

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
AllExceptNewest,
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/invalid_symlinks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::common_items::ExcludedItems;
use crate::common_messages::Messages;
use crate::common_traits::*;

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down
4 changes: 2 additions & 2 deletions czkawka_core/src/same_music.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::common_items::ExcludedItems;
use crate::common_messages::Messages;
use crate::common_traits::*;

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down Expand Up @@ -666,7 +666,7 @@ impl SameMusic {
for file_entry in vec_file_entry {
let thing = file_entry.genre.trim().to_lowercase();
if !thing.is_empty() {
hash_map.entry(thing.clone()).or_insert_with(Vec::new).push(file_entry);
hash_map.entry(thing).or_insert_with(Vec::new).push(file_entry);
}
}
for (_title, vec_file_entry) in hash_map {
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/similar_images.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub struct FileEntry {
}

/// Used by CLI tool when we cannot use directly values
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Copy)]
pub enum SimilarityPreset {
Original,
VeryHigh,
Expand Down
7 changes: 4 additions & 3 deletions czkawka_core/src/similar_videos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ impl SimilarVideos {
if self.excluded_items.is_excluded(&current_file_name) {
continue 'dir;
}
let current_file_name_str = current_file_name.to_string_lossy().to_string();

let fe: FileEntry = FileEntry {
path: current_file_name.clone(),
Expand All @@ -401,15 +402,15 @@ impl SimilarVideos {
Err(_inspected) => {
warnings.push(flc!(
"core_file_modified_before_epoch",
generate_translation_hashmap(vec![("name", current_file_name.display().to_string())])
generate_translation_hashmap(vec![("name", current_file_name_str.clone())])
));
0
}
},
Err(e) => {
warnings.push(flc!(
"core_file_no_modification_date",
generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())])
generate_translation_hashmap(vec![("name", current_file_name_str.clone()), ("reason", e.to_string())])
));
0
}
Expand All @@ -418,7 +419,7 @@ impl SimilarVideos {
error: String::new(),
};

fe_result.push((current_file_name.to_string_lossy().to_string(), fe));
fe_result.push((current_file_name_str, fe));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion czkawka_core/src/temporary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct ProgressData {
pub files_checked: usize,
}

#[derive(Eq, PartialEq, Clone, Debug)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum DeleteMethod {
None,
Delete,
Expand Down
14 changes: 7 additions & 7 deletions czkawka_gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ homepage = "https://github.com/qarmin/czkawka"
repository = "https://github.com/qarmin/czkawka"

[dependencies]
gdk4 = "0.5.5"
glib = "0.16.7"
gdk4 = "0.6.0"
glib = "0.17.1"

humansize = "2.1.3"
chrono = "0.4.23"
Expand All @@ -20,7 +20,7 @@ chrono = "0.4.23"
crossbeam-channel = "0.5.6"

# To get information about progress
futures = "0.3.25"
futures = "0.3.26"

# For saving/loading config files to specific directories
directories-next = "2.0.0"
Expand All @@ -38,22 +38,22 @@ regex = "1.7.1"
image_hasher = "1.1.2"

# Move files to trash
trash = "3.0.0"
trash = "3.0.1"

# For moving files(why std::fs doesn't have such features)
fs_extra = "1.2.0"
fs_extra = "1.3.0"

# Language
i18n-embed = { version = "0.13.8", features = ["fluent-system", "desktop-requester"] }
i18n-embed-fl = "0.6.5"
rust-embed = "6.4.2"
once_cell = "1.17.0"
once_cell = "1.17.1"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["combaseapi", "objbase", "shobjidl_core", "windef", "winerror", "wtypesbase", "winuser"] }

[dependencies.gtk4]
version = "0.5.5"
version = "0.6.1"
default-features = false
features = ["v4_6"]

Expand Down
10 changes: 9 additions & 1 deletion czkawka_gui/i18n/en/czkawka_gui.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ popover_custom_all_in_group_label = Don't select all records in group
popover_custom_mode_unselect = Unselect Custom
popover_custom_mode_select = Select Custom
popover_sort_file_name = File name
popover_sort_folder_name = Folder name
popover_sort_full_name = Full name
popover_sort_size = Size
popover_sort_selection = Selection
popover_invalid_regex = Regex is invalid
popover_valid_regex = Regex is valid
Expand All @@ -250,6 +255,7 @@ bottom_save_button = Save
bottom_symlink_button = Symlink
bottom_hardlink_button = Hardlink
bottom_move_button = Move
bottom_sort_button = Sort
bottom_search_button_tooltip = Start search
bottom_select_button_tooltip = Select records. Only selected files/folders can be later processed.
Expand All @@ -268,10 +274,12 @@ bottom_hardlink_button_not_available_tooltip =
Button is disabled, because hardlinks cannot be created.
Hardlinks only works with administrator privileges on Windows, so be sure to run app as administrator.
If app already works with such privileges check for similar issues on Github.
bottom_move_button_tooltip =
bottom_move_button_tooltip =
Moves files to chosen directory.
It copies all files to the directory without preserving the directory tree.
When trying to move two files with identical name to folder, second will fail and show error.
bottom_sort_button_tooltip =
Sorts files/folders according to selected method.
bottom_show_errors_tooltip = Show/Hide bottom text panel.
bottom_show_upper_notebook_tooltip = Show/Hide upper notebook panel.
Expand Down
Loading

0 comments on commit f1c6e6d

Please sign in to comment.