Add some code
This commit is contained in:
parent
3bd24918ba
commit
9728b43580
10 changed files with 244 additions and 42 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -1722,13 +1722,12 @@ checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libheif-rs"
|
name = "libheif-rs"
|
||||||
version = "0.19.2"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "749fcebc2069f334599304546cfa891c30be08cdf4f358ed984a2c71c5e0031f"
|
checksum = "37d09b0d2d69da084eeeda9534662bc6b6096fbce3f307149750c0e572ad0ccd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"enumn",
|
"enumn",
|
||||||
"four-cc",
|
"four-cc",
|
||||||
"libc",
|
|
||||||
"libheif-sys",
|
"libheif-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -584,6 +584,7 @@ fn parse_checking_method(src: &str) -> Result<CheckingMethod, &'static str> {
|
||||||
match src.to_ascii_lowercase().as_str() {
|
match src.to_ascii_lowercase().as_str() {
|
||||||
"name" => Ok(CheckingMethod::Name),
|
"name" => Ok(CheckingMethod::Name),
|
||||||
"size" => Ok(CheckingMethod::Size),
|
"size" => Ok(CheckingMethod::Size),
|
||||||
|
"size_name" => Ok(CheckingMethod::SizeName),
|
||||||
"hash" => Ok(CheckingMethod::Hash),
|
"hash" => Ok(CheckingMethod::Hash),
|
||||||
_ => Err("Couldn't parse the search method (allowed: NAME, SIZE, HASH)"),
|
_ => Err("Couldn't parse the search method (allowed: NAME, SIZE, HASH)"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ infer = "0.13.0"
|
||||||
num_cpus = "1.15.0"
|
num_cpus = "1.15.0"
|
||||||
|
|
||||||
# Heif/Heic
|
# Heif/Heic
|
||||||
libheif-rs = { version = "0.19.2", optional = true }
|
libheif-rs = { version = "0.18.0", optional = true } # TODO update this, decode function is missing in this version
|
||||||
anyhow = { version = "1.0", optional = true }
|
anyhow = { version = "1.0", optional = true }
|
||||||
|
|
||||||
state="0.5.3"
|
state="0.5.3"
|
||||||
|
|
|
@ -30,6 +30,7 @@ pub struct ProgressData {
|
||||||
pub enum CheckingMethod {
|
pub enum CheckingMethod {
|
||||||
None,
|
None,
|
||||||
Name,
|
Name,
|
||||||
|
SizeName,
|
||||||
Size,
|
Size,
|
||||||
Hash,
|
Hash,
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,8 @@ pub struct Info {
|
||||||
pub number_of_duplicated_files_by_hash: usize,
|
pub number_of_duplicated_files_by_hash: usize,
|
||||||
pub number_of_groups_by_name: usize,
|
pub number_of_groups_by_name: usize,
|
||||||
pub number_of_duplicated_files_by_name: usize,
|
pub number_of_duplicated_files_by_name: usize,
|
||||||
|
pub number_of_groups_by_size_name: usize,
|
||||||
|
pub number_of_duplicated_files_by_size_name: usize,
|
||||||
pub lost_space_by_size: u64,
|
pub lost_space_by_size: u64,
|
||||||
pub lost_space_by_hash: u64,
|
pub lost_space_by_hash: u64,
|
||||||
}
|
}
|
||||||
|
@ -152,7 +154,13 @@ impl DuplicateFinder {
|
||||||
|
|
||||||
match self.check_method {
|
match self.check_method {
|
||||||
CheckingMethod::Name => {
|
CheckingMethod::Name => {
|
||||||
self.stopped_search = !self.check_files_size_name(stop_receiver, progress_sender); // TODO restore this to name
|
self.stopped_search = !self.check_files_name(stop_receiver, progress_sender); // TODO restore this to name
|
||||||
|
if self.stopped_search {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CheckingMethod::SizeName => {
|
||||||
|
self.stopped_search = !self.check_files_size_name(stop_receiver, progress_sender);
|
||||||
if self.stopped_search {
|
if self.stopped_search {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -225,6 +233,11 @@ impl DuplicateFinder {
|
||||||
&self.files_with_identical_size
|
&self.files_with_identical_size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub const fn get_files_sorted_by_size_name(&self) -> &BTreeMap<(u64, String), Vec<FileEntry>> {
|
||||||
|
&self.files_with_identical_size_names
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn get_files_sorted_by_hash(&self) -> &BTreeMap<u64, Vec<Vec<FileEntry>>> {
|
pub const fn get_files_sorted_by_hash(&self) -> &BTreeMap<u64, Vec<Vec<FileEntry>>> {
|
||||||
&self.files_with_identical_hashes
|
&self.files_with_identical_hashes
|
||||||
|
@ -323,6 +336,11 @@ impl DuplicateFinder {
|
||||||
&self.files_with_identical_size_referenced
|
&self.files_with_identical_size_referenced
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn get_files_with_identical_size_names_referenced(&self) -> &BTreeMap<(u64, String), (FileEntry, Vec<FileEntry>)> {
|
||||||
|
&self.files_with_identical_size_names_referenced
|
||||||
|
}
|
||||||
|
|
||||||
fn check_files_name(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool {
|
fn check_files_name(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool {
|
||||||
let group_by_func = if self.case_sensitive_name_comparison {
|
let group_by_func = if self.case_sensitive_name_comparison {
|
||||||
|fe: &FileEntry| fe.path.file_name().unwrap().to_string_lossy().to_string()
|
|fe: &FileEntry| fe.path.file_name().unwrap().to_string_lossy().to_string()
|
||||||
|
@ -484,12 +502,13 @@ impl DuplicateFinder {
|
||||||
})
|
})
|
||||||
.collect::<Vec<(FileEntry, Vec<FileEntry>)>>();
|
.collect::<Vec<(FileEntry, Vec<FileEntry>)>>();
|
||||||
for (fe, vec_fe) in vec {
|
for (fe, vec_fe) in vec {
|
||||||
self.files_with_identical_names_referenced.insert(fe.path.to_string_lossy().to_string(), (fe, vec_fe));
|
self.files_with_identical_size_names_referenced
|
||||||
|
.insert((fe.size, fe.path.to_string_lossy().to_string()), (fe, vec_fe));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.calculate_name_stats(); // TODO change this
|
self.calculate_size_name_stats();
|
||||||
|
|
||||||
Common::print_time(start_time, SystemTime::now(), "check_files_name");
|
Common::print_time(start_time, SystemTime::now(), "check_files_size_name");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
DirTraversalResult::SuccessFolders { .. } => {
|
DirTraversalResult::SuccessFolders { .. } => {
|
||||||
|
@ -499,6 +518,22 @@ impl DuplicateFinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calculate_size_name_stats(&mut self) {
|
||||||
|
if self.use_reference_folders {
|
||||||
|
for ((size, _name), (_fe, vector)) in &self.files_with_identical_size_names_referenced {
|
||||||
|
self.information.number_of_duplicated_files_by_size_name += vector.len();
|
||||||
|
self.information.number_of_groups_by_size_name += 1;
|
||||||
|
self.information.lost_space_by_size += (vector.len() as u64) * size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for ((size, _name), vector) in &self.files_with_identical_size_names {
|
||||||
|
self.information.number_of_duplicated_files_by_size_name += vector.len() - 1;
|
||||||
|
self.information.number_of_groups_by_size_name += 1;
|
||||||
|
self.information.lost_space_by_size += (vector.len() as u64 - 1) * size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Read file length and puts it to different boxes(each for different lengths)
|
/// Read file length and puts it to different boxes(each for different lengths)
|
||||||
/// If in box is only 1 result, then it is removed
|
/// If in box is only 1 result, then it is removed
|
||||||
fn check_files_size(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool {
|
fn check_files_size(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool {
|
||||||
|
@ -1036,6 +1071,11 @@ impl DuplicateFinder {
|
||||||
let _tuple: (u64, usize, usize) = delete_files(vector, &self.delete_method, &mut self.text_messages, self.dryrun);
|
let _tuple: (u64, usize, usize) = delete_files(vector, &self.delete_method, &mut self.text_messages, self.dryrun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CheckingMethod::SizeName => {
|
||||||
|
for vector in self.files_with_identical_size_names.values() {
|
||||||
|
let _tuple: (u64, usize, usize) = delete_files(vector, &self.delete_method, &mut self.text_messages, self.dryrun);
|
||||||
|
}
|
||||||
|
}
|
||||||
CheckingMethod::Hash => {
|
CheckingMethod::Hash => {
|
||||||
for vector_vectors in self.files_with_identical_hashes.values() {
|
for vector_vectors in self.files_with_identical_hashes.values() {
|
||||||
for vector in vector_vectors.iter() {
|
for vector in vector_vectors.iter() {
|
||||||
|
@ -1169,6 +1209,30 @@ impl SaveResults for DuplicateFinder {
|
||||||
write!(writer, "Not found any files with same names.").unwrap();
|
write!(writer, "Not found any files with same names.").unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CheckingMethod::SizeName => {
|
||||||
|
if !self.files_with_identical_names.is_empty() {
|
||||||
|
writeln!(
|
||||||
|
writer,
|
||||||
|
"-------------------------------------------------Files with same size and names-------------------------------------------------"
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
writeln!(
|
||||||
|
writer,
|
||||||
|
"Found {} files in {} groups with same size and name(may have different content)",
|
||||||
|
self.information.number_of_duplicated_files_by_size_name, self.information.number_of_groups_by_size_name,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
for ((size, name), vector) in self.files_with_identical_size_names.iter().rev() {
|
||||||
|
writeln!(writer, "Name - {}, {} - {} files ", name, format_size(*size, BINARY), vector.len()).unwrap();
|
||||||
|
for j in vector {
|
||||||
|
writeln!(writer, "{}", j.path.display()).unwrap();
|
||||||
|
}
|
||||||
|
writeln!(writer).unwrap();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
write!(writer, "Not found any files with same size and names.").unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
CheckingMethod::Size => {
|
CheckingMethod::Size => {
|
||||||
if !self.files_with_identical_size.is_empty() {
|
if !self.files_with_identical_size.is_empty() {
|
||||||
writeln!(
|
writeln!(
|
||||||
|
@ -1253,6 +1317,20 @@ impl PrintResults for DuplicateFinder {
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CheckingMethod::SizeName => {
|
||||||
|
for i in &self.files_with_identical_size_names {
|
||||||
|
number_of_files += i.1.len() as u64;
|
||||||
|
number_of_groups += 1;
|
||||||
|
}
|
||||||
|
println!("Found {number_of_files} files in {number_of_groups} groups with same size and name(may have different content)",);
|
||||||
|
for ((size, name), vector) in &self.files_with_identical_size_names {
|
||||||
|
println!("Name - {}, {} - {} files ", name, format_size(*size, BINARY), vector.len());
|
||||||
|
for j in vector {
|
||||||
|
println!("{}", j.path.display());
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
CheckingMethod::Hash => {
|
CheckingMethod::Hash => {
|
||||||
for vector in self.files_with_identical_hashes.values() {
|
for vector in self.files_with_identical_hashes.values() {
|
||||||
for j in vector {
|
for j in vector {
|
||||||
|
|
|
@ -28,6 +28,7 @@ duplicate_case_sensitive_name_tooltip =
|
||||||
|
|
||||||
Disabling such option will group names without checking if each letter is same size e.g. żoŁD <-> Żołd
|
Disabling such option will group names without checking if each letter is same size e.g. żoŁD <-> Żołd
|
||||||
|
|
||||||
|
duplicate_mode_size_name_combo_box = Size and Name
|
||||||
duplicate_mode_name_combo_box = Name
|
duplicate_mode_name_combo_box = Name
|
||||||
duplicate_mode_size_combo_box = Size
|
duplicate_mode_size_combo_box = Size
|
||||||
duplicate_mode_hash_combo_box = Hash
|
duplicate_mode_hash_combo_box = Hash
|
||||||
|
@ -447,6 +448,7 @@ progress_scanning_music_tags_end = Comparing tags of {$file_checked}/{$all_files
|
||||||
progress_scanning_music_tags = Reading tags of {$file_checked}/{$all_files} music file
|
progress_scanning_music_tags = Reading tags of {$file_checked}/{$all_files} music file
|
||||||
progress_scanning_empty_folders = Scanning {$folder_number} folder
|
progress_scanning_empty_folders = Scanning {$folder_number} folder
|
||||||
progress_scanning_size = Scanning size of {$file_number} file
|
progress_scanning_size = Scanning size of {$file_number} file
|
||||||
|
progress_scanning_size_name = Scanning name and size of {$file_number} file
|
||||||
progress_scanning_name = Scanning name of {$file_number} file
|
progress_scanning_name = Scanning name of {$file_number} file
|
||||||
progress_analyzed_partial_hash = Analyzed partial hash of {$file_checked}/{$all_files} files
|
progress_analyzed_partial_hash = Analyzed partial hash of {$file_checked}/{$all_files} files
|
||||||
progress_analyzed_full_hash = Analyzed full hash of {$file_checked}/{$all_files} files
|
progress_analyzed_full_hash = Analyzed full hash of {$file_checked}/{$all_files} files
|
||||||
|
|
|
@ -99,8 +99,29 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
|
||||||
match df.get_check_method() {
|
match df.get_check_method() {
|
||||||
CheckingMethod::Name => {
|
CheckingMethod::Name => {
|
||||||
duplicates_number = information.number_of_duplicated_files_by_name;
|
duplicates_number = information.number_of_duplicated_files_by_name;
|
||||||
// duplicates_size = 0;
|
duplicates_size = 0;
|
||||||
duplicates_group = information.number_of_groups_by_name;
|
duplicates_group = information.number_of_groups_by_name;
|
||||||
|
}
|
||||||
|
CheckingMethod::Hash => {
|
||||||
|
duplicates_number = information.number_of_duplicated_files_by_hash;
|
||||||
|
duplicates_size = information.lost_space_by_hash;
|
||||||
|
duplicates_group = information.number_of_groups_by_hash;
|
||||||
|
}
|
||||||
|
CheckingMethod::Size => {
|
||||||
|
duplicates_number = information.number_of_duplicated_files_by_size;
|
||||||
|
duplicates_size = information.lost_space_by_size;
|
||||||
|
duplicates_group = information.number_of_groups_by_size;
|
||||||
|
}
|
||||||
|
CheckingMethod::SizeName => {
|
||||||
|
duplicates_number = information.number_of_duplicated_files_by_size_name;
|
||||||
|
duplicates_size = information.lost_space_by_size;
|
||||||
|
duplicates_group = information.number_of_groups_by_size_name;
|
||||||
|
}
|
||||||
|
CheckingMethod::None => {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if duplicates_size == 0 {
|
||||||
entry_info.set_text(
|
entry_info.set_text(
|
||||||
flg!(
|
flg!(
|
||||||
"compute_found_duplicates_name",
|
"compute_found_duplicates_name",
|
||||||
|
@ -108,11 +129,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
CheckingMethod::Hash => {
|
|
||||||
duplicates_number = information.number_of_duplicated_files_by_hash;
|
|
||||||
duplicates_size = information.lost_space_by_hash;
|
|
||||||
duplicates_group = information.number_of_groups_by_hash;
|
|
||||||
entry_info.set_text(
|
entry_info.set_text(
|
||||||
flg!(
|
flg!(
|
||||||
"compute_found_duplicates_hash_size",
|
"compute_found_duplicates_hash_size",
|
||||||
|
@ -125,26 +142,6 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
|
||||||
.as_str(),
|
.as_str(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
CheckingMethod::Size => {
|
|
||||||
duplicates_number = information.number_of_duplicated_files_by_size;
|
|
||||||
duplicates_size = information.lost_space_by_size;
|
|
||||||
duplicates_group = information.number_of_groups_by_size;
|
|
||||||
entry_info.set_text(
|
|
||||||
flg!(
|
|
||||||
"compute_found_duplicates_hash_size",
|
|
||||||
generate_translation_hashmap(vec![
|
|
||||||
("number_files", duplicates_number.to_string()),
|
|
||||||
("number_groups", duplicates_group.to_string()),
|
|
||||||
("size", format_size(duplicates_size, BINARY))
|
|
||||||
])
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
CheckingMethod::None => {
|
|
||||||
panic!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create GUI
|
// Create GUI
|
||||||
{
|
{
|
||||||
|
@ -335,6 +332,65 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CheckingMethod::SizeName => {
|
||||||
|
let btreemap = df.get_files_with_identical_size_names_referenced();
|
||||||
|
|
||||||
|
for (_size, (base_file_entry, vector)) in btreemap.iter().rev() {
|
||||||
|
// Sort
|
||||||
|
let vector = if vector.len() >= 2 {
|
||||||
|
let mut vector = vector.clone();
|
||||||
|
vector.sort_unstable_by_key(|e| {
|
||||||
|
let t = split_path(e.path.as_path());
|
||||||
|
(t.0, t.1)
|
||||||
|
});
|
||||||
|
vector
|
||||||
|
} else {
|
||||||
|
vector.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
// HEADER
|
||||||
|
let (directory, file) = split_path(&base_file_entry.path);
|
||||||
|
let values: [(u32, &dyn ToValue); COLUMNS_NUMBER] = [
|
||||||
|
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
|
||||||
|
(ColumnsDuplicates::SelectionButton as u32, &false),
|
||||||
|
(ColumnsDuplicates::Size as u32, (&format_size(base_file_entry.size, BINARY))),
|
||||||
|
(ColumnsDuplicates::SizeAsBytes as u32, &base_file_entry.size),
|
||||||
|
(ColumnsDuplicates::Name as u32, &file),
|
||||||
|
(ColumnsDuplicates::Path as u32, &directory),
|
||||||
|
(
|
||||||
|
ColumnsDuplicates::Modification as u32,
|
||||||
|
&(NaiveDateTime::from_timestamp_opt(base_file_entry.modified_date as i64, 0).unwrap().to_string()),
|
||||||
|
),
|
||||||
|
(ColumnsDuplicates::ModificationAsSecs as u32, &(base_file_entry.modified_date)),
|
||||||
|
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
|
||||||
|
(ColumnsDuplicates::IsHeader as u32, &true),
|
||||||
|
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
|
||||||
|
];
|
||||||
|
|
||||||
|
// MEAT
|
||||||
|
list_store.set(&list_store.append(), &values);
|
||||||
|
for entry in vector {
|
||||||
|
let (directory, file) = split_path(&entry.path);
|
||||||
|
let values: [(u32, &dyn ToValue); COLUMNS_NUMBER] = [
|
||||||
|
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
|
||||||
|
(ColumnsDuplicates::SelectionButton as u32, &false),
|
||||||
|
(ColumnsDuplicates::Size as u32, (&format_size(entry.size, BINARY))),
|
||||||
|
(ColumnsDuplicates::SizeAsBytes as u32, &entry.size),
|
||||||
|
(ColumnsDuplicates::Name as u32, &file),
|
||||||
|
(ColumnsDuplicates::Path as u32, &directory),
|
||||||
|
(
|
||||||
|
ColumnsDuplicates::Modification as u32,
|
||||||
|
&(NaiveDateTime::from_timestamp_opt(entry.modified_date as i64, 0).unwrap().to_string()),
|
||||||
|
),
|
||||||
|
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
|
||||||
|
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
|
||||||
|
(ColumnsDuplicates::IsHeader as u32, &false),
|
||||||
|
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
|
||||||
|
];
|
||||||
|
list_store.set(&list_store.append(), &values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
CheckingMethod::None => {
|
CheckingMethod::None => {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
@ -507,6 +563,58 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CheckingMethod::SizeName => {
|
||||||
|
let btreemap = df.get_files_sorted_by_size_name();
|
||||||
|
|
||||||
|
for (_size, vector) in btreemap.iter().rev() {
|
||||||
|
// Sort
|
||||||
|
let vector = if vector.len() >= 2 {
|
||||||
|
let mut vector = vector.clone();
|
||||||
|
vector.sort_unstable_by_key(|e| {
|
||||||
|
let t = split_path(e.path.as_path());
|
||||||
|
(t.0, t.1)
|
||||||
|
});
|
||||||
|
vector
|
||||||
|
} else {
|
||||||
|
vector.clone()
|
||||||
|
};
|
||||||
|
let values: [(u32, &dyn ToValue); COLUMNS_NUMBER] = [
|
||||||
|
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
|
||||||
|
(ColumnsDuplicates::SelectionButton as u32, &false),
|
||||||
|
(ColumnsDuplicates::Size as u32, (&String::new())),
|
||||||
|
(ColumnsDuplicates::SizeAsBytes as u32, &0),
|
||||||
|
(ColumnsDuplicates::Name as u32, (&String::new())),
|
||||||
|
(ColumnsDuplicates::Path as u32, (&String::new())),
|
||||||
|
(ColumnsDuplicates::Modification as u32, &String::new()), // No text in 3 column
|
||||||
|
(ColumnsDuplicates::ModificationAsSecs as u32, &(0)), // Not used here
|
||||||
|
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
|
||||||
|
(ColumnsDuplicates::IsHeader as u32, &true),
|
||||||
|
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
|
||||||
|
];
|
||||||
|
|
||||||
|
list_store.set(&list_store.append(), &values);
|
||||||
|
for entry in vector {
|
||||||
|
let (directory, file) = split_path(&entry.path);
|
||||||
|
let values: [(u32, &dyn ToValue); COLUMNS_NUMBER] = [
|
||||||
|
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
|
||||||
|
(ColumnsDuplicates::SelectionButton as u32, &false),
|
||||||
|
(ColumnsDuplicates::Size as u32, (&format_size(entry.size, BINARY))),
|
||||||
|
(ColumnsDuplicates::SizeAsBytes as u32, &entry.size),
|
||||||
|
(ColumnsDuplicates::Name as u32, &file),
|
||||||
|
(ColumnsDuplicates::Path as u32, &directory),
|
||||||
|
(
|
||||||
|
ColumnsDuplicates::Modification as u32,
|
||||||
|
&(NaiveDateTime::from_timestamp_opt(entry.modified_date as i64, 0).unwrap().to_string()),
|
||||||
|
),
|
||||||
|
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
|
||||||
|
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
|
||||||
|
(ColumnsDuplicates::IsHeader as u32, &false),
|
||||||
|
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
|
||||||
|
];
|
||||||
|
list_store.set(&list_store.append(), &values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
CheckingMethod::None => {
|
CheckingMethod::None => {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,16 @@ pub fn connect_progress_window(
|
||||||
));
|
));
|
||||||
taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE);
|
taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE);
|
||||||
}
|
}
|
||||||
|
common_dir_traversal::CheckingMethod::SizeName => {
|
||||||
|
label_stage.show();
|
||||||
|
grid_progress_stages.hide();
|
||||||
|
|
||||||
|
label_stage.set_text(&flg!(
|
||||||
|
"progress_scanning_size_name",
|
||||||
|
generate_translation_hashmap(vec![("file_number", item.entries_checked.to_string())])
|
||||||
|
));
|
||||||
|
taskbar_state.borrow().set_progress_state(TBPF_INDETERMINATE);
|
||||||
|
}
|
||||||
common_dir_traversal::CheckingMethod::Size => {
|
common_dir_traversal::CheckingMethod::Size => {
|
||||||
label_stage.show();
|
label_stage.show();
|
||||||
grid_progress_stages.hide();
|
grid_progress_stages.hide();
|
||||||
|
|
|
@ -549,9 +549,8 @@ impl GuiMainNotebook {
|
||||||
CheckingMethod::Hash => flg!("duplicate_mode_hash_combo_box"),
|
CheckingMethod::Hash => flg!("duplicate_mode_hash_combo_box"),
|
||||||
CheckingMethod::Size => flg!("duplicate_mode_size_combo_box"),
|
CheckingMethod::Size => flg!("duplicate_mode_size_combo_box"),
|
||||||
CheckingMethod::Name => flg!("duplicate_mode_name_combo_box"),
|
CheckingMethod::Name => flg!("duplicate_mode_name_combo_box"),
|
||||||
_ => {
|
CheckingMethod::SizeName => flg!("duplicate_mode_size_name_combo_box"),
|
||||||
panic!()
|
CheckingMethod::None => panic!(),
|
||||||
}
|
|
||||||
};
|
};
|
||||||
self.combo_box_duplicate_check_method.append_text(&text);
|
self.combo_box_duplicate_check_method.append_text(&text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub struct CheckMethodStruct {
|
||||||
pub check_method: CheckingMethod,
|
pub check_method: CheckingMethod,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DUPLICATES_CHECK_METHOD_COMBO_BOX: [CheckMethodStruct; 3] = [
|
pub const DUPLICATES_CHECK_METHOD_COMBO_BOX: [CheckMethodStruct; 4] = [
|
||||||
CheckMethodStruct {
|
CheckMethodStruct {
|
||||||
eng_name: "Hash",
|
eng_name: "Hash",
|
||||||
check_method: CheckingMethod::Hash,
|
check_method: CheckingMethod::Hash,
|
||||||
|
@ -42,6 +42,10 @@ pub const DUPLICATES_CHECK_METHOD_COMBO_BOX: [CheckMethodStruct; 3] = [
|
||||||
eng_name: "Name",
|
eng_name: "Name",
|
||||||
check_method: CheckingMethod::Name,
|
check_method: CheckingMethod::Name,
|
||||||
},
|
},
|
||||||
|
CheckMethodStruct {
|
||||||
|
eng_name: "Size and Name",
|
||||||
|
check_method: CheckingMethod::SizeName,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
|
Loading…
Reference in a new issue