2022-06-01 03:52:55 +12:00
|
|
|
use std::cell::RefCell;
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
use gdk4::gdk_pixbuf::{InterpType, Pixbuf};
|
|
|
|
use gtk4::prelude::*;
|
2022-06-09 07:42:51 +12:00
|
|
|
use gtk4::{Align, CheckButton, Image, ListStore, Orientation, ScrolledWindow, TreeIter, TreeModel, TreePath, TreeSelection, Widget};
|
|
|
|
use image::DynamicImage;
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-07-25 06:48:02 +12:00
|
|
|
#[cfg(feature = "heif")]
|
|
|
|
use czkawka_core::common::get_dynamic_image_from_heic;
|
|
|
|
use czkawka_core::common::HEIC_EXTENSIONS;
|
|
|
|
|
2022-06-01 03:52:55 +12:00
|
|
|
use crate::flg;
|
2022-01-14 03:58:33 +13:00
|
|
|
use crate::gui_structs::gui_data::GuiData;
|
2022-07-20 05:09:52 +12:00
|
|
|
use crate::help_functions::{
|
|
|
|
count_number_of_groups, get_all_direct_children, get_full_name_from_path_name, get_max_file_name, get_pixbuf_from_dynamic_image, resize_pixbuf_dimension,
|
|
|
|
};
|
2022-01-20 10:35:07 +13:00
|
|
|
use crate::localizer_core::generate_translation_hashmap;
|
2022-06-22 03:24:08 +12:00
|
|
|
use crate::notebook_info::{NotebookObject, NOTEBOOKS_INFO};
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-04-06 02:40:41 +12:00
|
|
|
const BIG_PREVIEW_SIZE: i32 = 600;
|
2022-06-09 07:42:51 +12:00
|
|
|
const SMALL_PREVIEW_SIZE: i32 = 130;
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
pub fn connect_button_compare(gui_data: &GuiData) {
|
|
|
|
let button_compare = gui_data.bottom_buttons.buttons_compare.clone();
|
|
|
|
let window_compare = gui_data.compare_images.window_compare.clone();
|
|
|
|
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
|
|
|
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
|
|
|
|
let scrolled_window_compare_choose_images = gui_data.compare_images.scrolled_window_compare_choose_images.clone();
|
|
|
|
|
|
|
|
let label_group_info = gui_data.compare_images.label_group_info.clone();
|
|
|
|
|
|
|
|
let button_go_previous_compare_group = gui_data.compare_images.button_go_previous_compare_group.clone();
|
|
|
|
let button_go_next_compare_group = gui_data.compare_images.button_go_next_compare_group.clone();
|
|
|
|
|
|
|
|
let check_button_left_preview_text = gui_data.compare_images.check_button_left_preview_text.clone();
|
|
|
|
let check_button_right_preview_text = gui_data.compare_images.check_button_right_preview_text.clone();
|
|
|
|
|
|
|
|
let shared_numbers_of_groups = gui_data.compare_images.shared_numbers_of_groups.clone();
|
|
|
|
let shared_current_of_groups = gui_data.compare_images.shared_current_of_groups.clone();
|
2022-01-17 05:54:44 +13:00
|
|
|
let shared_current_path = gui_data.compare_images.shared_current_path.clone();
|
2022-01-11 00:19:28 +13:00
|
|
|
let shared_image_cache = gui_data.compare_images.shared_image_cache.clone();
|
|
|
|
let shared_using_for_preview = gui_data.compare_images.shared_using_for_preview.clone();
|
|
|
|
|
|
|
|
let image_compare_left = gui_data.compare_images.image_compare_left.clone();
|
|
|
|
let image_compare_right = gui_data.compare_images.image_compare_right.clone();
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
window_compare.set_default_size(700, 700);
|
|
|
|
|
2022-01-11 00:19:28 +13:00
|
|
|
button_compare.connect_clicked(move |_| {
|
|
|
|
let nb_number = notebook_main.current_page().unwrap();
|
|
|
|
let tree_view = &main_tree_views[nb_number as usize];
|
2022-06-22 03:24:08 +12:00
|
|
|
let nb_object = &NOTEBOOKS_INFO[nb_number as usize];
|
2022-01-11 00:19:28 +13:00
|
|
|
let model = tree_view.model().unwrap();
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let group_number = count_number_of_groups(tree_view, nb_object.column_header.unwrap());
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
if group_number == 0 {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check selected items
|
2023-01-29 06:54:02 +13:00
|
|
|
let (current_group, tree_path) = get_current_group_and_iter_from_selection(&model, &tree_view.selection(), nb_object.column_header.unwrap());
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-01-11 06:52:02 +13:00
|
|
|
*shared_current_of_groups.borrow_mut() = current_group;
|
|
|
|
*shared_numbers_of_groups.borrow_mut() = group_number;
|
|
|
|
|
2022-01-11 00:19:28 +13:00
|
|
|
populate_groups_at_start(
|
|
|
|
nb_object,
|
|
|
|
&model,
|
2023-01-29 06:54:02 +13:00
|
|
|
&shared_current_path,
|
2022-01-17 05:54:44 +13:00
|
|
|
tree_path,
|
2022-01-11 00:19:28 +13:00
|
|
|
&image_compare_left,
|
|
|
|
&image_compare_right,
|
|
|
|
current_group,
|
|
|
|
group_number,
|
|
|
|
&check_button_left_preview_text,
|
|
|
|
&check_button_right_preview_text,
|
|
|
|
&scrolled_window_compare_choose_images,
|
|
|
|
&label_group_info,
|
2023-01-29 06:54:02 +13:00
|
|
|
&shared_image_cache,
|
|
|
|
&shared_using_for_preview,
|
2022-01-11 06:52:02 +13:00
|
|
|
&button_go_previous_compare_group,
|
|
|
|
&button_go_next_compare_group,
|
2022-01-11 00:19:28 +13:00
|
|
|
);
|
|
|
|
|
|
|
|
window_compare.show();
|
|
|
|
});
|
|
|
|
|
|
|
|
let shared_image_cache = gui_data.compare_images.shared_image_cache.clone();
|
2022-01-17 05:54:44 +13:00
|
|
|
let shared_current_path = gui_data.compare_images.shared_current_path.clone();
|
2022-01-11 00:19:28 +13:00
|
|
|
let shared_using_for_preview = gui_data.compare_images.shared_using_for_preview.clone();
|
|
|
|
let shared_current_of_groups = gui_data.compare_images.shared_current_of_groups.clone();
|
|
|
|
let shared_numbers_of_groups = gui_data.compare_images.shared_numbers_of_groups.clone();
|
|
|
|
let window_compare = gui_data.compare_images.window_compare.clone();
|
|
|
|
let image_compare_left = gui_data.compare_images.image_compare_left.clone();
|
|
|
|
let image_compare_right = gui_data.compare_images.image_compare_right.clone();
|
2022-05-22 20:59:09 +12:00
|
|
|
window_compare.connect_close_request(move |window_compare| {
|
2022-01-11 00:19:28 +13:00
|
|
|
window_compare.hide();
|
|
|
|
*shared_image_cache.borrow_mut() = Vec::new();
|
2022-01-17 05:54:44 +13:00
|
|
|
*shared_current_path.borrow_mut() = None;
|
2022-01-11 00:19:28 +13:00
|
|
|
*shared_current_of_groups.borrow_mut() = 0;
|
|
|
|
*shared_numbers_of_groups.borrow_mut() = 0;
|
|
|
|
*shared_using_for_preview.borrow_mut() = (None, None);
|
|
|
|
image_compare_left.set_from_pixbuf(None);
|
|
|
|
image_compare_right.set_from_pixbuf(None);
|
2023-10-05 19:06:47 +13:00
|
|
|
glib::Propagation::Stop
|
2022-01-11 00:19:28 +13:00
|
|
|
});
|
|
|
|
|
|
|
|
let button_go_previous_compare_group = gui_data.compare_images.button_go_previous_compare_group.clone();
|
|
|
|
let button_go_next_compare_group = gui_data.compare_images.button_go_next_compare_group.clone();
|
|
|
|
let label_group_info = gui_data.compare_images.label_group_info.clone();
|
|
|
|
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
|
|
|
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
|
|
|
|
let scrolled_window_compare_choose_images = gui_data.compare_images.scrolled_window_compare_choose_images.clone();
|
|
|
|
|
|
|
|
let check_button_left_preview_text = gui_data.compare_images.check_button_left_preview_text.clone();
|
|
|
|
let check_button_right_preview_text = gui_data.compare_images.check_button_right_preview_text.clone();
|
|
|
|
|
|
|
|
let shared_current_of_groups = gui_data.compare_images.shared_current_of_groups.clone();
|
|
|
|
let shared_numbers_of_groups = gui_data.compare_images.shared_numbers_of_groups.clone();
|
2022-01-17 05:54:44 +13:00
|
|
|
let shared_current_path = gui_data.compare_images.shared_current_path.clone();
|
2022-01-11 00:19:28 +13:00
|
|
|
let shared_image_cache = gui_data.compare_images.shared_image_cache.clone();
|
|
|
|
let shared_using_for_preview = gui_data.compare_images.shared_using_for_preview.clone();
|
|
|
|
|
|
|
|
let image_compare_left = gui_data.compare_images.image_compare_left.clone();
|
|
|
|
let image_compare_right = gui_data.compare_images.image_compare_right.clone();
|
|
|
|
|
|
|
|
button_go_previous_compare_group.connect_clicked(move |button_go_previous_compare_group| {
|
|
|
|
let nb_number = notebook_main.current_page().unwrap();
|
|
|
|
let tree_view = &main_tree_views[nb_number as usize];
|
2022-06-22 03:24:08 +12:00
|
|
|
let nb_object = &NOTEBOOKS_INFO[nb_number as usize];
|
2022-01-11 00:19:28 +13:00
|
|
|
let model = tree_view.model().unwrap();
|
|
|
|
|
|
|
|
*shared_current_of_groups.borrow_mut() -= 1;
|
|
|
|
|
|
|
|
let current_group = *shared_current_of_groups.borrow();
|
|
|
|
let group_number = *shared_numbers_of_groups.borrow();
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let tree_path = move_iter(&model, shared_current_path.borrow().as_ref().unwrap(), nb_object.column_header.unwrap(), false);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
populate_groups_at_start(
|
|
|
|
nb_object,
|
|
|
|
&model,
|
2023-01-29 06:54:02 +13:00
|
|
|
&shared_current_path,
|
2022-02-02 05:08:41 +13:00
|
|
|
tree_path,
|
2022-01-11 00:19:28 +13:00
|
|
|
&image_compare_left,
|
|
|
|
&image_compare_right,
|
|
|
|
current_group,
|
|
|
|
group_number,
|
|
|
|
&check_button_left_preview_text,
|
|
|
|
&check_button_right_preview_text,
|
|
|
|
&scrolled_window_compare_choose_images,
|
|
|
|
&label_group_info,
|
2023-01-29 06:54:02 +13:00
|
|
|
&shared_image_cache,
|
|
|
|
&shared_using_for_preview,
|
2022-01-11 06:52:02 +13:00
|
|
|
button_go_previous_compare_group,
|
|
|
|
&button_go_next_compare_group,
|
2022-01-11 00:19:28 +13:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
let button_go_previous_compare_group = gui_data.compare_images.button_go_previous_compare_group.clone();
|
|
|
|
let button_go_next_compare_group = gui_data.compare_images.button_go_next_compare_group.clone();
|
|
|
|
let label_group_info = gui_data.compare_images.label_group_info.clone();
|
|
|
|
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
|
|
|
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
|
|
|
|
let scrolled_window_compare_choose_images = gui_data.compare_images.scrolled_window_compare_choose_images.clone();
|
|
|
|
|
|
|
|
let check_button_left_preview_text = gui_data.compare_images.check_button_left_preview_text.clone();
|
|
|
|
let check_button_right_preview_text = gui_data.compare_images.check_button_right_preview_text.clone();
|
|
|
|
|
|
|
|
let shared_current_of_groups = gui_data.compare_images.shared_current_of_groups.clone();
|
|
|
|
let shared_numbers_of_groups = gui_data.compare_images.shared_numbers_of_groups.clone();
|
2022-01-17 05:54:44 +13:00
|
|
|
let shared_current_path = gui_data.compare_images.shared_current_path.clone();
|
2022-01-11 00:19:28 +13:00
|
|
|
let shared_image_cache = gui_data.compare_images.shared_image_cache.clone();
|
|
|
|
let shared_using_for_preview = gui_data.compare_images.shared_using_for_preview.clone();
|
|
|
|
|
|
|
|
let image_compare_left = gui_data.compare_images.image_compare_left.clone();
|
|
|
|
let image_compare_right = gui_data.compare_images.image_compare_right.clone();
|
|
|
|
|
|
|
|
button_go_next_compare_group.connect_clicked(move |button_go_next_compare_group| {
|
|
|
|
let nb_number = notebook_main.current_page().unwrap();
|
|
|
|
let tree_view = &main_tree_views[nb_number as usize];
|
2022-06-22 03:24:08 +12:00
|
|
|
let nb_object = &NOTEBOOKS_INFO[nb_number as usize];
|
2022-01-11 00:19:28 +13:00
|
|
|
let model = tree_view.model().unwrap();
|
|
|
|
|
|
|
|
*shared_current_of_groups.borrow_mut() += 1;
|
|
|
|
|
|
|
|
let current_group = *shared_current_of_groups.borrow();
|
|
|
|
let group_number = *shared_numbers_of_groups.borrow();
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let tree_path = move_iter(&model, shared_current_path.borrow().as_ref().unwrap(), nb_object.column_header.unwrap(), true);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
populate_groups_at_start(
|
|
|
|
nb_object,
|
|
|
|
&model,
|
2023-01-29 06:54:02 +13:00
|
|
|
&shared_current_path,
|
2022-01-17 05:54:44 +13:00
|
|
|
tree_path,
|
2022-01-11 00:19:28 +13:00
|
|
|
&image_compare_left,
|
|
|
|
&image_compare_right,
|
|
|
|
current_group,
|
|
|
|
group_number,
|
|
|
|
&check_button_left_preview_text,
|
|
|
|
&check_button_right_preview_text,
|
|
|
|
&scrolled_window_compare_choose_images,
|
|
|
|
&label_group_info,
|
2023-01-29 06:54:02 +13:00
|
|
|
&shared_image_cache,
|
|
|
|
&shared_using_for_preview,
|
2022-01-11 06:52:02 +13:00
|
|
|
&button_go_previous_compare_group,
|
|
|
|
button_go_next_compare_group,
|
2022-01-11 00:19:28 +13:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
let check_button_left_preview_text = gui_data.compare_images.check_button_left_preview_text.clone();
|
|
|
|
let shared_using_for_preview = gui_data.compare_images.shared_using_for_preview.clone();
|
|
|
|
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
2022-01-17 05:54:44 +13:00
|
|
|
let shared_current_path = gui_data.compare_images.shared_current_path.clone();
|
2022-01-11 00:19:28 +13:00
|
|
|
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
|
2022-05-22 20:59:09 +12:00
|
|
|
check_button_left_preview_text.connect_toggled(move |check_button_left_preview_text| {
|
2022-01-11 00:19:28 +13:00
|
|
|
let nb_number = notebook_main.current_page().unwrap();
|
|
|
|
let tree_view = &main_tree_views[nb_number as usize];
|
2022-06-22 03:24:08 +12:00
|
|
|
let nb_object = &NOTEBOOKS_INFO[nb_number as usize];
|
2022-01-11 00:19:28 +13:00
|
|
|
let model = tree_view.model().unwrap().downcast::<ListStore>().unwrap();
|
|
|
|
|
2022-01-17 05:54:44 +13:00
|
|
|
let main_tree_path = shared_current_path.borrow().as_ref().unwrap().clone();
|
2022-01-11 00:19:28 +13:00
|
|
|
let this_tree_path = shared_using_for_preview.borrow().0.clone().unwrap();
|
|
|
|
if main_tree_path == this_tree_path {
|
|
|
|
return; // Selected header, so we don't need to select result in treeview
|
|
|
|
// TODO this should be handled by disabling entirely check box
|
|
|
|
}
|
|
|
|
|
|
|
|
let is_active = check_button_left_preview_text.is_active();
|
|
|
|
model.set_value(&model.iter(&this_tree_path).unwrap(), nb_object.column_selection as u32, &is_active.to_value());
|
|
|
|
});
|
|
|
|
|
|
|
|
let check_button_right_preview_text = gui_data.compare_images.check_button_right_preview_text.clone();
|
|
|
|
let shared_using_for_preview = gui_data.compare_images.shared_using_for_preview.clone();
|
2022-01-17 05:54:44 +13:00
|
|
|
let shared_current_path = gui_data.compare_images.shared_current_path.clone();
|
2022-01-11 00:19:28 +13:00
|
|
|
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
|
|
|
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
|
2022-05-22 20:59:09 +12:00
|
|
|
|
|
|
|
check_button_right_preview_text.connect_toggled(move |check_button_right_preview_text| {
|
2022-01-11 00:19:28 +13:00
|
|
|
let nb_number = notebook_main.current_page().unwrap();
|
|
|
|
let tree_view = &main_tree_views[nb_number as usize];
|
2022-06-22 03:24:08 +12:00
|
|
|
let nb_object = &NOTEBOOKS_INFO[nb_number as usize];
|
2022-01-11 00:19:28 +13:00
|
|
|
let model = tree_view.model().unwrap().downcast::<ListStore>().unwrap();
|
|
|
|
|
2022-01-17 05:54:44 +13:00
|
|
|
let main_tree_path = shared_current_path.borrow().as_ref().unwrap().clone();
|
2022-01-11 00:19:28 +13:00
|
|
|
let this_tree_path = shared_using_for_preview.borrow().1.clone().unwrap();
|
|
|
|
if main_tree_path == this_tree_path {
|
|
|
|
return; // Selected header, so we don't need to select result in treeview
|
|
|
|
// TODO this should be handled by disabling entirely check box
|
|
|
|
}
|
|
|
|
|
|
|
|
let is_active = check_button_right_preview_text.is_active();
|
|
|
|
model.set_value(&model.iter(&this_tree_path).unwrap(), nb_object.column_selection as u32, &is_active.to_value());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn populate_groups_at_start(
|
|
|
|
nb_object: &NotebookObject,
|
|
|
|
model: &TreeModel,
|
2023-01-29 06:54:02 +13:00
|
|
|
shared_current_path: &Rc<RefCell<Option<TreePath>>>,
|
2022-01-17 05:54:44 +13:00
|
|
|
tree_path: TreePath,
|
2022-06-01 03:52:55 +12:00
|
|
|
image_compare_left: &Image,
|
|
|
|
image_compare_right: &Image,
|
2022-01-11 00:19:28 +13:00
|
|
|
current_group: u32,
|
|
|
|
group_number: u32,
|
2022-06-01 03:52:55 +12:00
|
|
|
check_button_left_preview_text: &CheckButton,
|
|
|
|
check_button_right_preview_text: &CheckButton,
|
|
|
|
scrolled_window_compare_choose_images: &ScrolledWindow,
|
2022-05-22 20:59:09 +12:00
|
|
|
label_group_info: >k4::Label,
|
2023-01-29 06:54:02 +13:00
|
|
|
shared_image_cache: &Rc<RefCell<Vec<(String, String, Image, Image, TreePath)>>>,
|
|
|
|
shared_using_for_preview: &Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>,
|
2022-05-22 20:59:09 +12:00
|
|
|
button_go_previous_compare_group: >k4::Button,
|
|
|
|
button_go_next_compare_group: >k4::Button,
|
2022-01-11 00:19:28 +13:00
|
|
|
) {
|
2022-01-11 06:52:02 +13:00
|
|
|
if current_group == 1 {
|
|
|
|
button_go_previous_compare_group.set_sensitive(false);
|
|
|
|
} else {
|
|
|
|
button_go_previous_compare_group.set_sensitive(true);
|
|
|
|
}
|
|
|
|
if current_group == group_number {
|
|
|
|
button_go_next_compare_group.set_sensitive(false);
|
|
|
|
} else {
|
|
|
|
button_go_next_compare_group.set_sensitive(true);
|
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let all_vec = get_all_path(model, &tree_path, nb_object.column_header.unwrap(), nb_object.column_path, nb_object.column_name);
|
2022-01-17 05:54:44 +13:00
|
|
|
*shared_current_path.borrow_mut() = Some(tree_path);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
let cache_all_images = generate_cache_for_results(all_vec);
|
|
|
|
|
|
|
|
// This is safe, because cache have at least 2 results
|
2022-05-22 20:59:09 +12:00
|
|
|
image_compare_left.set_paintable(cache_all_images[0].2.paintable().as_ref());
|
|
|
|
image_compare_right.set_paintable(cache_all_images[1].2.paintable().as_ref());
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
*shared_using_for_preview.borrow_mut() = (Some(cache_all_images[0].4.clone()), Some(cache_all_images[1].4.clone()));
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
check_button_left_preview_text.set_label(Some(&format!("1. {}", get_max_file_name(&cache_all_images[0].0, 60))));
|
|
|
|
check_button_right_preview_text.set_label(Some(&format!("2. {}", get_max_file_name(&cache_all_images[1].0, 60))));
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
label_group_info.set_text(
|
2022-01-20 10:35:07 +13:00
|
|
|
flg!(
|
2022-01-11 00:19:28 +13:00
|
|
|
"compare_groups_number",
|
|
|
|
generate_translation_hashmap(vec![
|
|
|
|
("current_group", current_group.to_string()),
|
|
|
|
("all_groups", group_number.to_string()),
|
|
|
|
("images_in_group", cache_all_images.len().to_string())
|
|
|
|
])
|
|
|
|
)
|
|
|
|
.as_str(),
|
|
|
|
);
|
|
|
|
|
|
|
|
populate_similar_scrolled_view(
|
|
|
|
scrolled_window_compare_choose_images,
|
|
|
|
&cache_all_images,
|
|
|
|
image_compare_left,
|
|
|
|
image_compare_right,
|
2023-01-29 06:54:02 +13:00
|
|
|
shared_using_for_preview,
|
|
|
|
shared_image_cache,
|
2022-01-11 00:19:28 +13:00
|
|
|
check_button_left_preview_text,
|
|
|
|
check_button_right_preview_text,
|
|
|
|
model,
|
|
|
|
nb_object.column_selection,
|
|
|
|
);
|
|
|
|
|
|
|
|
*shared_image_cache.borrow_mut() = cache_all_images.clone();
|
|
|
|
|
|
|
|
let mut found = false;
|
2022-07-20 05:09:52 +12:00
|
|
|
for i in get_all_direct_children(&scrolled_window_compare_choose_images.child().unwrap().downcast::<gtk4::Viewport>().unwrap()) {
|
2022-01-11 00:19:28 +13:00
|
|
|
if i.widget_name() == "all_box" {
|
2022-05-22 20:59:09 +12:00
|
|
|
let gtk_box = i.downcast::<gtk4::Box>().unwrap();
|
2022-01-11 00:19:28 +13:00
|
|
|
update_bottom_buttons(>k_box, shared_using_for_preview, shared_image_cache);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert!(found);
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let is_active = model.get::<bool>(&model.iter(&cache_all_images[0].4).unwrap(), nb_object.column_selection);
|
2022-01-11 00:19:28 +13:00
|
|
|
check_button_left_preview_text.set_active(is_active);
|
2022-05-22 20:59:09 +12:00
|
|
|
let is_active = model.get::<bool>(&model.iter(&cache_all_images[1].4).unwrap(), nb_object.column_selection);
|
2022-01-11 00:19:28 +13:00
|
|
|
check_button_right_preview_text.set_active(is_active);
|
|
|
|
}
|
|
|
|
|
2022-06-01 03:52:55 +12:00
|
|
|
fn generate_cache_for_results(vector_with_path: Vec<(String, String, TreePath)>) -> Vec<(String, String, Image, Image, TreePath)> {
|
2022-01-11 00:19:28 +13:00
|
|
|
// TODO use here threads,
|
|
|
|
// For now threads cannot be used because Image and TreeIter cannot be used in threads
|
|
|
|
let mut cache_all_images = Vec::new();
|
|
|
|
for (full_path, name, tree_path) in vector_with_path {
|
2022-06-01 03:52:55 +12:00
|
|
|
let small_img = Image::new();
|
|
|
|
let big_img = Image::new();
|
2022-04-06 02:40:41 +12:00
|
|
|
|
2022-06-09 07:42:51 +12:00
|
|
|
let mut pixbuf = get_pixbuf_from_dynamic_image(&DynamicImage::new_rgb8(1, 1)).unwrap();
|
2023-12-17 11:21:09 +13:00
|
|
|
let extension_lowercase = full_path.split('.').last().map(str::to_lowercase);
|
|
|
|
let is_heic = match extension_lowercase {
|
|
|
|
Some(extension) => HEIC_EXTENSIONS.iter().any(|e| e == &extension),
|
|
|
|
None => false,
|
|
|
|
};
|
2022-06-09 07:42:51 +12:00
|
|
|
|
2023-02-27 05:28:21 +13:00
|
|
|
if is_heic {
|
2022-06-09 07:42:51 +12:00
|
|
|
#[allow(clippy::never_loop)]
|
|
|
|
'czystka: loop {
|
|
|
|
#[cfg(feature = "heif")]
|
|
|
|
if is_heic {
|
|
|
|
match get_dynamic_image_from_heic(&full_path) {
|
|
|
|
Ok(t) => {
|
|
|
|
match get_pixbuf_from_dynamic_image(&t) {
|
|
|
|
Ok(t) => {
|
|
|
|
pixbuf = t;
|
|
|
|
}
|
|
|
|
Err(e) => {
|
2023-01-29 06:54:02 +13:00
|
|
|
println!("Failed to open image {full_path}, reason {e}");
|
2022-06-09 07:42:51 +12:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
Err(e) => {
|
2023-01-29 06:54:02 +13:00
|
|
|
println!("Failed to open image {full_path}, reason {e}");
|
2022-04-06 02:40:41 +12:00
|
|
|
}
|
|
|
|
};
|
2022-06-09 07:42:51 +12:00
|
|
|
break 'czystka;
|
|
|
|
}
|
|
|
|
break 'czystka;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
match Pixbuf::from_file(&full_path) {
|
|
|
|
Ok(t) => {
|
|
|
|
pixbuf = t;
|
|
|
|
}
|
|
|
|
Err(e) => {
|
2022-12-21 20:44:26 +13:00
|
|
|
println!("Failed to open image {full_path}, reason {e}");
|
2022-06-09 07:42:51 +12:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2022-04-06 02:40:41 +12:00
|
|
|
|
2022-06-09 07:42:51 +12:00
|
|
|
#[allow(clippy::never_loop)]
|
|
|
|
loop {
|
2023-04-05 18:08:43 +12:00
|
|
|
let Some(pixbuf_big) = resize_pixbuf_dimension(&pixbuf, (BIG_PREVIEW_SIZE, BIG_PREVIEW_SIZE), InterpType::Bilinear) else {
|
|
|
|
println!("Failed to resize image {full_path}.");
|
|
|
|
break;
|
2022-06-09 07:42:51 +12:00
|
|
|
};
|
2023-04-05 18:08:43 +12:00
|
|
|
let Some(pixbuf_small) = resize_pixbuf_dimension(&pixbuf_big, (SMALL_PREVIEW_SIZE, SMALL_PREVIEW_SIZE), InterpType::Bilinear) else {
|
|
|
|
println!("Failed to resize image {full_path}.");
|
|
|
|
break;
|
2022-06-09 07:42:51 +12:00
|
|
|
};
|
|
|
|
|
|
|
|
big_img.set_from_pixbuf(Some(&pixbuf_big));
|
|
|
|
small_img.set_from_pixbuf(Some(&pixbuf_small));
|
|
|
|
break;
|
|
|
|
}
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
cache_all_images.push((full_path, name, big_img, small_img, tree_path));
|
|
|
|
}
|
|
|
|
cache_all_images
|
|
|
|
}
|
|
|
|
|
2022-06-01 03:52:55 +12:00
|
|
|
fn get_all_path(model: &TreeModel, current_path: &TreePath, column_header: i32, column_path: i32, column_name: i32) -> Vec<(String, String, TreePath)> {
|
2022-01-17 05:54:44 +13:00
|
|
|
let used_iter = model.iter(current_path).unwrap();
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
assert!(model.get::<bool>(&used_iter, column_header));
|
|
|
|
let using_reference = !model.get::<String>(&used_iter, column_path).is_empty();
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
let mut returned_vector = Vec::new();
|
|
|
|
|
|
|
|
if using_reference {
|
2022-05-22 20:59:09 +12:00
|
|
|
let name = model.get::<String>(&used_iter, column_name);
|
|
|
|
let path = model.get::<String>(&used_iter, column_path);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
let full_name = get_full_name_from_path_name(&path, &name);
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
returned_vector.push((full_name, name, model.path(&used_iter)));
|
2022-01-11 00:19:28 +13:00
|
|
|
}
|
|
|
|
|
2023-01-29 06:54:02 +13:00
|
|
|
assert!(model.iter_next(&used_iter), "Found only header!");
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
loop {
|
2022-05-22 20:59:09 +12:00
|
|
|
let name = model.get::<String>(&used_iter, column_name);
|
|
|
|
let path = model.get::<String>(&used_iter, column_path);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
let full_name = get_full_name_from_path_name(&path, &name);
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
returned_vector.push((full_name, name, model.path(&used_iter)));
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
if !model.iter_next(&used_iter) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
if model.get::<bool>(&used_iter, column_header) {
|
2022-01-11 00:19:28 +13:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert!(returned_vector.len() > 1);
|
|
|
|
|
|
|
|
returned_vector
|
|
|
|
}
|
|
|
|
|
2022-06-01 03:52:55 +12:00
|
|
|
fn move_iter(model: &TreeModel, tree_path: &TreePath, column_header: i32, go_next: bool) -> TreePath {
|
2022-01-17 05:54:44 +13:00
|
|
|
let tree_iter = model.iter(tree_path).unwrap();
|
2022-02-02 05:08:41 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
assert!(model.get::<bool>(&tree_iter, column_header));
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
if go_next {
|
2023-01-29 06:54:02 +13:00
|
|
|
assert!(model.iter_next(&tree_iter), "Found only header!");
|
2022-01-11 00:19:28 +13:00
|
|
|
} else {
|
2023-01-29 06:54:02 +13:00
|
|
|
assert!(model.iter_previous(&tree_iter), "Found only header!");
|
2022-01-11 00:19:28 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
loop {
|
|
|
|
if go_next {
|
2022-01-17 05:54:44 +13:00
|
|
|
if !model.iter_next(&tree_iter) {
|
2022-01-11 00:19:28 +13:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
2022-01-17 05:54:44 +13:00
|
|
|
if !model.iter_previous(&tree_iter) {
|
2022-01-11 00:19:28 +13:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
if model.get::<bool>(&tree_iter, column_header) {
|
2022-01-11 00:19:28 +13:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-05-22 20:59:09 +12:00
|
|
|
model.path(&tree_iter)
|
2022-01-11 00:19:28 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
fn populate_similar_scrolled_view(
|
|
|
|
scrolled_window: &ScrolledWindow,
|
|
|
|
image_cache: &[(String, String, Image, Image, TreePath)],
|
|
|
|
image_compare_left: &Image,
|
|
|
|
image_compare_right: &Image,
|
2023-01-29 06:54:02 +13:00
|
|
|
shared_using_for_preview: &Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>,
|
|
|
|
shared_image_cache: &Rc<RefCell<Vec<(String, String, Image, Image, TreePath)>>>,
|
2022-01-11 00:19:28 +13:00
|
|
|
check_button_left_preview_text: &CheckButton,
|
|
|
|
check_button_right_preview_text: &CheckButton,
|
|
|
|
model: &TreeModel,
|
|
|
|
column_selection: i32,
|
|
|
|
) {
|
2022-05-22 20:59:09 +12:00
|
|
|
scrolled_window.set_child(None::<&Widget>);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let all_gtk_box = gtk4::Box::new(Orientation::Horizontal, 5);
|
2022-01-11 00:19:28 +13:00
|
|
|
all_gtk_box.set_widget_name("all_box");
|
2022-06-09 07:42:51 +12:00
|
|
|
all_gtk_box.set_halign(Align::Fill);
|
|
|
|
all_gtk_box.set_valign(Align::Fill);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
for (number, (path, _name, big_thumbnail, small_thumbnail, tree_path)) in image_cache.iter().enumerate() {
|
2022-05-22 20:59:09 +12:00
|
|
|
let small_box = gtk4::Box::new(Orientation::Vertical, 3);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let smaller_box = gtk4::Box::new(Orientation::Horizontal, 2);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let button_left = gtk4::Button::builder().label(&flg!("compare_move_left_button")).build();
|
|
|
|
let label = gtk4::Label::builder().label(&(number + 1).to_string()).build();
|
|
|
|
let button_right = gtk4::Button::builder().label(&flg!("compare_move_right_button")).build();
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
let image_compare_left = image_compare_left.clone();
|
|
|
|
let image_compare_right = image_compare_right.clone();
|
|
|
|
|
|
|
|
let big_thumbnail_clone = big_thumbnail.clone();
|
|
|
|
let tree_path_clone = tree_path.clone();
|
|
|
|
let all_gtk_box_clone = all_gtk_box.clone();
|
|
|
|
let shared_using_for_preview_clone = shared_using_for_preview.clone();
|
|
|
|
let shared_image_cache_clone = shared_image_cache.clone();
|
|
|
|
let check_button_left_preview_text_clone = check_button_left_preview_text.clone();
|
|
|
|
let model_clone = model.clone();
|
|
|
|
let path_clone = path.clone();
|
|
|
|
|
|
|
|
button_left.connect_clicked(move |_button_left| {
|
|
|
|
shared_using_for_preview_clone.borrow_mut().0 = Some(tree_path_clone.clone());
|
2023-01-29 06:54:02 +13:00
|
|
|
update_bottom_buttons(&all_gtk_box_clone, &shared_using_for_preview_clone, &shared_image_cache_clone);
|
2022-05-22 20:59:09 +12:00
|
|
|
image_compare_left.set_paintable(big_thumbnail_clone.paintable().as_ref());
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let is_active = model_clone.get::<bool>(&model_clone.iter(&tree_path_clone).unwrap(), column_selection);
|
2022-01-11 00:19:28 +13:00
|
|
|
check_button_left_preview_text_clone.set_active(is_active);
|
2022-05-22 20:59:09 +12:00
|
|
|
check_button_left_preview_text_clone.set_label(Some(&format!("{}. {}", number + 1, get_max_file_name(&path_clone, 60))));
|
2022-01-11 00:19:28 +13:00
|
|
|
});
|
|
|
|
|
|
|
|
let big_thumbnail_clone = big_thumbnail.clone();
|
|
|
|
let tree_path_clone = tree_path.clone();
|
|
|
|
let all_gtk_box_clone = all_gtk_box.clone();
|
|
|
|
let shared_using_for_preview_clone = shared_using_for_preview.clone();
|
|
|
|
let shared_image_cache_clone = shared_image_cache.clone();
|
|
|
|
let check_button_right_preview_text_clone = check_button_right_preview_text.clone();
|
|
|
|
let model_clone = model.clone();
|
|
|
|
let path_clone = path.clone();
|
|
|
|
|
|
|
|
button_right.connect_clicked(move |_button_right| {
|
|
|
|
shared_using_for_preview_clone.borrow_mut().1 = Some(tree_path_clone.clone());
|
2023-01-29 06:54:02 +13:00
|
|
|
update_bottom_buttons(&all_gtk_box_clone, &shared_using_for_preview_clone, &shared_image_cache_clone);
|
2022-05-22 20:59:09 +12:00
|
|
|
image_compare_right.set_paintable(big_thumbnail_clone.paintable().as_ref());
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let is_active = model_clone.get::<bool>(&model_clone.iter(&tree_path_clone).unwrap(), column_selection);
|
2022-01-11 00:19:28 +13:00
|
|
|
check_button_right_preview_text_clone.set_active(is_active);
|
2022-05-22 20:59:09 +12:00
|
|
|
check_button_right_preview_text_clone.set_label(Some(&format!("{}. {}", number + 1, get_max_file_name(&path_clone, 60))));
|
2022-01-11 00:19:28 +13:00
|
|
|
});
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
smaller_box.append(&button_left);
|
|
|
|
smaller_box.append(&label);
|
|
|
|
smaller_box.append(&button_right);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
small_box.append(&smaller_box);
|
2022-06-09 07:42:51 +12:00
|
|
|
small_box.set_halign(Align::Fill);
|
|
|
|
small_box.set_valign(Align::Fill);
|
|
|
|
small_box.set_hexpand_set(true);
|
|
|
|
small_box.set_vexpand_set(true);
|
|
|
|
small_thumbnail.set_halign(Align::Fill);
|
|
|
|
small_thumbnail.set_valign(Align::Fill);
|
|
|
|
small_thumbnail.set_hexpand(true);
|
|
|
|
small_thumbnail.set_hexpand_set(true);
|
|
|
|
small_thumbnail.set_vexpand(true);
|
|
|
|
small_thumbnail.set_vexpand_set(true);
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
small_box.append(small_thumbnail);
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
all_gtk_box.append(&small_box);
|
2022-01-11 00:19:28 +13:00
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
all_gtk_box.show();
|
|
|
|
scrolled_window.set_child(Some(&all_gtk_box));
|
2022-01-11 00:19:28 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
fn update_bottom_buttons(
|
2022-05-22 20:59:09 +12:00
|
|
|
all_gtk_box: >k4::Box,
|
2023-01-29 06:54:02 +13:00
|
|
|
shared_using_for_preview: &Rc<RefCell<(Option<TreePath>, Option<TreePath>)>>,
|
|
|
|
image_cache: &Rc<RefCell<Vec<(String, String, Image, Image, TreePath)>>>,
|
2022-01-11 00:19:28 +13:00
|
|
|
) {
|
2022-07-25 06:48:02 +12:00
|
|
|
let left_tree_view = (shared_using_for_preview.borrow()).0.clone().unwrap();
|
|
|
|
let right_tree_view = (shared_using_for_preview.borrow()).1.clone().unwrap();
|
2022-01-11 00:19:28 +13:00
|
|
|
|
2022-07-20 05:09:52 +12:00
|
|
|
for (number, i) in get_all_direct_children(all_gtk_box).into_iter().enumerate() {
|
2022-01-11 00:19:28 +13:00
|
|
|
let cache_tree_path = (*image_cache.borrow())[number].4.clone();
|
|
|
|
let is_chosen = cache_tree_path != right_tree_view && cache_tree_path != left_tree_view;
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
let bx = i.downcast::<gtk4::Box>().unwrap();
|
2022-12-07 20:18:30 +13:00
|
|
|
let smaller_bx = bx.first_child().unwrap().downcast::<gtk4::Box>().unwrap();
|
2022-07-20 05:09:52 +12:00
|
|
|
for items in get_all_direct_children(&smaller_bx) {
|
2022-05-22 20:59:09 +12:00
|
|
|
if let Ok(btn) = items.downcast::<gtk4::Button>() {
|
2022-01-11 00:19:28 +13:00
|
|
|
btn.set_sensitive(is_chosen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-29 06:54:02 +13:00
|
|
|
fn get_current_group_and_iter_from_selection(model: &TreeModel, selection: &TreeSelection, column_header: i32) -> (u32, TreePath) {
|
2022-01-11 00:19:28 +13:00
|
|
|
let mut current_group = 1;
|
|
|
|
let mut possible_group = 1;
|
|
|
|
let mut header_clone: TreeIter;
|
|
|
|
let mut possible_header: TreeIter;
|
|
|
|
|
|
|
|
let selected_records = selection.selected_rows().0;
|
|
|
|
|
|
|
|
let iter = model.iter_first().unwrap(); // Checking that treeview is not empty should be done before
|
2022-02-02 05:08:41 +13:00
|
|
|
header_clone = iter; // if nothing selected, use first group
|
|
|
|
possible_header = iter; // if nothing selected, use first group
|
2022-05-22 20:59:09 +12:00
|
|
|
assert!(model.get::<bool>(&iter, column_header)); // First element should be header
|
2022-01-11 00:19:28 +13:00
|
|
|
|
|
|
|
if !selected_records.is_empty() {
|
|
|
|
let first_selected_record = selected_records[0].clone();
|
|
|
|
loop {
|
|
|
|
if !model.iter_next(&iter) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
if model.get::<bool>(&iter, column_header) {
|
2022-01-11 00:19:28 +13:00
|
|
|
possible_group += 1;
|
2022-02-02 05:08:41 +13:00
|
|
|
possible_header = iter;
|
2022-01-11 00:19:28 +13:00
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
if model.path(&iter) == first_selected_record {
|
2022-02-02 05:08:41 +13:00
|
|
|
header_clone = possible_header;
|
2022-01-11 00:19:28 +13:00
|
|
|
current_group = possible_group;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-22 20:59:09 +12:00
|
|
|
(current_group, model.path(&header_clone))
|
2022-01-11 00:19:28 +13:00
|
|
|
}
|