Improve deleting files in Similar files in GUI (#75)

pull/77/head
Rafał Mikrut 4 years ago committed by GitHub
parent beb14f9f1d
commit aa63a14f68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -15,12 +15,11 @@ use chrono::NaiveDateTime;
use crossbeam_channel::unbounded;
use czkawka_core::big_file::BigFile;
use czkawka_core::common_traits::SaveResults;
use czkawka_core::duplicate::CheckingMethod;
use czkawka_core::duplicate::{CheckingMethod, DuplicateFinder};
use czkawka_core::empty_files::EmptyFiles;
use czkawka_core::empty_folder::EmptyFolder;
use czkawka_core::similar_files::SimilarImages;
use czkawka_core::temporary::Temporary;
use duplicate::DuplicateFinder;
use gtk::prelude::*;
use gtk::{Builder, SelectionMode, TreeIter, TreeView};
use std::cell::RefCell;
@ -425,11 +424,8 @@ fn main() {
// Connect Notebook Tabs
{
let shared_buttons = shared_buttons.clone();
let buttons_array = buttons_array.clone();
let notebook_main_children_names = notebook_main_children_names.clone();
let notebook_main_clone = notebook_main.clone();
notebook_main_clone.connect_switch_page(move |_, _, number| {
@ -684,6 +680,9 @@ fn main() {
let selection = tree_view.get_selection();
let (selection_rows, tree_model) = selection.get_selected_rows();
if selection_rows.is_empty() {
return;
}
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
// let new_tree_model = TreeModel::new(); // TODO - maybe create new model when inserting a new data, because this seems to be not optimal when using thousands of rows
@ -711,6 +710,9 @@ fn main() {
let selection = tree_view.get_selection();
let (selection_rows, tree_model) = selection.get_selected_rows();
if selection_rows.is_empty() {
return;
}
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
// let new_tree_model = TreeModel::new(); // TODO - maybe create new model when inserting a new data, because this seems to be not optimal when using thousands of rows
@ -791,6 +793,9 @@ fn main() {
let selection = tree_view.get_selection();
let (selection_rows, tree_model) = selection.get_selected_rows();
if selection_rows.is_empty() {
return;
}
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
// let new_tree_model = TreeModel::new(); // TODO - maybe create new model when inserting a new data, because this seems to be not optimal when using thousands of rows
@ -818,6 +823,9 @@ fn main() {
let selection = tree_view.get_selection();
let (selection_rows, tree_model) = selection.get_selected_rows();
if selection_rows.is_empty() {
return;
}
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
// let new_tree_model = TreeModel::new(); // TODO - maybe create new model when inserting a new data, because this seems to be not optimal when using thousands of rows
@ -845,6 +853,9 @@ fn main() {
let selection = tree_view.get_selection();
let (selection_rows, tree_model) = selection.get_selected_rows();
if selection_rows.is_empty() {
return;
}
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
// let new_tree_model = TreeModel::new(); // TODO - maybe create new model when inserting a new data, because this seems to be not optimal when using thousands of rows
@ -872,31 +883,105 @@ fn main() {
let selection = tree_view.get_selection();
let (selection_rows, tree_model) = selection.get_selected_rows();
if selection_rows.is_empty() {
return;
}
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
// let new_tree_model = TreeModel::new(); // TODO - maybe create new model when inserting a new data, because this seems to be not optimal when using thousands of 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
let mut vec_path_to_delete: Vec<(String, String)> = Vec::new();
// Just remove file, later must be deleted list entry with all occurencies
for tree_path in selection_rows.iter().rev() {
let name = tree_model.get_value(&tree_model.get_iter(tree_path).unwrap(), ColumnsBigFiles::Name as i32).get::<String>().unwrap().unwrap();
let path = tree_model.get_value(&tree_model.get_iter(tree_path).unwrap(), ColumnsBigFiles::Path as i32).get::<String>().unwrap().unwrap();
let name = tree_model.get_value(&tree_model.get_iter(tree_path).unwrap(), ColumnsSimilarImages::Name as i32).get::<String>().unwrap().unwrap();
let path = tree_model.get_value(&tree_model.get_iter(tree_path).unwrap(), ColumnsSimilarImages::Path as i32).get::<String>().unwrap().unwrap();
if fs::remove_file(format!("{}/{}", path, name)).is_err() {
messages += format!(
"Failed to remove file {}/{}. It is possible that you already deleted it, because similar images shows all possible file doesn't exists or you don't have permissions.\n",
path, name
)
.as_str()
}
vec_path_to_delete.push((path, name));
}
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
for path_to_delete in vec_path_to_delete {
let mut vec_tree_path_to_delete: Vec<gtk::TreePath> = Vec::new();
let iter = list_store.get_iter_first().unwrap();
let mut take_child_mode = false; // When original image is searched one, we must remove all occurences of its children
let mut prepared_for_delete;
loop {
prepared_for_delete = false;
if take_child_mode {
let color = tree_model.get_value(&iter, ColumnsSimilarImages::Color as i32).get::<String>().unwrap().unwrap();
if color == HEADER_ROW_COLOR {
take_child_mode = false;
} else {
prepared_for_delete = true;
}
} else {
let path = tree_model.get_value(&iter, ColumnsSimilarImages::Path as i32).get::<String>().unwrap().unwrap();
if path == path_to_delete.0 {
let name = tree_model.get_value(&iter, ColumnsSimilarImages::Name as i32).get::<String>().unwrap().unwrap();
if name == path_to_delete.1 {
let color = tree_model.get_value(&iter, ColumnsSimilarImages::Color as i32).get::<String>().unwrap().unwrap();
if color == HEADER_ROW_COLOR {
take_child_mode = true;
}
prepared_for_delete = true;
}
}
}
match fs::remove_file(format!("{}/{}", path, name)) {
Ok(_) => {
list_store.remove(&list_store.get_iter(tree_path).unwrap());
if prepared_for_delete {
vec_tree_path_to_delete.push(list_store.get_path(&iter).unwrap());
}
if !list_store.iter_next(&iter) {
break;
}
}
for tree_path in vec_tree_path_to_delete.iter().rev() {
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
}
}
// End run to remove single header rows(without duplicates)
if let Some(next_iter) = list_store.get_iter_first() {
let mut header_was_before = false;
let mut vec_tree_path_to_delete: Vec<gtk::TreePath> = Vec::new();
let mut current_iter = next_iter.clone();
loop {
let color = tree_model.get_value(&next_iter, ColumnsSimilarImages::Color as i32).get::<String>().unwrap().unwrap();
if color == HEADER_ROW_COLOR {
if header_was_before {
vec_tree_path_to_delete.push(list_store.get_path(&current_iter).unwrap());
} else {
header_was_before = true;
}
} else {
header_was_before = false;
}
Err(_) => {
messages += format!(
"Failed to remove file {}/{}. It is possible that you already deleted it, because similar images shows all possible file doesn't exists or you don't have permissions.\n",
path, name
)
.as_str()
current_iter = next_iter.clone();
if !list_store.iter_next(&next_iter) {
break;
}
}
}
// Last step, remove orphan header if exists
if let Some(iter) = list_store.get_iter_first() {
if !list_store.iter_next(&iter) {
list_store.clear();
}
}
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
selection.unselect_all();
}

Loading…
Cancel
Save