Clean GUI code, make it easier to understand and change (#462)

* Add static variable for basic notebook data

* Opening, selecting results by space, enter and mouse

* Now hard/symbolic links

* Now deleting

* Now popovers

* Move tests to different function

* Don't crash when there is no selected records

* Button symlinks

* Now move

* Compute results

* Move again

* Again Popovers

* More popovers and more

* Key clicking, removing

* KEY_DELETE

* No more GuiData clone

* Adding directories

* Reorganize a little files
This commit is contained in:
Rafał Mikrut 2021-11-25 08:36:49 +01:00 committed by GitHub
parent 78b49dee3d
commit c9719758c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1461 additions and 2161 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 Rafał Mikrut
Copyright (c) 2020-2021 Rafał Mikrut
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,4 +1,6 @@
use humansize::{file_size_opts as options, FileSize};
use std::cell::RefCell;
use std::collections::HashMap;
use crate::gui_data::GuiData;
use crate::help_functions::*;
@ -10,6 +12,7 @@ use czkawka_core::similar_images;
use glib::Receiver;
use gtk::prelude::*;
use std::path::PathBuf;
use std::rc::Rc;
pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<Message>) {
let buttons_search = gui_data.bottom_buttons.buttons_search.clone();
@ -129,28 +132,31 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
};
let values: [(u32, &dyn ToValue); 8] = [
(0, &false),
(1, &false),
(2, &name),
(3, (&(format!("{} results", vector.len())))),
(4, (&"".to_string())), // No text in 3 column
(5, (&(0))), // Not used here
(6, &(HEADER_ROW_COLOR.to_string())),
(7, &(TEXT_COLOR.to_string())),
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Name as u32, &name),
(ColumnsDuplicates::Path as u32, (&(format!("{} results", vector.len())))),
(ColumnsDuplicates::Modification as u32, (&"".to_string())), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, (&(0))), // Not used here
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::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); 8] = [
(0, &true),
(1, &false),
(2, &file),
(3, &directory),
(4, &(format!("{} - ({})", NaiveDateTime::from_timestamp(entry.modified_date as i64, 0), entry.size.file_size(options::BINARY).unwrap()))),
(5, &(entry.modified_date)),
(6, &(MAIN_ROW_COLOR.to_string())),
(7, &(TEXT_COLOR.to_string())),
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Name as u32, &file),
(ColumnsDuplicates::Path as u32, &directory),
(
ColumnsDuplicates::Modification as u32,
&(format!("{} - ({})", NaiveDateTime::from_timestamp(entry.modified_date as i64, 0), entry.size.file_size(options::BINARY).unwrap())),
),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
}
@ -174,17 +180,17 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
};
let values: [(u32, &dyn ToValue); 8] = [
(0, &false),
(1, &false),
(2, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))),
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Name as u32, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))),
(
3,
ColumnsDuplicates::Path as u32,
&(format!("{} ({} bytes) lost", ((vector.len() - 1) as u64 * *size as u64).file_size(options::BINARY).unwrap(), (vector.len() - 1) as u64 * *size as u64)),
),
(4, &"".to_string()), // No text in 3 column
(5, &(0)),
(6, &(HEADER_ROW_COLOR.to_string())),
(7, &(TEXT_COLOR.to_string())),
(ColumnsDuplicates::Modification as u32, &"".to_string()), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, &(0)),
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -192,14 +198,14 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
let (directory, file) = split_path(&entry.path);
let values: [(u32, &dyn ToValue); 8] = [
(0, &true),
(1, &false),
(2, &file),
(3, &directory),
(4, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())),
(5, &(entry.modified_date)),
(6, &(MAIN_ROW_COLOR.to_string())),
(7, &(TEXT_COLOR.to_string())),
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Name as u32, &file),
(ColumnsDuplicates::Path as u32, &directory),
(ColumnsDuplicates::Modification as u32, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -223,31 +229,31 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
vector.clone()
};
let values: [(u32, &dyn ToValue); 8] = [
(0, &false),
(1, &false),
(2, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))),
(ColumnsDuplicates::ActivatableSelectButton as u32, &false),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Name as u32, &(format!("{} x {} ({} bytes)", vector.len(), size.file_size(options::BINARY).unwrap(), size))),
(
3,
ColumnsDuplicates::Path as u32,
&(format!("{} ({} bytes) lost", ((vector.len() - 1) as u64 * *size as u64).file_size(options::BINARY).unwrap(), (vector.len() - 1) as u64 * *size as u64)),
),
(4, &"".to_string()), // No text in 3 column
(5, &(0)), // Not used here
(6, &(HEADER_ROW_COLOR.to_string())),
(7, &(TEXT_COLOR.to_string())),
(ColumnsDuplicates::Modification as u32, &"".to_string()), // No text in 3 column
(ColumnsDuplicates::ModificationAsSecs as u32, &(0)), // Not used here
(ColumnsDuplicates::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsDuplicates::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); 8] = [
(0, &true),
(1, &false),
(2, &file),
(3, &directory),
(4, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())),
(5, &(entry.modified_date)),
(6, &(MAIN_ROW_COLOR.to_string())),
(7, &(TEXT_COLOR.to_string())),
(ColumnsDuplicates::ActivatableSelectButton as u32, &true),
(ColumnsDuplicates::SelectionButton as u32, &false),
(ColumnsDuplicates::Name as u32, &file),
(ColumnsDuplicates::Path as u32, &directory),
(ColumnsDuplicates::Modification as u32, &(NaiveDateTime::from_timestamp(entry.modified_date as i64, 0).to_string())),
(ColumnsDuplicates::ModificationAsSecs as u32, &(entry.modified_date)),
(ColumnsDuplicates::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsDuplicates::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
}
@ -265,21 +271,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_duplication_state.borrow_mut() = df;
if duplicates_number > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("symlink").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("hardlink").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("symlink").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("hardlink").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::Duplicate, &["save", "delete", "select", "symlink", "hardlink", "move"], duplicates_number > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Duplicate).unwrap(), &buttons_array, &buttons_names);
}
}
@ -309,7 +302,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for path in vector {
let (directory, file) = split_path(&path);
let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(hashmap.get(&path).unwrap().modified_date as i64, 0).to_string()))];
let values: [(u32, &dyn ToValue); 4] = [
(ColumnsEmptyFolders::SelectionButton as u32, &false),
(ColumnsEmptyFolders::Name as u32, &file),
(ColumnsEmptyFolders::Path as u32, &directory),
(ColumnsEmptyFolders::Modification as u32, &(NaiveDateTime::from_timestamp(hashmap.get(&path).unwrap().modified_date as i64, 0).to_string())),
];
list_store.set(&list_store.append(), &values);
}
print_text_messages_to_text_view(text_messages, &text_view_errors);
@ -319,17 +317,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_empty_folders_state.borrow_mut() = ef;
if empty_folder_number > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::EmptyDirectories, &["save", "delete", "select", "move"], empty_folder_number > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyDirectories).unwrap(), &buttons_array, &buttons_names);
}
}
@ -360,7 +349,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for file_entry in vector {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))];
let values: [(u32, &dyn ToValue); 4] = [
(ColumnsEmptyFiles::SelectionButton as u32, &false),
(ColumnsEmptyFiles::Name as u32, &file),
(ColumnsEmptyFiles::Path as u32, &directory),
(ColumnsEmptyFiles::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
];
list_store.set(&list_store.append(), &values);
}
print_text_messages_to_text_view(text_messages, &text_view_errors);
@ -370,17 +364,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_empty_files_state.borrow_mut() = vf;
if empty_files_number > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::EmptyFiles, &["save", "delete", "select", "move"], empty_files_number > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::EmptyFiles).unwrap(), &buttons_array, &buttons_names);
}
}
@ -411,11 +396,11 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for file_entry in vector {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 5] = [
(0, &false),
(1, &(format!("{} ({} bytes)", size.file_size(options::BINARY).unwrap(), size))),
(2, &file),
(3, &directory),
(4, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
(ColumnsBigFiles::SelectionButton as u32, &false),
(ColumnsBigFiles::Size as u32, &(format!("{} ({} bytes)", size.file_size(options::BINARY).unwrap(), size))),
(ColumnsBigFiles::Name as u32, &file),
(ColumnsBigFiles::Path as u32, &directory),
(ColumnsBigFiles::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
];
list_store.set(&list_store.append(), &values);
}
@ -427,17 +412,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_big_files_state.borrow_mut() = bf;
if biggest_files_number > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::BigFiles, &["save", "delete", "select", "move"], biggest_files_number > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BigFiles).unwrap(), &buttons_array, &buttons_names);
}
}
@ -468,7 +444,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for file_entry in vector {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 4] = [(0, &false), (1, &file), (2, &directory), (3, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string()))];
let values: [(u32, &dyn ToValue); 4] = [
(ColumnsTemporaryFiles::SelectionButton as u32, &false),
(ColumnsTemporaryFiles::Name as u32, &file),
(ColumnsTemporaryFiles::Path as u32, &directory),
(ColumnsTemporaryFiles::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
];
list_store.set(&list_store.append(), &values);
}
print_text_messages_to_text_view(text_messages, &text_view_errors);
@ -478,17 +459,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_temporary_files_state.borrow_mut() = tf;
if temporary_files_number > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::Temporary, &["save", "delete", "select", "move"], temporary_files_number > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Temporary).unwrap(), &buttons_array, &buttons_names);
}
}
@ -525,18 +497,18 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Header
let values: [(u32, &dyn ToValue); 12] = [
(0, &false),
(1, &false),
(2, &"".to_string()),
(3, &"".to_string()),
(4, &(0)),
(5, &"".to_string()),
(6, &"".to_string()),
(7, &"".to_string()),
(8, &"".to_string()),
(9, &(0)),
(10, &(HEADER_ROW_COLOR.to_string())),
(11, &(TEXT_COLOR.to_string())),
(ColumnsSimilarImages::ActivatableSelectButton as u32, &false),
(ColumnsSimilarImages::SelectionButton as u32, &false),
(ColumnsSimilarImages::Similarity as u32, &"".to_string()),
(ColumnsSimilarImages::Size as u32, &"".to_string()),
(ColumnsSimilarImages::SizeAsBytes as u32, &(0)),
(ColumnsSimilarImages::Dimensions as u32, &"".to_string()),
(ColumnsSimilarImages::Name as u32, &"".to_string()),
(ColumnsSimilarImages::Path as u32, &"".to_string()),
(ColumnsSimilarImages::Modification as u32, &"".to_string()),
(ColumnsSimilarImages::ModificationAsSecs as u32, &(0)),
(ColumnsSimilarImages::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
@ -544,18 +516,18 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for file_entry in vec_file_entry.iter() {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 12] = [
(0, &true),
(1, &false),
(2, &(similar_images::get_string_from_similarity(&file_entry.similarity, hash_size).to_string())),
(3, &file_entry.size.file_size(options::BINARY).unwrap()),
(4, &file_entry.size),
(5, &file_entry.dimensions),
(6, &file),
(7, &directory),
(8, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
(9, &(file_entry.modified_date)),
(10, &(MAIN_ROW_COLOR.to_string())),
(11, &(TEXT_COLOR.to_string())),
(ColumnsSimilarImages::ActivatableSelectButton as u32, &true),
(ColumnsSimilarImages::SelectionButton as u32, &false),
(ColumnsSimilarImages::Similarity as u32, &(similar_images::get_string_from_similarity(&file_entry.similarity, hash_size).to_string())),
(ColumnsSimilarImages::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()),
(ColumnsSimilarImages::SizeAsBytes as u32, &file_entry.size),
(ColumnsSimilarImages::Dimensions as u32, &file_entry.dimensions),
(ColumnsSimilarImages::Name as u32, &file),
(ColumnsSimilarImages::Path as u32, &directory),
(ColumnsSimilarImages::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
(ColumnsSimilarImages::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSimilarImages::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSimilarImages::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
}
@ -568,21 +540,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_similar_images_state.borrow_mut() = sf;
if base_images_size > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("symlink").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("hardlink").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("symlink").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("hardlink").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::SimilarImages, &["save", "delete", "select", "symlink", "hardlink", "move"], base_images_size > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarImages).unwrap(), &buttons_array, &buttons_names);
}
}
@ -620,7 +579,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
// Header
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsSimilarVideos::ActivatableSelectButton as u32, &false),
(ColumnsSimilarVideos::ActiveSelectButton as u32, &false),
(ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &"".to_string()),
(ColumnsSimilarVideos::SizeAsBytes as u32, &(0)),
(ColumnsSimilarVideos::Name as u32, &"".to_string()),
@ -637,7 +596,7 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 10] = [
(ColumnsSimilarVideos::ActivatableSelectButton as u32, &true),
(ColumnsSimilarVideos::ActiveSelectButton as u32, &false),
(ColumnsSimilarVideos::SelectionButton as u32, &false),
(ColumnsSimilarVideos::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()),
(ColumnsSimilarVideos::SizeAsBytes as u32, &file_entry.size),
(ColumnsSimilarVideos::Name as u32, &file),
@ -658,21 +617,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_similar_videos_state.borrow_mut() = ff;
if base_videos_size > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("symlink").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("hardlink").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("symlink").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("hardlink").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::SimilarVideos, &["save", "delete", "select", "symlink", "hardlink", "move"], base_videos_size > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SimilarVideos).unwrap(), &buttons_array, &buttons_names);
}
}
@ -718,71 +664,71 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
};
let values: [(u32, &dyn ToValue); 15] = [
(0, &false),
(1, &false),
(2, &"".to_string()),
(3, &(0)),
(4, &"".to_string()),
(5, &"".to_string()),
(ColumnsSameMusic::ActivatableSelectButton as u32, &false),
(ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &"".to_string()),
(ColumnsSameMusic::SizeAsBytes as u32, &(0)),
(ColumnsSameMusic::Name as u32, &"".to_string()),
(ColumnsSameMusic::Path as u32, &"".to_string()),
(
6,
ColumnsSameMusic::Title as u32,
&(match is_title {
true => text.clone(),
false => "".to_string(),
}),
),
(
7,
ColumnsSameMusic::Artist as u32,
&(match is_artist {
true => text.clone(),
false => "".to_string(),
}),
),
(
8,
ColumnsSameMusic::AlbumTitle as u32,
&(match is_album_title {
true => text.clone(),
false => "".to_string(),
}),
),
(
9,
ColumnsSameMusic::AlbumArtist as u32,
&(match is_album_artist {
true => text.clone(),
false => "".to_string(),
}),
),
(
10,
ColumnsSameMusic::Year as u32,
&(match is_year {
true => text.clone(),
false => "".to_string(),
}),
),
(11, &"".to_string()),
(12, &(0)),
(13, &(HEADER_ROW_COLOR.to_string())),
(14, &(TEXT_COLOR.to_string())),
(ColumnsSameMusic::Modification as u32, &"".to_string()),
(ColumnsSameMusic::ModificationAsSecs as u32, &(0)),
(ColumnsSameMusic::Color as u32, &(HEADER_ROW_COLOR.to_string())),
(ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
for file_entry in vec_file_entry {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 15] = [
(0, &true),
(1, &false),
(2, &file_entry.size.file_size(options::BINARY).unwrap()),
(3, &file_entry.size),
(4, &file),
(5, &directory),
(6, &file_entry.title),
(7, &file_entry.artist),
(8, &file_entry.album_title),
(9, &file_entry.album_artist),
(10, &file_entry.year.to_string()),
(11, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
(12, &(file_entry.modified_date)),
(13, &(MAIN_ROW_COLOR.to_string())),
(14, &(TEXT_COLOR.to_string())),
(ColumnsSameMusic::ActivatableSelectButton as u32, &true),
(ColumnsSameMusic::SelectionButton as u32, &false),
(ColumnsSameMusic::Size as u32, &file_entry.size.file_size(options::BINARY).unwrap()),
(ColumnsSameMusic::SizeAsBytes as u32, &file_entry.size),
(ColumnsSameMusic::Name as u32, &file),
(ColumnsSameMusic::Path as u32, &directory),
(ColumnsSameMusic::Title as u32, &file_entry.title),
(ColumnsSameMusic::Artist as u32, &file_entry.artist),
(ColumnsSameMusic::AlbumTitle as u32, &file_entry.album_title),
(ColumnsSameMusic::AlbumArtist as u32, &file_entry.album_artist),
(ColumnsSameMusic::Year as u32, &file_entry.year.to_string()),
(ColumnsSameMusic::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
(ColumnsSameMusic::ModificationAsSecs as u32, &(file_entry.modified_date)),
(ColumnsSameMusic::Color as u32, &(MAIN_ROW_COLOR.to_string())),
(ColumnsSameMusic::TextColor as u32, &(TEXT_COLOR.to_string())),
];
list_store.set(&list_store.append(), &values);
}
@ -794,21 +740,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_same_music_state.borrow_mut() = mf;
if same_music_number > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("symlink").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("hardlink").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("symlink").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("hardlink").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::SameMusic, &["save", "delete", "select", "symlink", "hardlink", "move"], same_music_number > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::SameMusic).unwrap(), &buttons_array, &buttons_names);
}
}
@ -841,12 +774,12 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for file_entry in vector {
let (directory, file) = split_path(&file_entry.symlink_path);
let values: [(u32, &dyn ToValue); 6] = [
(0, &false),
(1, &file),
(2, &directory),
(3, &file_entry.destination_path.to_string_lossy().to_string()),
(4, &get_text_from_invalid_symlink_cause(&file_entry.type_of_error)),
(5, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
(ColumnsInvalidSymlinks::SelectionButton as u32, &false),
(ColumnsInvalidSymlinks::Name as u32, &file),
(ColumnsInvalidSymlinks::Path as u32, &directory),
(ColumnsInvalidSymlinks::DestinationPath as u32, &file_entry.destination_path.to_string_lossy().to_string()),
(ColumnsInvalidSymlinks::TypeOfError as u32, &get_text_from_invalid_symlink_cause(&file_entry.type_of_error)),
(ColumnsInvalidSymlinks::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
];
list_store.set(&list_store.append(), &values);
}
@ -857,17 +790,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_same_invalid_symlinks.borrow_mut() = ifs;
if invalid_symlinks > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::Symlinks, &["save", "delete", "select", "move"], invalid_symlinks > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::Symlinks).unwrap(), &buttons_array, &buttons_names);
}
}
@ -899,11 +823,11 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
for file_entry in vector {
let (directory, file) = split_path(&file_entry.path);
let values: [(u32, &dyn ToValue); 5] = [
(0, &false),
(1, &file),
(2, &directory),
(3, &file_entry.error_string),
(4, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
(ColumnsBrokenFiles::SelectionButton as u32, &false),
(ColumnsBrokenFiles::Name as u32, &file),
(ColumnsBrokenFiles::Path as u32, &directory),
(ColumnsBrokenFiles::ErrorType as u32, &file_entry.error_string),
(ColumnsBrokenFiles::Modification as u32, &(NaiveDateTime::from_timestamp(file_entry.modified_date as i64, 0).to_string())),
];
list_store.set(&list_store.append(), &values);
}
@ -914,17 +838,8 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
{
*shared_broken_files_state.borrow_mut() = br;
if broken_files_number > 0 {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("save").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("delete").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("select").unwrap() = true;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("move").unwrap() = true;
} else {
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("save").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("delete").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("select").unwrap() = false;
*shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap().get_mut("move").unwrap() = false;
}
set_specific_buttons_as_active(&shared_buttons, &NotebookMainEnum::BrokenFiles, &["save", "delete", "select", "move"], broken_files_number > 0);
set_buttons(&mut *shared_buttons.borrow_mut().get_mut(&NotebookMainEnum::BrokenFiles).unwrap(), &buttons_array, &buttons_names);
}
}
@ -934,3 +849,9 @@ pub fn connect_compute_results(gui_data: &GuiData, glib_stop_receiver: Receiver<
glib::Continue(true)
});
}
fn set_specific_buttons_as_active(buttons_array: &Rc<RefCell<HashMap<NotebookMainEnum, HashMap<String, bool>>>>, notebook_enum: &NotebookMainEnum, buttons: &[&str], value_to_set: bool) {
for i in buttons {
*buttons_array.borrow_mut().get_mut(notebook_enum).unwrap().get_mut(*i).unwrap() = value_to_set;
}
}

View File

@ -2,7 +2,7 @@ use crate::gui_data::GuiData;
use crate::help_functions::*;
use crate::notebook_enums::*;
use gtk::prelude::*;
use gtk::Align;
use gtk::{Align, CheckButton, TextView};
use std::collections::BTreeMap;
use std::fs;
use std::fs::Metadata;
@ -10,159 +10,59 @@ use std::fs::Metadata;
// TODO add support for checking if really symlink doesn't point to correct directory/file
pub fn connect_button_delete(gui_data: &GuiData) {
let gui_data = gui_data.clone();
let buttons_delete = gui_data.bottom_buttons.buttons_delete.clone();
let tree_view_duplicate_finder = gui_data.main_notebook.tree_view_duplicate_finder.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let window_main = gui_data.window_main.clone();
let tree_view_empty_folder_finder = gui_data.main_notebook.tree_view_empty_folder_finder.clone();
let tree_view_big_files_finder = gui_data.main_notebook.tree_view_big_files_finder.clone();
let tree_view_empty_files_finder = gui_data.main_notebook.tree_view_empty_files_finder.clone();
let tree_view_temporary_files_finder = gui_data.main_notebook.tree_view_temporary_files_finder.clone();
let tree_view_similar_images_finder = gui_data.main_notebook.tree_view_similar_images_finder.clone();
let tree_view_similar_videos_finder = gui_data.main_notebook.tree_view_similar_videos_finder.clone();
let tree_view_same_music_finder = gui_data.main_notebook.tree_view_same_music_finder.clone();
let tree_view_invalid_symlinks = gui_data.main_notebook.tree_view_invalid_symlinks.clone();
let tree_view_broken_files = gui_data.main_notebook.tree_view_broken_files.clone();
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone();
let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone();
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
buttons_delete.connect_clicked(move |_| {
// TODO maybe add to this dialog info how much things will be deleted
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) {
return;
}
match to_notebook_main_enum(notebook_main.current_page().unwrap()) {
NotebookMainEnum::Duplicate => {
if !check_button_settings_confirm_group_deletion.is_active()
|| !check_if_deleting_all_files_in_group(
&tree_view_duplicate_finder.clone(),
ColumnsDuplicates::Color as i32,
ColumnsDuplicates::ActiveSelectButton as i32,
&window_main,
&check_button_settings_confirm_group_deletion,
)
{
let nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
if let Some(column_color) = nb_object.column_color {
if !check_button_settings_confirm_group_deletion.is_active() || !check_if_deleting_all_files_in_group(tree_view, column_color, nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion) {
tree_remove(
&tree_view_duplicate_finder.clone(),
ColumnsDuplicates::Name as i32,
ColumnsDuplicates::Path as i32,
ColumnsDuplicates::Color as i32,
ColumnsDuplicates::ActiveSelectButton as i32,
&gui_data,
nb_object.column_name,
nb_object.column_path,
column_color,
nb_object.column_selection,
&check_button_settings_use_trash,
&text_view_errors,
);
}
} else {
if nb_number == NotebookMainEnum::EmptyDirectories as u32 {
empty_folder_remover(&tree_view.clone(), nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors);
} else {
basic_remove(&tree_view.clone(), nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors);
}
NotebookMainEnum::EmptyDirectories => {
empty_folder_remover(
&tree_view_empty_folder_finder.clone(),
ColumnsEmptyFolders::Name as i32,
ColumnsEmptyFolders::Path as i32,
ColumnsEmptyFolders::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::EmptyFiles => {
basic_remove(
&tree_view_empty_files_finder.clone(),
ColumnsEmptyFiles::Name as i32,
ColumnsEmptyFiles::Path as i32,
ColumnsEmptyFiles::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::Temporary => {
basic_remove(
&tree_view_temporary_files_finder.clone(),
ColumnsTemporaryFiles::Name as i32,
ColumnsTemporaryFiles::Path as i32,
ColumnsTemporaryFiles::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::BigFiles => {
basic_remove(&tree_view_big_files_finder.clone(), ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, ColumnsBigFiles::ActiveSelectButton as i32, &gui_data);
}
match &nb_object.notebook_type {
NotebookMainEnum::SimilarImages => {
if !check_button_settings_confirm_group_deletion.is_active()
|| !check_if_deleting_all_files_in_group(
&tree_view_similar_images_finder.clone(),
ColumnsSimilarImages::Color as i32,
ColumnsSimilarImages::ActiveSelectButton as i32,
&window_main,
&check_button_settings_confirm_group_deletion,
)
{
tree_remove(
&tree_view_similar_images_finder.clone(),
ColumnsSimilarImages::Name as i32,
ColumnsSimilarImages::Path as i32,
ColumnsSimilarImages::Color as i32,
ColumnsSimilarImages::ActiveSelectButton as i32,
&gui_data,
);
image_preview_similar_images.hide();
}
NotebookMainEnum::Duplicate => {
image_preview_duplicates.hide();
}
NotebookMainEnum::SimilarVideos => {
if !check_button_settings_confirm_group_deletion.is_active()
|| !check_if_deleting_all_files_in_group(
&tree_view_similar_videos_finder.clone(),
ColumnsSimilarVideos::Color as i32,
ColumnsSimilarVideos::ActiveSelectButton as i32,
&window_main,
&check_button_settings_confirm_group_deletion,
)
{
tree_remove(
&tree_view_similar_videos_finder.clone(),
ColumnsSimilarVideos::Name as i32,
ColumnsSimilarVideos::Path as i32,
ColumnsSimilarVideos::Color as i32,
ColumnsSimilarVideos::ActiveSelectButton as i32,
&gui_data,
);
}
}
NotebookMainEnum::SameMusic => {
if !check_button_settings_confirm_group_deletion.is_active()
|| !check_if_deleting_all_files_in_group(
&tree_view_same_music_finder.clone(),
ColumnsSameMusic::Color as i32,
ColumnsSameMusic::ActiveSelectButton as i32,
&window_main,
&check_button_settings_confirm_group_deletion,
)
{
tree_remove(
&tree_view_same_music_finder.clone(),
ColumnsSameMusic::Name as i32,
ColumnsSameMusic::Path as i32,
ColumnsSameMusic::Color as i32,
ColumnsSameMusic::ActiveSelectButton as i32,
&gui_data,
);
}
}
NotebookMainEnum::Symlinks => {
basic_remove(
&tree_view_invalid_symlinks.clone(),
ColumnsInvalidSymlinks::Name as i32,
ColumnsInvalidSymlinks::Path as i32,
ColumnsInvalidSymlinks::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::BrokenFiles => {
basic_remove(
&tree_view_broken_files.clone(),
ColumnsBrokenFiles::Name as i32,
ColumnsBrokenFiles::Path as i32,
ColumnsInvalidSymlinks::ActiveSelectButton as i32,
&gui_data,
);
}
_ => {}
}
});
}
@ -289,9 +189,8 @@ pub fn check_if_deleting_all_files_in_group(tree_view: &gtk::TreeView, column_co
false
}
pub fn empty_folder_remover(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, gui_data: &GuiData) {
let text_view_errors = gui_data.text_view_errors.clone();
let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active();
pub fn empty_folder_remover(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, check_button_settings_use_trash: &CheckButton, text_view_errors: &TextView) {
let use_trash = check_button_settings_use_trash.is_active();
let model = get_list_store(tree_view);
@ -308,6 +207,10 @@ pub fn empty_folder_remover(tree_view: &gtk::TreeView, column_file_name: i32, co
}
}
if selected_rows.is_empty() {
return; // No selected rows
}
let mut messages: String = "".to_string();
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
@ -390,20 +293,19 @@ pub fn empty_folder_remover(tree_view: &gtk::TreeView, column_file_name: i32, co
text_view_errors.buffer().unwrap().set_text(messages.as_str());
}
pub fn basic_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, gui_data: &GuiData) {
let text_view_errors = gui_data.text_view_errors.clone();
let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active();
pub fn basic_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, check_button_settings_use_trash: &CheckButton, text_view_errors: &TextView) {
let use_trash = check_button_settings_use_trash.is_active();
let model = get_list_store(tree_view);
let mut messages: String = "".to_string();
let mut selection_rows = Vec::new();
let mut selected_rows = Vec::new();
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
selection_rows.push(model.path(&iter).unwrap());
selected_rows.push(model.path(&iter).unwrap());
}
if !model.iter_next(&iter) {
@ -412,8 +314,12 @@ pub fn basic_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_pat
}
}
if selected_rows.is_empty() {
return; // No selected rows
}
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
for tree_path in selection_rows.iter().rev() {
for tree_path in selected_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap();
let name = model.value(&iter, column_file_name).get::<String>().unwrap();
@ -440,9 +346,8 @@ pub fn basic_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_pat
}
// Remove all occurrences - remove every element which have same path and name as even non selected ones
pub fn tree_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, gui_data: &GuiData) {
let text_view_errors = gui_data.text_view_errors.clone();
let use_trash = gui_data.settings.check_button_settings_use_trash.clone().is_active();
pub fn tree_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, check_button_settings_use_trash: &CheckButton, text_view_errors: &TextView) {
let use_trash = check_button_settings_use_trash.is_active();
let model = get_list_store(tree_view);
@ -451,16 +356,15 @@ pub fn tree_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_path
let mut vec_path_to_delete: Vec<(String, String)> = Vec::new();
let mut map_with_path_to_delete: BTreeMap<String, Vec<String>> = Default::default(); // BTreeMap<Path,Vec<FileName>>
let mut selection_rows = Vec::new();
let mut selected_rows = Vec::new();
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
// TODO, this maybe isn't required if we will be sure that any header cannot be selected
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
selection_rows.push(model.path(&iter).unwrap());
selected_rows.push(model.path(&iter).unwrap());
} else {
panic!("Header row shouldn't have selected, selection button");
panic!("Header row shouldn't be selected, please report bug.");
}
}
@ -470,8 +374,12 @@ pub fn tree_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_path
}
}
if selected_rows.is_empty() {
return; // No selected rows
}
// Save to variable paths of files, and remove it when not removing all occurrences.
for tree_path in selection_rows.iter().rev() {
for tree_path in selected_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap();
let file_name = model.value(&iter, column_file_name).get::<String>().unwrap();
@ -500,74 +408,7 @@ pub fn tree_remove(tree_view: &gtk::TreeView, column_file_name: i32, column_path
}
}
// Remove only child from header
if let Some(first_iter) = model.iter_first() {
let mut vec_tree_path_to_delete: Vec<gtk::TreePath> = Vec::new();
let mut current_iter = first_iter;
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
panic!("First deleted element, should be a header"); // First element should be header
};
let mut next_iter;
let mut next_next_iter;
'main: loop {
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
panic!("First deleted element, should be a header"); // First element should be header
};
next_iter = current_iter.clone();
if !model.iter_next(&next_iter) {
// There is only single header left (H1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
break 'main;
}
if model.value(&next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
// There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
current_iter = next_iter.clone();
continue 'main;
}
next_next_iter = next_iter.clone();
if !model.iter_next(&next_next_iter) {
// There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
break 'main;
}
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
// One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
current_iter = next_next_iter.clone();
continue 'main;
}
loop {
// (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD)
if !model.iter_next(&next_next_iter) {
break 'main;
}
// Move to next header
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
current_iter = next_next_iter.clone();
continue 'main;
}
}
}
for tree_path in vec_tree_path_to_delete.iter().rev() {
model.remove(&model.iter(tree_path).unwrap());
}
}
// Last step, remove orphan header if exists
if let Some(iter) = model.iter_first() {
if !model.iter_next(&iter) {
model.clear();
}
}
clean_invalid_headers(&model, column_color);
text_view_errors.buffer().unwrap().set_text(messages.as_str());
}

View File

@ -3,78 +3,74 @@ use crate::help_functions::*;
use crate::notebook_enums::*;
use czkawka_core::duplicate::make_hard_link;
use gtk::prelude::*;
use gtk::{TreeIter, TreePath};
use gtk::{TextView, TreeIter, TreePath};
use std::fs;
use std::path::PathBuf;
pub fn connect_button_hardlink(gui_data: &GuiData) {
let gui_data = gui_data.clone();
pub fn connect_button_hardlink_symlink(gui_data: &GuiData) {
let buttons_hardlink = gui_data.bottom_buttons.buttons_hardlink.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let tree_view_duplicate_finder = gui_data.main_notebook.tree_view_duplicate_finder.clone();
let tree_view_similar_images_finder = gui_data.main_notebook.tree_view_similar_images_finder.clone();
let tree_view_similar_videos_finder = gui_data.main_notebook.tree_view_similar_videos_finder.clone();
let tree_view_same_music_finder = gui_data.main_notebook.tree_view_same_music_finder.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone();
let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone();
buttons_hardlink.connect_clicked(move |_| match to_notebook_main_enum(notebook_main.current_page().unwrap()) {
NotebookMainEnum::Duplicate => {
hardlink_symlink(
tree_view_duplicate_finder.clone(),
ColumnsDuplicates::Name as i32,
ColumnsDuplicates::Path as i32,
ColumnsDuplicates::Color as i32,
ColumnsDuplicates::ActiveSelectButton as i32,
true,
&gui_data,
);
}
NotebookMainEnum::SameMusic => {
hardlink_symlink(
tree_view_same_music_finder.clone(),
ColumnsSameMusic::Name as i32,
ColumnsSameMusic::Path as i32,
ColumnsSameMusic::Color as i32,
ColumnsSameMusic::ActiveSelectButton as i32,
true,
&gui_data,
);
}
let text_view_errors = gui_data.text_view_errors.clone();
buttons_hardlink.connect_clicked(move |_| {
let nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
let column_color = nb_object.column_color.expect("Hardinkning can be only used for tree views with grouped results");
hardlink_symlink(tree_view, nb_object.column_name, nb_object.column_path, column_color, nb_object.column_selection, true, &text_view_errors);
match &nb_object.notebook_type {
NotebookMainEnum::SimilarImages => {
hardlink_symlink(
tree_view_similar_images_finder.clone(),
ColumnsSimilarImages::Name as i32,
ColumnsSimilarImages::Path as i32,
ColumnsSimilarImages::Color as i32,
ColumnsSimilarImages::ActiveSelectButton as i32,
true,
&gui_data,
);
image_preview_similar_images.hide();
}
NotebookMainEnum::SimilarVideos => {
hardlink_symlink(
tree_view_similar_videos_finder.clone(),
ColumnsSimilarVideos::Name as i32,
ColumnsSimilarVideos::Path as i32,
ColumnsSimilarVideos::Color as i32,
ColumnsSimilarVideos::ActiveSelectButton as i32,
true,
&gui_data,
);
NotebookMainEnum::Duplicate => {
image_preview_duplicates.hide();
}
_ => {}
}
});
let buttons_symlink = gui_data.bottom_buttons.buttons_symlink.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone();
let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone();
let text_view_errors = gui_data.text_view_errors.clone();
buttons_symlink.connect_clicked(move |_| {
let nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
let column_color = nb_object.column_color.expect("Symlinking can be only used for tree views with grouped results");
hardlink_symlink(tree_view, nb_object.column_name, nb_object.column_path, column_color, nb_object.column_selection, false, &text_view_errors);
match &nb_object.notebook_type {
NotebookMainEnum::SimilarImages => {
image_preview_similar_images.hide();
}
NotebookMainEnum::Duplicate => {
image_preview_duplicates.hide();
}
_ => {}
}
e => panic!("Not existent {:?}", e),
});
}
pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, hardlinking: bool, gui_data: &GuiData) {
let text_view_errors = gui_data.text_view_errors.clone();
reset_text_view(&text_view_errors);
pub fn hardlink_symlink(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, hardlinking: bool, text_view_errors: &TextView) {
reset_text_view(text_view_errors);
let model = get_list_store(&tree_view);
let model = get_list_store(tree_view);
#[derive(Debug)]
struct SymHardlinkData {
@ -92,8 +88,12 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_
let mut selected_rows = Vec::new();
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR && model.value(&iter, column_selection).get::<bool>().unwrap() {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
selected_rows.push(model.path(&iter).unwrap());
} else {
panic!("Header row shouldn't be selected, please report bug.");
}
}
if !model.iter_next(&iter) {
break;
@ -101,6 +101,10 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_
}
}
if selected_rows.is_empty() {
return; // No selected rows
}
let mut current_symhardlink_data: Option<SymHardlinkData> = None;
let mut current_selected_index = 0;
loop {
@ -165,12 +169,11 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_
match make_hard_link(&PathBuf::from(&symhardlink_data.original_data), &PathBuf::from(&file_to_hardlink)) {
Ok(_) => (),
Err(e) => {
add_text_to_text_view(&text_view_errors, format!("Failed to hardlink {}, reason {}", file_to_hardlink, e).as_str());
add_text_to_text_view(text_view_errors, format!("Failed to hardlink {}, reason {}", file_to_hardlink, e).as_str());
continue;
}
}
}
println!();
}
} else {
for symhardlink_data in vec_symhardlink_data {
@ -178,7 +181,7 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_
match fs::remove_file(&file_to_symlink) {
Ok(_) => (),
Err(e) => {
add_text_to_text_view(&text_view_errors, format!("Failed to remove file {} when creating symlink, reason {}", file_to_symlink, e).as_str());
add_text_to_text_view(text_view_errors, format!("Failed to remove file {} when creating symlink, reason {}", file_to_symlink, e).as_str());
continue;
}
};
@ -188,7 +191,7 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_
match std::os::unix::fs::symlink(&symhardlink_data.original_data, &file_to_symlink) {
Ok(_) => (),
Err(e) => {
add_text_to_text_view(&text_view_errors, format!("Failed to remove file {} when creating symlink, reason {}", file_to_symlink, e).as_str());
add_text_to_text_view(text_view_errors, format!("Failed to remove file {} when creating symlink, reason {}", file_to_symlink, e).as_str());
continue;
}
};
@ -204,72 +207,11 @@ pub fn hardlink_symlink(tree_view: gtk::TreeView, column_file_name: i32, column_
};
}
}
println!();
}
}
for tree_path in vec_tree_path_to_remove.iter().rev() {
model.remove(&model.iter(tree_path).unwrap());
}
// Remove only child from header
if let Some(first_iter) = model.iter_first() {
let mut vec_tree_path_to_delete: Vec<gtk::TreePath> = Vec::new();
let mut current_iter = first_iter;
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
panic!(); // First element should be header
};
let mut next_iter;
let mut next_next_iter;
'main: loop {
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
panic!(); // First element should be header
};
next_iter = current_iter.clone();
if !model.iter_next(&next_iter) {
// There is only single header left (H1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
break 'main;
}
if model.value(&next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
// There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
current_iter = next_iter.clone();
continue 'main;
}
next_next_iter = next_iter.clone();
if !model.iter_next(&next_next_iter) {
// There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
break 'main;
}
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
// One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
current_iter = next_next_iter.clone();
continue 'main;
}
loop {
// (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD)
if !model.iter_next(&next_next_iter) {
break 'main;
}
// Move to next header
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
current_iter = next_next_iter.clone();
continue 'main;
}
}
}
for tree_path in vec_tree_path_to_delete.iter().rev() {
model.remove(&model.iter(tree_path).unwrap());
}
}
clean_invalid_headers(&model, column_color);
}

View File

@ -2,141 +2,58 @@ use crate::gui_data::GuiData;
use crate::help_functions::*;
use crate::notebook_enums::*;
use gtk::prelude::*;
use gtk::TreePath;
use std::path::{Path, PathBuf};
pub fn connect_button_move(gui_data: &GuiData) {
let gui_data = gui_data.clone();
let buttons_move = gui_data.bottom_buttons.buttons_move.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let tree_view_duplicate_finder = gui_data.main_notebook.tree_view_duplicate_finder.clone();
let tree_view_empty_folder_finder = gui_data.main_notebook.tree_view_empty_folder_finder.clone();
let tree_view_big_files_finder = gui_data.main_notebook.tree_view_big_files_finder.clone();
let tree_view_empty_files_finder = gui_data.main_notebook.tree_view_empty_files_finder.clone();
let tree_view_temporary_files_finder = gui_data.main_notebook.tree_view_temporary_files_finder.clone();
let tree_view_similar_images_finder = gui_data.main_notebook.tree_view_similar_images_finder.clone();
let tree_view_same_music_finder = gui_data.main_notebook.tree_view_same_music_finder.clone();
let tree_view_invalid_symlinks = gui_data.main_notebook.tree_view_invalid_symlinks.clone();
let tree_view_broken_files = gui_data.main_notebook.tree_view_broken_files.clone();
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone();
let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone();
let entry_info = gui_data.entry_info.clone();
let text_view_errors = gui_data.text_view_errors.clone();
let window_main = gui_data.window_main.clone();
buttons_move.connect_clicked(move |_| {
let nb_number = notebook_main.current_page().unwrap();
let tree_view = &main_tree_views[nb_number as usize];
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
buttons_move.connect_clicked(move |_| match to_notebook_main_enum(notebook_main.current_page().unwrap()) {
NotebookMainEnum::Duplicate => {
move_things(
tree_view_duplicate_finder.clone(),
ColumnsDuplicates::Name as i32,
ColumnsDuplicates::Path as i32,
Some(ColumnsDuplicates::Color as i32),
ColumnsDuplicates::ActiveSelectButton as i32,
&gui_data,
tree_view,
nb_object.column_name,
nb_object.column_path,
nb_object.column_color,
nb_object.column_selection,
&entry_info,
&text_view_errors,
&window_main,
);
}
NotebookMainEnum::SameMusic => {
move_things(
tree_view_same_music_finder.clone(),
ColumnsSameMusic::Name as i32,
ColumnsSameMusic::Path as i32,
Some(ColumnsSameMusic::Color as i32),
ColumnsSameMusic::ActiveSelectButton as i32,
&gui_data,
);
}
match &nb_object.notebook_type {
NotebookMainEnum::SimilarImages => {
move_things(
tree_view_similar_images_finder.clone(),
ColumnsSimilarImages::Name as i32,
ColumnsSimilarImages::Path as i32,
Some(ColumnsSimilarImages::Color as i32),
ColumnsSimilarImages::ActiveSelectButton as i32,
&gui_data,
);
image_preview_similar_images.hide();
}
NotebookMainEnum::SimilarVideos => {
move_things(
tree_view_similar_images_finder.clone(),
ColumnsSimilarVideos::Name as i32,
ColumnsSimilarVideos::Path as i32,
Some(ColumnsSimilarVideos::Color as i32),
ColumnsSimilarVideos::ActiveSelectButton as i32,
&gui_data,
);
NotebookMainEnum::Duplicate => {
image_preview_duplicates.hide();
}
NotebookMainEnum::BigFiles => {
move_things(
tree_view_big_files_finder.clone(),
ColumnsBigFiles::Name as i32,
ColumnsBigFiles::Path as i32,
None,
ColumnsBigFiles::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::BrokenFiles => {
move_things(
tree_view_broken_files.clone(),
ColumnsBrokenFiles::Name as i32,
ColumnsBrokenFiles::Path as i32,
None,
ColumnsBrokenFiles::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::EmptyDirectories => {
move_things(
tree_view_empty_folder_finder.clone(),
ColumnsEmptyFolders::Name as i32,
ColumnsEmptyFolders::Path as i32,
None,
ColumnsEmptyFolders::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::EmptyFiles => {
move_things(
tree_view_empty_files_finder.clone(),
ColumnsEmptyFiles::Name as i32,
ColumnsEmptyFiles::Path as i32,
None,
ColumnsEmptyFiles::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::Symlinks => {
move_things(
tree_view_invalid_symlinks.clone(),
ColumnsInvalidSymlinks::Name as i32,
ColumnsInvalidSymlinks::Path as i32,
None,
ColumnsInvalidSymlinks::ActiveSelectButton as i32,
&gui_data,
);
}
NotebookMainEnum::Temporary => {
move_things(
tree_view_temporary_files_finder.clone(),
ColumnsTemporaryFiles::Name as i32,
ColumnsTemporaryFiles::Path as i32,
None,
ColumnsTemporaryFiles::ActiveSelectButton as i32,
&gui_data,
);
_ => {}
}
});
}
// TODO create and show folder chooser where user can select path
fn move_things(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32, column_color: Option<i32>, column_selection: i32, gui_data: &GuiData) {
let text_view_errors = gui_data.text_view_errors.clone();
let window_main = gui_data.window_main.clone();
reset_text_view(&text_view_errors);
// TODO add progress bar
fn move_things(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_color: Option<i32>, column_selection: i32, entry_info: &gtk::Entry, text_view_errors: &gtk::TextView, window_main: &gtk::Window) {
reset_text_view(text_view_errors);
let chooser = gtk::FileChooserDialog::with_buttons(
Some("Choose folder to which you want to move duplicated files"),
Some(&window_main),
Some(window_main),
gtk::FileChooserAction::SelectFolder,
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
);
@ -146,36 +63,30 @@ fn move_things(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32
if response_type == gtk::ResponseType::Ok {
let folders = chooser.filenames();
if folders.len() != 1 {
add_text_to_text_view(&text_view_errors, format!("Only 1 path must be selected to be able to copy there duplicated files, found {:?}", folders).as_str());
add_text_to_text_view(text_view_errors, format!("Only 1 path must be selected to be able to copy there duplicated files, found {:?}", folders).as_str());
} else {
let folder = folders[0].clone();
if let Some(column_color) = column_color {
move_with_tree(tree_view, column_file_name, column_path, column_color, column_selection, gui_data, folder);
move_with_tree(tree_view, column_file_name, column_path, column_color, column_selection, folder, entry_info, text_view_errors);
} else {
move_with_list(tree_view, column_file_name, column_path, column_selection, gui_data, folder);
move_with_list(tree_view, column_file_name, column_path, column_selection, folder, entry_info, text_view_errors);
}
}
}
chooser.close();
}
fn move_with_tree(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, gui_data: &GuiData, destination_folder: PathBuf) {
let text_view_errors = gui_data.text_view_errors.clone();
let entry_info = gui_data.entry_info.clone();
fn move_with_tree(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, destination_folder: PathBuf, entry_info: &gtk::Entry, text_view_errors: &gtk::TextView) {
let model = get_list_store(tree_view);
let model = get_list_store(&tree_view);
let mut messages: String = "".to_string();
let mut selection_rows = Vec::new();
let mut selected_rows = Vec::new();
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
// TODO, this maybe isn't required if we will be sure that any header cannot be selected
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
selection_rows.push(model.path(&iter).unwrap());
selected_rows.push(model.path(&iter).unwrap());
} else {
panic!("Header row shouldn't have selected, selection button");
panic!("Header row shouldn't be selected, please report bug.");
}
}
@ -185,119 +96,24 @@ fn move_with_tree(tree_view: gtk::TreeView, column_file_name: i32, column_path:
}
}
let mut moved_files: u32 = 0;
// Save to variable paths of files, and remove it when not removing all occurrences.
'next_result: for tree_path in selection_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap();
let file_name = model.value(&iter, column_file_name).get::<String>().unwrap();
let path = model.value(&iter, column_path).get::<String>().unwrap();
let thing = format!("{}/{}", path, file_name);
let destination_file = destination_folder.join(file_name);
if Path::new(&thing).is_dir() {
if let Err(e) = fs_extra::dir::move_dir(&thing, &destination_file, &fs_extra::dir::CopyOptions::new()) {
messages += format!("Failed to move folder, reason {}\n", e).as_str();
continue 'next_result;
}
} else {
if let Err(e) = fs_extra::file::move_file(&thing, &destination_file, &fs_extra::file::CopyOptions::new()) {
messages += format!("Failed to move file, reason {}\n", e).as_str();
continue 'next_result;
}
}
model.remove(&iter);
moved_files += 1;
}
entry_info.set_text(format!("Properly moved {}/{} files/folders", moved_files, selection_rows.len()).as_str());
// TODO move this to different function, this is used in different places
// Remove only child from header
if let Some(first_iter) = model.iter_first() {
let mut vec_tree_path_to_delete: Vec<gtk::TreePath> = Vec::new();
let mut current_iter = first_iter;
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
panic!("First deleted element, should be a header"); // First element should be header
};
let mut next_iter;
let mut next_next_iter;
'main: loop {
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
panic!("First deleted element, should be a header"); // First element should be header
};
next_iter = current_iter.clone();
if !model.iter_next(&next_iter) {
// There is only single header left (H1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
break 'main;
if selected_rows.is_empty() {
return; // No selected rows
}
if model.value(&next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
// There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
current_iter = next_iter.clone();
continue 'main;
}
move_files_common(&selected_rows, &model, column_file_name, column_path, &destination_folder, entry_info, text_view_errors);
next_next_iter = next_iter.clone();
if !model.iter_next(&next_next_iter) {
// There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
break 'main;
}
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
// One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
current_iter = next_next_iter.clone();
continue 'main;
}
loop {
// (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD)
if !model.iter_next(&next_next_iter) {
break 'main;
}
// Move to next header
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
current_iter = next_next_iter.clone();
continue 'main;
}
}
}
for tree_path in vec_tree_path_to_delete.iter().rev() {
model.remove(&model.iter(tree_path).unwrap());
}
}
// Last step, remove orphan header if exists
if let Some(iter) = model.iter_first() {
if !model.iter_next(&iter) {
model.clear();
}
}
text_view_errors.buffer().unwrap().set_text(messages.as_str());
clean_invalid_headers(&model, column_color);
}
fn move_with_list(tree_view: gtk::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, gui_data: &GuiData, destination_folder: PathBuf) {
let text_view_errors = gui_data.text_view_errors.clone();
let entry_info = gui_data.entry_info.clone();
let model = get_list_store(&tree_view);
fn move_with_list(tree_view: &gtk::TreeView, column_file_name: i32, column_path: i32, column_selection: i32, destination_folder: PathBuf, entry_info: &gtk::Entry, text_view_errors: &gtk::TextView) {
let model = get_list_store(tree_view);
let mut messages: String = "".to_string();
let mut selection_rows = Vec::new();
let mut selected_rows = Vec::new();
if let Some(iter) = model.iter_first() {
loop {
if model.value(&iter, column_selection).get::<bool>().unwrap() {
selection_rows.push(model.path(&iter).unwrap());
selected_rows.push(model.path(&iter).unwrap());
}
if !model.iter_next(&iter) {
@ -306,10 +122,20 @@ fn move_with_list(tree_view: gtk::TreeView, column_file_name: i32, column_path:
}
}
if selected_rows.is_empty() {
return; // No selected rows
}
move_files_common(&selected_rows, &model, column_file_name, column_path, &destination_folder, entry_info, text_view_errors)
}
fn move_files_common(selected_rows: &[TreePath], model: &gtk::ListStore, column_file_name: i32, column_path: i32, destination_folder: &Path, entry_info: &gtk::Entry, text_view_errors: &gtk::TextView) {
let mut messages: String = "".to_string();
let mut moved_files: u32 = 0;
// Save to variable paths of files, and remove it when not removing all occurrences.
'next_result: for tree_path in selection_rows.iter().rev() {
'next_result: for tree_path in selected_rows.iter().rev() {
let iter = model.iter(tree_path).unwrap();
let file_name = model.value(&iter, column_file_name).get::<String>().unwrap();
@ -331,7 +157,7 @@ fn move_with_list(tree_view: gtk::TreeView, column_file_name: i32, column_path:
model.remove(&iter);
moved_files += 1;
}
entry_info.set_text(format!("Properly moved {}/{} files/folders", moved_files, selection_rows.len()).as_str());
entry_info.set_text(format!("Properly moved {}/{} files/folders", moved_files, selected_rows.len()).as_str());
text_view_errors.buffer().unwrap().set_text(messages.as_str());
}

View File

@ -2,10 +2,14 @@ use crate::gui_data::GuiData;
use crate::notebook_enums::*;
use czkawka_core::common_traits::SaveResults;
use gtk::prelude::*;
use gtk::{Button, Entry};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
pub fn connect_button_save(gui_data: &GuiData) {
let gui_data = gui_data.clone();
let buttons_save = gui_data.bottom_buttons.buttons_save.clone();
let buttons_save_clone = gui_data.bottom_buttons.buttons_save.clone();
let shared_duplication_state = gui_data.shared_duplication_state.clone();
let shared_empty_folders_state = gui_data.shared_empty_folders_state.clone();
let shared_big_files_state = gui_data.shared_big_files_state.clone();
@ -16,6 +20,8 @@ pub fn connect_button_save(gui_data: &GuiData) {
let shared_same_music_state = gui_data.shared_same_music_state.clone();
let shared_same_invalid_symlinks = gui_data.shared_same_invalid_symlinks.clone();
let shared_broken_files_state = gui_data.shared_broken_files_state.clone();
let shared_buttons = gui_data.shared_buttons.clone();
let entry_info = gui_data.entry_info.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
buttons_save.connect_clicked(move |_| {
let file_name;
@ -72,14 +78,10 @@ pub fn connect_button_save(gui_data: &GuiData) {
shared_broken_files_state.borrow_mut().save_results_to_file(file_name);
}
}
post_save_things(file_name, &to_notebook_main_enum(notebook_main.current_page().unwrap()), &gui_data);
post_save_things(file_name, &to_notebook_main_enum(notebook_main.current_page().unwrap()), &shared_buttons, &entry_info, &buttons_save_clone);
});
}
fn post_save_things(file_name: &str, type_of_tab: &NotebookMainEnum, gui_data: &GuiData) {
let entry_info = gui_data.entry_info.clone();
let buttons_save = gui_data.bottom_buttons.buttons_save.clone();
let shared_buttons = gui_data.shared_buttons.clone();
fn post_save_things(file_name: &str, type_of_tab: &NotebookMainEnum, shared_buttons: &Rc<RefCell<HashMap<NotebookMainEnum, HashMap<String, bool>>>>, entry_info: &Entry, buttons_save: &Button) {
entry_info.set_text(format!("Saved results to file {}", file_name).as_str());
// Set state
{

View File

@ -1,68 +1,61 @@
use crate::gui_data::GuiData;
use crate::gui_popovers::GuiPopovers;
use crate::help_functions::PopoverTypes;
use crate::notebook_enums::*;
use gtk::prelude::*;
use std::collections::HashMap;
// TODO Replace `all`, `image_size` etc. with this
// pub enum PopoverType {
// All,
// ImageSize,
// Reverse,
// Custom,
// Date,
// }
pub fn connect_button_select(gui_data: &GuiData) {
// let mode = ["all", "image_size", "reverse", "custom", "date"];
let mut hashmap: HashMap<NotebookMainEnum, Vec<&str>> = Default::default();
let mut hashmap: HashMap<NotebookMainEnum, Vec<PopoverTypes>> = Default::default();
{
// Remember to update connect_popovers file, because this data are connected to each others
hashmap.insert(NotebookMainEnum::SimilarImages, vec!["all", "image_size", "reverse", "custom", "date"]);
hashmap.insert(NotebookMainEnum::SimilarVideos, vec!["all", "reverse", "custom", "date"]);
hashmap.insert(NotebookMainEnum::Duplicate, vec!["all", "reverse", "custom", "date"]);
hashmap.insert(NotebookMainEnum::SameMusic, vec!["all", "reverse", "custom", "date"]);
hashmap.insert(NotebookMainEnum::SimilarImages, vec![PopoverTypes::All, PopoverTypes::ImageSize, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date]);
hashmap.insert(NotebookMainEnum::SimilarVideos, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date]);
hashmap.insert(NotebookMainEnum::Duplicate, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date]);
hashmap.insert(NotebookMainEnum::SameMusic, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date]);
hashmap.insert(NotebookMainEnum::EmptyFiles, vec!["all", "reverse", "custom"]);
hashmap.insert(NotebookMainEnum::EmptyDirectories, vec!["all", "reverse", "custom"]);
hashmap.insert(NotebookMainEnum::BigFiles, vec!["all", "reverse", "custom"]);
hashmap.insert(NotebookMainEnum::Symlinks, vec!["all", "reverse", "custom"]);
hashmap.insert(NotebookMainEnum::Temporary, vec!["all", "reverse", "custom"]);
hashmap.insert(NotebookMainEnum::BrokenFiles, vec!["all", "reverse", "custom"]);
hashmap.insert(NotebookMainEnum::EmptyFiles, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]);
hashmap.insert(NotebookMainEnum::EmptyDirectories, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]);
hashmap.insert(NotebookMainEnum::BigFiles, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]);
hashmap.insert(NotebookMainEnum::Symlinks, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]);
hashmap.insert(NotebookMainEnum::Temporary, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]);
hashmap.insert(NotebookMainEnum::BrokenFiles, vec![PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom]);
}
assert_eq!(hashmap.len(), NUMBER_OF_NOTEBOOK_MAIN_TABS);
let gui_data = gui_data.clone();
let popovers = gui_data.popovers.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let buttons_select_clone = gui_data.bottom_buttons.buttons_select.clone();
let popover_select = gui_data.popovers.popover_select.clone();
let buttons_select = gui_data.bottom_buttons.buttons_select.clone();
buttons_select_clone.connect_clicked(move |_| {
show_required_popovers(&gui_data, &to_notebook_main_enum(notebook_main.current_page().unwrap()), &hashmap);
show_required_popovers(&popovers, &to_notebook_main_enum(notebook_main.current_page().unwrap()), &hashmap);
popover_select.set_relative_to(Some(&buttons_select));
popover_select.popup();
});
}
fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, hashmap: &HashMap<NotebookMainEnum, Vec<&str>>) {
let buttons_popover_select_all = gui_data.popovers.buttons_popover_select_all.clone();
let buttons_popover_unselect_all = gui_data.popovers.buttons_popover_unselect_all.clone();
let buttons_popover_reverse = gui_data.popovers.buttons_popover_reverse.clone();
let buttons_popover_select_all_except_oldest = gui_data.popovers.buttons_popover_select_all_except_oldest.clone();
let buttons_popover_select_all_except_newest = gui_data.popovers.buttons_popover_select_all_except_newest.clone();
let buttons_popover_select_one_oldest = gui_data.popovers.buttons_popover_select_one_oldest.clone();
let buttons_popover_select_one_newest = gui_data.popovers.buttons_popover_select_one_newest.clone();
let buttons_popover_select_custom = gui_data.popovers.buttons_popover_select_custom.clone();
let buttons_popover_unselect_custom = gui_data.popovers.buttons_popover_unselect_custom.clone();
let buttons_popover_select_all_images_except_biggest = gui_data.popovers.buttons_popover_select_all_images_except_biggest.clone();
let buttons_popover_select_all_images_except_smallest = gui_data.popovers.buttons_popover_select_all_images_except_smallest.clone();
fn show_required_popovers(popovers: &GuiPopovers, current_mode: &NotebookMainEnum, hashmap: &HashMap<NotebookMainEnum, Vec<PopoverTypes>>) {
let buttons_popover_select_all = popovers.buttons_popover_select_all.clone();
let buttons_popover_unselect_all = popovers.buttons_popover_unselect_all.clone();
let buttons_popover_reverse = popovers.buttons_popover_reverse.clone();
let buttons_popover_select_all_except_oldest = popovers.buttons_popover_select_all_except_oldest.clone();
let buttons_popover_select_all_except_newest = popovers.buttons_popover_select_all_except_newest.clone();
let buttons_popover_select_one_oldest = popovers.buttons_popover_select_one_oldest.clone();
let buttons_popover_select_one_newest = popovers.buttons_popover_select_one_newest.clone();
let buttons_popover_select_custom = popovers.buttons_popover_select_custom.clone();
let buttons_popover_unselect_custom = popovers.buttons_popover_unselect_custom.clone();
let buttons_popover_select_all_images_except_biggest = popovers.buttons_popover_select_all_images_except_biggest.clone();
let buttons_popover_select_all_images_except_smallest = popovers.buttons_popover_select_all_images_except_smallest.clone();
let separator_select_custom = gui_data.popovers.separator_select_custom.clone();
let separator_select_date = gui_data.popovers.separator_select_date.clone();
let separator_select_image_size = gui_data.popovers.separator_select_image_size.clone();
let separator_select_reverse = gui_data.popovers.separator_select_reverse.clone();
let separator_select_custom = popovers.separator_select_custom.clone();
let separator_select_date = popovers.separator_select_date.clone();
let separator_select_image_size = popovers.separator_select_image_size.clone();
let separator_select_reverse = popovers.separator_select_reverse.clone();
let vec = hashmap.get(current_mode).unwrap();
if vec.contains(&"all") {
if vec.contains(&PopoverTypes::All) {
buttons_popover_select_all.show();
buttons_popover_unselect_all.show();
} else {
@ -70,7 +63,7 @@ fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, h
buttons_popover_unselect_all.hide();
}
if vec.contains(&"image_size") {
if vec.contains(&PopoverTypes::ImageSize) {
buttons_popover_select_all_images_except_biggest.show();
buttons_popover_select_all_images_except_smallest.show();
separator_select_image_size.show();
@ -80,7 +73,7 @@ fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, h
separator_select_image_size.hide();
}
if vec.contains(&"reverse") {
if vec.contains(&PopoverTypes::Reverse) {
buttons_popover_reverse.show();
separator_select_reverse.show();
} else {
@ -88,7 +81,7 @@ fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, h
separator_select_reverse.hide();
}
if vec.contains(&"custom") {
if vec.contains(&PopoverTypes::Custom) {
buttons_popover_select_custom.show();
buttons_popover_unselect_custom.show();
separator_select_custom.show();
@ -98,7 +91,7 @@ fn show_required_popovers(gui_data: &GuiData, current_mode: &NotebookMainEnum, h
separator_select_custom.hide();
}
if vec.contains(&"date") {
if vec.contains(&PopoverTypes::Date) {
buttons_popover_select_all_except_oldest.show();
buttons_popover_select_all_except_newest.show();
buttons_popover_select_one_oldest.show();

View File

@ -1,70 +0,0 @@
use crate::connect_button_hardlink::hardlink_symlink;
use crate::gui_data::GuiData;
use crate::help_functions::*;
use crate::notebook_enums::*;
use gtk::prelude::*;
pub fn connect_button_symlink(gui_data: &GuiData) {
let gui_data = gui_data.clone();
let buttons_symlink = gui_data.bottom_buttons.buttons_symlink.clone();
let notebook_main = gui_data.main_notebook.notebook_main.clone();
let tree_view_duplicate_finder = gui_data.main_notebook.tree_view_duplicate_finder.clone();
let tree_view_similar_images_finder = gui_data.main_notebook.tree_view_similar_images_finder.clone();
let tree_view_similar_videos_finder = gui_data.main_notebook.tree_view_similar_videos_finder.clone();
let tree_view_same_music_finder = gui_data.main_notebook.tree_view_same_music_finder.clone();
let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone();
let image_preview_duplicates = gui_data.main_notebook.image_preview_duplicates.clone();
buttons_symlink.connect_clicked(move |_| match to_notebook_main_enum(notebook_main.current_page().unwrap()) {
NotebookMainEnum::Duplicate => {
hardlink_symlink(
tree_view_duplicate_finder.clone(),
ColumnsDuplicates::Name as i32,
ColumnsDuplicates::Path as i32,
ColumnsDuplicates::Color as i32,
ColumnsDuplicates::ActiveSelectButton as i32,
false,
&gui_data,
);
image_preview_duplicates.hide();
}
NotebookMainEnum::SameMusic => {
hardlink_symlink(
tree_view_same_music_finder.clone(),
ColumnsSameMusic::Name as i32,
ColumnsSameMusic::Path as i32,
ColumnsSameMusic::Color as i32,
ColumnsSameMusic::ActiveSelectButton as i32,
false,
&gui_data,
);
}
NotebookMainEnum::SimilarImages => {
hardlink_symlink(
tree_view_similar_images_finder.clone(),
ColumnsSimilarImages::Name as i32,
ColumnsSimilarImages::Path as i32,
ColumnsSimilarImages::Color as i32,
ColumnsSimilarImages::ActiveSelectButton as i32,
false,
&gui_data,
);
image_preview_similar_images.hide();
}
NotebookMainEnum::SimilarVideos => {
hardlink_symlink(
tree_view_similar_videos_finder.clone(),
ColumnsSimilarVideos::Name as i32,
ColumnsSimilarVideos::Path as i32,
ColumnsSimilarVideos::Color as i32,
ColumnsSimilarVideos::ActiveSelectButton as i32,
false,
&gui_data,
);
}
e => panic!("Not existent {:?}", e),
});
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
use crate::gui_data::GuiData;
use crate::help_functions::get_list_store;
use crate::help_functions::{get_list_store, ColumnsDirectory};
use gtk::prelude::*;
use gtk::{TreeView, Window};
#[cfg(target_family = "windows")]
use czkawka_core::common::Common;
@ -12,34 +13,7 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) {
let window_main = gui_data.window_main.clone();
let buttons_manual_add_directory = gui_data.upper_notebook.buttons_manual_add_directory.clone();
buttons_manual_add_directory.connect_clicked(move |_| {
let dialog_manual_add_directory = gtk::Dialog::with_buttons(Some("Add directory manually"), Some(&window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]);
let entry: gtk::Entry = gtk::Entry::new();
for widgets in dialog_manual_add_directory.children() {
// By default GtkBox is child of dialog, so we can easily add other things to it
widgets.clone().downcast::<gtk::Box>().unwrap().add(&entry);
}
dialog_manual_add_directory.show_all();
let response_type = dialog_manual_add_directory.run();
if response_type == gtk::ResponseType::Ok {
let text = entry.text().to_string().trim().to_string();
#[cfg(target_family = "windows")]
let text = Common::normalize_windows_path(text).to_string_lossy().to_string();
if !text.is_empty() {
let list_store = get_list_store(&tree_view_included_directories);
let values: [(u32, &dyn ToValue); 1] = [(0, &text)];
list_store.set(&list_store.append(), &values);
}
} else {
dialog_manual_add_directory.close();
return;
}
dialog_manual_add_directory.close();
add_manually_directories(&window_main, &tree_view_included_directories);
});
}
// Add manually excluded directory
@ -48,39 +22,7 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) {
let window_main = gui_data.window_main.clone();
let buttons_manual_add_excluded_directory = gui_data.upper_notebook.buttons_manual_add_excluded_directory.clone();
buttons_manual_add_excluded_directory.connect_clicked(move |_| {
let dialog_manual_add_directory = gtk::Dialog::with_buttons(
Some("Add excluded directory manually"),
Some(&window_main),
gtk::DialogFlags::MODAL,
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
);
let entry: gtk::Entry = gtk::Entry::new();
for widgets in dialog_manual_add_directory.children() {
// By default GtkBox is child of dialog, so we can easily add other things to it
widgets.clone().downcast::<gtk::Box>().unwrap().add(&entry);
}
dialog_manual_add_directory.show_all();
let response_type = dialog_manual_add_directory.run();
if response_type == gtk::ResponseType::Ok {
let text = entry.text().to_string().trim().to_string();
#[cfg(target_family = "windows")]
let text = Common::normalize_windows_path(text).to_string_lossy().to_string();
if !text.is_empty() {
let list_store = get_list_store(&tree_view_excluded_directories);
let values: [(u32, &dyn ToValue); 1] = [(0, &text)];
list_store.set(&list_store.append(), &values);
}
} else {
dialog_manual_add_directory.close();
return;
}
dialog_manual_add_directory.close();
add_manually_directories(&window_main, &tree_view_excluded_directories);
});
}
// Add included directory
@ -89,26 +31,7 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) {
let window_main = gui_data.window_main.clone();
let buttons_add_included_directory = gui_data.upper_notebook.buttons_add_included_directory.clone();
buttons_add_included_directory.connect_clicked(move |_| {
let chooser = gtk::FileChooserDialog::with_buttons(
Some("Folders to include"),
Some(&window_main),
gtk::FileChooserAction::SelectFolder,
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
);
chooser.set_select_multiple(true);
chooser.show_all();
let response_type = chooser.run();
if response_type == gtk::ResponseType::Ok {
let folder = chooser.filenames();
let list_store = get_list_store(&tree_view_included_directories);
for file_entry in &folder {
let values: [(u32, &dyn ToValue); 1] = [(0, &file_entry.to_string_lossy().to_string())];
list_store.set(&list_store.append(), &values);
}
}
chooser.close();
add_chosen_directories(&window_main, &tree_view_included_directories, false);
});
}
// Add excluded directory
@ -117,26 +40,7 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) {
let window_main = gui_data.window_main.clone();
let buttons_add_excluded_directory = gui_data.upper_notebook.buttons_add_excluded_directory.clone();
buttons_add_excluded_directory.connect_clicked(move |_| {
let chooser = gtk::FileChooserDialog::with_buttons(
Some("Folders to exclude"),
Some(&window_main),
gtk::FileChooserAction::SelectFolder,
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
);
chooser.set_select_multiple(true);
chooser.show_all();
let response_type = chooser.run();
if response_type == gtk::ResponseType::Ok {
let folder = chooser.filenames();
let list_store = get_list_store(&tree_view_excluded_directories);
for file_entry in &folder {
let values: [(u32, &dyn ToValue); 1] = [(0, &file_entry.to_string_lossy().to_string())];
list_store.set(&list_store.append(), &values);
}
}
chooser.close();
add_chosen_directories(&window_main, &tree_view_excluded_directories, true);
});
}
// Remove Excluded Folder
@ -170,3 +74,53 @@ pub fn connect_selection_of_directories(gui_data: &GuiData) {
});
}
}
fn add_chosen_directories(window_main: &Window, tree_view: &TreeView, excluded_items: bool) {
let folders_to = if excluded_items { "Folders to exclude" } else { "Folders to include" };
let chooser = gtk::FileChooserDialog::with_buttons(Some(folders_to), Some(window_main), gtk::FileChooserAction::SelectFolder, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]);
chooser.set_select_multiple(true);
chooser.show_all();
let response_type = chooser.run();
if response_type == gtk::ResponseType::Ok {
let folder = chooser.filenames();
let list_store = get_list_store(tree_view);
for file_entry in &folder {
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &file_entry.to_string_lossy().to_string())];
list_store.set(&list_store.append(), &values);
}
}
chooser.close();
}
fn add_manually_directories(window_main: &Window, tree_view: &TreeView) {
let dialog_manual_add_directory = gtk::Dialog::with_buttons(Some("Add directory manually"), Some(window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]);
let entry: gtk::Entry = gtk::Entry::new();
for widgets in dialog_manual_add_directory.children() {
// By default GtkBox is child of dialog, so we can easily add other things to it
widgets.clone().downcast::<gtk::Box>().unwrap().add(&entry);
}
dialog_manual_add_directory.show_all();
let response_type = dialog_manual_add_directory.run();
if response_type == gtk::ResponseType::Ok {
let text = entry.text().to_string().trim().to_string();
#[cfg(target_family = "windows")]
let text = Common::normalize_windows_path(text).to_string_lossy().to_string();
if !text.is_empty() {
let list_store = get_list_store(tree_view);
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &text)];
list_store.set(&list_store.append(), &values);
}
} else {
dialog_manual_add_directory.close();
return;
}
dialog_manual_add_directory.close();
}

View File

@ -29,26 +29,33 @@ pub fn connect_settings(gui_data: &GuiData) {
// Connect save configuration button
{
let gui_data = gui_data.clone();
let upper_notebook = gui_data.upper_notebook.clone();
let settings = gui_data.settings.clone();
let text_view_errors = gui_data.text_view_errors.clone();
let button_settings_save_configuration = gui_data.settings.button_settings_save_configuration.clone();
button_settings_save_configuration.connect_clicked(move |_| {
save_configuration(&gui_data, true);
save_configuration(true, &upper_notebook, &settings, &text_view_errors);
});
}
// Connect load configuration button
{
let gui_data = gui_data.clone();
let upper_notebook = gui_data.upper_notebook.clone();
let settings = gui_data.settings.clone();
let text_view_errors = gui_data.text_view_errors.clone();
let button_settings_load_configuration = gui_data.settings.button_settings_load_configuration.clone();
let scrolled_window_errors = gui_data.scrolled_window_errors.clone();
button_settings_load_configuration.connect_clicked(move |_| {
load_configuration(&gui_data, true);
load_configuration(true, &upper_notebook, &settings, &text_view_errors, &scrolled_window_errors);
});
}
// Connect reset configuration button
{
let gui_data = gui_data.clone();
let upper_notebook = gui_data.upper_notebook.clone();
let settings = gui_data.settings.clone();
let text_view_errors = gui_data.text_view_errors.clone();
let button_settings_reset_configuration = gui_data.settings.button_settings_reset_configuration.clone();
button_settings_reset_configuration.connect_clicked(move |_| {
reset_configuration(&gui_data, true);
reset_configuration(true, &upper_notebook, &settings, &text_view_errors);
});
}
}

View File

@ -9,18 +9,18 @@ pub fn create_tree_view_duplicates(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsDuplicates::ActiveSelectButton as i32)
.value(&iter, ColumnsDuplicates::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsDuplicates::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsDuplicates::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "activatable", ColumnsDuplicates::ActivatableSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsDuplicates::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsDuplicates::SelectionButton as i32);
column.add_attribute(&renderer, "cell-background", ColumnsDuplicates::Color as i32);
tree_view.append_column(&column);
@ -67,17 +67,17 @@ pub fn create_tree_view_empty_folders(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsEmptyFolders::ActiveSelectButton as i32)
.value(&iter, ColumnsEmptyFolders::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsEmptyFolders::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsEmptyFolders::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsEmptyFolders::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsEmptyFolders::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
@ -117,17 +117,17 @@ pub fn create_tree_view_big_files(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsBigFiles::ActiveSelectButton as i32)
.value(&iter, ColumnsBigFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsBigFiles::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsBigFiles::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsBigFiles::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsBigFiles::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
@ -176,17 +176,17 @@ pub fn create_tree_view_temporary_files(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsTemporaryFiles::ActiveSelectButton as i32)
.value(&iter, ColumnsTemporaryFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsTemporaryFiles::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsTemporaryFiles::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsTemporaryFiles::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsTemporaryFiles::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
@ -226,17 +226,17 @@ pub fn create_tree_view_empty_files(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsEmptyFiles::ActiveSelectButton as i32)
.value(&iter, ColumnsEmptyFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsEmptyFiles::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsEmptyFiles::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsEmptyFiles::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsEmptyFiles::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
@ -276,18 +276,18 @@ pub fn create_tree_view_similar_images(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsSimilarImages::ActiveSelectButton as i32)
.value(&iter, ColumnsSimilarImages::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsSimilarImages::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsSimilarImages::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "activatable", ColumnsSimilarImages::ActivatableSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsSimilarImages::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsSimilarImages::SelectionButton as i32);
column.add_attribute(&renderer, "cell-background", ColumnsSimilarImages::Color as i32);
tree_view.append_column(&column);
@ -367,18 +367,18 @@ pub fn create_tree_view_similar_videos(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsSimilarVideos::ActiveSelectButton as i32)
.value(&iter, ColumnsSimilarVideos::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsSimilarVideos::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsSimilarVideos::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "activatable", ColumnsSimilarVideos::ActivatableSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsSimilarVideos::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsSimilarVideos::SelectionButton as i32);
column.add_attribute(&renderer, "cell-background", ColumnsSimilarVideos::Color as i32);
tree_view.append_column(&column);
@ -446,18 +446,18 @@ pub fn create_tree_view_same_music(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsSameMusic::ActiveSelectButton as i32)
.value(&iter, ColumnsSameMusic::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsSameMusic::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsSameMusic::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "activatable", ColumnsSameMusic::ActivatableSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsSameMusic::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsSameMusic::SelectionButton as i32);
column.add_attribute(&renderer, "cell-background", ColumnsSameMusic::Color as i32);
tree_view.append_column(&column);
@ -570,17 +570,17 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsInvalidSymlinks::ActiveSelectButton as i32)
.value(&iter, ColumnsInvalidSymlinks::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsInvalidSymlinks::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsInvalidSymlinks::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsInvalidSymlinks::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsInvalidSymlinks::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();
@ -638,17 +638,17 @@ pub fn create_tree_view_broken_files(tree_view: &mut gtk::TreeView) {
renderer.connect_toggled(move |_r, path| {
let iter = model.iter(&path).unwrap();
let mut fixed = model
.value(&iter, ColumnsBrokenFiles::ActiveSelectButton as i32)
.value(&iter, ColumnsBrokenFiles::SelectionButton as i32)
.get::<bool>()
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
fixed = !fixed;
model.set_value(&iter, ColumnsBrokenFiles::ActiveSelectButton as u32, &fixed.to_value());
model.set_value(&iter, ColumnsBrokenFiles::SelectionButton as u32, &fixed.to_value());
});
let column = gtk::TreeViewColumn::new();
column.pack_start(&renderer, true);
column.set_resizable(false);
column.set_fixed_width(30);
column.add_attribute(&renderer, "active", ColumnsBrokenFiles::ActiveSelectButton as i32);
column.add_attribute(&renderer, "active", ColumnsBrokenFiles::SelectionButton as i32);
tree_view.append_column(&column);
let renderer = gtk::CellRendererText::new();

View File

@ -1,187 +0,0 @@
use crate::help_functions::*;
use gtk::prelude::*;
const KEY_ENTER: u16 = 36;
const KEY_SPACE: u16 = 65;
// TODO add option to open files and folders from context menu activated by pressing ONCE with right mouse button
pub fn opening_double_click_function_duplicates(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsDuplicates::Name as i32, ColumnsDuplicates::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsDuplicates::Name as i32, ColumnsDuplicates::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_duplicates(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsDuplicates::Name as u32, ColumnsDuplicates::Path as u32, ColumnsDuplicates::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_empty_folders(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_empty_folders(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsEmptyFolders::Name as u32, ColumnsEmptyFolders::Path as u32, ColumnsEmptyFolders::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_empty_files(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_empty_files(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsEmptyFiles::Name as u32, ColumnsEmptyFiles::Path as u32, ColumnsEmptyFiles::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_temporary_files(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_temporary_files(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsTemporaryFiles::Name as u32, ColumnsTemporaryFiles::Path as u32, ColumnsTemporaryFiles::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_big_files(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_big_files(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsBigFiles::Name as u32, ColumnsBigFiles::Path as u32, ColumnsBigFiles::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_same_music(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsSameMusic::Name as i32, ColumnsSameMusic::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsSameMusic::Name as i32, ColumnsSameMusic::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_same_music(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsSameMusic::Name as u32, ColumnsSameMusic::Path as u32, ColumnsSameMusic::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_similar_images(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsSimilarImages::Name as i32, ColumnsSimilarImages::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsSimilarImages::Name as i32, ColumnsSimilarImages::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_similar_images(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsSimilarImages::Name as u32, ColumnsSimilarImages::Path as u32, ColumnsSimilarImages::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_similar_videos(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsSimilarVideos::Name as i32, ColumnsSimilarVideos::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsSimilarVideos::Name as i32, ColumnsSimilarVideos::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_similar_videos(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsSimilarVideos::Name as u32, ColumnsSimilarVideos::Path as u32, ColumnsSimilarVideos::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_invalid_symlinks(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_invalid_symlinks(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsInvalidSymlinks::Name as u32, ColumnsInvalidSymlinks::Path as u32, ColumnsInvalidSymlinks::ActiveSelectButton as u32)
}
pub fn opening_double_click_function_broken_files(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function_broken_files(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
handle_tree_keypress(tree_view, event, ColumnsBrokenFiles::Name as u32, ColumnsBrokenFiles::Path as u32, ColumnsBrokenFiles::ActiveSelectButton as u32)
}
enum OpenMode {
OnlyPath,
PathAndName,
}
fn common_mark_function(tree_view: &gtk::TreeView, column_name: u32) {
let selection = tree_view.selection();
let (selection_rows, tree_model) = selection.selected_rows();
let model = get_list_store(tree_view);
for tree_path in selection_rows.iter().rev() {
let value = !tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name as i32).get::<bool>().unwrap();
model.set_value(&tree_model.iter(tree_path).unwrap(), column_name, &value.to_value());
}
}
fn common_open_function(tree_view: &gtk::TreeView, column_name: i32, column_path: i32, opening_mode: OpenMode) {
let selection = tree_view.selection();
let (selection_rows, tree_model) = selection.selected_rows();
for tree_path in selection_rows.iter().rev() {
let end_path;
let name = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name).get::<String>().unwrap();
let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::<String>().unwrap();
match opening_mode {
OpenMode::OnlyPath => {
end_path = path;
}
OpenMode::PathAndName => {
end_path = format!("{}/{}", path, name);
}
}
open::that_in_background(&end_path);
// if let Err(e) = open::that(&end_path) {
// println!("Failed to open {} - Error {}", end_path, e);
// }
}
}
fn handle_tree_keypress(tree_view: &gtk::TreeView, event: &gdk::EventKey, name_column: u32, path_column: u32, mark_column: u32) -> gtk::Inhibit {
match event.keycode() {
Some(KEY_ENTER) => {
// Enter
common_open_function(tree_view, name_column as i32, path_column as i32, OpenMode::PathAndName);
}
Some(KEY_SPACE) => {
// Space
common_mark_function(tree_view, mark_column);
}
_ => {}
}
gtk::Inhibit(false)
}

View File

@ -1,3 +1,4 @@
use crate::notebook_enums::NUMBER_OF_NOTEBOOK_MAIN_TABS;
use gtk::prelude::*;
use gtk::TreeView;
@ -217,4 +218,19 @@ impl GuiMainNotebook {
image_preview_duplicates,
}
}
pub fn get_main_tree_views(&self) -> [TreeView; NUMBER_OF_NOTEBOOK_MAIN_TABS] {
[
self.tree_view_duplicate_finder.clone(),
self.tree_view_empty_folder_finder.clone(),
self.tree_view_big_files_finder.clone(),
self.tree_view_empty_files_finder.clone(),
self.tree_view_temporary_files_finder.clone(),
self.tree_view_similar_images_finder.clone(),
self.tree_view_similar_videos_finder.clone(),
self.tree_view_same_music_finder.clone(),
self.tree_view_invalid_symlinks.clone(),
self.tree_view_broken_files.clone(),
]
}
}

View File

@ -1,3 +1,4 @@
use crate::notebook_enums::{NotebookMainEnum, NUMBER_OF_NOTEBOOK_MAIN_TABS};
use czkawka_core::big_file::BigFile;
use czkawka_core::broken_files::BrokenFiles;
use czkawka_core::common_messages::Messages;
@ -15,6 +16,163 @@ use gtk::{ListStore, TextView};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
#[derive(Eq, PartialEq)]
pub enum PopoverTypes {
All,
ImageSize,
Reverse,
Custom,
Date,
None,
}
pub struct NotebookObject {
pub notebook_type: NotebookMainEnum,
pub available_modes: [PopoverTypes; 4],
pub column_activatable_button: Option<i32>,
pub column_path: i32,
pub column_name: i32,
pub column_selection: i32,
pub column_color: Option<i32>,
pub column_dimensions: Option<i32>,
pub column_size: Option<i32>,
pub column_size_as_bytes: Option<i32>,
pub column_modification_as_secs: Option<i32>,
}
pub static NOTEBOOKS_INFOS: [NotebookObject; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
NotebookObject {
notebook_type: NotebookMainEnum::Duplicate,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date],
column_activatable_button: Some(ColumnsDuplicates::ActivatableSelectButton as i32),
column_path: ColumnsDuplicates::Path as i32,
column_name: ColumnsDuplicates::Name as i32,
column_selection: ColumnsDuplicates::SelectionButton as i32,
column_color: Some(ColumnsDuplicates::Color as i32),
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
column_modification_as_secs: Some(ColumnsDuplicates::ModificationAsSecs as i32),
},
NotebookObject {
notebook_type: NotebookMainEnum::EmptyDirectories,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None],
column_activatable_button: None,
column_path: ColumnsEmptyFolders::Path as i32,
column_name: ColumnsEmptyFolders::Name as i32,
column_selection: ColumnsEmptyFolders::SelectionButton as i32,
column_color: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
column_modification_as_secs: None,
},
NotebookObject {
notebook_type: NotebookMainEnum::BigFiles,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None],
column_activatable_button: None,
column_path: ColumnsBigFiles::Path as i32,
column_name: ColumnsBigFiles::Name as i32,
column_selection: ColumnsBigFiles::SelectionButton as i32,
column_color: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
column_modification_as_secs: None,
},
NotebookObject {
notebook_type: NotebookMainEnum::EmptyFiles,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None],
column_activatable_button: None,
column_path: ColumnsEmptyFiles::Path as i32,
column_name: ColumnsEmptyFiles::Name as i32,
column_selection: ColumnsEmptyFiles::SelectionButton as i32,
column_color: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
column_modification_as_secs: None,
},
NotebookObject {
notebook_type: NotebookMainEnum::Temporary,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None],
column_activatable_button: None,
column_path: ColumnsTemporaryFiles::Path as i32,
column_name: ColumnsTemporaryFiles::Name as i32,
column_selection: ColumnsTemporaryFiles::SelectionButton as i32,
column_color: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
column_modification_as_secs: None,
},
NotebookObject {
notebook_type: NotebookMainEnum::SimilarImages,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date],
column_activatable_button: Some(ColumnsSimilarImages::ActivatableSelectButton as i32),
column_path: ColumnsSimilarImages::Path as i32,
column_name: ColumnsSimilarImages::Name as i32,
column_selection: ColumnsSimilarImages::SelectionButton as i32,
column_color: Some(ColumnsSimilarImages::Color as i32),
column_dimensions: Some(ColumnsSimilarImages::Dimensions as i32),
column_size: Some(ColumnsSimilarImages::Size as i32),
column_size_as_bytes: Some(ColumnsSimilarImages::SizeAsBytes as i32),
column_modification_as_secs: Some(ColumnsSimilarImages::ModificationAsSecs as i32),
},
NotebookObject {
notebook_type: NotebookMainEnum::SimilarVideos,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date],
column_activatable_button: Some(ColumnsSimilarVideos::ActivatableSelectButton as i32),
column_path: ColumnsSimilarVideos::Path as i32,
column_name: ColumnsSimilarVideos::Name as i32,
column_selection: ColumnsSimilarVideos::SelectionButton as i32,
column_color: Some(ColumnsSimilarVideos::Color as i32),
column_dimensions: None,
column_size: Some(ColumnsSimilarVideos::Size as i32),
column_size_as_bytes: Some(ColumnsSimilarVideos::SizeAsBytes as i32),
column_modification_as_secs: Some(ColumnsSimilarVideos::ModificationAsSecs as i32),
},
NotebookObject {
notebook_type: NotebookMainEnum::SameMusic,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::Date],
column_activatable_button: Some(ColumnsSameMusic::ActivatableSelectButton as i32),
column_path: ColumnsSameMusic::Path as i32,
column_name: ColumnsSameMusic::Name as i32,
column_selection: ColumnsSameMusic::SelectionButton as i32,
column_color: Some(ColumnsSameMusic::Color as i32),
column_dimensions: None,
column_size: None,
column_size_as_bytes: Some(ColumnsSameMusic::SizeAsBytes as i32),
column_modification_as_secs: Some(ColumnsSameMusic::ModificationAsSecs as i32),
},
NotebookObject {
notebook_type: NotebookMainEnum::Symlinks,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None],
column_activatable_button: None,
column_path: ColumnsInvalidSymlinks::Path as i32,
column_name: ColumnsInvalidSymlinks::Name as i32,
column_selection: ColumnsInvalidSymlinks::SelectionButton as i32,
column_color: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
column_modification_as_secs: None,
},
NotebookObject {
notebook_type: NotebookMainEnum::BrokenFiles,
available_modes: [PopoverTypes::All, PopoverTypes::Reverse, PopoverTypes::Custom, PopoverTypes::None],
column_activatable_button: None,
column_path: ColumnsBrokenFiles::Path as i32,
column_name: ColumnsBrokenFiles::Name as i32,
column_selection: ColumnsBrokenFiles::SelectionButton as i32,
column_color: None,
column_dimensions: None,
column_size: None,
column_size_as_bytes: None,
column_modification_as_secs: None,
},
];
pub enum Message {
Duplicates(DuplicateFinder),
EmptyFolders(EmptyFolder),
@ -28,11 +186,10 @@ pub enum Message {
BrokenFiles(BrokenFiles),
}
#[derive(Debug)]
pub enum ColumnsDuplicates {
// Columns for duplicate treeview
ActivatableSelectButton = 0,
ActiveSelectButton,
SelectionButton,
Name,
Path,
Modification,
@ -43,7 +200,7 @@ pub enum ColumnsDuplicates {
pub enum ColumnsEmptyFolders {
// Columns for empty folder treeview
ActiveSelectButton = 0,
SelectionButton = 0,
Name,
Path,
Modification,
@ -53,27 +210,27 @@ pub enum ColumnsDirectory {
Path = 0,
}
pub enum ColumnsBigFiles {
ActiveSelectButton = 0,
SelectionButton = 0,
Size,
Name,
Path,
Modification,
}
pub enum ColumnsEmptyFiles {
ActiveSelectButton = 0,
SelectionButton = 0,
Name,
Path,
Modification,
}
pub enum ColumnsTemporaryFiles {
ActiveSelectButton = 0,
SelectionButton = 0,
Name,
Path,
Modification,
}
pub enum ColumnsSimilarImages {
ActivatableSelectButton = 0,
ActiveSelectButton,
SelectionButton,
Similarity,
Size,
SizeAsBytes,
@ -88,7 +245,7 @@ pub enum ColumnsSimilarImages {
pub enum ColumnsSimilarVideos {
ActivatableSelectButton = 0,
ActiveSelectButton,
SelectionButton,
Size,
SizeAsBytes,
Name,
@ -100,7 +257,7 @@ pub enum ColumnsSimilarVideos {
}
pub enum ColumnsSameMusic {
ActivatableSelectButton = 0,
ActiveSelectButton,
SelectionButton,
Size,
SizeAsBytes,
Name,
@ -116,7 +273,7 @@ pub enum ColumnsSameMusic {
TextColor,
}
pub enum ColumnsInvalidSymlinks {
ActiveSelectButton = 0,
SelectionButton = 0,
Name,
Path,
DestinationPath,
@ -125,7 +282,7 @@ pub enum ColumnsInvalidSymlinks {
}
pub enum ColumnsBrokenFiles {
ActiveSelectButton = 0,
SelectionButton = 0,
Name,
Path,
ErrorType,
@ -217,46 +374,6 @@ pub fn add_text_to_text_view(text_view: &TextView, string_to_append: &str) {
buffer.set_text(format!("{}\n{}", current_text, string_to_append).as_str());
}
pub fn select_function_duplicates(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
// let name = tree_model.value(&tree_model.iter(tree_path).unwrap(),ColumnsDuplicates::Name as i32).get::<String>().unwrap();
// let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Path as i32).get::<String>().unwrap();
// let modification = tree_model.value(&tree_model.iter(tree_path).unwrap(),ColumnsDuplicates::Modification as i32).get::<String>().unwrap();
let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Color as i32).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}
pub fn select_function_same_music(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSameMusic::Color as i32).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}
pub fn select_function_similar_images(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarImages::Color as i32).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}
pub fn select_function_similar_videos(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarVideos::Color as i32).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}
pub fn set_buttons(hashmap: &mut HashMap<String, bool>, buttons_array: &[gtk::Button], button_names: &[String]) {
for (index, button) in buttons_array.iter().enumerate() {
if *hashmap.get_mut(button_names[index].as_str()).unwrap() {
@ -294,3 +411,96 @@ pub fn change_dimension_to_krotka(dimensions: String) -> (u64, u64) {
let number2 = vec[1].parse::<u64>().expect("Invalid data in image dimension in position 1");
(number1, number2)
}
pub fn get_notebook_enum_from_tree_view(tree_view: &gtk::TreeView) -> NotebookMainEnum {
match (*tree_view).widget_name().to_string().as_str() {
"tree_view_duplicate_finder" => NotebookMainEnum::Duplicate,
"tree_view_empty_folder_finder" => NotebookMainEnum::EmptyDirectories,
"tree_view_empty_files_finder" => NotebookMainEnum::EmptyFiles,
"tree_view_temporary_files_finder" => NotebookMainEnum::Temporary,
"tree_view_big_files_finder" => NotebookMainEnum::BigFiles,
"tree_view_similar_images_finder" => NotebookMainEnum::SimilarImages,
"tree_view_similar_videos_finder" => NotebookMainEnum::SimilarVideos,
"tree_view_same_music_finder" => NotebookMainEnum::SameMusic,
"tree_view_invalid_symlinks" => NotebookMainEnum::Symlinks,
"tree_view_broken_files" => NotebookMainEnum::BrokenFiles,
_ => panic!(),
}
}
pub fn get_notebook_object_from_tree_view(tree_view: &gtk::TreeView) -> &NotebookObject {
let nb_enum = get_notebook_enum_from_tree_view(tree_view);
&NOTEBOOKS_INFOS[nb_enum as usize]
}
// After e.g. deleting files, header may become orphan or have one child, so should be deleted in this case
pub fn clean_invalid_headers(model: &gtk::ListStore, column_color: i32) {
// Remove only child from header
if let Some(first_iter) = model.iter_first() {
let mut vec_tree_path_to_delete: Vec<gtk::TreePath> = Vec::new();
let mut current_iter = first_iter;
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
panic!("First deleted element, should be a header"); // First element should be header
};
let mut next_iter;
let mut next_next_iter;
'main: loop {
if model.value(&current_iter, column_color).get::<String>().unwrap() != HEADER_ROW_COLOR {
panic!("First deleted element, should be a header"); // First element should be header
};
next_iter = current_iter.clone();
if !model.iter_next(&next_iter) {
// There is only single header left (H1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
break 'main;
}
if model.value(&next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
// There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
current_iter = next_iter.clone();
continue 'main;
}
next_next_iter = next_iter.clone();
if !model.iter_next(&next_next_iter) {
// There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
break 'main;
}
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
// One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
vec_tree_path_to_delete.push(model.path(&current_iter).unwrap());
vec_tree_path_to_delete.push(model.path(&next_iter).unwrap());
current_iter = next_next_iter.clone();
continue 'main;
}
loop {
// (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD)
if !model.iter_next(&next_next_iter) {
break 'main;
}
// Move to next header
if model.value(&next_next_iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
current_iter = next_next_iter.clone();
continue 'main;
}
}
}
for tree_path in vec_tree_path_to_delete.iter().rev() {
model.remove(&model.iter(tree_path).unwrap());
}
}
// Last step, remove orphan header if exists
if let Some(iter) = model.iter_first() {
if !model.iter_next(&iter) {
model.clear();
}
}
}

View File

@ -1,8 +1,9 @@
use crate::connect_button_delete::{basic_remove, check_if_can_delete_files, check_if_deleting_all_files_in_group, empty_folder_remover, tree_remove};
use crate::create_tree_view::*;
use crate::double_click_opening::*;
use crate::gui_data::*;
use crate::help_functions::*;
use crate::notebook_enums::NotebookMainEnum;
use crate::opening_selecting_records::*;
use czkawka_core::similar_images::SIMILAR_VALUES;
use czkawka_core::similar_videos::MAX_TOLERANCE;
use directories_next::ProjectDirs;
@ -14,6 +15,8 @@ use std::cmp::Ordering;
use std::fs;
use std::path::Path;
const KEY_DELETE: u16 = 119;
pub fn initialize_gui(gui_data: &mut GuiData) {
//// Initialize button
{
@ -99,55 +102,57 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_duplicates(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_duplicates);
tree_view.connect_key_press_event(opening_enter_function_duplicates);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.connect_button_release_event(move |tree_view, _event| {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
show_preview(
tree_view,
&text_view_errors_cloned,
&check_button_settings_show_preview_duplicates_cloned,
&image_preview_duplicates_cloned,
ColumnsDuplicates::Path as i32,
ColumnsDuplicates::Name as i32,
nb_object.column_path,
nb_object.column_name,
);
gtk::Inhibit(false)
});
tree_view.set_widget_name("tree_view_duplicate_finder");
gui_data.main_notebook.tree_view_duplicate_finder = tree_view.clone();
scrolled_window_duplicate_finder.add(&tree_view);
scrolled_window_duplicate_finder.show_all();
let text_view_errors_cloned = text_view_errors.clone();
let gui_data = gui_data.clone();
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
let window_main = gui_data.window_main.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
if button_number == KEY_DELETE {
if tree_view.selection().selected_rows().0.is_empty() {
return gtk::Inhibit(false);
}
if !check_if_can_delete_files(&gui_data.settings.check_button_settings_confirm_deletion, &gui_data.window_main) {
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) {
return gtk::Inhibit(false);
}
if gui_data.settings.check_button_settings_confirm_group_deletion.is_active()
&& check_if_deleting_all_files_in_group(
&tree_view.clone(),
ColumnsDuplicates::Color as i32,
ColumnsDuplicates::ActiveSelectButton as i32,
&gui_data.window_main,
&gui_data.settings.check_button_settings_confirm_group_deletion,
)
if check_button_settings_confirm_group_deletion.is_active()
&& check_if_deleting_all_files_in_group(&tree_view.clone(), nb_object.column_color.unwrap(), nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion)
{
return gtk::Inhibit(false);
}
tree_remove(
tree_view,
ColumnsDuplicates::Name as i32,
ColumnsDuplicates::Path as i32,
ColumnsDuplicates::Color as i32,
ColumnsDuplicates::ActiveSelectButton as i32,
&gui_data,
nb_object.column_name,
nb_object.column_path,
nb_object.column_color.unwrap(),
nb_object.column_selection,
&check_button_settings_use_trash,
&text_view_errors,
);
image_preview_duplicates.hide();
}
@ -157,8 +162,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
&text_view_errors_cloned,
&check_button_settings_show_preview_duplicates,
&image_preview_duplicates,
ColumnsDuplicates::Path as i32,
ColumnsDuplicates::Name as i32,
nb_object.column_path,
nb_object.column_name,
);
gtk::Inhibit(false)
});
@ -174,19 +179,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_empty_folders(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_empty_folders);
tree_view.connect_key_press_event(opening_enter_function_empty_folders);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.set_widget_name("tree_view_empty_folder_finder");
gui_data.main_notebook.tree_view_empty_folder_finder = tree_view.clone();
scrolled_window_empty_folder_finder.add(&tree_view);
scrolled_window_empty_folder_finder.show_all();
let gui_data = gui_data.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
empty_folder_remover(tree_view, ColumnsEmptyFolders::Name as i32, ColumnsEmptyFolders::Path as i32, ColumnsEmptyFolders::ActiveSelectButton as i32, &gui_data);
if button_number == KEY_DELETE {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::EmptyDirectories as usize];
empty_folder_remover(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors);
}
}
gtk::Inhibit(false)
@ -203,19 +211,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_empty_files(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_empty_files);
tree_view.connect_key_press_event(opening_enter_function_empty_files);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.set_widget_name("tree_view_empty_files_finder");
gui_data.main_notebook.tree_view_empty_files_finder = tree_view.clone();
scrolled_window_empty_files_finder.add(&tree_view);
scrolled_window_empty_files_finder.show_all();
let gui_data = gui_data.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
basic_remove(tree_view, ColumnsEmptyFiles::Name as i32, ColumnsEmptyFiles::Path as i32, ColumnsEmptyFiles::ActiveSelectButton as i32, &gui_data);
if button_number == KEY_DELETE {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::EmptyFiles as usize];
basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors);
}
}
gtk::Inhibit(false)
@ -232,19 +243,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_temporary_files(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_temporary_files);
tree_view.connect_key_press_event(opening_enter_function_temporary_files);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.set_widget_name("tree_view_temporary_files_finder");
gui_data.main_notebook.tree_view_temporary_files_finder = tree_view.clone();
scrolled_window_temporary_files_finder.add(&tree_view);
scrolled_window_temporary_files_finder.show_all();
let gui_data = gui_data.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
basic_remove(tree_view, ColumnsTemporaryFiles::Name as i32, ColumnsTemporaryFiles::Path as i32, ColumnsTemporaryFiles::ActiveSelectButton as i32, &gui_data);
if button_number == KEY_DELETE {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Temporary as usize];
basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors);
}
}
gtk::Inhibit(false)
@ -261,19 +275,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_big_files(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_big_files);
tree_view.connect_key_press_event(opening_enter_function_big_files);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.set_widget_name("tree_view_big_files_finder");
gui_data.main_notebook.tree_view_big_files_finder = tree_view.clone();
scrolled_window_big_files_finder.add(&tree_view);
scrolled_window_big_files_finder.show_all();
let gui_data = gui_data.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
basic_remove(tree_view, ColumnsBigFiles::Name as i32, ColumnsBigFiles::Path as i32, ColumnsBigFiles::ActiveSelectButton as i32, &gui_data);
if button_number == KEY_DELETE {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::BigFiles as usize];
basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors);
}
}
gtk::Inhibit(false)
@ -307,56 +324,58 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_similar_images(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_similar_images);
tree_view.connect_key_press_event(opening_enter_function_similar_images);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_button_release_event(move |tree_view, _event| {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
show_preview(
tree_view,
&text_view_errors,
&check_button_settings_show_preview_similar_images,
&image_preview_similar_images,
ColumnsSimilarImages::Path as i32,
ColumnsSimilarImages::Name as i32,
nb_object.column_path,
nb_object.column_name,
);
gtk::Inhibit(false)
});
tree_view.set_widget_name("tree_view_similar_images_finder");
gui_data.main_notebook.tree_view_similar_images_finder = tree_view.clone();
scrolled_window_similar_images_finder.add(&tree_view);
scrolled_window_similar_images_finder.show_all();
let image_preview_similar_images = image_preview_similar_images_clone.clone();
let text_view_errors = gui_data.text_view_errors.clone();
let check_button_settings_show_preview_similar_images = gui_data.settings.check_button_settings_show_preview_similar_images.clone();
let gui_data = gui_data.clone();
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
let window_main = gui_data.window_main.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
if button_number == KEY_DELETE {
if tree_view.selection().selected_rows().0.is_empty() {
return gtk::Inhibit(false);
}
if !check_if_can_delete_files(&gui_data.settings.check_button_settings_confirm_deletion, &gui_data.window_main) {
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) {
return gtk::Inhibit(false);
}
if gui_data.settings.check_button_settings_confirm_group_deletion.is_active()
&& check_if_deleting_all_files_in_group(
&tree_view.clone(),
ColumnsSimilarImages::Color as i32,
ColumnsSimilarImages::ActiveSelectButton as i32,
&gui_data.window_main,
&gui_data.settings.check_button_settings_confirm_group_deletion,
)
if check_button_settings_confirm_group_deletion.is_active()
&& check_if_deleting_all_files_in_group(&tree_view.clone(), nb_object.column_color.unwrap(), nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion)
{
return gtk::Inhibit(false);
}
tree_remove(
tree_view,
ColumnsSimilarImages::Name as i32,
ColumnsSimilarImages::Path as i32,
ColumnsSimilarImages::Color as i32,
ColumnsSimilarImages::ActiveSelectButton as i32,
&gui_data,
nb_object.column_name,
nb_object.column_path,
nb_object.column_color.unwrap(),
nb_object.column_selection,
&check_button_settings_use_trash,
&text_view_errors,
);
image_preview_similar_images_clone.hide();
}
@ -366,8 +385,8 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
&text_view_errors,
&check_button_settings_show_preview_similar_images,
&image_preview_similar_images,
ColumnsSimilarImages::Path as i32,
ColumnsSimilarImages::Name as i32,
nb_object.column_path,
nb_object.column_name,
);
gtk::Inhibit(false)
});
@ -376,7 +395,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
{
let col_types: [glib::types::Type; 10] = [
glib::types::Type::BOOL, // ActivatableSelectButton
glib::types::Type::BOOL, // ActiveSelectButton
glib::types::Type::BOOL, // SelectionButton
glib::types::Type::STRING, // Size
glib::types::Type::U64, // SizeAsBytes
glib::types::Type::STRING, // Name
@ -395,42 +414,43 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_similar_videos(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_similar_videos);
tree_view.connect_key_press_event(opening_enter_function_similar_videos);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.set_widget_name("tree_view_similar_videos_finder");
gui_data.main_notebook.tree_view_similar_videos_finder = tree_view.clone();
scrolled_window_similar_videos_finder.add(&tree_view);
scrolled_window_similar_videos_finder.show_all();
let gui_data = gui_data.clone();
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
let window_main = gui_data.window_main.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
if button_number == KEY_DELETE {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarVideos as usize];
if tree_view.selection().selected_rows().0.is_empty() {
return gtk::Inhibit(false);
}
if !check_if_can_delete_files(&gui_data.settings.check_button_settings_confirm_deletion, &gui_data.window_main) {
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) {
return gtk::Inhibit(false);
}
if gui_data.settings.check_button_settings_confirm_group_deletion.is_active()
&& check_if_deleting_all_files_in_group(
&tree_view.clone(),
ColumnsSimilarVideos::Color as i32,
ColumnsSimilarVideos::ActiveSelectButton as i32,
&gui_data.window_main,
&gui_data.settings.check_button_settings_confirm_group_deletion,
)
if check_button_settings_confirm_group_deletion.is_active()
&& check_if_deleting_all_files_in_group(&tree_view.clone(), nb_object.column_color.unwrap(), nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion)
{
return gtk::Inhibit(false);
}
tree_remove(
tree_view,
ColumnsSimilarVideos::Name as i32,
ColumnsSimilarVideos::Path as i32,
ColumnsSimilarVideos::Color as i32,
ColumnsSimilarVideos::ActiveSelectButton as i32,
&gui_data,
nb_object.column_name,
nb_object.column_path,
nb_object.column_color.unwrap(),
nb_object.column_selection,
&check_button_settings_use_trash,
&text_view_errors,
);
}
}
@ -465,42 +485,43 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_same_music(&mut tree_view);
tree_view.selection().set_select_function(Some(Box::new(select_function_same_music)));
tree_view.connect_button_press_event(opening_double_click_function_same_music);
tree_view.connect_key_press_event(opening_enter_function_same_music);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.set_widget_name("tree_view_same_music_finder");
gui_data.main_notebook.tree_view_same_music_finder = tree_view.clone();
scrolled_window_same_music_finder.add(&tree_view);
scrolled_window_same_music_finder.show_all();
let gui_data = gui_data.clone();
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
let window_main = gui_data.window_main.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
if button_number == KEY_DELETE {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SameMusic as usize];
if tree_view.selection().selected_rows().0.is_empty() {
return gtk::Inhibit(false);
}
if !check_if_can_delete_files(&gui_data.settings.check_button_settings_confirm_deletion, &gui_data.window_main) {
if !check_if_can_delete_files(&check_button_settings_confirm_group_deletion, &window_main) {
return gtk::Inhibit(false);
}
if gui_data.settings.check_button_settings_confirm_group_deletion.is_active()
&& check_if_deleting_all_files_in_group(
&tree_view.clone(),
ColumnsSameMusic::Color as i32,
ColumnsSameMusic::ActiveSelectButton as i32,
&gui_data.window_main,
&gui_data.settings.check_button_settings_confirm_group_deletion,
)
if check_button_settings_confirm_group_deletion.is_active()
&& check_if_deleting_all_files_in_group(&tree_view.clone(), nb_object.column_color.unwrap(), nb_object.column_selection, &window_main, &check_button_settings_confirm_group_deletion)
{
return gtk::Inhibit(false);
}
tree_remove(
tree_view,
ColumnsSameMusic::Name as i32,
ColumnsSameMusic::Path as i32,
ColumnsSameMusic::Color as i32,
ColumnsSameMusic::ActiveSelectButton as i32,
&gui_data,
nb_object.column_name,
nb_object.column_path,
nb_object.column_color.unwrap(),
nb_object.column_selection,
&check_button_settings_use_trash,
&text_view_errors,
);
}
}
@ -525,19 +546,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_invalid_symlinks(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_invalid_symlinks);
tree_view.connect_key_press_event(opening_enter_function_invalid_symlinks);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.set_widget_name("tree_view_invalid_symlinks");
gui_data.main_notebook.tree_view_invalid_symlinks = tree_view.clone();
scrolled_window_invalid_symlinks.add(&tree_view);
scrolled_window_invalid_symlinks.show_all();
let gui_data = gui_data.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
basic_remove(tree_view, ColumnsInvalidSymlinks::Name as i32, ColumnsInvalidSymlinks::Path as i32, ColumnsInvalidSymlinks::ActiveSelectButton as i32, &gui_data);
if button_number == KEY_DELETE {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Symlinks as usize];
basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors);
}
}
gtk::Inhibit(false)
@ -554,19 +578,22 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
create_tree_view_broken_files(&mut tree_view);
tree_view.connect_button_press_event(opening_double_click_function_broken_files);
tree_view.connect_key_press_event(opening_enter_function_broken_files);
tree_view.connect_button_press_event(opening_double_click_function);
tree_view.connect_key_press_event(opening_enter_function);
tree_view.set_widget_name("tree_view_broken_files");
gui_data.main_notebook.tree_view_broken_files = tree_view.clone();
scrolled_window_broken_files.add(&tree_view);
scrolled_window_broken_files.show_all();
let gui_data = gui_data.clone();
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let text_view_errors = gui_data.text_view_errors.clone();
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
basic_remove(tree_view, ColumnsBrokenFiles::Name as i32, ColumnsBrokenFiles::Path as i32, ColumnsBrokenFiles::ActiveSelectButton as i32, &gui_data);
if button_number == KEY_DELETE {
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::BrokenFiles as usize];
basic_remove(tree_view, nb_object.column_name, nb_object.column_path, nb_object.column_selection, &check_button_settings_use_trash, &text_view_errors);
}
}
gtk::Inhibit(false)
@ -598,7 +625,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
if button_number == KEY_DELETE {
let list_store = get_list_store(tree_view);
let selection = tree_view.selection();
@ -630,7 +657,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
tree_view.connect_key_release_event(move |tree_view, e| {
if let Some(button_number) = e.keycode() {
// Handle delete button
if button_number == 119 {
if button_number == KEY_DELETE {
let list_store = get_list_store(tree_view);
let selection = tree_view.selection();
@ -659,6 +686,7 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
});
}
}
fn show_preview(tree_view: &TreeView, text_view_errors: &TextView, check_button_settings_show_preview: &CheckButton, image_preview_similar_images: &Image, column_path: i32, column_name: i32) {
let (selected_rows, tree_model) = tree_view.selection().selected_rows();

View File

@ -1,7 +1,9 @@
// Remove console window in Windows OS
#![windows_subsystem = "windows"]
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::too_many_arguments)]
mod compute_results;
mod connect_about_buttons;
mod connect_button_delete;
mod connect_button_hardlink;
@ -10,8 +12,6 @@ mod connect_button_save;
mod connect_button_search;
mod connect_button_select;
mod connect_button_stop;
mod connect_button_symlink;
mod connect_compute_results;
mod connect_header_buttons;
mod connect_hide_text_view_errors;
mod connect_notebook_tabs;
@ -21,7 +21,6 @@ mod connect_selection_of_directories;
mod connect_settings;
mod connect_similar_image_size_change;
mod create_tree_view;
mod double_click_opening;
mod gui_about;
mod gui_bottom_buttons;
mod gui_data;
@ -34,15 +33,18 @@ mod gui_upper_notepad;
mod help_functions;
mod initialize_gui;
mod notebook_enums;
mod opening_selecting_records;
mod saving_loading;
mod taskbar_progress;
#[cfg(not(target_os = "windows"))]
mod taskbar_progress_dummy;
#[cfg(target_os = "windows")]
mod taskbar_progress_win;
mod tests;
use czkawka_core::*;
use crate::compute_results::*;
use crate::connect_about_buttons::*;
use crate::connect_button_delete::*;
use crate::connect_button_hardlink::*;
@ -51,8 +53,6 @@ use crate::connect_button_save::*;
use crate::connect_button_search::*;
use crate::connect_button_select::*;
use crate::connect_button_stop::*;
use crate::connect_button_symlink::*;
use crate::connect_compute_results::*;
use crate::connect_header_buttons::*;
use crate::connect_hide_text_view_errors::*;
use crate::connect_notebook_tabs::*;
@ -64,6 +64,7 @@ use crate::connect_similar_image_size_change::*;
use crate::gui_data::*;
use crate::initialize_gui::*;
use crate::saving_loading::*;
use crate::tests::validate_notebook_data;
use gtk::prelude::*;
use std::{env, process};
@ -107,8 +108,9 @@ fn main() {
let (futures_sender_broken_files, futures_receiver_broken_files): (futures::channel::mpsc::UnboundedSender<broken_files::ProgressData>, futures::channel::mpsc::UnboundedReceiver<broken_files::ProgressData>) = futures::channel::mpsc::unbounded();
initialize_gui(&mut gui_data);
reset_configuration(&gui_data, false); // Fallback for invalid loading setting project
load_configuration(&gui_data, false);
validate_notebook_data(&gui_data); // Must be run after initialization of gui, to check if everything was properly setup
reset_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors); // Fallback for invalid loading setting project
load_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors, &gui_data.scrolled_window_errors);
connect_button_delete(&gui_data);
connect_button_save(&gui_data);
@ -128,8 +130,7 @@ fn main() {
);
connect_button_select(&gui_data);
connect_button_stop(&gui_data);
connect_button_symlink(&gui_data);
connect_button_hardlink(&gui_data);
connect_button_hardlink_symlink(&gui_data);
connect_button_move(&gui_data);
connect_notebook_tabs(&gui_data);
connect_selection_of_directories(&gui_data);
@ -159,7 +160,7 @@ fn main() {
let window_main = gui_data.window_main.clone();
let taskbar_state = gui_data.taskbar_state.clone();
window_main.connect_delete_event(move |_, _| {
save_configuration(&gui_data, false); // Save configuration at exit
save_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors); // Save configuration at exit
gtk::main_quit();
taskbar_state.borrow_mut().release();
Inhibit(false)

View File

@ -0,0 +1,119 @@
use crate::help_functions::*;
use gtk::prelude::*;
const KEY_ENTER: u16 = 36;
const KEY_SPACE: u16 = 65;
// TODO add option to open files and folders from context menu activated by pressing ONCE with right mouse button
pub fn opening_double_click_function(tree_view: &gtk::TreeView, event: &gdk::EventButton) -> gtk::Inhibit {
let nt_object = get_notebook_object_from_tree_view(tree_view);
if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 1 {
common_open_function(tree_view, nt_object.column_name, nt_object.column_path, OpenMode::PathAndName);
} else if event.event_type() == gdk::EventType::DoubleButtonPress && event.button() == 3 {
common_open_function(tree_view, nt_object.column_name, nt_object.column_path, OpenMode::OnlyPath);
}
gtk::Inhibit(false)
}
pub fn opening_enter_function(tree_view: &gtk::TreeView, event: &gdk::EventKey) -> gtk::Inhibit {
let nt_object = get_notebook_object_from_tree_view(tree_view);
handle_tree_keypress(tree_view, event, nt_object.column_name, nt_object.column_path, nt_object.column_selection)
}
enum OpenMode {
OnlyPath,
PathAndName,
}
fn common_mark_function(tree_view: &gtk::TreeView, column_name: i32) {
let selection = tree_view.selection();
let (selected_rows, tree_model) = selection.selected_rows();
let model = get_list_store(tree_view);
for tree_path in selected_rows.iter().rev() {
let value = !tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name).get::<bool>().unwrap();
model.set_value(&tree_model.iter(tree_path).unwrap(), column_name as u32, &value.to_value());
}
}
fn common_open_function(tree_view: &gtk::TreeView, column_name: i32, column_path: i32, opening_mode: OpenMode) {
let selection = tree_view.selection();
let (selected_rows, tree_model) = selection.selected_rows();
for tree_path in selected_rows.iter().rev() {
let end_path;
let name = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_name).get::<String>().unwrap();
let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), column_path).get::<String>().unwrap();
match opening_mode {
OpenMode::OnlyPath => {
end_path = path;
}
OpenMode::PathAndName => {
end_path = format!("{}/{}", path, name);
}
}
open::that_in_background(&end_path);
// if let Err(e) = open::that(&end_path) {
// println!("Failed to open {} - Error {}", end_path, e);
// }
}
}
fn handle_tree_keypress(tree_view: &gtk::TreeView, event: &gdk::EventKey, name_column: i32, path_column: i32, mark_column: i32) -> gtk::Inhibit {
match event.keycode() {
Some(KEY_ENTER) => {
// Enter
common_open_function(tree_view, name_column, path_column, OpenMode::PathAndName);
}
Some(KEY_SPACE) => {
// Space
common_mark_function(tree_view, mark_column);
}
_ => {}
}
gtk::Inhibit(false)
}
pub fn select_function_duplicates(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
// let name = tree_model.value(&tree_model.iter(tree_path).unwrap(),ColumnsDuplicates::Name as i32).get::<String>().unwrap();
// let path = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Path as i32).get::<String>().unwrap();
// let modification = tree_model.value(&tree_model.iter(tree_path).unwrap(),ColumnsDuplicates::Modification as i32).get::<String>().unwrap();
let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsDuplicates::Color as i32).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}
pub fn select_function_same_music(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSameMusic::Color as i32).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}
pub fn select_function_similar_images(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarImages::Color as i32).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}
pub fn select_function_similar_videos(_tree_selection: &gtk::TreeSelection, tree_model: &gtk::TreeModel, tree_path: &gtk::TreePath, _is_path_currently_selected: bool) -> bool {
let color = tree_model.value(&tree_model.iter(tree_path).unwrap(), ColumnsSimilarVideos::Color as i32).get::<String>().unwrap();
if color == HEADER_ROW_COLOR {
return false;
}
true
}

View File

@ -1,7 +1,9 @@
use crate::gui_data::*;
use crate::gui_settings::GuiSettings;
use crate::gui_upper_notepad::GuiUpperNotebook;
use crate::help_functions::*;
use directories_next::ProjectDirs;
use gtk::prelude::*;
use gtk::{ScrolledWindow, TextView};
use std::fs::File;
use std::io::Write;
use std::path::Path;
@ -11,9 +13,9 @@ use std::{env, fs};
const SAVE_FILE_NAME: &str = "czkawka_gui_config.txt";
pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
let check_button_settings_save_at_exit = gui_data.settings.check_button_settings_save_at_exit.clone();
let text_view_errors = gui_data.text_view_errors.clone();
pub fn save_configuration(manual_execution: bool, upper_notebook: &GuiUpperNotebook, settings: &GuiSettings, text_view_errors: &TextView) {
let check_button_settings_save_at_exit = settings.check_button_settings_save_at_exit.clone();
let text_view_errors = text_view_errors.clone();
reset_text_view(&text_view_errors);
@ -40,7 +42,7 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
//// Included Directories
data_to_save.push("--included_directories:".to_string());
let tree_view_included_directories = gui_data.upper_notebook.tree_view_included_directories.clone();
let tree_view_included_directories = upper_notebook.tree_view_included_directories.clone();
let list_store = get_list_store(&tree_view_included_directories);
if let Some(iter) = list_store.iter_first() {
loop {
@ -53,7 +55,7 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
//// Excluded Directories
data_to_save.push("--excluded_directories:".to_string());
let tree_view_excluded_directories = gui_data.upper_notebook.tree_view_excluded_directories.clone();
let tree_view_excluded_directories = upper_notebook.tree_view_excluded_directories.clone();
let list_store = get_list_store(&tree_view_excluded_directories);
if let Some(iter) = list_store.iter_first() {
loop {
@ -67,7 +69,7 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
{
//// Excluded Items
data_to_save.push("--excluded_items:".to_string());
let entry_excluded_items = gui_data.upper_notebook.entry_excluded_items.clone();
let entry_excluded_items = upper_notebook.entry_excluded_items.clone();
for item in entry_excluded_items.text().split(',') {
if item.trim().is_empty() {
continue;
@ -77,7 +79,7 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
//// Allowed extensions
data_to_save.push("--allowed_extensions:".to_string());
let entry_allowed_extensions = gui_data.upper_notebook.entry_allowed_extensions.clone();
let entry_allowed_extensions = upper_notebook.entry_allowed_extensions.clone();
for extension in entry_allowed_extensions.text().split(',') {
if extension.trim().is_empty() {
continue;
@ -87,57 +89,57 @@ pub fn save_configuration(gui_data: &GuiData, manual_execution: bool) {
//// Save at exit
data_to_save.push("--save_at_exit:".to_string());
let check_button_settings_save_at_exit = gui_data.settings.check_button_settings_save_at_exit.clone();
let check_button_settings_save_at_exit = settings.check_button_settings_save_at_exit.clone();
data_to_save.push(check_button_settings_save_at_exit.is_active().to_string());
//// Load at start
data_to_save.push("--load_at_start:".to_string());
let check_button_settings_load_at_start = gui_data.settings.check_button_settings_load_at_start.clone();
let check_button_settings_load_at_start = settings.check_button_settings_load_at_start.clone();
data_to_save.push(check_button_settings_load_at_start.is_active().to_string());
//// Confirm deletion of files
data_to_save.push("--confirm_deletion:".to_string());
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
let check_button_settings_confirm_deletion = settings.check_button_settings_confirm_deletion.clone();
data_to_save.push(check_button_settings_confirm_deletion.is_active().to_string());
//// Confirm deletion of all files in group
data_to_save.push("--confirm_group_deletion:".to_string());
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
let check_button_settings_confirm_group_deletion = settings.check_button_settings_confirm_group_deletion.clone();
data_to_save.push(check_button_settings_confirm_group_deletion.is_active().to_string());
//// Show image previews in similar images
data_to_save.push("--show_previews_similar_images:".to_string());
let check_button_settings_show_preview_similar_images = gui_data.settings.check_button_settings_show_preview_similar_images.clone();
let check_button_settings_show_preview_similar_images = settings.check_button_settings_show_preview_similar_images.clone();
data_to_save.push(check_button_settings_show_preview_similar_images.is_active().to_string());
//// Show image previews in duplicates
data_to_save.push("--show_previews_duplicates:".to_string());
let check_button_settings_show_preview_duplicates = gui_data.settings.check_button_settings_show_preview_duplicates.clone();
let check_button_settings_show_preview_duplicates = settings.check_button_settings_show_preview_duplicates.clone();
data_to_save.push(check_button_settings_show_preview_duplicates.is_active().to_string());
//// Show bottom text panel with errors
data_to_save.push("--bottom_text_panel:".to_string());
let check_button_settings_show_text_view = gui_data.settings.check_button_settings_show_text_view.clone();
let check_button_settings_show_text_view = settings.check_button_settings_show_text_view.clone();
data_to_save.push(check_button_settings_show_text_view.is_active().to_string());
//// Hide/Show hard linked files, with same inodes
data_to_save.push("--hide_hard_links:".to_string());
let check_button_settings_hide_hard_links = gui_data.settings.check_button_settings_hide_hard_links.clone();
let check_button_settings_hide_hard_links = settings.check_button_settings_hide_hard_links.clone();
data_to_save.push(check_button_settings_hide_hard_links.is_active().to_string());
//// Use cache system
data_to_save.push("--use_cache:".to_string());
let check_button_settings_use_cache = gui_data.settings.check_button_settings_use_cache.clone();
let check_button_settings_use_cache = settings.check_button_settings_use_cache.clone();
data_to_save.push(check_button_settings_use_cache.is_active().to_string());
//// Delete to trash
data_to_save.push("--use_trash:".to_string());
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.clone();
let check_button_settings_use_trash = settings.check_button_settings_use_trash.clone();
data_to_save.push(check_button_settings_use_trash.is_active().to_string());
//// minimal cache file size
data_to_save.push("--cache_minimal_file_size:".to_string());
let entry_settings_cache_file_minimal_size = gui_data.settings.entry_settings_cache_file_minimal_size.clone();
let entry_settings_cache_file_minimal_size = settings.entry_settings_cache_file_minimal_size.clone();
data_to_save.push(entry_settings_cache_file_minimal_size.text().as_str().parse::<u64>().unwrap_or(2 * 1024 * 1024).to_string());
}
@ -194,8 +196,8 @@ enum TypeOfLoadedData {
CacheMinimalSize,
}
pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
let text_view_errors = gui_data.text_view_errors.clone();
pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNotebook, settings: &GuiSettings, text_view_errors: &TextView, scrolled_window_errors: &ScrolledWindow) {
let text_view_errors = text_view_errors.clone();
reset_text_view(&text_view_errors);
@ -450,7 +452,7 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
// Setting data
if manual_execution || loading_at_start {
//// Included Directories
let tree_view_included_directories = gui_data.upper_notebook.tree_view_included_directories.clone();
let tree_view_included_directories = upper_notebook.tree_view_included_directories.clone();
let list_store = get_list_store(&tree_view_included_directories);
list_store.clear();
@ -460,7 +462,7 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
}
//// Exclude Directories
let tree_view_excluded_directories = gui_data.upper_notebook.tree_view_excluded_directories.clone();
let tree_view_excluded_directories = upper_notebook.tree_view_excluded_directories.clone();
let list_store = get_list_store(&tree_view_excluded_directories);
list_store.clear();
@ -470,33 +472,33 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
}
//// Excluded Items
let entry_excluded_items = gui_data.upper_notebook.entry_excluded_items.clone();
let entry_excluded_items = upper_notebook.entry_excluded_items.clone();
entry_excluded_items.set_text(excluded_items.iter().map(|e| e.to_string() + ",").collect::<String>().as_str());
//// Allowed extensions
let entry_allowed_extensions = gui_data.upper_notebook.entry_allowed_extensions.clone();
let entry_allowed_extensions = upper_notebook.entry_allowed_extensions.clone();
entry_allowed_extensions.set_text(allowed_extensions.iter().map(|e| e.to_string() + ",").collect::<String>().as_str());
//// Buttons
gui_data.settings.check_button_settings_load_at_start.set_active(loading_at_start);
gui_data.settings.check_button_settings_save_at_exit.set_active(saving_at_exit);
gui_data.settings.check_button_settings_confirm_deletion.set_active(confirm_deletion);
gui_data.settings.check_button_settings_confirm_group_deletion.set_active(confirm_group_deletion);
gui_data.settings.check_button_settings_show_preview_similar_images.set_active(show_previews_similar_images);
gui_data.settings.check_button_settings_show_preview_duplicates.set_active(show_previews_duplicates);
settings.check_button_settings_load_at_start.set_active(loading_at_start);
settings.check_button_settings_save_at_exit.set_active(saving_at_exit);
settings.check_button_settings_confirm_deletion.set_active(confirm_deletion);
settings.check_button_settings_confirm_group_deletion.set_active(confirm_group_deletion);
settings.check_button_settings_show_preview_similar_images.set_active(show_previews_similar_images);
settings.check_button_settings_show_preview_duplicates.set_active(show_previews_duplicates);
gui_data.settings.check_button_settings_show_text_view.set_active(bottom_text_panel);
settings.check_button_settings_show_text_view.set_active(bottom_text_panel);
if !bottom_text_panel {
gui_data.scrolled_window_errors.hide();
scrolled_window_errors.hide();
} else {
gui_data.scrolled_window_errors.show();
scrolled_window_errors.show();
}
gui_data.settings.check_button_settings_hide_hard_links.set_active(hide_hard_links);
gui_data.settings.check_button_settings_use_cache.set_active(use_cache);
gui_data.settings.check_button_settings_use_trash.set_active(use_trash);
gui_data.settings.entry_settings_cache_file_minimal_size.set_text(cache_minimal_size.to_string().as_str());
settings.check_button_settings_hide_hard_links.set_active(hide_hard_links);
settings.check_button_settings_use_cache.set_active(use_cache);
settings.check_button_settings_use_trash.set_active(use_trash);
settings.entry_settings_cache_file_minimal_size.set_text(cache_minimal_size.to_string().as_str());
} else {
gui_data.settings.check_button_settings_load_at_start.set_active(false);
settings.check_button_settings_load_at_start.set_active(false);
}
if manual_execution {
@ -507,15 +509,15 @@ pub fn load_configuration(gui_data: &GuiData, manual_execution: bool) {
}
}
pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) {
pub fn reset_configuration(manual_clearing: bool, upper_notebook: &GuiUpperNotebook, settings: &GuiSettings, text_view_errors: &TextView) {
// TODO Maybe add popup dialog to confirm resetting
let text_view_errors = gui_data.text_view_errors.clone();
let text_view_errors = text_view_errors.clone();
reset_text_view(&text_view_errors);
// Resetting included directories
{
let tree_view_included_directories = gui_data.upper_notebook.tree_view_included_directories.clone();
let tree_view_included_directories = upper_notebook.tree_view_included_directories.clone();
let list_store = get_list_store(&tree_view_included_directories);
list_store.clear();
@ -539,7 +541,7 @@ pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) {
}
// Resetting excluded directories
{
let tree_view_excluded_directories = gui_data.upper_notebook.tree_view_excluded_directories.clone();
let tree_view_excluded_directories = upper_notebook.tree_view_excluded_directories.clone();
let list_store = get_list_store(&tree_view_excluded_directories);
list_store.clear();
if cfg!(target_family = "unix") {
@ -551,7 +553,7 @@ pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) {
}
// Resetting excluded items
{
let entry_excluded_items = gui_data.upper_notebook.entry_excluded_items.clone();
let entry_excluded_items = upper_notebook.entry_excluded_items.clone();
if cfg!(target_family = "unix") {
entry_excluded_items.set_text("*/.git/*,*/node_modules/*,*/lost+found/*,*/Trash/*,*/.Trash-*/*,*/snap/*,/home/*/.cache/*");
}
@ -561,23 +563,23 @@ pub fn reset_configuration(gui_data: &GuiData, manual_clearing: bool) {
}
// Resetting allowed extensions
{
let entry_allowed_extensions = gui_data.upper_notebook.entry_allowed_extensions.clone();
let entry_allowed_extensions = upper_notebook.entry_allowed_extensions.clone();
entry_allowed_extensions.set_text("");
}
// Set settings
{
gui_data.settings.check_button_settings_save_at_exit.set_active(true);
gui_data.settings.check_button_settings_load_at_start.set_active(true);
gui_data.settings.check_button_settings_confirm_deletion.set_active(true);
gui_data.settings.check_button_settings_confirm_group_deletion.set_active(true);
gui_data.settings.check_button_settings_show_preview_similar_images.set_active(true);
gui_data.settings.check_button_settings_show_preview_duplicates.set_active(true);
gui_data.settings.check_button_settings_show_text_view.set_active(true);
gui_data.settings.check_button_settings_hide_hard_links.set_active(true);
gui_data.settings.check_button_settings_use_cache.set_active(true);
gui_data.settings.check_button_settings_use_trash.set_active(false);
gui_data.settings.entry_settings_cache_file_minimal_size.set_text("2097152");
settings.check_button_settings_save_at_exit.set_active(true);
settings.check_button_settings_load_at_start.set_active(true);
settings.check_button_settings_confirm_deletion.set_active(true);
settings.check_button_settings_confirm_group_deletion.set_active(true);
settings.check_button_settings_show_preview_similar_images.set_active(true);
settings.check_button_settings_show_preview_duplicates.set_active(true);
settings.check_button_settings_show_text_view.set_active(true);
settings.check_button_settings_hide_hard_links.set_active(true);
settings.check_button_settings_use_cache.set_active(true);
settings.check_button_settings_use_trash.set_active(false);
settings.entry_settings_cache_file_minimal_size.set_text("2097152");
}
if manual_clearing {
add_text_to_text_view(&text_view_errors, "Current configuration was cleared.");

37
czkawka_gui/src/tests.rs Normal file
View File

@ -0,0 +1,37 @@
use crate::help_functions::{get_notebook_enum_from_tree_view, NOTEBOOKS_INFOS};
use crate::notebook_enums::{to_notebook_main_enum, NUMBER_OF_NOTEBOOK_MAIN_TABS};
use crate::GuiData;
pub fn validate_notebook_data(gui_data: &GuiData) {
// Test treeviews names, each treeview should have set name same as variable name
let tree_view_arr: [&gtk::TreeView; NUMBER_OF_NOTEBOOK_MAIN_TABS] = [
&gui_data.main_notebook.tree_view_duplicate_finder,
&gui_data.main_notebook.tree_view_similar_videos_finder,
&gui_data.main_notebook.tree_view_temporary_files_finder,
&gui_data.main_notebook.tree_view_big_files_finder,
&gui_data.main_notebook.tree_view_empty_files_finder,
&gui_data.main_notebook.tree_view_broken_files,
&gui_data.main_notebook.tree_view_empty_folder_finder,
&gui_data.main_notebook.tree_view_same_music_finder,
&gui_data.main_notebook.tree_view_similar_images_finder,
&gui_data.main_notebook.tree_view_invalid_symlinks,
];
for (_i, item) in tree_view_arr.iter().enumerate() {
// println!("Checking {} element", i);
get_notebook_enum_from_tree_view(item);
}
// This test main info about notebooks
// Should have same order as notebook enum types
for (i, item) in NOTEBOOKS_INFOS.iter().enumerate() {
let en = to_notebook_main_enum(i as u32);
assert_eq!(item.notebook_type, en);
}
// Tests if data returned from array get_notebook_enum_from_tree_view are in right
for (i, item) in gui_data.main_notebook.get_main_tree_views().iter().enumerate() {
let nb_en = get_notebook_enum_from_tree_view(item);
assert_eq!(to_notebook_main_enum(i as u32), nb_en);
}
}