GTK 4 compatibility fixes (#467)
App still require GTK 3.22(3.24 in near future), but converting to GTK 4 should be easier and faster
This commit is contained in:
parent
16772b1c52
commit
5836e3e5b3
|
@ -2,7 +2,7 @@ use crate::gui_data::GuiData;
|
||||||
use crate::help_functions::*;
|
use crate::help_functions::*;
|
||||||
use crate::notebook_enums::*;
|
use crate::notebook_enums::*;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{Align, CheckButton, TextView};
|
use gtk::{Align, CheckButton, Dialog, TextView};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::Metadata;
|
use std::fs::Metadata;
|
||||||
|
@ -11,7 +11,15 @@ use std::fs::Metadata;
|
||||||
|
|
||||||
pub fn connect_button_delete(gui_data: &GuiData) {
|
pub fn connect_button_delete(gui_data: &GuiData) {
|
||||||
let buttons_delete = gui_data.bottom_buttons.buttons_delete.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 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) {
|
||||||
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
||||||
let window_main = gui_data.window_main.clone();
|
let window_main = gui_data.window_main.clone();
|
||||||
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
|
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
|
||||||
|
@ -24,77 +32,50 @@ pub fn connect_button_delete(gui_data: &GuiData) {
|
||||||
let check_button_settings_use_trash = gui_data.settings.check_button_settings_use_trash.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();
|
let text_view_errors = gui_data.text_view_errors.clone();
|
||||||
|
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main).await {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
buttons_delete.connect_clicked(move |_| {
|
let nb_number = notebook_main.current_page().unwrap();
|
||||||
// TODO maybe add to this dialog info how much things will be deleted
|
let tree_view = &main_tree_views[nb_number as usize];
|
||||||
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) {
|
let nb_object = &NOTEBOOKS_INFOS[nb_number as usize];
|
||||||
return;
|
|
||||||
|
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).await {
|
||||||
|
tree_remove(
|
||||||
|
&tree_view.clone(),
|
||||||
|
nb_object.column_name,
|
||||||
|
nb_object.column_path,
|
||||||
|
column_color,
|
||||||
|
nb_object.column_selection,
|
||||||
|
&check_button_settings_use_trash,
|
||||||
|
&text_view_errors,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
let nb_number = notebook_main.current_page().unwrap();
|
if nb_number == NotebookMainEnum::EmptyDirectories as u32 {
|
||||||
let tree_view = &main_tree_views[nb_number as usize];
|
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);
|
||||||
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(),
|
|
||||||
nb_object.column_name,
|
|
||||||
nb_object.column_path,
|
|
||||||
column_color,
|
|
||||||
nb_object.column_selection,
|
|
||||||
&check_button_settings_use_trash,
|
|
||||||
&text_view_errors,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if nb_number == NotebookMainEnum::EmptyDirectories as u32 {
|
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);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match &nb_object.notebook_type {
|
match &nb_object.notebook_type {
|
||||||
NotebookMainEnum::SimilarImages => {
|
NotebookMainEnum::SimilarImages => {
|
||||||
image_preview_similar_images.hide();
|
image_preview_similar_images.hide();
|
||||||
}
|
|
||||||
NotebookMainEnum::Duplicate => {
|
|
||||||
image_preview_duplicates.hide();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
});
|
NotebookMainEnum::Duplicate => {
|
||||||
|
image_preview_duplicates.hide();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_if_can_delete_files(check_button_settings_confirm_deletion: >k::CheckButton, window_main: >k::Window) -> bool {
|
pub async fn check_if_can_delete_files(check_button_settings_confirm_deletion: >k::CheckButton, window_main: >k::Window) -> bool {
|
||||||
if check_button_settings_confirm_deletion.is_active() {
|
if check_button_settings_confirm_deletion.is_active() {
|
||||||
let confirmation_dialog_delete = gtk::Dialog::with_buttons(
|
let (confirmation_dialog_delete, check_button) = create_dialog_ask_for_deletion(window_main);
|
||||||
Some("Delete confirmation"),
|
|
||||||
Some(window_main),
|
|
||||||
gtk::DialogFlags::DESTROY_WITH_PARENT,
|
|
||||||
&[("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 next time");
|
|
||||||
check_button.set_active(true);
|
|
||||||
check_button.set_halign(Align::Center);
|
|
||||||
|
|
||||||
let button_box = confirmation_dialog_delete.children()[0].clone().downcast::<gtk::Box>().unwrap().children()[0].clone().downcast::<gtk::Box>().unwrap().children()[0]
|
let response_type = confirmation_dialog_delete.run_future().await;
|
||||||
.clone()
|
|
||||||
.downcast::<gtk::ButtonBox>()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let button_ok = button_box.children()[0].clone();
|
|
||||||
button_ok.grab_focus();
|
|
||||||
|
|
||||||
let internal_box = confirmation_dialog_delete.children()[0].clone().downcast::<gtk::Box>().unwrap();
|
|
||||||
internal_box.add(&label);
|
|
||||||
internal_box.add(&check_button);
|
|
||||||
|
|
||||||
confirmation_dialog_delete.show_all();
|
|
||||||
|
|
||||||
let response_type = confirmation_dialog_delete.run();
|
|
||||||
if response_type == gtk::ResponseType::Ok {
|
if response_type == gtk::ResponseType::Ok {
|
||||||
if !check_button.is_active() {
|
if !check_button.is_active() {
|
||||||
check_button_settings_confirm_deletion.set_active(false);
|
check_button_settings_confirm_deletion.set_active(false);
|
||||||
|
@ -109,8 +90,65 @@ pub fn check_if_can_delete_files(check_button_settings_confirm_deletion: >k::C
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
fn create_dialog_ask_for_deletion(window_main: >k::Window) -> (Dialog, CheckButton) {
|
||||||
|
let confirmation_dialog_delete = gtk::Dialog::with_buttons(
|
||||||
|
Some("Delete confirmation"),
|
||||||
|
Some(window_main),
|
||||||
|
gtk::DialogFlags::DESTROY_WITH_PARENT,
|
||||||
|
&[("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 next time");
|
||||||
|
check_button.set_active(true);
|
||||||
|
check_button.set_halign(Align::Center);
|
||||||
|
|
||||||
pub fn check_if_deleting_all_files_in_group(tree_view: >k::TreeView, column_color: i32, column_selection: i32, window_main: >k::Window, check_button_settings_confirm_group_deletion: >k::CheckButton) -> bool {
|
let button_box = confirmation_dialog_delete.children()[0].clone().downcast::<gtk::Box>().unwrap().children()[0].clone().downcast::<gtk::Box>().unwrap().children()[0]
|
||||||
|
.clone()
|
||||||
|
.downcast::<gtk::ButtonBox>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let button_ok = button_box.children()[0].clone();
|
||||||
|
button_ok.grab_focus();
|
||||||
|
|
||||||
|
let internal_box = confirmation_dialog_delete.children()[0].clone().downcast::<gtk::Box>().unwrap();
|
||||||
|
internal_box.add(&label);
|
||||||
|
internal_box.add(&check_button);
|
||||||
|
|
||||||
|
confirmation_dialog_delete.show_all();
|
||||||
|
(confirmation_dialog_delete, check_button)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_dialog_group_deletion(window_main: >k::Window) -> (Dialog, CheckButton) {
|
||||||
|
let confirmation_dialog_group_delete = gtk::Dialog::with_buttons(
|
||||||
|
Some("Confirmation of deleting all files in group"),
|
||||||
|
Some(window_main),
|
||||||
|
gtk::DialogFlags::MODAL,
|
||||||
|
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
|
||||||
|
);
|
||||||
|
let label: gtk::Label = gtk::Label::new(Some("In some groups there are selected all records."));
|
||||||
|
let label2: gtk::Label = gtk::Label::new(Some("Are you sure that you want to delete them?"));
|
||||||
|
let check_button: gtk::CheckButton = gtk::CheckButton::with_label("Ask next time");
|
||||||
|
check_button.set_active(true);
|
||||||
|
check_button.set_halign(Align::Center);
|
||||||
|
|
||||||
|
let button_box = get_dialog_box_child(&confirmation_dialog_group_delete).children()[0].clone().downcast::<gtk::Box>().unwrap().children()[0]
|
||||||
|
.clone()
|
||||||
|
.downcast::<gtk::ButtonBox>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let button_ok = button_box.children()[0].clone();
|
||||||
|
button_ok.grab_focus();
|
||||||
|
|
||||||
|
let internal_box = get_dialog_box_child(&confirmation_dialog_group_delete);
|
||||||
|
internal_box.add(&label);
|
||||||
|
internal_box.add(&label2);
|
||||||
|
internal_box.add(&check_button);
|
||||||
|
|
||||||
|
confirmation_dialog_group_delete.show_all();
|
||||||
|
(confirmation_dialog_group_delete, check_button)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn check_if_deleting_all_files_in_group(tree_view: >k::TreeView, column_color: i32, column_selection: i32, window_main: >k::Window, check_button_settings_confirm_group_deletion: >k::CheckButton) -> bool {
|
||||||
let model = get_list_store(tree_view);
|
let model = get_list_store(tree_view);
|
||||||
|
|
||||||
let mut selected_all_records: bool = true;
|
let mut selected_all_records: bool = true;
|
||||||
|
@ -141,38 +179,9 @@ pub fn check_if_deleting_all_files_in_group(tree_view: >k::TreeView, column_co
|
||||||
if !selected_all_records {
|
if !selected_all_records {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
let confirmation_dialog_group_delete = gtk::Dialog::with_buttons(
|
let (confirmation_dialog_group_delete, check_button) = create_dialog_group_deletion(window_main);
|
||||||
Some("Confirmation of deleting all files in group"),
|
|
||||||
Some(window_main),
|
|
||||||
gtk::DialogFlags::MODAL,
|
|
||||||
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
|
|
||||||
);
|
|
||||||
let label: gtk::Label = gtk::Label::new(Some("In some groups there are selected all records."));
|
|
||||||
let label2: gtk::Label = gtk::Label::new(Some("Are you sure that you want to delete them?"));
|
|
||||||
let check_button: gtk::CheckButton = gtk::CheckButton::with_label("Ask next time");
|
|
||||||
check_button.set_active(true);
|
|
||||||
check_button.set_halign(Align::Center);
|
|
||||||
|
|
||||||
let button_box = confirmation_dialog_group_delete.children()[0].clone().downcast::<gtk::Box>().unwrap().children()[0]
|
let response_type = confirmation_dialog_group_delete.run_future().await;
|
||||||
.clone()
|
|
||||||
.downcast::<gtk::Box>()
|
|
||||||
.unwrap()
|
|
||||||
.children()[0]
|
|
||||||
.clone()
|
|
||||||
.downcast::<gtk::ButtonBox>()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let button_ok = button_box.children()[0].clone();
|
|
||||||
button_ok.grab_focus();
|
|
||||||
|
|
||||||
let internal_box = confirmation_dialog_group_delete.children()[0].clone().downcast::<gtk::Box>().unwrap();
|
|
||||||
internal_box.add(&label);
|
|
||||||
internal_box.add(&label2);
|
|
||||||
internal_box.add(&check_button);
|
|
||||||
|
|
||||||
confirmation_dialog_group_delete.show_all();
|
|
||||||
|
|
||||||
let response_type = confirmation_dialog_group_delete.run();
|
|
||||||
if response_type == gtk::ResponseType::Ok {
|
if response_type == gtk::ResponseType::Ok {
|
||||||
if !check_button.is_active() {
|
if !check_button.is_active() {
|
||||||
check_button_settings_confirm_group_deletion.set_active(false);
|
check_button_settings_confirm_group_deletion.set_active(false);
|
||||||
|
|
|
@ -57,23 +57,28 @@ fn move_things(tree_view: >k::TreeView, column_file_name: i32, column_path: i3
|
||||||
gtk::FileChooserAction::SelectFolder,
|
gtk::FileChooserAction::SelectFolder,
|
||||||
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
|
&[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)],
|
||||||
);
|
);
|
||||||
chooser.set_select_multiple(true);
|
chooser.set_select_multiple(false);
|
||||||
chooser.show_all();
|
chooser.show_all();
|
||||||
let response_type = chooser.run();
|
|
||||||
if response_type == gtk::ResponseType::Ok {
|
let entry_info = entry_info.clone();
|
||||||
let folders = chooser.filenames();
|
let text_view_errors = text_view_errors.clone();
|
||||||
if folders.len() != 1 {
|
let tree_view = tree_view.clone();
|
||||||
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());
|
chooser.connect_response(move |file_chooser, response_type| {
|
||||||
} else {
|
if response_type == gtk::ResponseType::Ok {
|
||||||
let folder = folders[0].clone();
|
let folders = file_chooser.filenames();
|
||||||
if let Some(column_color) = column_color {
|
if folders.len() != 1 {
|
||||||
move_with_tree(tree_view, column_file_name, column_path, column_color, column_selection, folder, entry_info, text_view_errors);
|
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 {
|
} else {
|
||||||
move_with_list(tree_view, column_file_name, column_path, column_selection, folder, entry_info, text_view_errors);
|
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, folder, &entry_info, &text_view_errors);
|
||||||
|
} else {
|
||||||
|
move_with_list(&tree_view, column_file_name, column_path, column_selection, folder, &entry_info, &text_view_errors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
file_chooser.close();
|
||||||
chooser.close();
|
});
|
||||||
}
|
}
|
||||||
fn move_with_tree(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, destination_folder: PathBuf, entry_info: >k::Entry, text_view_errors: >k::TextView) {
|
fn move_with_tree(tree_view: >k::TreeView, column_file_name: i32, column_path: i32, column_color: i32, column_selection: i32, destination_folder: PathBuf, entry_info: >k::Entry, text_view_errors: >k::TextView) {
|
||||||
let model = get_list_store(tree_view);
|
let model = get_list_store(tree_view);
|
||||||
|
|
|
@ -15,6 +15,7 @@ use czkawka_core::similar_videos::SimilarVideos;
|
||||||
use czkawka_core::temporary::Temporary;
|
use czkawka_core::temporary::Temporary;
|
||||||
use glib::Sender;
|
use glib::Sender;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
use gtk::WindowPosition;
|
use gtk::WindowPosition;
|
||||||
use img_hash::{FilterType, HashAlg};
|
use img_hash::{FilterType, HashAlg};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::gui_data::GuiData;
|
use crate::gui_data::GuiData;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{ResponseType, WindowPosition};
|
use gtk::WindowPosition;
|
||||||
|
|
||||||
pub fn connect_button_about(gui_data: &GuiData) {
|
pub fn connect_button_about(gui_data: &GuiData) {
|
||||||
let about_dialog = gui_data.about.about_dialog.clone();
|
let about_dialog = gui_data.about.about_dialog.clone();
|
||||||
|
@ -8,9 +8,11 @@ pub fn connect_button_about(gui_data: &GuiData) {
|
||||||
button_app_info.connect_clicked(move |_| {
|
button_app_info.connect_clicked(move |_| {
|
||||||
about_dialog.set_position(WindowPosition::Center);
|
about_dialog.set_position(WindowPosition::Center);
|
||||||
about_dialog.show();
|
about_dialog.show();
|
||||||
let response = about_dialog.run();
|
|
||||||
if response != ResponseType::None {
|
// Prevent from deleting dialog after close
|
||||||
about_dialog.hide();
|
about_dialog.connect_delete_event(|e, _f| {
|
||||||
}
|
e.hide();
|
||||||
|
Inhibit(true)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,13 +213,11 @@ fn popover_one_oldest_newest(popover: >k::Popover, tree_view: >k::TreeView,
|
||||||
fn popover_custom_select_unselect(popover: >k::Popover, window_main: &Window, tree_view: >k::TreeView, column_color: Option<i32>, column_file_name: i32, column_path: i32, column_button_selection: u32, select_things: bool) {
|
fn popover_custom_select_unselect(popover: >k::Popover, window_main: &Window, tree_view: >k::TreeView, column_color: Option<i32>, column_file_name: i32, column_path: i32, column_button_selection: u32, select_things: bool) {
|
||||||
popover.popdown();
|
popover.popdown();
|
||||||
|
|
||||||
let wildcard: String;
|
|
||||||
enum WildcardType {
|
enum WildcardType {
|
||||||
Path,
|
Path,
|
||||||
Name,
|
Name,
|
||||||
PathName,
|
PathName,
|
||||||
}
|
}
|
||||||
let wildcard_type: WildcardType;
|
|
||||||
|
|
||||||
let window_title = match select_things {
|
let window_title = match select_things {
|
||||||
false => "Unselect Custom",
|
false => "Unselect Custom",
|
||||||
|
@ -231,9 +229,11 @@ fn popover_custom_select_unselect(popover: >k::Popover, window_main: &Window,
|
||||||
let confirmation_dialog_delete = gtk::Dialog::with_buttons(Some(window_title), Some(window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]);
|
let confirmation_dialog_delete = gtk::Dialog::with_buttons(Some(window_title), Some(window_main), gtk::DialogFlags::MODAL, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]);
|
||||||
let label: gtk::Label = gtk::Label::new(Some("Usage: */folder-nr*/* or name-version-*.txt"));
|
let label: gtk::Label = gtk::Label::new(Some("Usage: */folder-nr*/* or name-version-*.txt"));
|
||||||
|
|
||||||
let radio_path = gtk::RadioButton::with_label("Path");
|
let radio_path = gtk::RadioButton::builder().label("Path").build();
|
||||||
let radio_name = gtk::RadioButton::with_label_from_widget(&radio_path, "Name");
|
let radio_name_path = gtk::RadioButton::builder().label("Path + Name").build();
|
||||||
let radio_name_path = gtk::RadioButton::with_label_from_widget(&radio_path, "Path + Name");
|
radio_name_path.join_group(Some(&radio_path));
|
||||||
|
let radio_name = gtk::RadioButton::builder().label("Name").build();
|
||||||
|
radio_name.join_group(Some(&radio_path)); // TODO, not sure why this not exists for builder, but should
|
||||||
|
|
||||||
let entry_path = gtk::Entry::new();
|
let entry_path = gtk::Entry::new();
|
||||||
let entry_name = gtk::Entry::new();
|
let entry_name = gtk::Entry::new();
|
||||||
|
@ -263,73 +263,79 @@ fn popover_custom_select_unselect(popover: >k::Popover, window_main: &Window,
|
||||||
|
|
||||||
confirmation_dialog_delete.show_all();
|
confirmation_dialog_delete.show_all();
|
||||||
|
|
||||||
let response_type = confirmation_dialog_delete.run();
|
let tree_view = tree_view.clone();
|
||||||
if response_type == gtk::ResponseType::Ok {
|
confirmation_dialog_delete.connect_response(move |confirmation_dialog_delete, response_type| {
|
||||||
if radio_path.is_active() {
|
let wildcard_type: WildcardType;
|
||||||
wildcard_type = WildcardType::Path;
|
let wildcard: String;
|
||||||
wildcard = entry_path.text().to_string();
|
|
||||||
} else if radio_name.is_active() {
|
if response_type == gtk::ResponseType::Ok {
|
||||||
wildcard_type = WildcardType::Name;
|
if radio_path.is_active() {
|
||||||
wildcard = entry_name.text().to_string();
|
wildcard_type = WildcardType::Path;
|
||||||
} else if radio_name_path.is_active() {
|
wildcard = entry_path.text().to_string();
|
||||||
wildcard_type = WildcardType::PathName;
|
} else if radio_name.is_active() {
|
||||||
wildcard = entry_name_path.text().to_string();
|
wildcard_type = WildcardType::Name;
|
||||||
|
wildcard = entry_name.text().to_string();
|
||||||
|
} else if radio_name_path.is_active() {
|
||||||
|
wildcard_type = WildcardType::PathName;
|
||||||
|
wildcard = entry_name_path.text().to_string();
|
||||||
|
} else {
|
||||||
|
panic!("Non handled option in wildcard");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !wildcard.is_empty() {
|
||||||
|
let wildcard = wildcard.trim();
|
||||||
|
|
||||||
|
#[cfg(target_family = "windows")]
|
||||||
|
let wildcard = wildcard.replace("/", "\\");
|
||||||
|
#[cfg(target_family = "windows")]
|
||||||
|
let wildcard = wildcard.as_str();
|
||||||
|
|
||||||
|
let model = get_list_store(&tree_view);
|
||||||
|
|
||||||
|
let iter = model.iter_first().unwrap(); // Never should be available button where there is no available records
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if let Some(column_color) = column_color {
|
||||||
|
let color = model.value(&iter, column_color).get::<String>().unwrap();
|
||||||
|
if color == HEADER_ROW_COLOR {
|
||||||
|
if !model.iter_next(&iter) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = model.value(&iter, column_path).get::<String>().unwrap();
|
||||||
|
let name = model.value(&iter, column_file_name).get::<String>().unwrap();
|
||||||
|
match wildcard_type {
|
||||||
|
WildcardType::Path => {
|
||||||
|
if Common::regex_check(wildcard, path) {
|
||||||
|
model.set_value(&iter, column_button_selection, &select_things.to_value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WildcardType::Name => {
|
||||||
|
if Common::regex_check(wildcard, name) {
|
||||||
|
model.set_value(&iter, column_button_selection, &select_things.to_value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WildcardType::PathName => {
|
||||||
|
if Common::regex_check(wildcard, format!("{}/{}", path, name)) {
|
||||||
|
model.set_value(&iter, column_button_selection, &select_things.to_value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !model.iter_next(&iter) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("Non handled option in wildcard");
|
confirmation_dialog_delete.close();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
confirmation_dialog_delete.close();
|
confirmation_dialog_delete.close();
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
confirmation_dialog_delete.close();
|
|
||||||
}
|
|
||||||
if !wildcard.is_empty() {
|
|
||||||
let wildcard = wildcard.trim();
|
|
||||||
|
|
||||||
#[cfg(target_family = "windows")]
|
|
||||||
let wildcard = wildcard.replace("/", "\\");
|
|
||||||
#[cfg(target_family = "windows")]
|
|
||||||
let wildcard = wildcard.as_str();
|
|
||||||
|
|
||||||
let model = get_list_store(tree_view);
|
|
||||||
|
|
||||||
let iter = model.iter_first().unwrap(); // Never should be available button where there is no available records
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if let Some(column_color) = column_color {
|
|
||||||
let color = model.value(&iter, column_color).get::<String>().unwrap();
|
|
||||||
if color == HEADER_ROW_COLOR {
|
|
||||||
if !model.iter_next(&iter) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = model.value(&iter, column_path).get::<String>().unwrap();
|
|
||||||
let name = model.value(&iter, column_file_name).get::<String>().unwrap();
|
|
||||||
match wildcard_type {
|
|
||||||
WildcardType::Path => {
|
|
||||||
if Common::regex_check(wildcard, path) {
|
|
||||||
model.set_value(&iter, column_button_selection, &select_things.to_value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WildcardType::Name => {
|
|
||||||
if Common::regex_check(wildcard, name) {
|
|
||||||
model.set_value(&iter, column_button_selection, &select_things.to_value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WildcardType::PathName => {
|
|
||||||
if Common::regex_check(wildcard, format!("{}/{}", path, name)) {
|
|
||||||
model.set_value(&iter, column_button_selection, &select_things.to_value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !model.iter_next(&iter) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,18 +80,21 @@ fn add_chosen_directories(window_main: &Window, tree_view: &TreeView, excluded_i
|
||||||
let chooser = gtk::FileChooserDialog::with_buttons(Some(folders_to), Some(window_main), gtk::FileChooserAction::SelectFolder, &[("Ok", gtk::ResponseType::Ok), ("Close", gtk::ResponseType::Cancel)]);
|
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.set_select_multiple(true);
|
||||||
chooser.show_all();
|
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);
|
let tree_view = tree_view.clone();
|
||||||
|
chooser.connect_response(move |chooser, response_type| {
|
||||||
|
if response_type == gtk::ResponseType::Ok {
|
||||||
|
let folder = chooser.filenames();
|
||||||
|
|
||||||
for file_entry in &folder {
|
let list_store = get_list_store(&tree_view);
|
||||||
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &file_entry.to_string_lossy().to_string())];
|
|
||||||
list_store.set(&list_store.append(), &values);
|
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();
|
||||||
chooser.close();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_manually_directories(window_main: &Window, tree_view: &TreeView) {
|
fn add_manually_directories(window_main: &Window, tree_view: &TreeView) {
|
||||||
|
@ -105,22 +108,24 @@ fn add_manually_directories(window_main: &Window, tree_view: &TreeView) {
|
||||||
|
|
||||||
dialog_manual_add_directory.show_all();
|
dialog_manual_add_directory.show_all();
|
||||||
|
|
||||||
let response_type = dialog_manual_add_directory.run();
|
let tree_view = tree_view.clone();
|
||||||
if response_type == gtk::ResponseType::Ok {
|
dialog_manual_add_directory.connect_response(move |dialog_manual_add_directory, response_type| {
|
||||||
let text = entry.text().to_string().trim().to_string();
|
if response_type == gtk::ResponseType::Ok {
|
||||||
|
let text = entry.text().to_string().trim().to_string();
|
||||||
|
|
||||||
#[cfg(target_family = "windows")]
|
#[cfg(target_family = "windows")]
|
||||||
let text = Common::normalize_windows_path(text).to_string_lossy().to_string();
|
let text = Common::normalize_windows_path(text).to_string_lossy().to_string();
|
||||||
|
|
||||||
if !text.is_empty() {
|
if !text.is_empty() {
|
||||||
let list_store = get_list_store(tree_view);
|
let list_store = get_list_store(&tree_view);
|
||||||
|
|
||||||
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &text)];
|
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &text)];
|
||||||
list_store.set(&list_store.append(), &values);
|
list_store.set(&list_store.append(), &values);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dialog_manual_add_directory.close();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
dialog_manual_add_directory.close();
|
dialog_manual_add_directory.close();
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
dialog_manual_add_directory.close();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,14 @@ pub fn connect_settings(gui_data: &GuiData) {
|
||||||
let window_main = gui_data.window_main.clone();
|
let window_main = gui_data.window_main.clone();
|
||||||
let window_settings = gui_data.settings.window_settings.clone();
|
let window_settings = gui_data.settings.window_settings.clone();
|
||||||
button_settings.connect_clicked(move |_| {
|
button_settings.connect_clicked(move |_| {
|
||||||
|
window_main.set_position(WindowPosition::Center);
|
||||||
window_main.set_sensitive(false);
|
window_main.set_sensitive(false);
|
||||||
window_settings.show();
|
window_settings.show();
|
||||||
window_settings.set_position(WindowPosition::Center);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let window_main = gui_data.window_main.clone();
|
let window_main = gui_data.window_main.clone();
|
||||||
let window_settings = gui_data.settings.window_settings.clone();
|
let window_settings = gui_data.settings.window_settings.clone();
|
||||||
|
|
||||||
window_settings.hide_on_delete();
|
|
||||||
|
|
||||||
window_settings.connect_delete_event(move |window, _y| {
|
window_settings.connect_delete_event(move |window, _y| {
|
||||||
window.hide();
|
window.hide();
|
||||||
window_main.set_sensitive(true);
|
window_main.set_sensitive(true);
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub fn create_tree_view_duplicates(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsDuplicates::SelectionButton as i32)
|
.value(&iter, ColumnsDuplicates::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsDuplicates::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsDuplicates::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -69,7 +69,7 @@ pub fn create_tree_view_empty_folders(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsEmptyFolders::SelectionButton as i32)
|
.value(&iter, ColumnsEmptyFolders::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsEmptyFolders::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsEmptyFolders::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -119,7 +119,7 @@ pub fn create_tree_view_big_files(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsBigFiles::SelectionButton as i32)
|
.value(&iter, ColumnsBigFiles::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsBigFiles::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsBigFiles::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -178,7 +178,7 @@ pub fn create_tree_view_temporary_files(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsTemporaryFiles::SelectionButton as i32)
|
.value(&iter, ColumnsTemporaryFiles::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsTemporaryFiles::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsTemporaryFiles::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -228,7 +228,7 @@ pub fn create_tree_view_empty_files(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsEmptyFiles::SelectionButton as i32)
|
.value(&iter, ColumnsEmptyFiles::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsEmptyFiles::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsEmptyFiles::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -278,7 +278,7 @@ pub fn create_tree_view_similar_images(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsSimilarImages::SelectionButton as i32)
|
.value(&iter, ColumnsSimilarImages::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsSimilarImages::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsSimilarImages::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -369,7 +369,7 @@ pub fn create_tree_view_similar_videos(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsSimilarVideos::SelectionButton as i32)
|
.value(&iter, ColumnsSimilarVideos::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsSimilarVideos::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsSimilarVideos::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -448,7 +448,7 @@ pub fn create_tree_view_same_music(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsSameMusic::SelectionButton as i32)
|
.value(&iter, ColumnsSameMusic::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsSameMusic::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsSameMusic::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -572,7 +572,7 @@ pub fn create_tree_view_invalid_symlinks(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsInvalidSymlinks::SelectionButton as i32)
|
.value(&iter, ColumnsInvalidSymlinks::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsInvalidSymlinks::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsInvalidSymlinks::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
@ -640,7 +640,7 @@ pub fn create_tree_view_broken_files(tree_view: &mut gtk::TreeView) {
|
||||||
let mut fixed = model
|
let mut fixed = model
|
||||||
.value(&iter, ColumnsBrokenFiles::SelectionButton as i32)
|
.value(&iter, ColumnsBrokenFiles::SelectionButton as i32)
|
||||||
.get::<bool>()
|
.get::<bool>()
|
||||||
.unwrap_or_else(|err| panic!("ListStore value missing at path {}: {}", path, err));
|
.unwrap_or_else(|err| panic!("ListStore value missing at path {:?}: {}", path, err));
|
||||||
fixed = !fixed;
|
fixed = !fixed;
|
||||||
model.set_value(&iter, ColumnsBrokenFiles::SelectionButton as u32, &fixed.to_value());
|
model.set_value(&iter, ColumnsBrokenFiles::SelectionButton as u32, &fixed.to_value());
|
||||||
});
|
});
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub struct GuiData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiData {
|
impl GuiData {
|
||||||
pub fn new() -> Self {
|
pub fn new_with_application(application: >k::Application) -> Self {
|
||||||
//// Loading glade file content and build with it help UI
|
//// Loading glade file content and build with it help UI
|
||||||
let glade_src = include_str!("../ui/main_window.glade").to_string();
|
let glade_src = include_str!("../ui/main_window.glade").to_string();
|
||||||
let builder = Builder::from_string(glade_src.as_str());
|
let builder = Builder::from_string(glade_src.as_str());
|
||||||
|
@ -87,15 +87,16 @@ impl GuiData {
|
||||||
window_main.show_all();
|
window_main.show_all();
|
||||||
window_main.set_title("Czkawka");
|
window_main.set_title("Czkawka");
|
||||||
window_main.set_position(WindowPosition::Center);
|
window_main.set_position(WindowPosition::Center);
|
||||||
|
window_main.set_application(Some(application));
|
||||||
|
|
||||||
let main_notebook = GuiMainNotebook::create_from_builder(&builder);
|
let main_notebook = GuiMainNotebook::create_from_builder(&builder);
|
||||||
let upper_notebook = GuiUpperNotebook::create_from_builder(&builder);
|
let upper_notebook = GuiUpperNotebook::create_from_builder(&builder);
|
||||||
let popovers = GuiPopovers::create_from_builder();
|
let popovers = GuiPopovers::create_from_builder();
|
||||||
let bottom_buttons = GuiBottomButtons::create_from_builder(&builder);
|
let bottom_buttons = GuiBottomButtons::create_from_builder(&builder);
|
||||||
let progress_window = GuiProgressDialog::create_from_builder();
|
let progress_window = GuiProgressDialog::create_from_builder(&window_main);
|
||||||
let about = GuiAbout::create_from_builder();
|
let about = GuiAbout::create_from_builder();
|
||||||
let header = GuiHeader::create_from_builder(&builder);
|
let header = GuiHeader::create_from_builder(&builder);
|
||||||
let settings = GuiSettings::create_from_builder();
|
let settings = GuiSettings::create_from_builder(&window_main);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::Builder;
|
use gtk::{Builder, Window};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GuiProgressDialog {
|
pub struct GuiProgressDialog {
|
||||||
|
@ -16,11 +16,13 @@ pub struct GuiProgressDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiProgressDialog {
|
impl GuiProgressDialog {
|
||||||
pub fn create_from_builder() -> Self {
|
pub fn create_from_builder(window_main: &Window) -> Self {
|
||||||
let glade_src = include_str!("../ui/progress.glade").to_string();
|
let glade_src = include_str!("../ui/progress.glade").to_string();
|
||||||
let builder = Builder::from_string(glade_src.as_str());
|
let builder = Builder::from_string(glade_src.as_str());
|
||||||
|
|
||||||
let window_progress: gtk::Window = builder.object("window_progress").unwrap();
|
let window_progress: gtk::Window = builder.object("window_progress").unwrap();
|
||||||
|
window_progress.set_transient_for(Some(window_main));
|
||||||
|
window_progress.set_modal(true);
|
||||||
|
|
||||||
let progress_bar_current_stage: gtk::ProgressBar = builder.object("progress_bar_current_stage").unwrap();
|
let progress_bar_current_stage: gtk::ProgressBar = builder.object("progress_bar_current_stage").unwrap();
|
||||||
let progress_bar_all_stages: gtk::ProgressBar = builder.object("progress_bar_all_stages").unwrap();
|
let progress_bar_all_stages: gtk::ProgressBar = builder.object("progress_bar_all_stages").unwrap();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{Builder, WindowPosition};
|
use gtk::{Builder, Window};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GuiSettings {
|
pub struct GuiSettings {
|
||||||
|
@ -29,12 +29,13 @@ pub struct GuiSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiSettings {
|
impl GuiSettings {
|
||||||
pub fn create_from_builder() -> Self {
|
pub fn create_from_builder(window_main: &Window) -> Self {
|
||||||
let glade_src = include_str!("../ui/settings.glade").to_string();
|
let glade_src = include_str!("../ui/settings.glade").to_string();
|
||||||
let builder = Builder::from_string(glade_src.as_str());
|
let builder = Builder::from_string(glade_src.as_str());
|
||||||
|
|
||||||
let window_settings: gtk::Window = builder.object("window_settings").unwrap();
|
let window_settings: gtk::Window = builder.object("window_settings").unwrap();
|
||||||
window_settings.set_position(WindowPosition::Center);
|
window_settings.set_modal(true);
|
||||||
|
window_settings.set_transient_for(Some(window_main));
|
||||||
|
|
||||||
// General
|
// General
|
||||||
let check_button_settings_save_at_exit: gtk::CheckButton = builder.object("check_button_settings_save_at_exit").unwrap();
|
let check_button_settings_save_at_exit: gtk::CheckButton = builder.object("check_button_settings_save_at_exit").unwrap();
|
||||||
|
|
|
@ -400,7 +400,7 @@ pub fn get_list_store(tree_view: >k::TreeView) -> ListStore {
|
||||||
tree_view.model().unwrap().downcast::<gtk::ListStore>().unwrap()
|
tree_view.model().unwrap().downcast::<gtk::ListStore>().unwrap()
|
||||||
}
|
}
|
||||||
pub fn get_dialog_box_child(dialog: >k::Dialog) -> gtk::Box {
|
pub fn get_dialog_box_child(dialog: >k::Dialog) -> gtk::Box {
|
||||||
dialog.children()[0].clone().downcast::<gtk::Box>().unwrap()
|
dialog.child().unwrap().downcast::<gtk::Box>().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_dimension_to_krotka(dimensions: String) -> (u64, u64) {
|
pub fn change_dimension_to_krotka(dimensions: String) -> (u64, u64) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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::connect_button_delete::{basic_remove, empty_folder_remover};
|
||||||
use crate::create_tree_view::*;
|
use crate::create_tree_view::*;
|
||||||
|
use crate::delete_things;
|
||||||
use crate::gui_data::*;
|
use crate::gui_data::*;
|
||||||
use crate::help_functions::*;
|
use crate::help_functions::*;
|
||||||
use crate::notebook_enums::NotebookMainEnum;
|
use crate::notebook_enums::NotebookMainEnum;
|
||||||
|
@ -122,49 +123,17 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
|
||||||
scrolled_window_duplicate_finder.add(&tree_view);
|
scrolled_window_duplicate_finder.add(&tree_view);
|
||||||
scrolled_window_duplicate_finder.show_all();
|
scrolled_window_duplicate_finder.show_all();
|
||||||
|
|
||||||
let text_view_errors_cloned = text_view_errors.clone();
|
let gui_data_clone = 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| {
|
tree_view.connect_key_release_event(move |tree_view, e| {
|
||||||
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
|
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::Duplicate as usize];
|
||||||
if let Some(button_number) = e.keycode() {
|
if let Some(button_number) = e.keycode() {
|
||||||
// Handle delete button
|
// Handle delete button
|
||||||
if button_number == KEY_DELETE {
|
if button_number == KEY_DELETE {
|
||||||
if tree_view.selection().selected_rows().0.is_empty() {
|
glib::MainContext::default().spawn_local(delete_things(gui_data_clone.clone()));
|
||||||
return gtk::Inhibit(false);
|
|
||||||
}
|
|
||||||
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) {
|
|
||||||
return gtk::Inhibit(false);
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
show_preview(
|
show_preview(tree_view, &text_view_errors, &check_button_settings_show_preview_duplicates, &image_preview_duplicates, nb_object.column_path, nb_object.column_name);
|
||||||
tree_view,
|
|
||||||
&text_view_errors_cloned,
|
|
||||||
&check_button_settings_show_preview_duplicates,
|
|
||||||
&image_preview_duplicates,
|
|
||||||
nb_object.column_path,
|
|
||||||
nb_object.column_name,
|
|
||||||
);
|
|
||||||
gtk::Inhibit(false)
|
gtk::Inhibit(false)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -298,7 +267,6 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
|
||||||
}
|
}
|
||||||
// Similar Images
|
// Similar Images
|
||||||
{
|
{
|
||||||
let image_preview_similar_images_clone = image_preview_similar_images.clone();
|
|
||||||
image_preview_similar_images.hide();
|
image_preview_similar_images.hide();
|
||||||
|
|
||||||
let col_types: [glib::types::Type; 12] = [
|
let col_types: [glib::types::Type; 12] = [
|
||||||
|
@ -345,39 +313,16 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
|
||||||
scrolled_window_similar_images_finder.add(&tree_view);
|
scrolled_window_similar_images_finder.add(&tree_view);
|
||||||
scrolled_window_similar_images_finder.show_all();
|
scrolled_window_similar_images_finder.show_all();
|
||||||
|
|
||||||
let image_preview_similar_images = image_preview_similar_images_clone.clone();
|
let image_preview_similar_images = gui_data.main_notebook.image_preview_similar_images.clone();
|
||||||
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 = gui_data.settings.check_button_settings_show_preview_similar_images.clone();
|
||||||
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
|
let gui_data_clone = gui_data.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();
|
let text_view_errors = gui_data.text_view_errors.clone();
|
||||||
tree_view.connect_key_release_event(move |tree_view, e| {
|
tree_view.connect_key_release_event(move |tree_view, e| {
|
||||||
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
|
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarImages as usize];
|
||||||
if let Some(button_number) = e.keycode() {
|
if let Some(button_number) = e.keycode() {
|
||||||
// Handle delete button
|
// Handle delete button
|
||||||
if button_number == KEY_DELETE {
|
if button_number == KEY_DELETE {
|
||||||
if tree_view.selection().selected_rows().0.is_empty() {
|
glib::MainContext::default().spawn_local(delete_things(gui_data_clone.clone()));
|
||||||
return gtk::Inhibit(false);
|
|
||||||
}
|
|
||||||
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) {
|
|
||||||
return gtk::Inhibit(false);
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
show_preview(
|
show_preview(
|
||||||
|
@ -422,36 +367,12 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
|
||||||
scrolled_window_similar_videos_finder.add(&tree_view);
|
scrolled_window_similar_videos_finder.add(&tree_view);
|
||||||
scrolled_window_similar_videos_finder.show_all();
|
scrolled_window_similar_videos_finder.show_all();
|
||||||
|
|
||||||
let check_button_settings_confirm_deletion = gui_data.settings.check_button_settings_confirm_deletion.clone();
|
let gui_data_clone = gui_data.clone();
|
||||||
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
|
tree_view.connect_key_release_event(move |_tree_view, e| {
|
||||||
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() {
|
if let Some(button_number) = e.keycode() {
|
||||||
// Handle delete button
|
// Handle delete button
|
||||||
if button_number == KEY_DELETE {
|
if button_number == KEY_DELETE {
|
||||||
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SimilarVideos as usize];
|
glib::MainContext::default().spawn_local(delete_things(gui_data_clone.clone()));
|
||||||
if tree_view.selection().selected_rows().0.is_empty() {
|
|
||||||
return gtk::Inhibit(false);
|
|
||||||
}
|
|
||||||
if !check_if_can_delete_files(&check_button_settings_confirm_deletion, &window_main) {
|
|
||||||
return gtk::Inhibit(false);
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gtk::Inhibit(false)
|
gtk::Inhibit(false)
|
||||||
|
@ -493,36 +414,12 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
|
||||||
scrolled_window_same_music_finder.add(&tree_view);
|
scrolled_window_same_music_finder.add(&tree_view);
|
||||||
scrolled_window_same_music_finder.show_all();
|
scrolled_window_same_music_finder.show_all();
|
||||||
|
|
||||||
let check_button_settings_confirm_group_deletion = gui_data.settings.check_button_settings_confirm_group_deletion.clone();
|
let gui_data_clone = gui_data.clone();
|
||||||
let window_main = gui_data.window_main.clone();
|
tree_view.connect_key_release_event(move |_tree_view, e| {
|
||||||
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() {
|
if let Some(button_number) = e.keycode() {
|
||||||
// Handle delete button
|
// Handle delete button
|
||||||
if button_number == KEY_DELETE {
|
if button_number == KEY_DELETE {
|
||||||
let nb_object = &NOTEBOOKS_INFOS[NotebookMainEnum::SameMusic as usize];
|
glib::MainContext::default().spawn_local(delete_things(gui_data_clone.clone()));
|
||||||
|
|
||||||
if tree_view.selection().selected_rows().0.is_empty() {
|
|
||||||
return gtk::Inhibit(false);
|
|
||||||
}
|
|
||||||
if !check_if_can_delete_files(&check_button_settings_confirm_group_deletion, &window_main) {
|
|
||||||
return gtk::Inhibit(false);
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gtk::Inhibit(false)
|
gtk::Inhibit(false)
|
||||||
|
@ -678,8 +575,6 @@ pub fn initialize_gui(gui_data: &mut GuiData) {
|
||||||
let window_progress = gui_data.progress_window.window_progress.clone();
|
let window_progress = gui_data.progress_window.window_progress.clone();
|
||||||
let stop_sender = gui_data.stop_sender.clone();
|
let stop_sender = gui_data.stop_sender.clone();
|
||||||
|
|
||||||
window_progress.hide_on_delete();
|
|
||||||
|
|
||||||
window_progress.connect_delete_event(move |_e, _y| {
|
window_progress.connect_delete_event(move |_e, _y| {
|
||||||
stop_sender.send(()).unwrap();
|
stop_sender.send(()).unwrap();
|
||||||
gtk::Inhibit(true)
|
gtk::Inhibit(true)
|
||||||
|
|
|
@ -66,112 +66,89 @@ use crate::initialize_gui::*;
|
||||||
use crate::saving_loading::*;
|
use crate::saving_loading::*;
|
||||||
use crate::tests::validate_notebook_data;
|
use crate::tests::validate_notebook_data;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use std::{env, process};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut exit_program_after_initialization: bool = false;
|
let application = gtk::Application::builder().application_id("com.github.qarmin").build();
|
||||||
// Printing version
|
application.connect_activate(|application| {
|
||||||
{
|
let mut gui_data: GuiData = GuiData::new_with_application(application);
|
||||||
let all_arguments: Vec<String> = env::args().skip(1).collect(); // Not need to check program name
|
|
||||||
|
|
||||||
for i in all_arguments {
|
// Used for getting data from thread
|
||||||
if i == "-v" || i == "--version" {
|
let (glib_stop_sender, glib_stop_receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
||||||
println!("Czkawka GUI {}", CZKAWKA_VERSION);
|
|
||||||
process::exit(0);
|
|
||||||
}
|
|
||||||
if i == "-q" || i == "--quit" {
|
|
||||||
exit_program_after_initialization = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk::init().expect("Failed to initialize GTK.");
|
// Futures progress report
|
||||||
|
let (futures_sender_duplicate_files, futures_receiver_duplicate_files): (futures::channel::mpsc::UnboundedSender<duplicate::ProgressData>, futures::channel::mpsc::UnboundedReceiver<duplicate::ProgressData>) =
|
||||||
|
futures::channel::mpsc::unbounded();
|
||||||
|
let (futures_sender_empty_files, futures_receiver_empty_files): (futures::channel::mpsc::UnboundedSender<empty_files::ProgressData>, futures::channel::mpsc::UnboundedReceiver<empty_files::ProgressData>) = futures::channel::mpsc::unbounded();
|
||||||
|
let (futures_sender_empty_folder, futures_receiver_empty_folder): (futures::channel::mpsc::UnboundedSender<empty_folder::ProgressData>, futures::channel::mpsc::UnboundedReceiver<empty_folder::ProgressData>) =
|
||||||
|
futures::channel::mpsc::unbounded();
|
||||||
|
let (futures_sender_big_file, futures_receiver_big_file): (futures::channel::mpsc::UnboundedSender<big_file::ProgressData>, futures::channel::mpsc::UnboundedReceiver<big_file::ProgressData>) = futures::channel::mpsc::unbounded();
|
||||||
|
let (futures_sender_same_music, futures_receiver_same_music): (futures::channel::mpsc::UnboundedSender<same_music::ProgressData>, futures::channel::mpsc::UnboundedReceiver<same_music::ProgressData>) = futures::channel::mpsc::unbounded();
|
||||||
|
let (futures_sender_similar_images, futures_receiver_similar_images): (futures::channel::mpsc::UnboundedSender<similar_images::ProgressData>, futures::channel::mpsc::UnboundedReceiver<similar_images::ProgressData>) =
|
||||||
|
futures::channel::mpsc::unbounded();
|
||||||
|
let (futures_sender_similar_videos, futures_receiver_similar_videos): (futures::channel::mpsc::UnboundedSender<similar_videos::ProgressData>, futures::channel::mpsc::UnboundedReceiver<similar_videos::ProgressData>) =
|
||||||
|
futures::channel::mpsc::unbounded();
|
||||||
|
let (futures_sender_temporary, futures_receiver_temporary): (futures::channel::mpsc::UnboundedSender<temporary::ProgressData>, futures::channel::mpsc::UnboundedReceiver<temporary::ProgressData>) = futures::channel::mpsc::unbounded();
|
||||||
|
let (futures_sender_invalid_symlinks, futures_receiver_invalid_symlinks): (futures::channel::mpsc::UnboundedSender<invalid_symlinks::ProgressData>, futures::channel::mpsc::UnboundedReceiver<invalid_symlinks::ProgressData>) =
|
||||||
|
futures::channel::mpsc::unbounded();
|
||||||
|
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();
|
||||||
|
|
||||||
let mut gui_data: GuiData = GuiData::new();
|
initialize_gui(&mut gui_data);
|
||||||
|
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);
|
||||||
|
|
||||||
// Used for getting data from thread
|
connect_button_delete(&gui_data);
|
||||||
let (glib_stop_sender, glib_stop_receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
connect_button_save(&gui_data);
|
||||||
|
connect_button_search(
|
||||||
|
&gui_data,
|
||||||
|
glib_stop_sender,
|
||||||
|
futures_sender_duplicate_files,
|
||||||
|
futures_sender_empty_files,
|
||||||
|
futures_sender_empty_folder,
|
||||||
|
futures_sender_big_file,
|
||||||
|
futures_sender_same_music,
|
||||||
|
futures_sender_similar_images,
|
||||||
|
futures_sender_similar_videos,
|
||||||
|
futures_sender_temporary,
|
||||||
|
futures_sender_invalid_symlinks,
|
||||||
|
futures_sender_broken_files,
|
||||||
|
);
|
||||||
|
connect_button_select(&gui_data);
|
||||||
|
connect_button_stop(&gui_data);
|
||||||
|
connect_button_hardlink_symlink(&gui_data);
|
||||||
|
connect_button_move(&gui_data);
|
||||||
|
connect_notebook_tabs(&gui_data);
|
||||||
|
connect_selection_of_directories(&gui_data);
|
||||||
|
connect_popovers(&gui_data);
|
||||||
|
connect_compute_results(&gui_data, glib_stop_receiver);
|
||||||
|
connect_progress_window(
|
||||||
|
&gui_data,
|
||||||
|
futures_receiver_duplicate_files,
|
||||||
|
futures_receiver_empty_files,
|
||||||
|
futures_receiver_empty_folder,
|
||||||
|
futures_receiver_big_file,
|
||||||
|
futures_receiver_same_music,
|
||||||
|
futures_receiver_similar_images,
|
||||||
|
futures_receiver_similar_videos,
|
||||||
|
futures_receiver_temporary,
|
||||||
|
futures_receiver_invalid_symlinks,
|
||||||
|
futures_receiver_broken_files,
|
||||||
|
);
|
||||||
|
connect_hide_text_view_errors(&gui_data);
|
||||||
|
connect_settings(&gui_data);
|
||||||
|
connect_button_about(&gui_data);
|
||||||
|
connect_about_buttons(&gui_data);
|
||||||
|
connect_similar_image_size_change(&gui_data);
|
||||||
|
|
||||||
// Futures progress report
|
|
||||||
let (futures_sender_duplicate_files, futures_receiver_duplicate_files): (futures::channel::mpsc::UnboundedSender<duplicate::ProgressData>, futures::channel::mpsc::UnboundedReceiver<duplicate::ProgressData>) = futures::channel::mpsc::unbounded();
|
|
||||||
let (futures_sender_empty_files, futures_receiver_empty_files): (futures::channel::mpsc::UnboundedSender<empty_files::ProgressData>, futures::channel::mpsc::UnboundedReceiver<empty_files::ProgressData>) = futures::channel::mpsc::unbounded();
|
|
||||||
let (futures_sender_empty_folder, futures_receiver_empty_folder): (futures::channel::mpsc::UnboundedSender<empty_folder::ProgressData>, futures::channel::mpsc::UnboundedReceiver<empty_folder::ProgressData>) = futures::channel::mpsc::unbounded();
|
|
||||||
let (futures_sender_big_file, futures_receiver_big_file): (futures::channel::mpsc::UnboundedSender<big_file::ProgressData>, futures::channel::mpsc::UnboundedReceiver<big_file::ProgressData>) = futures::channel::mpsc::unbounded();
|
|
||||||
let (futures_sender_same_music, futures_receiver_same_music): (futures::channel::mpsc::UnboundedSender<same_music::ProgressData>, futures::channel::mpsc::UnboundedReceiver<same_music::ProgressData>) = futures::channel::mpsc::unbounded();
|
|
||||||
let (futures_sender_similar_images, futures_receiver_similar_images): (futures::channel::mpsc::UnboundedSender<similar_images::ProgressData>, futures::channel::mpsc::UnboundedReceiver<similar_images::ProgressData>) =
|
|
||||||
futures::channel::mpsc::unbounded();
|
|
||||||
let (futures_sender_similar_videos, futures_receiver_similar_videos): (futures::channel::mpsc::UnboundedSender<similar_videos::ProgressData>, futures::channel::mpsc::UnboundedReceiver<similar_videos::ProgressData>) =
|
|
||||||
futures::channel::mpsc::unbounded();
|
|
||||||
let (futures_sender_temporary, futures_receiver_temporary): (futures::channel::mpsc::UnboundedSender<temporary::ProgressData>, futures::channel::mpsc::UnboundedReceiver<temporary::ProgressData>) = futures::channel::mpsc::unbounded();
|
|
||||||
let (futures_sender_invalid_symlinks, futures_receiver_invalid_symlinks): (futures::channel::mpsc::UnboundedSender<invalid_symlinks::ProgressData>, futures::channel::mpsc::UnboundedReceiver<invalid_symlinks::ProgressData>) =
|
|
||||||
futures::channel::mpsc::unbounded();
|
|
||||||
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);
|
|
||||||
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);
|
|
||||||
connect_button_search(
|
|
||||||
&gui_data,
|
|
||||||
glib_stop_sender,
|
|
||||||
futures_sender_duplicate_files,
|
|
||||||
futures_sender_empty_files,
|
|
||||||
futures_sender_empty_folder,
|
|
||||||
futures_sender_big_file,
|
|
||||||
futures_sender_same_music,
|
|
||||||
futures_sender_similar_images,
|
|
||||||
futures_sender_similar_videos,
|
|
||||||
futures_sender_temporary,
|
|
||||||
futures_sender_invalid_symlinks,
|
|
||||||
futures_sender_broken_files,
|
|
||||||
);
|
|
||||||
connect_button_select(&gui_data);
|
|
||||||
connect_button_stop(&gui_data);
|
|
||||||
connect_button_hardlink_symlink(&gui_data);
|
|
||||||
connect_button_move(&gui_data);
|
|
||||||
connect_notebook_tabs(&gui_data);
|
|
||||||
connect_selection_of_directories(&gui_data);
|
|
||||||
connect_popovers(&gui_data);
|
|
||||||
connect_compute_results(&gui_data, glib_stop_receiver);
|
|
||||||
connect_progress_window(
|
|
||||||
&gui_data,
|
|
||||||
futures_receiver_duplicate_files,
|
|
||||||
futures_receiver_empty_files,
|
|
||||||
futures_receiver_empty_folder,
|
|
||||||
futures_receiver_big_file,
|
|
||||||
futures_receiver_same_music,
|
|
||||||
futures_receiver_similar_images,
|
|
||||||
futures_receiver_similar_videos,
|
|
||||||
futures_receiver_temporary,
|
|
||||||
futures_receiver_invalid_symlinks,
|
|
||||||
futures_receiver_broken_files,
|
|
||||||
);
|
|
||||||
connect_hide_text_view_errors(&gui_data);
|
|
||||||
connect_settings(&gui_data);
|
|
||||||
connect_button_about(&gui_data);
|
|
||||||
connect_about_buttons(&gui_data);
|
|
||||||
connect_similar_image_size_change(&gui_data);
|
|
||||||
|
|
||||||
// Quit the program when X in main window was clicked
|
|
||||||
{
|
|
||||||
let window_main = gui_data.window_main.clone();
|
let window_main = gui_data.window_main.clone();
|
||||||
let taskbar_state = gui_data.taskbar_state.clone();
|
let taskbar_state = gui_data.taskbar_state.clone();
|
||||||
window_main.connect_delete_event(move |_, _| {
|
window_main.connect_delete_event(move |_, _| {
|
||||||
save_configuration(false, &gui_data.upper_notebook, &gui_data.settings, &gui_data.text_view_errors); // 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();
|
taskbar_state.borrow_mut().release();
|
||||||
Inhibit(false)
|
Inhibit(false)
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
// We start the gtk main loop.
|
application.run();
|
||||||
gtk::main();
|
|
||||||
|
|
||||||
// Quiting if quit flag was provided
|
|
||||||
if exit_program_after_initialization {
|
|
||||||
gtk::main_quit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,7 +456,7 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb
|
||||||
list_store.clear();
|
list_store.clear();
|
||||||
|
|
||||||
for directory in included_directories {
|
for directory in included_directories {
|
||||||
let values: [(u32, &dyn ToValue); 1] = [(0, &directory)];
|
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &directory)];
|
||||||
list_store.set(&list_store.append(), &values);
|
list_store.set(&list_store.append(), &values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +466,7 @@ pub fn load_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb
|
||||||
list_store.clear();
|
list_store.clear();
|
||||||
|
|
||||||
for directory in excluded_directories {
|
for directory in excluded_directories {
|
||||||
let values: [(u32, &dyn ToValue); 1] = [(0, &directory)];
|
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &directory)];
|
||||||
list_store.set(&list_store.append(), &values);
|
list_store.set(&list_store.append(), &values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +535,7 @@ pub fn reset_configuration(manual_clearing: bool, upper_notebook: &GuiUpperNoteb
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let values: [(u32, &dyn ToValue); 1] = [(0, ¤t_dir)];
|
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, ¤t_dir)];
|
||||||
list_store.set(&list_store.append(), &values);
|
list_store.set(&list_store.append(), &values);
|
||||||
}
|
}
|
||||||
// Resetting excluded directories
|
// Resetting excluded directories
|
||||||
|
@ -545,7 +545,7 @@ pub fn reset_configuration(manual_clearing: bool, upper_notebook: &GuiUpperNoteb
|
||||||
list_store.clear();
|
list_store.clear();
|
||||||
if cfg!(target_family = "unix") {
|
if cfg!(target_family = "unix") {
|
||||||
for i in ["/proc", "/dev", "/sys", "/run", "/snap"].iter() {
|
for i in ["/proc", "/dev", "/sys", "/run", "/snap"].iter() {
|
||||||
let values: [(u32, &dyn ToValue); 1] = [(0, &i)];
|
let values: [(u32, &dyn ToValue); 1] = [(ColumnsDirectory::Path as u32, &i)];
|
||||||
list_store.set(&list_store.append(), &values);
|
list_store.set(&list_store.append(), &values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue