Add confirmation dialog when deleting files
This commit is contained in:
parent
d3652c1e86
commit
df065115f6
|
@ -32,96 +32,6 @@ Author: Rafał Mikrut
|
|||
<!-- interface-name Czkawka -->
|
||||
<!-- interface-description Czkawka is simple and fast app to find duplicates, empty folders etc. -->
|
||||
<!-- interface-authors Rafa\305\202 Mikrut -->
|
||||
<object class="GtkDialog" id="delete_confirmation_dialog">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">applications-engineering</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">9</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="yes_dialog_option">
|
||||
<property name="label" translatable="yes">Yes</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="no_option_dialog">
|
||||
<property name="label" translatable="yes">No</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"> Are you sure that you want to delete this files?</property>
|
||||
<attributes>
|
||||
<attribute name="stretch" value="condensed"/>
|
||||
<attribute name="scale" value="1"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAlignment">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xscale">0</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="ask_in_future">
|
||||
<property name="label" translatable="yes">Ask for this in future?</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkWindow" id="main_window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="default_width">1000</property>
|
||||
|
|
|
@ -73,6 +73,9 @@ fn main() {
|
|||
let shared_temporary_files_state: Rc<RefCell<_>> = Rc::new(RefCell::new(Temporary::new()));
|
||||
let shared_big_files_state: Rc<RefCell<_>> = Rc::new(RefCell::new(BigFile::new()));
|
||||
|
||||
// State of confirmation dialogs
|
||||
let shared_confirmation_dialog_delete_dialog_showing_state: Rc<RefCell<_>> = Rc::new(RefCell::new(true));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// GUI Entry
|
||||
|
@ -825,143 +828,178 @@ fn main() {
|
|||
let scrolled_window_duplicate_finder = scrolled_window_duplicate_finder.clone();
|
||||
let notebook_chooser_tool_children_names = notebook_chooser_tool_children_names.clone();
|
||||
let notebook_chooser_tool = notebook_chooser_tool.clone();
|
||||
buttons_delete.connect_clicked(move |_| match notebook_chooser_tool_children_names.get(notebook_chooser_tool.get_current_page().unwrap() as usize).unwrap().as_str() {
|
||||
"notebook_duplicate_finder_label" => {
|
||||
let tree_view = scrolled_window_duplicate_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
let main_window = main_window.clone();
|
||||
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
|
||||
buttons_delete.connect_clicked(move |_| {
|
||||
if *shared_confirmation_dialog_delete_dialog_showing_state.borrow_mut() {
|
||||
let confirmation_dialog_delete = gtk::Dialog::with_buttons(
|
||||
Option::from("Delete confirmation"),
|
||||
Option::from(&main_window),
|
||||
gtk::DialogFlags::MODAL,
|
||||
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
|
||||
);
|
||||
let label: gtk::Label = gtk::Label::new(Some("Are you sure that you want to delete files?"));
|
||||
let check_button: gtk::CheckButton = gtk::CheckButton::with_label("Ask in future");
|
||||
check_button.set_active(true);
|
||||
|
||||
// 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
|
||||
for tree_path in selection_rows.iter().rev() {
|
||||
let name = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsDuplicates::Name as i32).get::<String>().unwrap().unwrap();
|
||||
let path = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsDuplicates::Path as i32).get::<String>().unwrap().unwrap();
|
||||
|
||||
match fs::remove_file(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(),
|
||||
}
|
||||
for widgets in confirmation_dialog_delete.get_children() {
|
||||
// By default GtkBox is child of dialog, so we can easily add other things to it
|
||||
widgets.clone().downcast::<gtk::Box>().unwrap().add(&label);
|
||||
widgets.downcast::<gtk::Box>().unwrap().add(&check_button);
|
||||
}
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
}
|
||||
"scrolled_window_empty_folder_finder" => {
|
||||
let tree_view = scrolled_window_empty_folder_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
confirmation_dialog_delete.show_all();
|
||||
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
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
|
||||
for tree_path in selection_rows.iter().rev() {
|
||||
let name = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsEmptyFolders::Name as i32).get::<String>().unwrap().unwrap();
|
||||
let path = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsEmptyFolders::Path as i32).get::<String>().unwrap().unwrap();
|
||||
|
||||
match fs::remove_dir(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove folder {}/{} because folder doesn't exists, you don't have permissions or isn't empty.\n", path, name).as_str(),
|
||||
let response_type = confirmation_dialog_delete.run();
|
||||
if response_type == gtk::ResponseType::Ok {
|
||||
if !check_button.get_active() {
|
||||
*shared_confirmation_dialog_delete_dialog_showing_state.borrow_mut() = false;
|
||||
}
|
||||
} else {
|
||||
confirmation_dialog_delete.close();
|
||||
return;
|
||||
}
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
confirmation_dialog_delete.close();
|
||||
}
|
||||
"scrolled_window_empty_files_finder" => {
|
||||
let tree_view = scrolled_window_empty_files_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
|
||||
match notebook_chooser_tool_children_names.get(notebook_chooser_tool.get_current_page().unwrap() as usize).unwrap().as_str() {
|
||||
"notebook_duplicate_finder_label" => {
|
||||
let tree_view = scrolled_window_duplicate_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
|
||||
// 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 (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
|
||||
|
||||
let mut messages: String = "".to_string();
|
||||
// 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
|
||||
|
||||
// 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() {
|
||||
let name = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsEmptyFiles::Name as i32).get::<String>().unwrap().unwrap();
|
||||
let path = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsEmptyFiles::Path as i32).get::<String>().unwrap().unwrap();
|
||||
let mut messages: String = "".to_string();
|
||||
|
||||
match fs::remove_file(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
// 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() {
|
||||
let name = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsDuplicates::Name as i32).get::<String>().unwrap().unwrap();
|
||||
let path = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsDuplicates::Path as i32).get::<String>().unwrap().unwrap();
|
||||
|
||||
match fs::remove_file(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(),
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(),
|
||||
}
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
}
|
||||
"scrolled_window_empty_folder_finder" => {
|
||||
let tree_view = scrolled_window_empty_folder_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
}
|
||||
"scrolled_window_temporary_files_finder" => {
|
||||
let tree_view = scrolled_window_temporary_files_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
|
||||
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
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 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();
|
||||
|
||||
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
|
||||
for tree_path in selection_rows.iter().rev() {
|
||||
let name = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsEmptyFolders::Name as i32).get::<String>().unwrap().unwrap();
|
||||
let path = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsEmptyFolders::Path as i32).get::<String>().unwrap().unwrap();
|
||||
|
||||
// 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() {
|
||||
let name = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsTemporaryFiles::Name as i32).get::<String>().unwrap().unwrap();
|
||||
let path = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsTemporaryFiles::Path as i32).get::<String>().unwrap().unwrap();
|
||||
|
||||
match fs::remove_file(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
match fs::remove_dir(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove folder {}/{} because folder doesn't exists, you don't have permissions or isn't empty.\n", path, name).as_str(),
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(),
|
||||
}
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
}
|
||||
"scrolled_window_empty_files_finder" => {
|
||||
let tree_view = scrolled_window_empty_files_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
}
|
||||
"notebook_big_file_finder" => {
|
||||
let tree_view = scrolled_window_big_files_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
let list_store = tree_model.clone().downcast::<gtk::ListStore>().unwrap();
|
||||
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
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 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();
|
||||
|
||||
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
|
||||
for tree_path in selection_rows.iter().rev() {
|
||||
let name = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsEmptyFiles::Name as i32).get::<String>().unwrap().unwrap();
|
||||
let path = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsEmptyFiles::Path as i32).get::<String>().unwrap().unwrap();
|
||||
|
||||
// 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() {
|
||||
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();
|
||||
|
||||
match fs::remove_file(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
match fs::remove_file(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(),
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
}
|
||||
"scrolled_window_temporary_files_finder" => {
|
||||
let tree_view = scrolled_window_temporary_files_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
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
|
||||
for tree_path in selection_rows.iter().rev() {
|
||||
let name = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsTemporaryFiles::Name as i32).get::<String>().unwrap().unwrap();
|
||||
let path = tree_model.get_value(&tree_model.get_iter(&tree_path).unwrap(), ColumnsTemporaryFiles::Path as i32).get::<String>().unwrap().unwrap();
|
||||
|
||||
match fs::remove_file(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
}
|
||||
"notebook_big_file_finder" => {
|
||||
let tree_view = scrolled_window_big_files_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
|
||||
let selection = tree_view.get_selection();
|
||||
|
||||
let (selection_rows, tree_model) = selection.get_selected_rows();
|
||||
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
|
||||
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();
|
||||
|
||||
match fs::remove_file(format!("{}/{}", path, name)) {
|
||||
Ok(_) => {
|
||||
list_store.remove(&list_store.get_iter(&tree_path).unwrap());
|
||||
}
|
||||
Err(_) => messages += format!("Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n", path, name).as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
text_view_errors.get_buffer().unwrap().set_text(messages.as_str());
|
||||
selection.unselect_all();
|
||||
}
|
||||
e => panic!("Not existent {}", e),
|
||||
}
|
||||
e => panic!("Not existent {}", e),
|
||||
});
|
||||
}
|
||||
// Select button
|
||||
|
|
Loading…
Reference in a new issue