2021-11-28 08:49:20 +13:00
use std ::path ::{ Path , PathBuf } ;
use gtk ::prelude ::* ;
2021-12-01 01:53:04 +13:00
use gtk ::{ ResponseType , TreePath } ;
2021-11-28 08:49:20 +13:00
2021-11-20 20:32:28 +13:00
use crate ::gui_data ::GuiData ;
use crate ::help_functions ::* ;
use crate ::notebook_enums ::* ;
pub fn connect_button_move ( gui_data : & GuiData ) {
let buttons_move = gui_data . bottom_buttons . buttons_move . clone ( ) ;
let notebook_main = gui_data . main_notebook . notebook_main . clone ( ) ;
2021-11-25 20:36:49 +13:00
let main_tree_views = gui_data . main_notebook . get_main_tree_views ( ) ;
2021-11-20 20:32:28 +13:00
let image_preview_similar_images = gui_data . main_notebook . image_preview_similar_images . clone ( ) ;
2021-11-25 20:36:49 +13:00
let image_preview_duplicates = gui_data . main_notebook . image_preview_duplicates . clone ( ) ;
2021-11-20 20:32:28 +13:00
2021-11-25 20:36:49 +13:00
let entry_info = gui_data . entry_info . clone ( ) ;
let text_view_errors = gui_data . text_view_errors . clone ( ) ;
let window_main = gui_data . window_main . clone ( ) ;
buttons_move . 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_INFOS [ nb_number as usize ] ;
move_things (
tree_view ,
nb_object . column_name ,
nb_object . column_path ,
nb_object . column_color ,
nb_object . column_selection ,
& entry_info ,
& text_view_errors ,
& window_main ,
) ;
match & nb_object . notebook_type {
NotebookMainEnum ::SimilarImages = > {
image_preview_similar_images . hide ( ) ;
}
NotebookMainEnum ::Duplicate = > {
image_preview_duplicates . hide ( ) ;
}
_ = > { }
2021-11-20 20:32:28 +13:00
}
} ) ;
}
2021-11-25 20:36:49 +13:00
// TODO add progress bar
fn move_things ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , column_color : Option < i32 > , column_selection : i32 , entry_info : & gtk ::Entry , text_view_errors : & gtk ::TextView , window_main : & gtk ::Window ) {
reset_text_view ( text_view_errors ) ;
2021-11-20 20:32:28 +13:00
2021-12-01 01:53:04 +13:00
let chooser = gtk ::FileChooserDialog ::builder ( )
. title ( " Choose folder to which you want to move duplicated files " )
. action ( gtk ::FileChooserAction ::SelectFolder )
2021-12-01 23:09:47 +13:00
. transient_for ( window_main )
2021-12-01 01:53:04 +13:00
. build ( ) ;
chooser . add_button ( " Ok " , ResponseType ::Ok ) ;
chooser . add_button ( " Close " , ResponseType ::Cancel ) ;
2021-11-28 04:44:30 +13:00
chooser . set_select_multiple ( false ) ;
2021-11-20 20:32:28 +13:00
chooser . show_all ( ) ;
2021-11-28 04:44:30 +13:00
let entry_info = entry_info . clone ( ) ;
let text_view_errors = text_view_errors . clone ( ) ;
let tree_view = tree_view . clone ( ) ;
chooser . connect_response ( move | file_chooser , response_type | {
if response_type = = gtk ::ResponseType ::Ok {
let folders = file_chooser . filenames ( ) ;
if folders . len ( ) ! = 1 {
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 ( ) ) ;
2021-11-20 20:32:28 +13:00
} else {
2021-11-28 04:44:30 +13:00
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 ) ;
}
2021-11-20 20:32:28 +13:00
}
}
2021-11-28 04:44:30 +13:00
file_chooser . close ( ) ;
} ) ;
2021-11-20 20:32:28 +13:00
}
2021-11-28 08:57:10 +13:00
2021-11-25 20:36:49 +13:00
fn move_with_tree ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , column_color : i32 , column_selection : i32 , destination_folder : PathBuf , entry_info : & gtk ::Entry , text_view_errors : & gtk ::TextView ) {
let model = get_list_store ( tree_view ) ;
2021-11-20 20:32:28 +13:00
2021-11-25 20:36:49 +13:00
let mut selected_rows = Vec ::new ( ) ;
2021-11-20 20:32:28 +13:00
if let Some ( iter ) = model . iter_first ( ) {
loop {
if model . value ( & iter , column_selection ) . get ::< bool > ( ) . unwrap ( ) {
if model . value ( & iter , column_color ) . get ::< String > ( ) . unwrap ( ) = = MAIN_ROW_COLOR {
2021-11-25 20:36:49 +13:00
selected_rows . push ( model . path ( & iter ) . unwrap ( ) ) ;
2021-11-20 20:32:28 +13:00
} else {
2021-11-25 20:36:49 +13:00
panic! ( " Header row shouldn't be selected, please report bug. " ) ;
2021-11-20 20:32:28 +13:00
}
}
if ! model . iter_next ( & iter ) {
break ;
}
}
}
2021-11-25 20:36:49 +13:00
if selected_rows . is_empty ( ) {
return ; // No selected rows
2021-11-20 20:32:28 +13:00
}
2021-11-25 20:36:49 +13:00
move_files_common ( & selected_rows , & model , column_file_name , column_path , & destination_folder , entry_info , text_view_errors ) ;
2021-11-20 20:32:28 +13:00
2021-11-25 20:36:49 +13:00
clean_invalid_headers ( & model , column_color ) ;
2021-11-20 20:32:28 +13:00
}
2021-11-25 20:36:49 +13:00
fn move_with_list ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , column_selection : i32 , destination_folder : PathBuf , entry_info : & gtk ::Entry , text_view_errors : & gtk ::TextView ) {
let model = get_list_store ( tree_view ) ;
2021-11-20 20:32:28 +13:00
2021-11-25 20:36:49 +13:00
let mut selected_rows = Vec ::new ( ) ;
2021-11-20 20:32:28 +13:00
if let Some ( iter ) = model . iter_first ( ) {
loop {
if model . value ( & iter , column_selection ) . get ::< bool > ( ) . unwrap ( ) {
2021-11-25 20:36:49 +13:00
selected_rows . push ( model . path ( & iter ) . unwrap ( ) ) ;
2021-11-20 20:32:28 +13:00
}
if ! model . iter_next ( & iter ) {
break ;
}
}
}
2021-11-25 20:36:49 +13:00
if selected_rows . is_empty ( ) {
return ; // No selected rows
}
move_files_common ( & selected_rows , & model , column_file_name , column_path , & destination_folder , entry_info , text_view_errors )
}
fn move_files_common ( selected_rows : & [ TreePath ] , model : & gtk ::ListStore , column_file_name : i32 , column_path : i32 , destination_folder : & Path , entry_info : & gtk ::Entry , text_view_errors : & gtk ::TextView ) {
let mut messages : String = " " . to_string ( ) ;
2021-11-20 20:32:28 +13:00
let mut moved_files : u32 = 0 ;
// Save to variable paths of files, and remove it when not removing all occurrences.
2021-11-25 20:36:49 +13:00
' next_result : for tree_path in selected_rows . iter ( ) . rev ( ) {
2021-11-20 20:32:28 +13:00
let iter = model . iter ( tree_path ) . unwrap ( ) ;
let file_name = model . value ( & iter , column_file_name ) . get ::< String > ( ) . unwrap ( ) ;
let path = model . value ( & iter , column_path ) . get ::< String > ( ) . unwrap ( ) ;
let thing = format! ( " {} / {} " , path , file_name ) ;
let destination_file = destination_folder . join ( file_name ) ;
if Path ::new ( & thing ) . is_dir ( ) {
if let Err ( e ) = fs_extra ::dir ::move_dir ( & thing , & destination_file , & fs_extra ::dir ::CopyOptions ::new ( ) ) {
messages + = format! ( " Failed to move folder, reason {} \n " , e ) . as_str ( ) ;
continue 'next_result ;
}
} else {
if let Err ( e ) = fs_extra ::file ::move_file ( & thing , & destination_file , & fs_extra ::file ::CopyOptions ::new ( ) ) {
messages + = format! ( " Failed to move file, reason {} \n " , e ) . as_str ( ) ;
continue 'next_result ;
}
}
model . remove ( & iter ) ;
moved_files + = 1 ;
}
2021-11-25 20:36:49 +13:00
entry_info . set_text ( format! ( " Properly moved {} / {} files/folders " , moved_files , selected_rows . len ( ) ) . as_str ( ) ) ;
2021-11-20 20:32:28 +13:00
text_view_errors . buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
}