2020-11-05 06:15:06 +13:00
|
|
|
use std::collections::BTreeMap;
|
2020-11-01 02:23:31 +13:00
|
|
|
use std::fs;
|
|
|
|
use std::fs::Metadata;
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
use gtk4::prelude::*;
|
|
|
|
use gtk4::{Align, CheckButton, Dialog, Orientation, ResponseType, TextView};
|
2021-11-28 08:49:20 +13:00
|
|
|
|
2022-01-20 10:35:07 +13:00
|
|
|
use crate::flg;
|
2022-01-14 03:58:33 +13:00
|
|
|
use crate::gui_structs::gui_data::GuiData;
|
2021-11-28 08:49:20 +13:00
|
|
|
use crate::help_functions::*;
|
2022-01-20 10:35:07 +13:00
|
|
|
use crate::localizer_core::generate_translation_hashmap;
|
2021-11-28 08:49:20 +13:00
|
|
|
use crate::notebook_enums::*;
|
2022-06-22 03:24:08 +12:00
|
|
|
use crate::notebook_info::NOTEBOOKS_INFO;
|
2021-11-28 08:49:20 +13:00
|
|
|
|
2020-12-22 04:09:39 +13:00
|
|
|
// TODO add support for checking if really symlink doesn't point to correct directory/file
|
|
|
|
|
2020-11-01 02:23:31 +13:00
|
|
|
pub fn connect_button_delete(gui_data: &GuiData) {
|
2021-01-11 08:12:08 +13:00
|
|
|
let buttons_delete = gui_data.bottom_buttons.buttons_delete.clone();
|
2021-11-28 04:44:30 +13:00
|
|
|
|
|
|
|
let gui_data = gui_data.clone(); // TODO this maybe can be replaced, not sure if worth to do it
|
|
|
|
|
|
|
|
buttons_delete.connect_clicked(move |_| {
|
|
|
|
glib::MainContext::default().spawn_local(delete_things(gui_data.clone()));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn delete_things(gui_data: GuiData) {
|
2021-12-13 00:02:53 +13:00
|
|
|
// validate_notebook_data(&gui_data);
|
2021-11-29 23:38:38 +13:00
|
|
|
|
2021-01-11 08:12:08 +13:00
|
|
|
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
2020-11-01 02:23:31 +13:00
|
|
|
let window_main = gui_data.window_main.clone();
|
2021-02-23 21:40:19 +13:00
|
|
|
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
|
2021-03-07 03:56:39 +13:00
|
|
|
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
|
2021-01-11 08:12:08 +13:00
|
|
|
let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone();
|
2021-11-25 20:36:49 +13:00
|
|
|
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();
|
|
|
|
|
2021-12-04 03:17:59 +13:00
|
|
|
let preview_path = gui_data.preview_path.clone();
|
|
|
|
|
2021-11-25 20:36:49 +13:00
|
|
|
let text_view_errors = gui_data.text_view_errors.clone();
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-11-28 04:44:30 +13:00
|
|
|
let nb_number = notebook_main.current_page().unwrap();
|
|
|
|
let tree_view = &main_tree_views[nb_number as usize];
|
2022-06-22 03:24:08 +12:00
|
|
|
let nb_object = &NOTEBOOKS_INFO[nb_number as usize];
|
2021-11-28 04:44:30 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let (number_of_selected_items, number_of_selected_groups) = check_how_much_elements_is_selected(tree_view, nb_object.column_header, nb_object.column_selection);
|
2021-12-22 06:23:17 +13:00
|
|
|
|
|
|
|
// Nothing is selected
|
|
|
|
if number_of_selected_items == 0 {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main, number_of_selected_items, number_of_selected_groups).await {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
if let Some(column_header) = nb_object.column_header {
|
2021-12-22 06:44:20 +13:00
|
|
|
if !check_button_settings_confirm_group_deletion.is_active()
|
|
|
|
|| !check_if_deleting_all_files_in_group(
|
|
|
|
tree_view,
|
2022-05-22 20:59:09 +12:00
|
|
|
column_header,
|
2021-12-22 06:44:20 +13:00
|
|
|
nb_object.column_selection,
|
2021-12-24 21:18:55 +13:00
|
|
|
nb_object.column_path,
|
2021-12-22 06:44:20 +13:00
|
|
|
&window_main,
|
|
|
|
&check_button_settings_confirm_group_deletion,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
{
|
|
|
|
tree_remove(
|
|
|
|
tree_view,
|
|
|
|
nb_object.column_name,
|
|
|
|
nb_object.column_path,
|
2022-05-22 20:59:09 +12:00
|
|
|
column_header,
|
2021-12-22 06:44:20 +13:00
|
|
|
nb_object.column_selection,
|
|
|
|
&check_button_settings_use_trash,
|
|
|
|
&text_view_errors,
|
|
|
|
);
|
2020-11-01 02:23:31 +13:00
|
|
|
}
|
2021-11-28 04:44:30 +13:00
|
|
|
} else {
|
|
|
|
if nb_number == NotebookMainEnum::EmptyDirectories as u32 {
|
2021-12-22 06:44:20 +13:00
|
|
|
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,
|
|
|
|
);
|
2021-11-25 20:36:49 +13:00
|
|
|
} else {
|
2021-12-22 06:44:20 +13:00
|
|
|
basic_remove(
|
|
|
|
tree_view,
|
|
|
|
nb_object.column_name,
|
|
|
|
nb_object.column_path,
|
|
|
|
nb_object.column_selection,
|
|
|
|
&check_button_settings_use_trash,
|
|
|
|
&text_view_errors,
|
|
|
|
);
|
2021-11-25 20:36:49 +13:00
|
|
|
}
|
2021-11-28 04:44:30 +13:00
|
|
|
}
|
2021-11-25 20:36:49 +13:00
|
|
|
|
2021-11-28 04:44:30 +13:00
|
|
|
match &nb_object.notebook_type {
|
2021-12-04 03:17:59 +13:00
|
|
|
NotebookMainEnum::SimilarImages | NotebookMainEnum::Duplicate => {
|
|
|
|
if nb_object.notebook_type == NotebookMainEnum::SimilarImages {
|
|
|
|
image_preview_similar_images.hide();
|
|
|
|
} else {
|
|
|
|
image_preview_duplicates.hide();
|
|
|
|
}
|
2023-01-29 06:54:02 +13:00
|
|
|
*preview_path.borrow_mut() = String::new();
|
2021-11-28 04:44:30 +13:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-12-22 06:44:20 +13:00
|
|
|
pub async fn check_if_can_delete_files(
|
2022-06-01 03:52:55 +12:00
|
|
|
check_button_settings_confirm_deletion: &CheckButton,
|
2022-05-22 20:59:09 +12:00
|
|
|
window_main: >k4::Window,
|
2021-12-22 06:44:20 +13:00
|
|
|
number_of_selected_items: u64,
|
|
|
|
number_of_selected_groups: u64,
|
|
|
|
) -> bool {
|
2021-06-26 04:07:13 +12:00
|
|
|
if check_button_settings_confirm_deletion.is_active() {
|
2021-12-22 06:23:17 +13:00
|
|
|
let (confirmation_dialog_delete, check_button) = create_dialog_ask_for_deletion(window_main, number_of_selected_items, number_of_selected_groups);
|
2021-11-28 04:44:30 +13:00
|
|
|
|
|
|
|
let response_type = confirmation_dialog_delete.run_future().await;
|
2022-11-26 08:38:27 +13:00
|
|
|
if response_type == ResponseType::Ok {
|
2021-06-26 04:07:13 +12:00
|
|
|
if !check_button.is_active() {
|
2021-03-07 20:57:48 +13:00
|
|
|
check_button_settings_confirm_deletion.set_active(false);
|
|
|
|
}
|
|
|
|
confirmation_dialog_delete.hide();
|
|
|
|
confirmation_dialog_delete.close();
|
|
|
|
} else {
|
|
|
|
confirmation_dialog_delete.hide();
|
|
|
|
confirmation_dialog_delete.close();
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
2021-11-28 08:57:10 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
fn create_dialog_ask_for_deletion(window_main: >k4::Window, number_of_selected_items: u64, number_of_selected_groups: u64) -> (Dialog, CheckButton) {
|
2023-02-19 22:21:14 +13:00
|
|
|
let dialog = Dialog::builder().title(flg!("delete_title_dialog")).transient_for(window_main).modal(true).build();
|
2022-01-20 10:35:07 +13:00
|
|
|
let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
|
|
|
|
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
|
2021-12-01 01:53:04 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
dialog.set_default_size(300, 0);
|
|
|
|
|
|
|
|
let label: gtk4::Label = gtk4::Label::new(Some(&flg!("delete_question_label")));
|
|
|
|
let label2: gtk4::Label = match number_of_selected_groups {
|
|
|
|
0 => gtk4::Label::new(Some(&flg!(
|
2021-12-22 06:44:20 +13:00
|
|
|
"delete_items_label",
|
|
|
|
generate_translation_hashmap(vec![("items", number_of_selected_items.to_string())])
|
|
|
|
))),
|
2022-05-22 20:59:09 +12:00
|
|
|
_ => gtk4::Label::new(Some(&flg!(
|
2021-12-22 06:23:17 +13:00
|
|
|
"delete_items_groups_label",
|
|
|
|
generate_translation_hashmap(vec![("items", number_of_selected_items.to_string()), ("groups", number_of_selected_groups.to_string())])
|
|
|
|
))),
|
|
|
|
};
|
2023-02-19 22:21:14 +13:00
|
|
|
|
|
|
|
let check_button: CheckButton = CheckButton::builder()
|
|
|
|
.label(flg!("dialogs_ask_next_time"))
|
|
|
|
.active(true)
|
|
|
|
.halign(Align::Center)
|
|
|
|
.margin_top(5)
|
|
|
|
.build();
|
2021-11-28 04:44:30 +13:00
|
|
|
|
|
|
|
button_ok.grab_focus();
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let parent = button_ok.parent().unwrap().parent().unwrap().downcast::<gtk4::Box>().unwrap(); // TODO Hack, but not so ugly as before
|
|
|
|
parent.set_orientation(Orientation::Vertical);
|
|
|
|
parent.insert_child_after(&label, None::<>k4::Widget>);
|
|
|
|
parent.insert_child_after(&label2, Some(&label));
|
|
|
|
parent.insert_child_after(&check_button, Some(&label2));
|
|
|
|
|
|
|
|
dialog.show();
|
2021-12-01 23:09:47 +13:00
|
|
|
(dialog, check_button)
|
2021-11-28 04:44:30 +13:00
|
|
|
}
|
2021-03-07 20:57:48 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
fn create_dialog_group_deletion(window_main: >k4::Window) -> (Dialog, CheckButton) {
|
2022-06-01 03:52:55 +12:00
|
|
|
let dialog = Dialog::builder()
|
2023-02-19 22:21:14 +13:00
|
|
|
.title(flg!("delete_all_files_in_group_title"))
|
2021-12-22 06:44:20 +13:00
|
|
|
.transient_for(window_main)
|
|
|
|
.modal(true)
|
|
|
|
.build();
|
2022-01-20 10:35:07 +13:00
|
|
|
let button_ok = dialog.add_button(&flg!("general_ok_button"), ResponseType::Ok);
|
|
|
|
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
|
2021-12-01 01:53:04 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let label: gtk4::Label = gtk4::Label::new(Some(&flg!("delete_all_files_in_group_label1")));
|
|
|
|
let label2: gtk4::Label = gtk4::Label::new(Some(&flg!("delete_all_files_in_group_label2")));
|
2023-02-19 22:21:14 +13:00
|
|
|
let check_button: CheckButton = CheckButton::builder().label(flg!("dialogs_ask_next_time")).active(true).halign(Align::Center).build();
|
2021-11-28 04:44:30 +13:00
|
|
|
|
|
|
|
button_ok.grab_focus();
|
|
|
|
|
2022-05-24 05:04:28 +12:00
|
|
|
let parent = button_ok.parent().unwrap().parent().unwrap().downcast::<gtk4::Box>().unwrap(); // TODO Hack, but not so ugly as before
|
|
|
|
parent.set_orientation(Orientation::Vertical);
|
|
|
|
parent.insert_child_after(&label, None::<>k4::Widget>);
|
|
|
|
parent.insert_child_after(&label2, Some(&label));
|
|
|
|
parent.insert_child_after(&check_button, Some(&label2));
|
2021-11-28 04:44:30 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
dialog.show();
|
2021-12-01 23:09:47 +13:00
|
|
|
(dialog, check_button)
|
2021-11-28 04:44:30 +13:00
|
|
|
}
|
|
|
|
|
2021-12-22 06:44:20 +13:00
|
|
|
pub async fn check_if_deleting_all_files_in_group(
|
2022-05-22 20:59:09 +12:00
|
|
|
tree_view: >k4::TreeView,
|
|
|
|
column_header: i32,
|
2021-12-22 06:44:20 +13:00
|
|
|
column_selection: i32,
|
2021-12-24 21:18:55 +13:00
|
|
|
column_path: i32,
|
2022-05-22 20:59:09 +12:00
|
|
|
window_main: >k4::Window,
|
2022-06-01 03:52:55 +12:00
|
|
|
check_button_settings_confirm_group_deletion: &CheckButton,
|
2021-12-22 06:44:20 +13:00
|
|
|
) -> bool {
|
2021-07-30 17:16:35 +12:00
|
|
|
let model = get_list_store(tree_view);
|
2021-03-07 03:56:39 +13:00
|
|
|
|
|
|
|
let mut selected_all_records: bool = true;
|
|
|
|
|
2021-07-16 16:51:54 +12:00
|
|
|
if let Some(iter) = model.iter_first() {
|
2022-05-22 20:59:09 +12:00
|
|
|
assert!(model.get::<bool>(&iter, column_header)); // First element should be header
|
2021-03-07 03:56:39 +13:00
|
|
|
|
2021-12-24 21:18:55 +13:00
|
|
|
// It is safe to remove any number of files in reference mode
|
2022-05-22 20:59:09 +12:00
|
|
|
if !model.get::<String>(&iter, column_path).is_empty() {
|
2021-12-24 21:18:55 +13:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-03-07 03:56:39 +13:00
|
|
|
loop {
|
2021-07-16 16:51:54 +12:00
|
|
|
if !model.iter_next(&iter) {
|
2021-03-07 03:56:39 +13:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
if model.get::<bool>(&iter, column_header) {
|
2021-03-07 03:56:39 +13:00
|
|
|
if selected_all_records {
|
|
|
|
break;
|
|
|
|
}
|
2021-07-16 16:51:54 +12:00
|
|
|
selected_all_records = true;
|
2021-03-07 03:56:39 +13:00
|
|
|
} else {
|
2022-05-22 20:59:09 +12:00
|
|
|
if !model.get::<bool>(&iter, column_selection) {
|
2021-07-16 16:51:54 +12:00
|
|
|
selected_all_records = false;
|
|
|
|
}
|
2021-03-07 03:56:39 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if !selected_all_records {
|
|
|
|
return false;
|
2023-01-29 06:54:02 +13:00
|
|
|
}
|
2021-11-28 04:44:30 +13:00
|
|
|
|
2023-01-29 06:54:02 +13:00
|
|
|
let (confirmation_dialog_group_delete, check_button) = create_dialog_group_deletion(window_main);
|
|
|
|
|
|
|
|
let response_type = confirmation_dialog_group_delete.run_future().await;
|
|
|
|
if response_type == ResponseType::Ok {
|
|
|
|
if !check_button.is_active() {
|
|
|
|
check_button_settings_confirm_group_deletion.set_active(false);
|
2021-03-07 03:56:39 +13:00
|
|
|
}
|
2023-01-29 06:54:02 +13:00
|
|
|
} else {
|
2021-03-07 20:57:48 +13:00
|
|
|
confirmation_dialog_group_delete.hide();
|
|
|
|
confirmation_dialog_group_delete.close();
|
2023-01-29 06:54:02 +13:00
|
|
|
return true;
|
2021-03-07 03:56:39 +13:00
|
|
|
}
|
2023-01-29 06:54:02 +13:00
|
|
|
confirmation_dialog_group_delete.hide();
|
|
|
|
confirmation_dialog_group_delete.close();
|
2021-03-07 03:56:39 +13:00
|
|
|
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2021-12-22 06:44:20 +13:00
|
|
|
pub fn empty_folder_remover(
|
2022-05-22 20:59:09 +12:00
|
|
|
tree_view: >k4::TreeView,
|
2021-12-22 06:44:20 +13:00
|
|
|
column_file_name: i32,
|
|
|
|
column_path: i32,
|
|
|
|
column_selection: i32,
|
|
|
|
check_button_settings_use_trash: &CheckButton,
|
|
|
|
text_view_errors: &TextView,
|
|
|
|
) {
|
2021-11-25 20:36:49 +13:00
|
|
|
let use_trash = check_button_settings_use_trash.is_active();
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-07-30 17:16:35 +12:00
|
|
|
let model = get_list_store(tree_view);
|
2020-11-05 06:15:06 +13:00
|
|
|
|
2021-07-16 16:51:54 +12:00
|
|
|
let mut selected_rows = Vec::new();
|
|
|
|
|
|
|
|
if let Some(iter) = model.iter_first() {
|
|
|
|
loop {
|
2022-05-22 20:59:09 +12:00
|
|
|
if model.get::<bool>(&iter, column_selection) {
|
|
|
|
selected_rows.push(model.path(&iter));
|
2021-07-16 16:51:54 +12:00
|
|
|
}
|
|
|
|
if !model.iter_next(&iter) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
|
|
|
|
2021-11-25 20:36:49 +13:00
|
|
|
if selected_rows.is_empty() {
|
|
|
|
return; // No selected rows
|
|
|
|
}
|
|
|
|
|
2023-01-29 06:54:02 +13:00
|
|
|
let mut messages: String = String::new();
|
2020-11-05 06:15:06 +13:00
|
|
|
|
|
|
|
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
|
2022-05-22 20:59:09 +12:00
|
|
|
for tree_path in selected_rows.iter().rev() {
|
2021-07-16 16:51:54 +12:00
|
|
|
let iter = model.iter(tree_path).unwrap();
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let name = model.get::<String>(&iter, column_file_name);
|
|
|
|
let path = model.get::<String>(&iter, column_path);
|
2020-11-05 06:15:06 +13:00
|
|
|
|
|
|
|
// We must check if folder is really empty or contains only other empty folders
|
|
|
|
let mut error_happened = false;
|
2021-12-22 06:23:17 +13:00
|
|
|
let mut folders_to_check: Vec<String> = vec![get_full_name_from_path_name(&path, &name)];
|
2020-11-05 06:15:06 +13:00
|
|
|
let mut current_folder: String;
|
|
|
|
let mut next_folder: String;
|
|
|
|
'dir: while !folders_to_check.is_empty() {
|
|
|
|
current_folder = folders_to_check.pop().unwrap();
|
|
|
|
let read_dir = match fs::read_dir(¤t_folder) {
|
|
|
|
Ok(t) => t,
|
2021-11-15 03:53:55 +13:00
|
|
|
Err(_inspected) => {
|
2020-11-05 06:15:06 +13:00
|
|
|
error_happened = true;
|
|
|
|
break 'dir;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
for entry in read_dir {
|
|
|
|
let entry_data = match entry {
|
|
|
|
Ok(t) => t,
|
2021-11-15 03:53:55 +13:00
|
|
|
Err(_inspected) => {
|
2020-11-05 06:15:06 +13:00
|
|
|
error_happened = true;
|
|
|
|
break 'dir;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let metadata: Metadata = match entry_data.metadata() {
|
|
|
|
Ok(t) => t,
|
2021-11-15 03:53:55 +13:00
|
|
|
Err(_inspected) => {
|
2020-11-05 06:15:06 +13:00
|
|
|
error_happened = true;
|
|
|
|
break 'dir;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
if metadata.is_dir() {
|
2023-01-29 06:54:02 +13:00
|
|
|
next_folder = String::new()
|
2020-11-05 06:15:06 +13:00
|
|
|
+ ¤t_folder
|
|
|
|
+ "/"
|
|
|
|
+ match &entry_data.file_name().into_string() {
|
2020-11-01 02:23:31 +13:00
|
|
|
Ok(t) => t,
|
2021-11-15 03:53:55 +13:00
|
|
|
Err(_inspected) => {
|
2020-11-01 02:23:31 +13:00
|
|
|
error_happened = true;
|
|
|
|
break 'dir;
|
|
|
|
}
|
|
|
|
};
|
2020-11-05 06:15:06 +13:00
|
|
|
folders_to_check.push(next_folder.clone());
|
|
|
|
} else {
|
|
|
|
error_happened = true;
|
2020-11-01 02:23:31 +13:00
|
|
|
}
|
|
|
|
}
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2020-11-05 06:15:06 +13:00
|
|
|
if !error_happened {
|
2021-03-12 02:31:59 +13:00
|
|
|
if !use_trash {
|
2021-12-22 06:23:17 +13:00
|
|
|
match fs::remove_dir_all(get_full_name_from_path_name(&path, &name)) {
|
2021-03-12 02:31:59 +13:00
|
|
|
Ok(_) => {
|
2021-07-16 16:51:54 +12:00
|
|
|
model.remove(&iter);
|
2021-03-12 02:31:59 +13:00
|
|
|
}
|
2021-11-15 03:53:55 +13:00
|
|
|
Err(_inspected) => error_happened = true,
|
2021-03-12 02:31:59 +13:00
|
|
|
}
|
|
|
|
} else {
|
2021-12-22 06:23:17 +13:00
|
|
|
match trash::delete(get_full_name_from_path_name(&path, &name)) {
|
2021-03-12 02:31:59 +13:00
|
|
|
Ok(_) => {
|
2021-07-16 16:51:54 +12:00
|
|
|
model.remove(&iter);
|
2021-03-12 02:31:59 +13:00
|
|
|
}
|
2021-11-15 03:53:55 +13:00
|
|
|
Err(_inspected) => error_happened = true,
|
2020-11-01 02:23:31 +13:00
|
|
|
}
|
|
|
|
}
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
|
|
|
if error_happened {
|
2022-01-20 10:35:07 +13:00
|
|
|
messages += &flg!(
|
2021-12-22 06:44:20 +13:00
|
|
|
"delete_folder_failed",
|
|
|
|
generate_translation_hashmap(vec![("dir", get_full_name_from_path_name(&path, &name))])
|
|
|
|
);
|
2021-12-20 02:45:10 +13:00
|
|
|
messages += "\n";
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
|
|
|
}
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
text_view_errors.buffer().set_text(messages.as_str());
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-12-22 06:44:20 +13:00
|
|
|
pub fn basic_remove(
|
2022-05-22 20:59:09 +12:00
|
|
|
tree_view: >k4::TreeView,
|
2021-12-22 06:44:20 +13:00
|
|
|
column_file_name: i32,
|
|
|
|
column_path: i32,
|
|
|
|
column_selection: i32,
|
|
|
|
check_button_settings_use_trash: &CheckButton,
|
|
|
|
text_view_errors: &TextView,
|
|
|
|
) {
|
2021-11-25 20:36:49 +13:00
|
|
|
let use_trash = check_button_settings_use_trash.is_active();
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-07-30 17:16:35 +12:00
|
|
|
let model = get_list_store(tree_view);
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2023-01-29 06:54:02 +13:00
|
|
|
let mut messages: String = String::new();
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-11-25 20:36:49 +13:00
|
|
|
let mut selected_rows = Vec::new();
|
2021-07-16 16:51:54 +12:00
|
|
|
|
|
|
|
if let Some(iter) = model.iter_first() {
|
|
|
|
loop {
|
2022-05-22 20:59:09 +12:00
|
|
|
if model.get::<bool>(&iter, column_selection) {
|
|
|
|
selected_rows.push(model.path(&iter));
|
2021-07-16 16:51:54 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
if !model.iter_next(&iter) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-25 20:36:49 +13:00
|
|
|
if selected_rows.is_empty() {
|
|
|
|
return; // No selected rows
|
|
|
|
}
|
|
|
|
|
2020-11-05 06:15:06 +13:00
|
|
|
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
|
2022-05-22 20:59:09 +12:00
|
|
|
for tree_path in selected_rows.iter().rev() {
|
2021-07-16 16:51:54 +12:00
|
|
|
let iter = model.iter(tree_path).unwrap();
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let name = model.get::<String>(&iter, column_file_name);
|
|
|
|
let path = model.get::<String>(&iter, column_path);
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-03-12 02:31:59 +13:00
|
|
|
if !use_trash {
|
2021-12-22 06:23:17 +13:00
|
|
|
match fs::remove_file(get_full_name_from_path_name(&path, &name)) {
|
2021-03-12 02:31:59 +13:00
|
|
|
Ok(_) => {
|
2021-07-16 16:51:54 +12:00
|
|
|
model.remove(&iter);
|
2021-03-12 02:31:59 +13:00
|
|
|
}
|
2021-12-20 02:45:10 +13:00
|
|
|
|
|
|
|
Err(e) => {
|
2022-01-20 10:35:07 +13:00
|
|
|
messages += flg!(
|
2021-12-22 06:44:20 +13:00
|
|
|
"delete_file_failed",
|
|
|
|
generate_translation_hashmap(vec![("name", get_full_name_from_path_name(&path, &name)), ("reason", e.to_string())])
|
|
|
|
)
|
|
|
|
.as_str();
|
2021-12-20 02:45:10 +13:00
|
|
|
messages += "\n";
|
|
|
|
}
|
2021-03-12 02:31:59 +13:00
|
|
|
}
|
|
|
|
} else {
|
2021-12-22 06:23:17 +13:00
|
|
|
match trash::delete(get_full_name_from_path_name(&path, &name)) {
|
2021-03-12 02:31:59 +13:00
|
|
|
Ok(_) => {
|
2021-07-16 16:51:54 +12:00
|
|
|
model.remove(&iter);
|
2021-03-12 02:31:59 +13:00
|
|
|
}
|
2021-12-20 02:45:10 +13:00
|
|
|
Err(e) => {
|
2022-01-20 10:35:07 +13:00
|
|
|
messages += flg!(
|
2021-12-22 06:44:20 +13:00
|
|
|
"delete_file_failed",
|
|
|
|
generate_translation_hashmap(vec![("name", get_full_name_from_path_name(&path, &name)), ("reason", e.to_string())])
|
|
|
|
)
|
|
|
|
.as_str();
|
2021-12-20 02:45:10 +13:00
|
|
|
messages += "\n";
|
|
|
|
}
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
text_view_errors.buffer().set_text(messages.as_str());
|
2020-11-09 22:09:22 +13:00
|
|
|
}
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2020-11-09 22:09:22 +13:00
|
|
|
// Remove all occurrences - remove every element which have same path and name as even non selected ones
|
2021-12-22 06:44:20 +13:00
|
|
|
pub fn tree_remove(
|
2022-05-22 20:59:09 +12:00
|
|
|
tree_view: >k4::TreeView,
|
2021-12-22 06:44:20 +13:00
|
|
|
column_file_name: i32,
|
|
|
|
column_path: i32,
|
2022-05-22 20:59:09 +12:00
|
|
|
column_header: i32,
|
2021-12-22 06:44:20 +13:00
|
|
|
column_selection: i32,
|
|
|
|
check_button_settings_use_trash: &CheckButton,
|
|
|
|
text_view_errors: &TextView,
|
|
|
|
) {
|
2021-11-25 20:36:49 +13:00
|
|
|
let use_trash = check_button_settings_use_trash.is_active();
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-07-30 17:16:35 +12:00
|
|
|
let model = get_list_store(tree_view);
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2023-01-29 06:54:02 +13:00
|
|
|
let mut messages: String = String::new();
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2020-11-05 06:15:06 +13:00
|
|
|
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>>
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-11-25 20:36:49 +13:00
|
|
|
let mut selected_rows = Vec::new();
|
2021-07-16 16:51:54 +12:00
|
|
|
|
|
|
|
if let Some(iter) = model.iter_first() {
|
|
|
|
loop {
|
2022-05-22 20:59:09 +12:00
|
|
|
if model.get::<bool>(&iter, column_selection) {
|
|
|
|
if !model.get::<bool>(&iter, column_header) {
|
|
|
|
selected_rows.push(model.path(&iter));
|
2021-11-22 18:48:07 +13:00
|
|
|
} else {
|
2021-11-25 20:36:49 +13:00
|
|
|
panic!("Header row shouldn't be selected, please report bug.");
|
2021-07-16 16:51:54 +12:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !model.iter_next(&iter) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-25 20:36:49 +13:00
|
|
|
if selected_rows.is_empty() {
|
|
|
|
return; // No selected rows
|
|
|
|
}
|
|
|
|
|
2020-11-09 22:09:22 +13:00
|
|
|
// Save to variable paths of files, and remove it when not removing all occurrences.
|
2021-11-25 20:36:49 +13:00
|
|
|
for tree_path in selected_rows.iter().rev() {
|
2021-07-16 16:51:54 +12:00
|
|
|
let iter = model.iter(tree_path).unwrap();
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let file_name = model.get::<String>(&iter, column_file_name);
|
|
|
|
let path = model.get::<String>(&iter, column_path);
|
2020-11-01 02:23:31 +13:00
|
|
|
|
2021-07-16 16:51:54 +12:00
|
|
|
model.remove(&iter);
|
2020-11-09 23:24:01 +13:00
|
|
|
|
2022-06-05 18:01:17 +12:00
|
|
|
map_with_path_to_delete.entry(path.clone()).or_insert_with(Vec::new).push(file_name);
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
// Delete duplicated entries, and remove real files
|
|
|
|
for (path, mut vec_file_name) in map_with_path_to_delete {
|
2022-07-25 06:48:02 +12:00
|
|
|
vec_file_name.sort_unstable();
|
2020-11-05 06:15:06 +13:00
|
|
|
vec_file_name.dedup();
|
|
|
|
for file_name in vec_file_name {
|
2021-03-12 02:31:59 +13:00
|
|
|
if !use_trash {
|
2021-12-22 06:23:17 +13:00
|
|
|
if let Err(e) = fs::remove_file(get_full_name_from_path_name(&path, &file_name)) {
|
2022-01-20 10:35:07 +13:00
|
|
|
messages += flg!(
|
2021-12-22 06:44:20 +13:00
|
|
|
"delete_file_failed",
|
|
|
|
generate_translation_hashmap(vec![("name", get_full_name_from_path_name(&path, &file_name)), ("reason", e.to_string())])
|
|
|
|
)
|
|
|
|
.as_str();
|
2021-12-20 02:45:10 +13:00
|
|
|
messages += "\n";
|
2021-03-12 02:31:59 +13:00
|
|
|
}
|
2021-12-22 06:23:17 +13:00
|
|
|
} else if let Err(e) = trash::delete(get_full_name_from_path_name(&path, &file_name)) {
|
2022-01-20 10:35:07 +13:00
|
|
|
messages += flg!(
|
2021-12-22 06:44:20 +13:00
|
|
|
"delete_file_failed",
|
|
|
|
generate_translation_hashmap(vec![("name", get_full_name_from_path_name(&path, &file_name)), ("reason", e.to_string())])
|
|
|
|
)
|
|
|
|
.as_str();
|
2021-12-20 02:45:10 +13:00
|
|
|
messages += "\n";
|
2020-11-05 06:15:06 +13:00
|
|
|
}
|
2021-03-12 02:31:59 +13:00
|
|
|
|
2020-11-05 06:15:06 +13:00
|
|
|
vec_path_to_delete.push((path.clone(), file_name.clone()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
clean_invalid_headers(&model, column_header, column_path);
|
2020-11-05 06:15:06 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
text_view_errors.buffer().set_text(messages.as_str());
|
2020-11-01 02:23:31 +13:00
|
|
|
}
|