Basic sorting
This commit is contained in:
parent
cf7cbbcff6
commit
021759b685
|
@ -1,3 +1,12 @@
|
|||
## Version 5.1.0 - ?.?.2023r
|
||||
- Added sort button - [](https://github.com/qarmin/czkawka/pull/?)
|
||||
- Allow to set number of thread used to scan -
|
||||
- Use FileChooserNative instead FileChooserDialog -
|
||||
- Fix invalid music tags in music files when using reference folders -
|
||||
- Updated pdf dependency - broken pdf will be
|
||||
- Changed strange PDF error message - "Try at" -
|
||||
- Improve thumbnail quality -
|
||||
|
||||
## Version 5.0.2 - 30.08.2022r
|
||||
- Fixed problem with missing some similar images when using similarity > 0 - [#799](https://github.com/qarmin/czkawka/pull/799)
|
||||
- Prebuilt Linux binaries are compiled without heif support - [24b](https://github.com/qarmin/czkawka/commit/24b64a32c65904c506b54270f0977ccbe5098cc8)
|
||||
|
|
|
@ -188,7 +188,7 @@ fn create_dialog_group_deletion(window_main: >k4::Window) -> (Dialog, CheckBut
|
|||
|
||||
let label: gtk4::Label = gtk4::Label::new(Some(&flg!("delete_all_files_in_group_label1")));
|
||||
let label2: gtk4::Label = gtk4::Label::new(Some(&flg!("delete_all_files_in_group_label2")));
|
||||
let check_button: CheckButton = CheckButton::builder().label(&flg!("dialogs_ask_next_time")).active(true).halign(Align::Center).build();
|
||||
let check_button: CheckButton = CheckButton::builder().label(flg!("dialogs_ask_next_time")).active(true).halign(Align::Center).build();
|
||||
|
||||
button_ok.grab_focus();
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ fn create_dialog_ask_for_linking(window_main: >k4::Window) -> (Dialog, CheckBu
|
|||
dialog.add_button(&flg!("general_close_button"), ResponseType::Cancel);
|
||||
|
||||
let label: gtk4::Label = gtk4::Label::new(Some(&flg!("hard_sym_link_label")));
|
||||
let check_button: CheckButton = CheckButton::builder().label(&flg!("dialogs_ask_next_time")).active(true).halign(Align::Center).build();
|
||||
let check_button: CheckButton = CheckButton::builder().label(flg!("dialogs_ask_next_time")).active(true).halign(Align::Center).build();
|
||||
|
||||
button_ok.grab_focus();
|
||||
|
||||
|
|
|
@ -594,7 +594,7 @@ fn popover_all_except_biggest_smallest(
|
|||
popover.popdown();
|
||||
}
|
||||
|
||||
pub fn connect_popovers(gui_data: &GuiData) {
|
||||
pub fn connect_popover_select(gui_data: &GuiData) {
|
||||
let popover_select = gui_data.popovers_select.popover_select.clone();
|
||||
let buttons_popover_select_all = gui_data.popovers_select.buttons_popover_select_all.clone();
|
||||
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
||||
|
|
174
czkawka_gui/src/connect_things/connect_popovers_sort.rs
Normal file
174
czkawka_gui/src/connect_things/connect_popovers_sort.rs
Normal file
|
@ -0,0 +1,174 @@
|
|||
use gtk4::prelude::*;
|
||||
use gtk4::{ListStore, TreeIter};
|
||||
|
||||
use crate::gui_structs::gui_data::GuiData;
|
||||
use crate::help_functions::*;
|
||||
use crate::notebook_info::NOTEBOOKS_INFO;
|
||||
|
||||
fn popover_sort_general<T>(popover: >k4::Popover, tree_view: >k4::TreeView, column_sort: i32, column_header: i32)
|
||||
where
|
||||
T: Ord + for<'b> glib::value::FromValue<'b> + 'static + std::fmt::Debug,
|
||||
{
|
||||
let model = get_list_store(tree_view);
|
||||
|
||||
if let Some(curr_iter) = model.iter_first() {
|
||||
assert!(model.get::<bool>(&curr_iter, column_header));
|
||||
assert!(model.iter_next(&curr_iter)); // Must be at least one item
|
||||
loop {
|
||||
let mut iters = Vec::new();
|
||||
let mut all_have = false;
|
||||
loop {
|
||||
if model.get::<bool>(&curr_iter, column_header) {
|
||||
assert!(model.iter_next(&curr_iter), "Empty header, this should not happens");
|
||||
break;
|
||||
}
|
||||
iters.push(curr_iter);
|
||||
if !model.iter_next(&curr_iter) {
|
||||
all_have = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if iters.len() == 1 {
|
||||
continue; // Can be equal 1 in reference folders
|
||||
}
|
||||
|
||||
sort_iters::<T>(&model, iters, column_sort);
|
||||
if all_have {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
popover.popdown();
|
||||
}
|
||||
|
||||
fn sort_iters<T>(model: &ListStore, mut iters: Vec<TreeIter>, column_sort: i32)
|
||||
where
|
||||
T: Ord + for<'b> glib::value::FromValue<'b> + 'static,
|
||||
{
|
||||
assert!(iters.len() >= 2);
|
||||
loop {
|
||||
let mut changed_item = false;
|
||||
for idx in 0..(iters.len() - 1) {
|
||||
if model.get::<T>(&iters[idx], column_sort) > model.get::<T>(&iters[idx + 1], column_sort) {
|
||||
model.swap(&iters[idx], &iters[idx + 1]);
|
||||
iters.swap(idx, idx + 1);
|
||||
changed_item = true;
|
||||
}
|
||||
}
|
||||
if !changed_item {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect_popover_sort(gui_data: &GuiData) {
|
||||
let popover_sort = gui_data.popovers_sort.popover_sort.clone();
|
||||
let buttons_popover_file_name = gui_data.popovers_sort.buttons_popover_sort_file_name.clone();
|
||||
let notebook_main = gui_data.main_notebook.notebook_main.clone();
|
||||
let main_tree_views = gui_data.main_notebook.get_main_tree_views();
|
||||
|
||||
buttons_popover_file_name.connect_clicked(move |_| {
|
||||
let nb_number = notebook_main.current_page().unwrap();
|
||||
let tree_view = &main_tree_views[nb_number as usize];
|
||||
let nb_object = &NOTEBOOKS_INFO[nb_number as usize];
|
||||
|
||||
popover_sort_general::<String>(&popover_sort, tree_view, nb_object.column_name, nb_object.column_header.unwrap());
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::connect_things::connect_popovers_sort::{popover_sort_general, sort_iters};
|
||||
use gtk4::prelude::*;
|
||||
use gtk4::{Popover, TreeView};
|
||||
|
||||
#[gtk4::test]
|
||||
fn test_sort_iters() {
|
||||
let columns_types: &[glib::types::Type] = &[glib::types::Type::U32, glib::types::Type::STRING];
|
||||
let list_store = gtk4::ListStore::new(columns_types);
|
||||
|
||||
let values_to_add: &[&[(u32, &dyn ToValue)]] = &[&[(0, &2), (1, &"AAA")], &[(0, &3), (1, &"CCC")], &[(0, &1), (1, &"BBB")]];
|
||||
for i in values_to_add {
|
||||
list_store.set(&list_store.append(), i);
|
||||
}
|
||||
let mut iters = Vec::new();
|
||||
let iter = list_store.iter_first().unwrap();
|
||||
iters.push(iter.clone());
|
||||
list_store.iter_next(&iter);
|
||||
iters.push(iter.clone());
|
||||
list_store.iter_next(&iter);
|
||||
iters.push(iter.clone());
|
||||
|
||||
sort_iters::<String>(&list_store, iters, 1);
|
||||
|
||||
let first = list_store.iter_first().unwrap();
|
||||
let second = first.clone();
|
||||
list_store.iter_next(&second);
|
||||
let third = second.clone();
|
||||
list_store.iter_next(&third);
|
||||
|
||||
assert_eq!(list_store.get::<String>(&first, 1), "AAA");
|
||||
assert_eq!(list_store.get::<String>(&second, 1), "BBB");
|
||||
assert_eq!(list_store.get::<String>(&third, 1), "CCC");
|
||||
|
||||
assert_eq!(list_store.get::<u32>(&first, 0), 2);
|
||||
assert_eq!(list_store.get::<u32>(&second, 0), 1);
|
||||
assert_eq!(list_store.get::<u32>(&third, 0), 3);
|
||||
}
|
||||
|
||||
#[gtk4::test]
|
||||
pub fn test_popover_sort_general_simple() {
|
||||
let columns_types: &[glib::types::Type] = &[glib::types::Type::BOOL, glib::types::Type::STRING];
|
||||
let list_store = gtk4::ListStore::new(columns_types);
|
||||
let tree_view = TreeView::builder().model(&list_store).build();
|
||||
let popover = Popover::new();
|
||||
|
||||
let values_to_add: &[&[(u32, &dyn ToValue)]] = &[&[(0, &true), (1, &"DDD")], &[(0, &false), (1, &"CCC")], &[(0, &false), (1, &"BBB")]];
|
||||
for i in values_to_add {
|
||||
list_store.set(&list_store.append(), i);
|
||||
}
|
||||
|
||||
popover_sort_general::<String>(&popover, &tree_view, 1, 0);
|
||||
|
||||
let expected = ["DDD", "BBB", "CCC"];
|
||||
let curr_iter = list_store.iter_first().unwrap();
|
||||
for exp in expected {
|
||||
let real = list_store.get::<String>(&curr_iter, 1);
|
||||
assert_eq!(real, exp);
|
||||
list_store.iter_next(&curr_iter);
|
||||
}
|
||||
}
|
||||
|
||||
#[gtk4::test]
|
||||
pub fn test_popover_sort_general() {
|
||||
let columns_types: &[glib::types::Type] = &[glib::types::Type::BOOL, glib::types::Type::STRING];
|
||||
let list_store = gtk4::ListStore::new(columns_types);
|
||||
let tree_view = TreeView::builder().model(&list_store).build();
|
||||
let popover = Popover::new();
|
||||
|
||||
let values_to_add: &[&[(u32, &dyn ToValue)]] = &[
|
||||
&[(0, &true), (1, &"AAA")],
|
||||
&[(0, &false), (1, &"CCC")],
|
||||
&[(0, &false), (1, &"BBB")],
|
||||
&[(0, &true), (1, &"TTT")],
|
||||
&[(0, &false), (1, &"PPP")],
|
||||
&[(0, &false), (1, &"AAA")],
|
||||
&[(0, &true), (1, &"RRR")],
|
||||
&[(0, &false), (1, &"WWW")],
|
||||
&[(0, &false), (1, &"ZZZ")],
|
||||
];
|
||||
for i in values_to_add {
|
||||
list_store.set(&list_store.append(), i);
|
||||
}
|
||||
|
||||
popover_sort_general::<String>(&popover, &tree_view, 1, 0);
|
||||
|
||||
let expected = ["AAA", "BBB", "CCC", "TTT", "AAA", "PPP", "RRR", "WWW", "ZZZ"];
|
||||
let curr_iter = list_store.iter_first().unwrap();
|
||||
for exp in expected {
|
||||
let real = list_store.get::<String>(&curr_iter, 1);
|
||||
assert_eq!(real, exp);
|
||||
list_store.iter_next(&curr_iter);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ pub mod connect_duplicate_buttons;
|
|||
pub mod connect_header_buttons;
|
||||
pub mod connect_notebook_tabs;
|
||||
pub mod connect_popovers_select;
|
||||
pub mod connect_popovers_sort;
|
||||
pub mod connect_progress_window;
|
||||
pub mod connect_selection_of_directories;
|
||||
pub mod connect_settings;
|
||||
|
|
|
@ -26,7 +26,6 @@ use connect_things::connect_change_language::*;
|
|||
use connect_things::connect_duplicate_buttons::connect_duplicate_combo_box;
|
||||
use connect_things::connect_header_buttons::*;
|
||||
use connect_things::connect_notebook_tabs::*;
|
||||
use connect_things::connect_popovers_select::*;
|
||||
use connect_things::connect_progress_window::*;
|
||||
use connect_things::connect_selection_of_directories::*;
|
||||
use connect_things::connect_settings::*;
|
||||
|
@ -38,6 +37,8 @@ use gui_structs::gui_data::*;
|
|||
|
||||
use crate::compute_results::*;
|
||||
use crate::connect_things::connect_button_sort::connect_button_sort;
|
||||
use crate::connect_things::connect_popovers_select::connect_popover_select;
|
||||
use crate::connect_things::connect_popovers_sort::connect_popover_sort;
|
||||
use crate::initialize_gui::*;
|
||||
use crate::language_functions::LANGUAGES_ALL;
|
||||
use crate::saving_loading::*;
|
||||
|
@ -170,7 +171,8 @@ fn build_ui(application: &Application, arguments: &[OsString]) {
|
|||
connect_duplicate_combo_box(&gui_data);
|
||||
connect_notebook_tabs(&gui_data);
|
||||
connect_selection_of_directories(&gui_data);
|
||||
connect_popovers(&gui_data);
|
||||
connect_popover_select(&gui_data);
|
||||
connect_popover_sort(&gui_data);
|
||||
connect_compute_results(&gui_data, glib_stop_receiver);
|
||||
connect_progress_window(
|
||||
&gui_data,
|
||||
|
|
Loading…
Reference in a new issue