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;
|
|
|
|
|
2021-11-28 08:49:20 +13:00
|
|
|
use gtk::prelude::*;
|
2021-12-01 01:53:04 +13:00
|
|
|
use gtk::{Align, CheckButton, Dialog, ResponseType, TextView};
|
2021-11-28 08:49:20 +13:00
|
|
|
|
2021-12-20 02:45:10 +13:00
|
|
|
use czkawka_core::fl;
|
|
|
|
|
2021-11-28 08:49:20 +13:00
|
|
|
use crate::gui_data::GuiData;
|
|
|
|
use crate::help_functions::*;
|
2021-12-20 02:45:10 +13:00
|
|
|
use crate::localizer::generate_translation_hashmap;
|
2021-11-28 08:49:20 +13:00
|
|
|
use crate::notebook_enums::*;
|
|
|
|
|
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];
|
|
|
|
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
|
|
|
|
|
2021-12-22 06:23:17 +13:00
|
|
|
let (number_of_selected_items, number_of_selected_groups) = check_how_much_elements_is_selected(tree_view, nb_object.column_color, nb_object.column_selection);
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2021-11-28 04:44:30 +13:00
|
|
|
if let Some(column_color) = nb_object.column_color {
|
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,
|
|
|
|
column_color,
|
|
|
|
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,
|
|
|
|
column_color,
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
*preview_path.borrow_mut() = "".to_string();
|
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(
|
|
|
|
check_button_settings_confirm_deletion: >k::CheckButton,
|
|
|
|
window_main: >k::Window,
|
|
|
|
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;
|
2021-03-07 20:57:48 +13:00
|
|
|
if response_type == gtk::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
|
|
|
|
2021-12-22 06:23:17 +13:00
|
|
|
fn create_dialog_ask_for_deletion(window_main: >k::Window, number_of_selected_items: u64, number_of_selected_groups: u64) -> (Dialog, CheckButton) {
|
2021-12-13 00:02:53 +13:00
|
|
|
let dialog = gtk::Dialog::builder().title(&fl!("delete_title_dialog")).transient_for(window_main).modal(true).build();
|
|
|
|
let button_ok = dialog.add_button(&fl!("general_ok_button"), ResponseType::Ok);
|
2021-12-12 04:16:14 +13:00
|
|
|
dialog.add_button(&fl!("general_close_button"), ResponseType::Cancel);
|
2021-12-01 01:53:04 +13:00
|
|
|
|
2021-12-13 00:02:53 +13:00
|
|
|
let label: gtk::Label = gtk::Label::new(Some(&fl!("delete_question_label")));
|
2021-12-22 06:23:17 +13:00
|
|
|
let label2: gtk::Label = match number_of_selected_groups {
|
2021-12-22 06:44:20 +13:00
|
|
|
0 => gtk::Label::new(Some(&fl!(
|
|
|
|
"delete_items_label",
|
|
|
|
generate_translation_hashmap(vec![("items", number_of_selected_items.to_string())])
|
|
|
|
))),
|
2021-12-22 06:23:17 +13:00
|
|
|
_ => gtk::Label::new(Some(&fl!(
|
|
|
|
"delete_items_groups_label",
|
|
|
|
generate_translation_hashmap(vec![("items", number_of_selected_items.to_string()), ("groups", number_of_selected_groups.to_string())])
|
|
|
|
))),
|
|
|
|
};
|
2021-12-13 00:02:53 +13:00
|
|
|
let check_button: gtk::CheckButton = gtk::CheckButton::with_label(&fl!("dialogs_ask_next_time"));
|
2021-11-28 04:44:30 +13:00
|
|
|
check_button.set_active(true);
|
|
|
|
check_button.set_halign(Align::Center);
|
|
|
|
|
|
|
|
button_ok.grab_focus();
|
|
|
|
|
2021-12-01 23:09:47 +13:00
|
|
|
let internal_box = get_dialog_box_child(&dialog);
|
2021-11-28 04:44:30 +13:00
|
|
|
internal_box.add(&label);
|
2021-12-22 06:23:17 +13:00
|
|
|
internal_box.add(&label2);
|
2021-11-28 04:44:30 +13:00
|
|
|
internal_box.add(&check_button);
|
2021-12-22 06:23:17 +13:00
|
|
|
internal_box.set_margin(5);
|
|
|
|
check_button.set_margin_top(5);
|
2021-11-28 04:44:30 +13:00
|
|
|
|
2021-12-01 23:09:47 +13:00
|
|
|
dialog.show_all();
|
|
|
|
(dialog, check_button)
|
2021-11-28 04:44:30 +13:00
|
|
|
}
|
2021-03-07 20:57:48 +13:00
|
|
|
|
2021-12-01 23:09:47 +13:00
|
|
|
fn create_dialog_group_deletion(window_main: >k::Window) -> (Dialog, CheckButton) {
|
2021-12-22 06:44:20 +13:00
|
|
|
let dialog = gtk::Dialog::builder()
|
|
|
|
.title(&fl!("delete_all_files_in_group_title"))
|
|
|
|
.transient_for(window_main)
|
|
|
|
.modal(true)
|
|
|
|
.build();
|
2021-12-13 00:02:53 +13:00
|
|
|
let button_ok = dialog.add_button(&fl!("general_ok_button"), ResponseType::Ok);
|
2021-12-12 04:16:14 +13:00
|
|
|
dialog.add_button(&fl!("general_close_button"), ResponseType::Cancel);
|
2021-12-01 01:53:04 +13:00
|
|
|
|
2021-12-13 00:02:53 +13:00
|
|
|
let label: gtk::Label = gtk::Label::new(Some(&fl!("delete_all_files_in_group_label1")));
|
|
|
|
let label2: gtk::Label = gtk::Label::new(Some(&fl!("delete_all_files_in_group_label2")));
|
|
|
|
let check_button: gtk::CheckButton = gtk::CheckButton::with_label(&fl!("dialogs_ask_next_time"));
|
2021-11-28 04:44:30 +13:00
|
|
|
check_button.set_active(true);
|
|
|
|
check_button.set_halign(Align::Center);
|
|
|
|
|
|
|
|
button_ok.grab_focus();
|
|
|
|
|
2021-12-01 23:09:47 +13:00
|
|
|
let internal_box = get_dialog_box_child(&dialog);
|
2021-11-28 04:44:30 +13:00
|
|
|
internal_box.add(&label);
|
|
|
|
internal_box.add(&label2);
|
|
|
|
internal_box.add(&check_button);
|
|
|
|
|
2021-12-01 23:09:47 +13:00
|
|
|
dialog.show_all();
|
|
|
|
(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(
|
|
|
|
tree_view: >k::TreeView,
|
|
|
|
column_color: i32,
|
|
|
|
column_selection: i32,
|
2021-12-24 21:18:55 +13:00
|
|
|
column_path: i32,
|
2021-12-22 06:44:20 +13:00
|
|
|
window_main: >k::Window,
|
|
|
|
check_button_settings_confirm_group_deletion: >k::CheckButton,
|
|
|
|
) -> 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() {
|
|
|
|
assert_eq!(model.value(&iter, column_color).get::<String>().unwrap(), HEADER_ROW_COLOR); // 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
|
|
|
|
if !model.value(&iter, column_path).get::<String>().unwrap().is_empty() {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-07-16 16:51:54 +12:00
|
|
|
if model.value(&iter, column_color).get::<String>().unwrap() == HEADER_ROW_COLOR {
|
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 {
|
2021-07-16 16:51:54 +12:00
|
|
|
if !model.value(&iter, column_selection).get::<bool>().unwrap() {
|
|
|
|
selected_all_records = false;
|
|
|
|
}
|
2021-03-07 03:56:39 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if !selected_all_records {
|
|
|
|
return false;
|
|
|
|
} else {
|
2021-11-28 04:44:30 +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;
|
2021-03-07 03:56:39 +13:00
|
|
|
if response_type == gtk::ResponseType::Ok {
|
2021-06-26 04:07:13 +12:00
|
|
|
if !check_button.is_active() {
|
2021-03-07 03:56:39 +13:00
|
|
|
check_button_settings_confirm_group_deletion.set_active(false);
|
|
|
|
}
|
|
|
|
} else {
|
2021-03-07 20:57:48 +13:00
|
|
|
confirmation_dialog_group_delete.hide();
|
|
|
|
confirmation_dialog_group_delete.close();
|
2021-03-07 03:56:39 +13:00
|
|
|
return true;
|
|
|
|
}
|
2021-03-07 20:57:48 +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(
|
|
|
|
tree_view: >k::TreeView,
|
|
|
|
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 {
|
|
|
|
if model.value(&iter, column_selection).get::<bool>().unwrap() {
|
|
|
|
selected_rows.push(model.path(&iter).unwrap());
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-11-05 06:15:06 +13:00
|
|
|
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
|
2021-07-16 16:51:54 +12:00
|
|
|
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();
|
|
|
|
let path = model.value(&iter, column_path).get::<String>().unwrap();
|
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() {
|
|
|
|
next_folder = "".to_owned()
|
|
|
|
+ ¤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 {
|
2021-12-22 06:44:20 +13:00
|
|
|
messages += &fl!(
|
|
|
|
"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
|
|
|
|
2021-06-26 04:07:13 +12:00
|
|
|
text_view_errors.buffer().unwrap().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(
|
|
|
|
tree_view: >k::TreeView,
|
|
|
|
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
|
|
|
|
2020-11-05 06:15:06 +13:00
|
|
|
let mut messages: String = "".to_string();
|
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 {
|
|
|
|
if model.value(&iter, column_selection).get::<bool>().unwrap() {
|
2021-11-25 20:36:49 +13:00
|
|
|
selected_rows.push(model.path(&iter).unwrap());
|
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
|
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();
|
|
|
|
|
|
|
|
let name = model.value(&iter, column_file_name).get::<String>().unwrap();
|
|
|
|
let path = model.value(&iter, column_path).get::<String>().unwrap();
|
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) => {
|
2021-12-22 06:44:20 +13:00
|
|
|
messages += fl!(
|
|
|
|
"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) => {
|
2021-12-22 06:44:20 +13:00
|
|
|
messages += fl!(
|
|
|
|
"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
|
|
|
|
2021-06-26 04:07:13 +12:00
|
|
|
text_view_errors.buffer().unwrap().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(
|
|
|
|
tree_view: >k::TreeView,
|
|
|
|
column_file_name: i32,
|
|
|
|
column_path: i32,
|
|
|
|
column_color: 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
|
|
|
|
2020-11-05 06:15:06 +13:00
|
|
|
let mut messages: String = "".to_string();
|
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 {
|
|
|
|
if model.value(&iter, column_selection).get::<bool>().unwrap() {
|
|
|
|
if model.value(&iter, column_color).get::<String>().unwrap() == MAIN_ROW_COLOR {
|
2021-11-25 20:36:49 +13:00
|
|
|
selected_rows.push(model.path(&iter).unwrap());
|
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();
|
|
|
|
|
|
|
|
let file_name = model.value(&iter, column_file_name).get::<String>().unwrap();
|
|
|
|
let path = model.value(&iter, column_path).get::<String>().unwrap();
|
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
|
|
|
|
2020-11-05 06:15:06 +13:00
|
|
|
map_with_path_to_delete.entry(path.clone()).or_insert_with(Vec::new);
|
|
|
|
map_with_path_to_delete.get_mut(path.as_str()).unwrap().push(file_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete duplicated entries, and remove real files
|
|
|
|
for (path, mut vec_file_name) in map_with_path_to_delete {
|
|
|
|
vec_file_name.sort();
|
|
|
|
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)) {
|
2021-12-22 06:44:20 +13:00
|
|
|
messages += fl!(
|
|
|
|
"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)) {
|
2021-12-22 06:44:20 +13:00
|
|
|
messages += fl!(
|
|
|
|
"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()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-24 21:18:55 +13:00
|
|
|
clean_invalid_headers(&model, column_color, column_path);
|
2020-11-05 06:15:06 +13:00
|
|
|
|
2021-06-26 04:07:13 +12:00
|
|
|
text_view_errors.buffer().unwrap().set_text(messages.as_str());
|
2020-11-01 02:23:31 +13:00
|
|
|
}
|