@ -36,49 +36,122 @@ pub fn connect_button_delete(gui_data: &GuiData) {
match to_notebook_main_enum ( notebook_main . current_page ( ) . unwrap ( ) ) {
match to_notebook_main_enum ( notebook_main . current_page ( ) . unwrap ( ) ) {
NotebookMainEnum ::Duplicate = > {
NotebookMainEnum ::Duplicate = > {
if ! check_button_settings_confirm_group_deletion . is_active ( ) | | ! check_if_deleting_all_files_in_group ( & tree_view_duplicate_finder . clone ( ) , ColumnsDuplicates ::Color as i32 , & window_main , & check_button_settings_confirm_group_deletion ) {
if ! check_button_settings_confirm_group_deletion . is_active ( )
tree_remove ( & tree_view_duplicate_finder . clone ( ) , ColumnsDuplicates ::Name as i32 , ColumnsDuplicates ::Path as i32 , ColumnsDuplicates ::Color as i32 , & gui_data ) ;
| | ! check_if_deleting_all_files_in_group (
& tree_view_duplicate_finder . clone ( ) ,
ColumnsDuplicates ::Color as i32 ,
ColumnsDuplicates ::ActiveSelectButton as i32 ,
& window_main ,
& check_button_settings_confirm_group_deletion ,
)
{
tree_remove (
& tree_view_duplicate_finder . clone ( ) ,
ColumnsDuplicates ::Name as i32 ,
ColumnsDuplicates ::Path as i32 ,
ColumnsDuplicates ::Color as i32 ,
ColumnsDuplicates ::ActiveSelectButton as i32 ,
& gui_data ,
) ;
}
}
}
}
NotebookMainEnum ::EmptyDirectories = > {
NotebookMainEnum ::EmptyDirectories = > {
empty_folder_remover ( & tree_view_empty_folder_finder . clone ( ) , ColumnsEmptyFolders ::Name as i32 , ColumnsEmptyFolders ::Path as i32 , & gui_data ) ;
empty_folder_remover (
& tree_view_empty_folder_finder . clone ( ) ,
ColumnsEmptyFolders ::Name as i32 ,
ColumnsEmptyFolders ::Path as i32 ,
ColumnsEmptyFolders ::ActiveSelectButton as i32 ,
& gui_data ,
) ;
}
}
NotebookMainEnum ::EmptyFiles = > {
NotebookMainEnum ::EmptyFiles = > {
basic_remove ( & tree_view_empty_files_finder . clone ( ) , ColumnsEmptyFiles ::Name as i32 , ColumnsEmptyFiles ::Path as i32 , & gui_data ) ;
basic_remove (
& tree_view_empty_files_finder . clone ( ) ,
ColumnsEmptyFiles ::Name as i32 ,
ColumnsEmptyFiles ::Path as i32 ,
ColumnsEmptyFiles ::ActiveSelectButton as i32 ,
& gui_data ,
) ;
}
}
NotebookMainEnum ::Temporary = > {
NotebookMainEnum ::Temporary = > {
basic_remove ( & tree_view_temporary_files_finder . clone ( ) , ColumnsTemporaryFiles ::Name as i32 , ColumnsTemporaryFiles ::Path as i32 , & gui_data ) ;
basic_remove (
& tree_view_temporary_files_finder . clone ( ) ,
ColumnsTemporaryFiles ::Name as i32 ,
ColumnsTemporaryFiles ::Path as i32 ,
ColumnsTemporaryFiles ::ActiveSelectButton as i32 ,
& gui_data ,
) ;
}
}
NotebookMainEnum ::BigFiles = > {
NotebookMainEnum ::BigFiles = > {
basic_remove ( & tree_view_big_files_finder . clone ( ) , ColumnsBigFiles ::Name as i32 , ColumnsBigFiles ::Path as i32 , & gui_data ) ;
basic_remove ( & tree_view_big_files_finder . clone ( ) , ColumnsBigFiles ::Name as i32 , ColumnsBigFiles ::Path as i32 , ColumnsBigFiles ::ActiveSelectButton as i32 , & gui_data ) ;
}
}
NotebookMainEnum ::SimilarImages = > {
NotebookMainEnum ::SimilarImages = > {
if ! check_button_settings_confirm_group_deletion . is_active ( )
if ! check_button_settings_confirm_group_deletion . is_active ( )
| | ! check_if_deleting_all_files_in_group ( & tree_view_similar_images_finder . clone ( ) , ColumnsSimilarImages ::Color as i32 , & window_main , & check_button_settings_confirm_group_deletion )
| | ! check_if_deleting_all_files_in_group (
& tree_view_similar_images_finder . clone ( ) ,
ColumnsSimilarImages ::Color as i32 ,
ColumnsSimilarImages ::ActiveSelectButton as i32 ,
& window_main ,
& check_button_settings_confirm_group_deletion ,
)
{
{
tree_remove (
tree_remove (
& tree_view_similar_images_finder . clone ( ) ,
& tree_view_similar_images_finder . clone ( ) ,
ColumnsSimilarImages ::Name as i32 ,
ColumnsSimilarImages ::Name as i32 ,
ColumnsSimilarImages ::Path as i32 ,
ColumnsSimilarImages ::Path as i32 ,
ColumnsSimilarImages ::Color as i32 ,
ColumnsSimilarImages ::Color as i32 ,
ColumnsSimilarImages ::ActiveSelectButton as i32 ,
& gui_data ,
& gui_data ,
) ;
) ;
image_preview_similar_images . hide ( ) ;
image_preview_similar_images . hide ( ) ;
}
}
}
}
NotebookMainEnum ::Zeroed = > {
NotebookMainEnum ::Zeroed = > {
basic_remove ( & tree_view_zeroed_files_finder . clone ( ) , ColumnsZeroedFiles ::Name as i32 , ColumnsZeroedFiles ::Path as i32 , & gui_data ) ;
basic_remove (
& tree_view_zeroed_files_finder . clone ( ) ,
ColumnsZeroedFiles ::Name as i32 ,
ColumnsZeroedFiles ::Path as i32 ,
ColumnsZeroedFiles ::ActiveSelectButton as i32 ,
& gui_data ,
) ;
}
}
NotebookMainEnum ::SameMusic = > {
NotebookMainEnum ::SameMusic = > {
if ! check_button_settings_confirm_group_deletion . is_active ( ) | | ! check_if_deleting_all_files_in_group ( & tree_view_same_music_finder . clone ( ) , ColumnsSameMusic ::Color as i32 , & window_main , & check_button_settings_confirm_group_deletion ) {
if ! check_button_settings_confirm_group_deletion . is_active ( )
tree_remove ( & tree_view_same_music_finder . clone ( ) , ColumnsSameMusic ::Name as i32 , ColumnsSameMusic ::Path as i32 , ColumnsSameMusic ::Color as i32 , & gui_data ) ;
| | ! check_if_deleting_all_files_in_group (
& tree_view_same_music_finder . clone ( ) ,
ColumnsSameMusic ::Color as i32 ,
ColumnsSameMusic ::ActiveSelectButton as i32 ,
& window_main ,
& check_button_settings_confirm_group_deletion ,
)
{
tree_remove (
& tree_view_same_music_finder . clone ( ) ,
ColumnsSameMusic ::Name as i32 ,
ColumnsSameMusic ::Path as i32 ,
ColumnsSameMusic ::Color as i32 ,
ColumnsSameMusic ::ActiveSelectButton as i32 ,
& gui_data ,
) ;
}
}
}
}
NotebookMainEnum ::Symlinks = > {
NotebookMainEnum ::Symlinks = > {
basic_remove ( & tree_view_invalid_symlinks . clone ( ) , ColumnsInvalidSymlinks ::Name as i32 , ColumnsInvalidSymlinks ::Path as i32 , & gui_data ) ;
basic_remove (
& tree_view_invalid_symlinks . clone ( ) ,
ColumnsInvalidSymlinks ::Name as i32 ,
ColumnsInvalidSymlinks ::Path as i32 ,
ColumnsInvalidSymlinks ::ActiveSelectButton as i32 ,
& gui_data ,
) ;
}
}
NotebookMainEnum ::BrokenFiles = > {
NotebookMainEnum ::BrokenFiles = > {
basic_remove ( & tree_view_broken_files . clone ( ) , ColumnsBrokenFiles ::Name as i32 , ColumnsBrokenFiles ::Path as i32 , & gui_data ) ;
basic_remove (
& tree_view_broken_files . clone ( ) ,
ColumnsBrokenFiles ::Name as i32 ,
ColumnsBrokenFiles ::Path as i32 ,
ColumnsInvalidSymlinks ::ActiveSelectButton as i32 ,
& gui_data ,
) ;
}
}
}
}
} ) ;
} ) ;
@ -127,39 +200,28 @@ pub fn check_if_can_delete_files(check_button_settings_confirm_deletion: >k::C
true
true
}
}
pub fn check_if_deleting_all_files_in_group ( tree_view : & gtk ::TreeView , column_color : i32 , window_main : & gtk ::Window , check_button_settings_confirm_group_deletion : & gtk ::CheckButton ) -> bool {
pub fn check_if_deleting_all_files_in_group ( tree_view : & gtk ::TreeView , column_color : i32 , column_selection : i32 , window_main : & gtk ::Window , check_button_settings_confirm_group_deletion : & gtk ::CheckButton ) -> bool {
let selection = tree_view . selection ( ) ;
let model = get_list_store ( & tree_view ) ;
let ( selection_rows , tree_model ) = selection . selected_rows ( ) ;
if selection_rows . is_empty ( ) {
return false ;
}
let mut current_selected_row = 0 ;
let mut selected_all_records : bool = true ;
let mut selected_all_records : bool = true ;
if let Some ( first_iter ) = tree_model . iter_first ( ) {
if let Some ( iter ) = model . iter_first ( ) {
let current_iter = first_iter ;
assert_eq! ( model . value ( & iter , column_color ) . get ::< String > ( ) . unwrap ( ) , HEADER_ROW_COLOR ) ; // First element should be header
if tree_model . value ( & current_iter , column_color ) . get ::< String > ( ) . unwrap ( ) ! = HEADER_ROW_COLOR {
panic! ( "First element, should be a header" ) ; // First element should be header
} ;
loop {
loop {
if ! tree_model . iter_next ( & current_iter ) {
if ! model . iter_next ( & iter ) {
if selected_all_records {
break ;
}
break ;
break ;
}
}
if tree_ model. value ( & current_ iter, column_color ) . get ::< String > ( ) . unwrap ( ) = = HEADER_ROW_COLOR {
if model. value ( & iter, column_color ) . get ::< String > ( ) . unwrap ( ) = = HEADER_ROW_COLOR {
if selected_all_records {
if selected_all_records {
break ;
break ;
}
}
} else if current_selected_row ! = selection_rows . len ( ) & & selection_rows [ current_selected_row ] = = tree_model . path ( & current_iter ) . unwrap ( ) {
selected_all_records = true ;
current_selected_row + = 1 ;
} else {
} else {
selected_all_records = false ;
if ! model . value ( & iter , column_selection ) . get ::< bool > ( ) . unwrap ( ) {
selected_all_records = false ;
}
}
}
}
}
} else {
} else {
@ -217,24 +279,33 @@ pub fn check_if_deleting_all_files_in_group(tree_view: >k::TreeView, column_co
false
false
}
}
pub fn empty_folder_remover ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , gui_data: & GuiData ) {
pub fn empty_folder_remover ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , column_selection: i32 , gui_data: & GuiData ) {
let text_view_errors = gui_data . text_view_errors . clone ( ) ;
let text_view_errors = gui_data . text_view_errors . clone ( ) ;
let use_trash = gui_data . settings . check_button_settings_use_trash . clone ( ) . is_active ( ) ;
let use_trash = gui_data . settings . check_button_settings_use_trash . clone ( ) . is_active ( ) ;
let selection = tree_view . selection ( ) ;
let model = get_list_store ( & tree_view ) ;
let ( selection_rows , tree_model ) = selection . selected_rows ( ) ;
let mut selected_rows = Vec ::new ( ) ;
if selection_rows . is_empty ( ) {
return ;
if let Some ( iter ) = model . iter_first ( ) {
loop {
if model . value ( & iter , column_selection ) . get ::< bool > ( ) . unwrap ( ) {
selected_rows . push ( model . path ( & iter ) . unwrap ( ) ) ;
}
if ! model . iter_next ( & iter ) {
break ;
}
}
}
}
let list_store = get_list_store ( & tree_view ) ;
let mut messages : String = "" . to_string ( ) ;
let mut messages : String = "" . to_string ( ) ;
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
for tree_path in selection_rows . iter ( ) . rev ( ) {
for tree_path in selected_rows . iter ( ) . rev ( ) {
let name = tree_model . value ( & tree_model . iter ( tree_path ) . unwrap ( ) , column_file_name ) . get ::< String > ( ) . unwrap ( ) ;
let iter = model . iter ( tree_path ) . unwrap ( ) ;
let path = tree_model . value ( & tree_model . iter ( tree_path ) . unwrap ( ) , column_path ) . get ::< String > ( ) . unwrap ( ) ;
let name = model . value ( & iter , column_file_name ) . get ::< String > ( ) . unwrap ( ) ;
let path = model . value ( & iter , column_path ) . get ::< String > ( ) . unwrap ( ) ;
// We must check if folder is really empty or contains only other empty folders
// We must check if folder is really empty or contains only other empty folders
let mut error_happened = false ;
let mut error_happened = false ;
@ -288,14 +359,14 @@ pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, co
if ! use_trash {
if ! use_trash {
match fs ::remove_dir_all ( format! ( "{}/{}" , path , name ) ) {
match fs ::remove_dir_all ( format! ( "{}/{}" , path , name ) ) {
Ok ( _ ) = > {
Ok ( _ ) = > {
list_store . remove ( & list_store. iter( tree_path ) . unwrap ( ) ) ;
model . remove ( & iter) ;
}
}
Err ( _ ) = > error_happened = true ,
Err ( _ ) = > error_happened = true ,
}
}
} else {
} else {
match trash ::delete ( format! ( "{}/{}" , path , name ) ) {
match trash ::delete ( format! ( "{}/{}" , path , name ) ) {
Ok ( _ ) = > {
Ok ( _ ) = > {
list_store . remove ( & list_store. iter( tree_path ) . unwrap ( ) ) ;
model . remove ( & iter) ;
}
}
Err ( _ ) = > error_happened = true ,
Err ( _ ) = > error_happened = true ,
}
}
@ -307,39 +378,48 @@ pub fn empty_folder_remover(tree_view: >k::TreeView, column_file_name: i32, co
}
}
text_view_errors . buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
text_view_errors . buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
selection . unselect_all ( ) ;
}
}
pub fn basic_remove ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , gui_data: & GuiData ) {
pub fn basic_remove ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , column_selection: i32 , gui_data: & GuiData ) {
let text_view_errors = gui_data . text_view_errors . clone ( ) ;
let text_view_errors = gui_data . text_view_errors . clone ( ) ;
let use_trash = gui_data . settings . check_button_settings_use_trash . clone ( ) . is_active ( ) ;
let use_trash = gui_data . settings . check_button_settings_use_trash . clone ( ) . is_active ( ) ;
let selection = tree_view . selection ( ) ;
let model = get_list_store ( & tree_view ) ;
let ( selection_rows , tree_model ) = selection . selected_rows ( ) ;
if selection_rows . is_empty ( ) {
return ;
}
let list_store = get_list_store ( & tree_view ) ;
let mut messages : String = "" . to_string ( ) ;
let mut messages : String = "" . to_string ( ) ;
let mut selection_rows = Vec ::new ( ) ;
if let Some ( iter ) = model . iter_first ( ) {
loop {
if model . value ( & iter , column_selection ) . get ::< bool > ( ) . unwrap ( ) {
selection_rows . push ( model . path ( & iter ) . unwrap ( ) ) ;
}
if ! model . iter_next ( & iter ) {
break ;
}
}
}
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
// Must be deleted from end to start, because when deleting entries, TreePath(and also TreeIter) will points to invalid data
for tree_path in selection_rows . iter ( ) . rev ( ) {
for tree_path in selection_rows . iter ( ) . rev ( ) {
let name = tree_model . value ( & tree_model . iter ( tree_path ) . unwrap ( ) , column_file_name ) . get ::< String > ( ) . unwrap ( ) ;
let iter = model . iter ( tree_path ) . unwrap ( ) ;
let path = tree_model . value ( & tree_model . iter ( tree_path ) . unwrap ( ) , column_path ) . get ::< String > ( ) . unwrap ( ) ;
let name = model . value ( & iter , column_file_name ) . get ::< String > ( ) . unwrap ( ) ;
let path = model . value ( & iter , column_path ) . get ::< String > ( ) . unwrap ( ) ;
if ! use_trash {
if ! use_trash {
match fs ::remove_file ( format! ( "{}/{}" , path , name ) ) {
match fs ::remove_file ( format! ( "{}/{}" , path , name ) ) {
Ok ( _ ) = > {
Ok ( _ ) = > {
list_store . remove ( & list_store . iter ( tree_path ) . unwrap ( ) ) ;
model . remove ( & iter) ;
}
}
Err ( _ ) = > messages + = format! ( "Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n" , path , name ) . as_str ( ) ,
Err ( _ ) = > messages + = format! ( "Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n" , path , name ) . as_str ( ) ,
}
}
} else {
} else {
match trash ::delete ( format! ( "{}/{}" , path , name ) ) {
match trash ::delete ( format! ( "{}/{}" , path , name ) ) {
Ok ( _ ) = > {
Ok ( _ ) = > {
list_store . remove ( & list_store. iter( tree_path ) . unwrap ( ) ) ;
model . remove ( & iter) ;
}
}
Err ( _ ) = > messages + = format! ( "Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n" , path , name ) . as_str ( ) ,
Err ( _ ) = > messages + = format! ( "Failed to remove file {}/{} because file doesn't exists or you don't have permissions.\n" , path , name ) . as_str ( ) ,
}
}
@ -347,33 +427,45 @@ pub fn basic_remove(tree_view: >k::TreeView, column_file_name: i32, column_pat
}
}
text_view_errors . buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
text_view_errors . buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
selection . unselect_all ( ) ;
}
}
// Remove all occurrences - remove every element which have same path and name as even non selected ones
// Remove all occurrences - remove every element which have same path and name as even non selected ones
pub fn tree_remove ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , column_color : i32 , gui_data: & GuiData ) {
pub fn tree_remove ( tree_view : & gtk ::TreeView , column_file_name : i32 , column_path : i32 , column_color : i32 , column_selection: i32 , gui_data: & GuiData ) {
let text_view_errors = gui_data . text_view_errors . clone ( ) ;
let text_view_errors = gui_data . text_view_errors . clone ( ) ;
let use_trash = gui_data . settings . check_button_settings_use_trash . clone ( ) . is_active ( ) ;
let use_trash = gui_data . settings . check_button_settings_use_trash . clone ( ) . is_active ( ) ;
let selection = tree_view . selection ( ) ;
let model = get_list_store ( & tree_view ) ;
let ( selection_rows , tree_model ) = selection . selected_rows ( ) ;
if selection_rows . is_empty ( ) {
return ;
}
let list_store = get_list_store ( & tree_view ) ;
let mut messages : String = "" . to_string ( ) ;
let mut messages : String = "" . to_string ( ) ;
let mut vec_path_to_delete : Vec < ( String , String ) > = Vec ::new ( ) ;
let mut vec_path_to_delete : Vec < ( String , String ) > = Vec ::new ( ) ;
let mut map_with_path_to_delete : BTreeMap < String , Vec < String > > = Default ::default ( ) ; // BTreeMap<Path,Vec<FileName>>
let mut map_with_path_to_delete : BTreeMap < String , Vec < String > > = Default ::default ( ) ; // BTreeMap<Path,Vec<FileName>>
let mut selection_rows = Vec ::new ( ) ;
if let Some ( iter ) = model . iter_first ( ) {
loop {
if model . value ( & iter , column_selection ) . get ::< bool > ( ) . unwrap ( ) {
// TODO, this maybe isn't required if we will be sure that any header cannot be selected
if model . value ( & iter , column_color ) . get ::< String > ( ) . unwrap ( ) = = MAIN_ROW_COLOR {
selection_rows . push ( model . path ( & iter ) . unwrap ( ) ) ;
}
}
if ! model . iter_next ( & iter ) {
break ;
}
}
}
// Save to variable paths of files, and remove it when not removing all occurrences.
// Save to variable paths of files, and remove it when not removing all occurrences.
for tree_path in selection_rows . iter ( ) . rev ( ) {
for tree_path in selection_rows . iter ( ) . rev ( ) {
let file_name = tree_model . value ( & tree_model . iter ( tree_path ) . unwrap ( ) , column_file_name ) . get ::< String > ( ) . unwrap ( ) ;
let iter = model . iter ( tree_path ) . unwrap ( ) ;
let path = tree_model . value ( & tree_model . iter ( tree_path ) . unwrap ( ) , column_path ) . get ::< String > ( ) . unwrap ( ) ;
let file_name = model . value ( & iter , column_file_name ) . get ::< String > ( ) . unwrap ( ) ;
let path = model . value ( & iter , column_path ) . get ::< String > ( ) . unwrap ( ) ;
list_store . remove ( & list_store . iter ( tree_path ) . unwrap ( ) ) ;
model . remove ( & iter) ;
map_with_path_to_delete . entry ( path . clone ( ) ) . or_insert_with ( Vec ::new ) ;
map_with_path_to_delete . entry ( path . clone ( ) ) . or_insert_with ( Vec ::new ) ;
map_with_path_to_delete . get_mut ( path . as_str ( ) ) . unwrap ( ) . push ( file_name ) ;
map_with_path_to_delete . get_mut ( path . as_str ( ) ) . unwrap ( ) . push ( file_name ) ;
@ -405,74 +497,73 @@ pub fn tree_remove(tree_view: >k::TreeView, column_file_name: i32, column_path
}
}
// Remove only child from header
// Remove only child from header
if let Some ( first_iter ) = list_store . iter_first ( ) {
if let Some ( first_iter ) = model . iter_first ( ) {
let mut vec_tree_path_to_delete : Vec < gtk ::TreePath > = Vec ::new ( ) ;
let mut vec_tree_path_to_delete : Vec < gtk ::TreePath > = Vec ::new ( ) ;
let mut current_iter = first_iter ;
let mut current_iter = first_iter ;
if tree_ model. value ( & current_iter , column_color ) . get ::< String > ( ) . unwrap ( ) ! = HEADER_ROW_COLOR {
if model. value ( & current_iter , column_color ) . get ::< String > ( ) . unwrap ( ) ! = HEADER_ROW_COLOR {
panic! ( "First deleted element, should be a header" ) ; // First element should be header
panic! ( "First deleted element, should be a header" ) ; // First element should be header
} ;
} ;
let mut next_iter ;
let mut next_iter ;
let mut next_next_iter ;
let mut next_next_iter ;
' main : loop {
' main : loop {
if tree_ model. value ( & current_iter , column_color ) . get ::< String > ( ) . unwrap ( ) ! = HEADER_ROW_COLOR {
if model. value ( & current_iter , column_color ) . get ::< String > ( ) . unwrap ( ) ! = HEADER_ROW_COLOR {
panic! ( "First deleted element, should be a header" ) ; // First element should be header
panic! ( "First deleted element, should be a header" ) ; // First element should be header
} ;
} ;
next_iter = current_iter . clone ( ) ;
next_iter = current_iter . clone ( ) ;
if ! list_store . iter_next ( & next_iter ) {
if ! model . iter_next ( & next_iter ) {
// There is only single header left (H1 -> END) -> (NOTHING)
// There is only single header left (H1 -> END) -> (NOTHING)
vec_tree_path_to_delete . push ( list_store . path ( & current_iter ) . unwrap ( ) ) ;
vec_tree_path_to_delete . push ( model . path ( & current_iter ) . unwrap ( ) ) ;
break 'main ;
break 'main ;
}
}
if tree_ model. value ( & next_iter , column_color ) . get ::< String > ( ) . unwrap ( ) = = HEADER_ROW_COLOR {
if model. value ( & next_iter , column_color ) . get ::< String > ( ) . unwrap ( ) = = HEADER_ROW_COLOR {
// There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2)
// There are two headers each others(we remove just first) -> (H1 -> H2) -> (H2)
vec_tree_path_to_delete . push ( list_store . path ( & current_iter ) . unwrap ( ) ) ;
vec_tree_path_to_delete . push ( model . path ( & current_iter ) . unwrap ( ) ) ;
current_iter = next_iter . clone ( ) ;
current_iter = next_iter . clone ( ) ;
continue 'main ;
continue 'main ;
}
}
next_next_iter = next_iter . clone ( ) ;
next_next_iter = next_iter . clone ( ) ;
if ! list_store . iter_next ( & next_next_iter ) {
if ! model . iter_next ( & next_next_iter ) {
// There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING)
// There is only one child of header left, so we remove it with header (H1 -> C1 -> END) -> (NOTHING)
vec_tree_path_to_delete . push ( list_store . path ( & current_iter ) . unwrap ( ) ) ;
vec_tree_path_to_delete . push ( model . path ( & current_iter ) . unwrap ( ) ) ;
vec_tree_path_to_delete . push ( list_store . path ( & next_iter ) . unwrap ( ) ) ;
vec_tree_path_to_delete . push ( model . path ( & next_iter ) . unwrap ( ) ) ;
break 'main ;
break 'main ;
}
}
if tree_ model. value ( & next_next_iter , column_color ) . get ::< String > ( ) . unwrap ( ) = = HEADER_ROW_COLOR {
if model. value ( & next_next_iter , column_color ) . get ::< String > ( ) . unwrap ( ) = = HEADER_ROW_COLOR {
// One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
// One child between two headers, we can remove them (H1 -> C1 -> H2) -> (H2)
vec_tree_path_to_delete . push ( list_store . path ( & current_iter ) . unwrap ( ) ) ;
vec_tree_path_to_delete . push ( model . path ( & current_iter ) . unwrap ( ) ) ;
vec_tree_path_to_delete . push ( list_store . path ( & next_iter ) . unwrap ( ) ) ;
vec_tree_path_to_delete . push ( model . path ( & next_iter ) . unwrap ( ) ) ;
current_iter = next_next_iter . clone ( ) ;
current_iter = next_next_iter . clone ( ) ;
continue 'main ;
continue 'main ;
}
}
loop {
loop {
// (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD)
// (H1 -> C1 -> C2 -> Cn -> END) -> (NO CHANGE, BECAUSE IS GOOD)
if ! list_store . iter_next ( & next_next_iter ) {
if ! model . iter_next ( & next_next_iter ) {
break 'main ;
break 'main ;
}
}
// Move to next header
// Move to next header
if tree_ model. value ( & next_next_iter , column_color ) . get ::< String > ( ) . unwrap ( ) = = HEADER_ROW_COLOR {
if model. value ( & next_next_iter , column_color ) . get ::< String > ( ) . unwrap ( ) = = HEADER_ROW_COLOR {
current_iter = next_next_iter . clone ( ) ;
current_iter = next_next_iter . clone ( ) ;
continue 'main ;
continue 'main ;
}
}
}
}
}
}
for tree_path in vec_tree_path_to_delete . iter ( ) . rev ( ) {
for tree_path in vec_tree_path_to_delete . iter ( ) . rev ( ) {
list_store. remove ( & list_store . iter ( & tree_path ) . unwrap ( ) ) ;
model. remove ( & model . iter ( & tree_path ) . unwrap ( ) ) ;
}
}
}
}
// Last step, remove orphan header if exists
// Last step, remove orphan header if exists
if let Some ( iter ) = list_store . iter_first ( ) {
if let Some ( iter ) = model . iter_first ( ) {
if ! list_store . iter_next ( & iter ) {
if ! model . iter_next ( & iter ) {
list_store . clear ( ) ;
model . clear ( ) ;
}
}
}
}
text_view_errors . buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
text_view_errors . buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
selection . unselect_all ( ) ;
}
}