2020-09-30 05:44:20 +13:00
mod help_functions ;
2020-09-23 22:17:19 +12:00
use czkawka_core ::* ;
2020-09-18 17:32:37 +12:00
use humansize ::{ file_size_opts as options , FileSize } ;
2020-09-02 05:34:39 +12:00
extern crate gtk ;
2020-09-30 05:44:20 +13:00
use crate ::help_functions ::* ;
2020-09-20 21:32:55 +12:00
use chrono ::NaiveDateTime ;
2020-10-01 03:38:45 +13:00
use czkawka_core ::common_traits ::SaveResults ;
2020-09-20 21:32:55 +12:00
use czkawka_core ::duplicate ::CheckingMethod ;
2020-09-22 21:24:55 +12:00
use czkawka_core ::empty_folder ::EmptyFolder ;
2020-09-10 07:32:23 +12:00
use duplicate ::DuplicateFinder ;
2020-09-02 05:34:39 +12:00
use gtk ::prelude ::* ;
2020-10-01 05:22:50 +13:00
use gtk ::{ Builder , SelectionMode , TreeIter , TreeView } ;
2020-09-22 21:24:55 +12:00
use std ::cell ::RefCell ;
2020-09-12 23:25:23 +12:00
use std ::collections ::HashMap ;
2020-09-22 21:24:55 +12:00
use std ::rc ::Rc ;
2020-09-30 05:44:20 +13:00
use std ::{ env , fs , process } ;
2020-09-26 03:47:40 +12:00
2020-09-02 05:34:39 +12:00
fn main ( ) {
2020-09-24 21:58:59 +12:00
// Printing version
2020-09-23 22:17:19 +12:00
{
let all_arguments : Vec < String > = env ::args ( ) . skip ( 1 ) . collect ( ) ; // Not need to check program name
for i in all_arguments {
if i = = " --v " | | i = = " --version " {
println! ( " Czkawka CLI {} " , CZKAWKA_VERSION ) ;
process ::exit ( 0 ) ;
}
}
}
2020-09-05 07:12:18 +12:00
gtk ::init ( ) . expect ( " Failed to initialize GTK. " ) ;
2020-09-25 02:11:59 +12:00
//// Loading glade file content and build with it help UI
2020-09-05 07:12:18 +12:00
let glade_src = include_str! ( " ../czkawka.glade " ) ;
2020-09-10 07:32:23 +12:00
let builder = Builder ::from_string ( glade_src ) ;
2020-09-05 07:12:18 +12:00
2020-09-25 02:11:59 +12:00
//// Windows
2020-09-08 02:07:29 +12:00
let main_window : gtk ::Window = builder . get_object ( " main_window " ) . unwrap ( ) ;
main_window . show_all ( ) ;
2020-09-24 08:05:44 +12:00
main_window . set_title ( " Czkawka GTK GUI " ) ;
2020-09-08 02:07:29 +12:00
2020-09-22 21:24:55 +12:00
////////////////////////////////////////////////////////////////////////////////////////////////
2020-09-25 02:11:59 +12:00
//// States
2020-09-22 21:24:55 +12:00
2020-09-24 21:58:59 +12:00
// Buttons State - to remember existence of different buttons on pages
2020-09-15 06:44:59 +12:00
2020-09-22 21:24:55 +12:00
let shared_buttons : Rc < RefCell < _ > > = Rc ::new ( RefCell ::new ( HashMap ::< String , HashMap < String , bool > > ::new ( ) ) ) ;
shared_buttons . borrow_mut ( ) . clear ( ) ;
2020-09-18 17:32:37 +12:00
2020-09-23 06:35:37 +12:00
// Show by default only search button
2020-09-16 05:17:13 +12:00
for i in [ " duplicate " , " empty_folder " ] . iter ( ) {
2020-09-22 21:24:55 +12:00
let mut temp_hashmap : HashMap < String , bool > = Default ::default ( ) ;
for j in [ " search " , " stop " , " resume " , " pause " , " select " , " delete " , " save " ] . iter ( ) {
if * j = = " search " {
temp_hashmap . insert ( j . to_string ( ) , true ) ;
} else {
temp_hashmap . insert ( j . to_string ( ) , false ) ;
}
}
shared_buttons . borrow_mut ( ) . insert ( i . to_string ( ) , temp_hashmap ) ;
2020-09-12 23:25:23 +12:00
}
2020-09-23 06:35:37 +12:00
2020-09-24 21:58:59 +12:00
// State of search results - probably are not necessary due
2020-09-22 21:24:55 +12:00
let shared_duplication_state : Rc < RefCell < _ > > = Rc ::new ( RefCell ::new ( DuplicateFinder ::new ( ) ) ) ;
let shared_empty_folders_state : Rc < RefCell < _ > > = Rc ::new ( RefCell ::new ( EmptyFolder ::new ( ) ) ) ;
2020-09-12 23:25:23 +12:00
2020-09-22 21:24:55 +12:00
////////////////////////////////////////////////////////////////////////////////////////////////
2020-09-10 07:32:23 +12:00
2020-09-25 02:11:59 +12:00
//// GUI Entry
2020-09-24 21:58:59 +12:00
let entry_duplicate_minimal_size : gtk ::Entry = builder . get_object ( " entry_duplicate_minimal_size " ) . unwrap ( ) ;
let entry_allowed_extensions : gtk ::Entry = builder . get_object ( " entry_allowed_extensions " ) . unwrap ( ) ;
let entry_excluded_items : gtk ::Entry = builder . get_object ( " entry_excluded_items " ) . unwrap ( ) ;
2020-09-22 21:24:55 +12:00
2020-09-25 02:11:59 +12:00
//// GUI Buttons
2020-09-10 07:32:23 +12:00
let buttons_search : gtk ::Button = builder . get_object ( " buttons_search " ) . unwrap ( ) ;
let buttons_stop : gtk ::Button = builder . get_object ( " buttons_stop " ) . unwrap ( ) ;
let buttons_resume : gtk ::Button = builder . get_object ( " buttons_resume " ) . unwrap ( ) ;
let buttons_pause : gtk ::Button = builder . get_object ( " buttons_pause " ) . unwrap ( ) ;
let buttons_select : gtk ::Button = builder . get_object ( " buttons_select " ) . unwrap ( ) ;
let buttons_delete : gtk ::Button = builder . get_object ( " buttons_delete " ) . unwrap ( ) ;
let buttons_save : gtk ::Button = builder . get_object ( " buttons_save " ) . unwrap ( ) ;
2020-09-30 10:00:15 +13:00
let buttons_add_included_directory : gtk ::Button = builder . get_object ( " buttons_add_included_directory " ) . unwrap ( ) ;
let buttons_remove_included_directory : gtk ::Button = builder . get_object ( " buttons_remove_included_directory " ) . unwrap ( ) ;
let buttons_add_excluded_directory : gtk ::Button = builder . get_object ( " buttons_add_excluded_directory " ) . unwrap ( ) ;
let buttons_remove_excluded_directory : gtk ::Button = builder . get_object ( " buttons_remove_excluded_directory " ) . unwrap ( ) ;
2020-09-30 08:17:58 +13:00
2020-10-01 03:38:45 +13:00
// Buttons search popover buttons
let buttons_popover_select_all : gtk ::Button = builder . get_object ( " buttons_popover_select_all " ) . unwrap ( ) ;
let buttons_popover_unselect_all : gtk ::Button = builder . get_object ( " buttons_popover_unselect_all " ) . unwrap ( ) ;
2020-10-01 05:22:50 +13:00
let buttons_popover_reverse : gtk ::Button = builder . get_object ( " buttons_popover_reverse " ) . unwrap ( ) ;
2020-10-01 03:38:45 +13:00
// let buttons_popover_select_all_except_oldest: gtk::Button = builder.get_object("buttons_popover_select_all_except_oldest").unwrap();
// let buttons_popover_select_all_except_newest: gtk::Button = builder.get_object("buttons_popover_select_all_except_newest").unwrap();
// let buttons_popover_select_one_oldest: gtk::Button = builder.get_object("buttons_popover_select_one_oldest").unwrap();
// let buttons_popover_select_one_newest: gtk::Button = builder.get_object("buttons_popover_select_one_newest").unwrap();
2020-09-20 21:32:55 +12:00
2020-10-01 01:47:39 +13:00
//// Popovers
2020-10-01 03:38:45 +13:00
let popover_select : gtk ::Popover = builder . get_object ( " popover_select " ) . unwrap ( ) ;
2020-10-01 01:47:39 +13:00
2020-09-30 07:19:36 +13:00
//// Check Buttons
let check_button_recursive : gtk ::CheckButton = builder . get_object ( " check_button_recursive " ) . unwrap ( ) ;
2020-09-30 08:17:58 +13:00
//// Radio Buttons
let radio_button_size : gtk ::RadioButton = builder . get_object ( " radio_button_size " ) . unwrap ( ) ;
let radio_button_hashmb : gtk ::RadioButton = builder . get_object ( " radio_button_hashmb " ) . unwrap ( ) ;
let radio_button_hash : gtk ::RadioButton = builder . get_object ( " radio_button_hash " ) . unwrap ( ) ;
2020-09-25 02:11:59 +12:00
//// Notebooks
2020-09-10 07:32:23 +12:00
let notebook_chooser_tool : gtk ::Notebook = builder . get_object ( " notebook_chooser_tool " ) . unwrap ( ) ;
let mut notebook_chooser_tool_children_names : Vec < String > = Vec ::new ( ) ;
for i in notebook_chooser_tool . get_children ( ) {
notebook_chooser_tool_children_names . push ( i . get_buildable_name ( ) . unwrap ( ) . to_string ( ) ) ;
}
2020-09-25 02:11:59 +12:00
//// Entry
let entry_info : gtk ::Entry = builder . get_object ( " entry_info " ) . unwrap ( ) ; // To show default
2020-09-10 07:32:23 +12:00
2020-09-25 02:11:59 +12:00
//// Text View
let text_view_errors : gtk ::TextView = builder . get_object ( " text_view_errors " ) . unwrap ( ) ;
//// Scrolled windows
2020-09-24 21:58:59 +12:00
// Main notebook
2020-09-10 07:32:23 +12:00
let scrolled_window_duplicate_finder : gtk ::ScrolledWindow = builder . get_object ( " scrolled_window_duplicate_finder " ) . unwrap ( ) ;
2020-09-22 21:24:55 +12:00
let scrolled_window_empty_folder_finder : gtk ::ScrolledWindow = builder . get_object ( " scrolled_window_empty_folder_finder " ) . unwrap ( ) ;
2020-09-10 07:32:23 +12:00
2020-09-24 21:58:59 +12:00
// Upper notebook
let scrolled_window_included_directories : gtk ::ScrolledWindow = builder . get_object ( " scrolled_window_included_directories " ) . unwrap ( ) ;
let scrolled_window_excluded_directories : gtk ::ScrolledWindow = builder . get_object ( " scrolled_window_excluded_directories " ) . unwrap ( ) ;
2020-09-25 02:11:59 +12:00
//// Set starting information in bottom panel
2020-09-10 07:32:23 +12:00
{
2020-09-25 02:11:59 +12:00
entry_info . set_text ( " Duplicated Files " ) ;
2020-09-10 07:32:23 +12:00
2020-09-24 21:58:59 +12:00
// Disable and show buttons
2020-09-10 07:32:23 +12:00
buttons_search . show ( ) ;
buttons_save . hide ( ) ;
2020-09-20 21:32:55 +12:00
buttons_delete . hide ( ) ;
2020-10-01 03:38:45 +13:00
buttons_stop . hide ( ) ;
buttons_resume . hide ( ) ;
buttons_pause . hide ( ) ;
buttons_select . hide ( ) ;
2020-09-24 21:58:59 +12:00
2020-09-30 07:19:36 +13:00
// Set Main ScrolledWindow Treeviews
{
// Duplicate Files
{
let col_types : [ glib ::types ::Type ; 4 ] = [ glib ::types ::Type ::String , glib ::types ::Type ::String , glib ::types ::Type ::String , glib ::types ::Type ::String ] ;
let list_store : gtk ::ListStore = gtk ::ListStore ::new ( & col_types ) ;
let mut tree_view : gtk ::TreeView = TreeView ::with_model ( & list_store ) ;
tree_view . get_selection ( ) . set_mode ( SelectionMode ::Multiple ) ;
tree_view . get_selection ( ) . set_select_function ( Some ( Box ::new ( select_function_3column ) ) ) ;
create_tree_view_duplicates ( & mut tree_view ) ;
scrolled_window_duplicate_finder . add ( & tree_view ) ;
scrolled_window_duplicate_finder . show_all ( ) ;
}
// Empty Folders
{
let col_types : [ glib ::types ::Type ; 4 ] = [ glib ::types ::Type ::String , glib ::types ::Type ::String , glib ::types ::Type ::String , glib ::types ::Type ::String ] ;
let list_store : gtk ::ListStore = gtk ::ListStore ::new ( & col_types ) ;
let mut tree_view : gtk ::TreeView = TreeView ::with_model ( & list_store ) ;
tree_view . get_selection ( ) . set_mode ( SelectionMode ::Multiple ) ;
create_tree_view_empty_folders ( & mut tree_view ) ;
scrolled_window_empty_folder_finder . add ( & tree_view ) ;
scrolled_window_empty_folder_finder . show_all ( ) ;
}
}
2020-09-30 05:44:20 +13:00
2020-09-27 04:16:12 +13:00
// Set Included Directory
2020-09-24 21:58:59 +12:00
{
2020-09-26 03:47:40 +12:00
let col_types : [ glib ::types ::Type ; 2 ] = [ glib ::types ::Type ::String , glib ::types ::Type ::String ] ;
2020-09-24 21:58:59 +12:00
let list_store : gtk ::ListStore = gtk ::ListStore ::new ( & col_types ) ;
let mut tree_view_included_directory : gtk ::TreeView = TreeView ::with_model ( & list_store ) ;
tree_view_included_directory . get_selection ( ) . set_mode ( SelectionMode ::Single ) ;
create_tree_view_directories ( & mut tree_view_included_directory ) ;
2020-09-26 03:47:40 +12:00
let col_indices = [ 0 , 1 ] ;
2020-09-24 21:58:59 +12:00
2020-09-26 03:47:40 +12:00
let values : [ & dyn ToValue ; 2 ] = [ & ( " /home/rafal/Pulpit " ) , & ( MAIN_ROW_COLOR . to_string ( ) ) ] ;
2020-09-24 21:58:59 +12:00
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
scrolled_window_included_directories . add ( & tree_view_included_directory ) ;
scrolled_window_included_directories . show_all ( ) ;
}
// Set Excluded Directory
{
2020-09-26 03:47:40 +12:00
let col_types : [ glib ::types ::Type ; 2 ] = [ glib ::types ::Type ::String , glib ::types ::Type ::String ] ;
2020-09-24 21:58:59 +12:00
let list_store : gtk ::ListStore = gtk ::ListStore ::new ( & col_types ) ;
let mut tree_view_excluded_directory : gtk ::TreeView = TreeView ::with_model ( & list_store ) ;
tree_view_excluded_directory . get_selection ( ) . set_mode ( SelectionMode ::Single ) ;
create_tree_view_directories ( & mut tree_view_excluded_directory ) ;
2020-09-30 07:19:36 +13:00
let col_indices = [ 0 , 1 ] ;
2020-10-01 01:47:39 +13:00
for i in [ " /proc " , " /dev " ] . iter ( ) {
2020-09-30 07:19:36 +13:00
let values : [ & dyn ToValue ; 2 ] = [ & i , & ( MAIN_ROW_COLOR . to_string ( ) ) ] ;
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
}
2020-09-24 21:58:59 +12:00
scrolled_window_excluded_directories . add ( & tree_view_excluded_directory ) ;
scrolled_window_excluded_directories . show_all ( ) ;
}
2020-09-10 07:32:23 +12:00
}
2020-09-23 06:35:37 +12:00
// Connecting events
2020-09-10 07:32:23 +12:00
{
2020-09-22 21:24:55 +12:00
// Connect Notebook Tabs
{
let shared_buttons = shared_buttons . clone ( ) ;
2020-09-23 06:35:37 +12:00
#[ allow(clippy::redundant_clone) ]
2020-09-22 21:24:55 +12:00
let buttons_search = buttons_search . clone ( ) ;
2020-09-23 06:35:37 +12:00
#[ allow(clippy::redundant_clone) ]
2020-09-22 21:24:55 +12:00
let buttons_stop = buttons_stop . clone ( ) ;
2020-09-23 06:35:37 +12:00
#[ allow(clippy::redundant_clone) ]
2020-09-22 21:24:55 +12:00
let buttons_resume = buttons_resume . clone ( ) ;
2020-09-23 06:35:37 +12:00
#[ allow(clippy::redundant_clone) ]
2020-09-22 21:24:55 +12:00
let buttons_pause = buttons_pause . clone ( ) ;
2020-09-23 06:35:37 +12:00
#[ allow(clippy::redundant_clone) ]
2020-09-22 21:24:55 +12:00
let buttons_select = buttons_select . clone ( ) ;
2020-09-23 06:35:37 +12:00
#[ allow(clippy::redundant_clone) ]
2020-09-22 21:24:55 +12:00
let buttons_delete = buttons_delete . clone ( ) ;
2020-09-23 06:35:37 +12:00
#[ allow(clippy::redundant_clone) ]
2020-09-22 21:24:55 +12:00
let buttons_save = buttons_save . clone ( ) ;
let notebook_chooser_tool_children_names = notebook_chooser_tool_children_names . clone ( ) ;
notebook_chooser_tool . connect_switch_page ( move | _ , _ , number | {
let page : & str ;
match notebook_chooser_tool_children_names . get ( number as usize ) . unwrap ( ) . as_str ( ) {
" notebook_duplicate_finder_label " = > {
page = " duplicate " ;
}
" scrolled_window_empty_folder_finder " = > {
page = " empty_folder " ;
}
e = > {
panic! ( " Not existent page {} " , e ) ;
}
} ;
2020-09-23 06:35:37 +12:00
if * shared_buttons . borrow_mut ( ) . get_mut ( page ) . unwrap ( ) . get_mut ( " search " ) . unwrap ( ) {
2020-09-22 21:24:55 +12:00
buttons_search . show ( ) ;
} else {
buttons_search . hide ( ) ;
}
2020-09-23 06:35:37 +12:00
if * shared_buttons . borrow_mut ( ) . get_mut ( page ) . unwrap ( ) . get_mut ( " stop " ) . unwrap ( ) {
2020-09-22 21:24:55 +12:00
buttons_stop . show ( ) ;
} else {
buttons_stop . hide ( ) ;
}
2020-09-23 06:35:37 +12:00
if * shared_buttons . borrow_mut ( ) . get_mut ( page ) . unwrap ( ) . get_mut ( " resume " ) . unwrap ( ) {
2020-09-22 21:24:55 +12:00
buttons_resume . show ( ) ;
} else {
buttons_resume . hide ( ) ;
}
2020-09-23 06:35:37 +12:00
if * shared_buttons . borrow_mut ( ) . get_mut ( page ) . unwrap ( ) . get_mut ( " pause " ) . unwrap ( ) {
2020-09-22 21:24:55 +12:00
buttons_pause . show ( ) ;
} else {
buttons_pause . hide ( ) ;
}
2020-09-23 06:35:37 +12:00
if * shared_buttons . borrow_mut ( ) . get_mut ( page ) . unwrap ( ) . get_mut ( " select " ) . unwrap ( ) {
2020-09-22 21:24:55 +12:00
buttons_select . show ( ) ;
} else {
buttons_select . hide ( ) ;
}
2020-09-23 06:35:37 +12:00
if * shared_buttons . borrow_mut ( ) . get_mut ( page ) . unwrap ( ) . get_mut ( " delete " ) . unwrap ( ) {
2020-09-22 21:24:55 +12:00
buttons_delete . show ( ) ;
} else {
buttons_delete . hide ( ) ;
}
2020-09-23 06:35:37 +12:00
if * shared_buttons . borrow_mut ( ) . get_mut ( page ) . unwrap ( ) . get_mut ( " save " ) . unwrap ( ) {
2020-09-22 21:24:55 +12:00
buttons_save . show ( ) ;
} else {
buttons_save . hide ( ) ;
}
} ) ;
}
2020-09-10 07:32:23 +12:00
2020-09-30 08:17:58 +13:00
//// Connect Buttons
2020-09-10 07:32:23 +12:00
2020-09-30 08:17:58 +13:00
// Down notepad
2020-09-30 05:44:20 +13:00
{
2020-09-30 08:17:58 +13:00
assert! ( notebook_chooser_tool_children_names . contains ( & " notebook_duplicate_finder_label " . to_string ( ) ) ) ;
assert! ( notebook_chooser_tool_children_names . contains ( & " scrolled_window_empty_folder_finder " . to_string ( ) ) ) ;
// Search button
{
let buttons_delete = buttons_delete . clone ( ) ;
2020-10-01 01:47:39 +13:00
let buttons_save = buttons_save . clone ( ) ;
let buttons_select = buttons_select . clone ( ) ;
let entry_info = entry_info . clone ( ) ;
2020-09-30 08:17:58 +13:00
let notebook_chooser_tool_children_names = notebook_chooser_tool_children_names . clone ( ) ;
let notebook_chooser_tool = notebook_chooser_tool . clone ( ) ;
let scrolled_window_duplicate_finder = scrolled_window_duplicate_finder . clone ( ) ;
let scrolled_window_empty_folder_finder = scrolled_window_empty_folder_finder . clone ( ) ;
2020-09-30 10:00:15 +13:00
let scrolled_window_included_directories = scrolled_window_included_directories . clone ( ) ;
let scrolled_window_excluded_directories = scrolled_window_excluded_directories . clone ( ) ;
2020-09-30 08:17:58 +13:00
let text_view_errors = text_view_errors . clone ( ) ;
2020-10-01 01:47:39 +13:00
let shared_duplication_state = shared_duplication_state . clone ( ) ;
let shared_empty_folders_state = shared_empty_folders_state . clone ( ) ;
let shared_buttons = shared_buttons . clone ( ) ;
2020-09-30 08:17:58 +13:00
buttons_search . connect_clicked ( move | _ | {
match notebook_chooser_tool_children_names . get ( notebook_chooser_tool . get_current_page ( ) . unwrap ( ) as usize ) . unwrap ( ) . as_str ( ) {
" notebook_duplicate_finder_label " = > {
// Find duplicates
let mut df = DuplicateFinder ::new ( ) ;
let check_method ;
if radio_button_size . get_active ( ) {
check_method = duplicate ::CheckingMethod ::Size ;
} else if radio_button_hashmb . get_active ( ) {
check_method = duplicate ::CheckingMethod ::HashMB ;
} else if radio_button_hash . get_active ( ) {
check_method = duplicate ::CheckingMethod ::Hash ;
} else {
panic! ( " No radio button is pressed " ) ;
2020-09-30 05:44:20 +13:00
}
2020-09-30 08:17:58 +13:00
{
df . set_included_directory ( get_string_from_list_store ( & scrolled_window_included_directories ) ) ;
df . set_excluded_directory ( get_string_from_list_store ( & scrolled_window_excluded_directories ) ) ;
df . set_recursive_search ( check_button_recursive . get_active ( ) ) ;
df . set_excluded_items ( entry_excluded_items . get_text ( ) . as_str ( ) . to_string ( ) ) ;
df . set_allowed_extensions ( entry_allowed_extensions . get_text ( ) . as_str ( ) . to_string ( ) ) ;
df . set_min_file_size ( match entry_duplicate_minimal_size . get_text ( ) . as_str ( ) . parse ::< u64 > ( ) {
Ok ( t ) = > t ,
Err ( _ ) = > 1024 , // By default
} ) ;
df . set_check_method ( check_method . clone ( ) ) ;
df . set_delete_method ( duplicate ::DeleteMethod ::None ) ;
df . find_duplicates ( ) ;
2020-09-30 05:44:20 +13:00
}
2020-09-30 08:17:58 +13:00
let information = df . get_information ( ) ;
let text_messages = df . get_text_messages ( ) ;
2020-09-20 21:32:55 +12:00
2020-09-30 08:17:58 +13:00
let duplicates_number : usize ;
let duplicates_size : u64 ;
let duplicates_group : usize ;
2020-09-30 05:44:20 +13:00
match check_method {
CheckingMethod ::Hash | CheckingMethod ::HashMB = > {
2020-09-30 08:17:58 +13:00
duplicates_number = information . number_of_duplicated_files_by_hash ;
duplicates_size = information . lost_space_by_hash ;
duplicates_group = information . number_of_groups_by_hash ;
}
CheckingMethod ::Size = > {
duplicates_number = information . number_of_duplicated_files_by_size ;
duplicates_size = information . lost_space_by_size ;
duplicates_group = information . number_of_groups_by_size ;
}
CheckingMethod ::None = > {
panic! ( ) ;
}
}
2020-09-20 21:32:55 +12:00
2020-09-30 08:17:58 +13:00
entry_info . set_text ( format! ( " Found {} duplicates files in {} groups which took {} . " , duplicates_number , duplicates_group , duplicates_size . file_size ( options ::BINARY ) . unwrap ( ) ) . as_str ( ) ) ;
// Create GUI
{
let list_store = scrolled_window_duplicate_finder
. get_children ( )
. get ( 0 )
. unwrap ( )
. clone ( )
. downcast ::< gtk ::TreeView > ( )
. unwrap ( )
. get_model ( )
. unwrap ( )
. downcast ::< gtk ::ListStore > ( )
. unwrap ( ) ;
list_store . clear ( ) ;
let col_indices = [ 0 , 1 , 2 , 3 ] ;
match check_method {
CheckingMethod ::Hash | CheckingMethod ::HashMB = > {
let btreemap = df . get_files_sorted_by_hash ( ) ;
for ( size , vectors_vector ) in btreemap . iter ( ) . rev ( ) {
for vector in vectors_vector {
let values : [ & dyn ToValue ; 4 ] = [
& ( vector . len ( ) . to_string ( ) + " x " + size . to_string ( ) . as_str ( ) ) ,
& ( " ( " . to_string ( ) + ( ( vector . len ( ) - 1 ) as u64 * * size as u64 ) . to_string ( ) . as_str ( ) + " ) " ) ,
& " Bytes lost " . to_string ( ) ,
& ( HEADER_ROW_COLOR . to_string ( ) ) ,
] ;
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
for entry in vector {
let path = & entry . path ;
let index = path . rfind ( '/' ) . unwrap ( ) ;
let values : [ & dyn ToValue ; 4 ] = [
& ( path [ index + 1 .. ] . to_string ( ) ) ,
& ( path [ .. index ] . to_string ( ) ) ,
2020-10-01 17:53:10 +13:00
& ( NaiveDateTime ::from_timestamp ( entry . modified_date as i64 , 0 ) . to_string ( ) ) ,
2020-09-30 08:17:58 +13:00
& ( MAIN_ROW_COLOR . to_string ( ) ) ,
] ;
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
}
}
}
}
CheckingMethod ::Size = > {
let btreemap = df . get_files_sorted_by_size ( ) ;
for ( size , vector ) in btreemap . iter ( ) . rev ( ) {
2020-09-30 05:44:20 +13:00
let values : [ & dyn ToValue ; 4 ] = [
& ( vector . len ( ) . to_string ( ) + " x " + size . to_string ( ) . as_str ( ) ) ,
& ( " ( " . to_string ( ) + ( ( vector . len ( ) - 1 ) as u64 * * size as u64 ) . to_string ( ) . as_str ( ) + " ) " ) ,
& " Bytes lost " . to_string ( ) ,
& ( HEADER_ROW_COLOR . to_string ( ) ) ,
] ;
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
for entry in vector {
let path = & entry . path ;
let index = path . rfind ( '/' ) . unwrap ( ) ;
let values : [ & dyn ToValue ; 4 ] = [
& ( path [ index + 1 .. ] . to_string ( ) ) ,
& ( path [ .. index ] . to_string ( ) ) ,
2020-10-01 17:53:10 +13:00
& ( NaiveDateTime ::from_timestamp ( entry . modified_date as i64 , 0 ) . to_string ( ) ) ,
2020-09-30 05:44:20 +13:00
& ( MAIN_ROW_COLOR . to_string ( ) ) ,
] ;
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
}
}
}
2020-09-30 08:17:58 +13:00
CheckingMethod ::None = > {
panic! ( ) ;
2020-09-22 21:24:55 +12:00
}
}
2020-09-30 08:17:58 +13:00
print_text_messages_to_text_view ( & text_messages , & text_view_errors ) ;
}
2020-09-30 05:44:20 +13:00
2020-09-30 08:17:58 +13:00
// Set state
{
* shared_duplication_state . borrow_mut ( ) = df ;
if duplicates_size > 0 {
buttons_save . show ( ) ;
buttons_delete . show ( ) ;
2020-10-01 01:47:39 +13:00
buttons_select . show ( ) ;
2020-09-30 08:17:58 +13:00
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " save " ) . unwrap ( ) = true ;
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " delete " ) . unwrap ( ) = true ;
2020-10-01 01:47:39 +13:00
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " select " ) . unwrap ( ) = true ;
2020-09-30 08:17:58 +13:00
} else {
buttons_save . hide ( ) ;
buttons_delete . hide ( ) ;
2020-10-01 01:47:39 +13:00
buttons_select . hide ( ) ;
2020-09-30 08:17:58 +13:00
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " save " ) . unwrap ( ) = false ;
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " delete " ) . unwrap ( ) = false ;
2020-10-01 05:22:50 +13:00
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " select " ) . unwrap ( ) = false ;
2020-09-30 08:17:58 +13:00
}
2020-09-30 05:44:20 +13:00
}
2020-09-20 21:32:55 +12:00
}
2020-09-30 08:17:58 +13:00
" scrolled_window_empty_folder_finder " = > {
// Find empty folders
// TODO Change to proper value
let mut ef = EmptyFolder ::new ( ) ;
ef . set_included_directory ( " /home/rafal/Pulpit " . to_string ( ) ) ;
ef . set_delete_folder ( false ) ;
ef . find_empty_folders ( ) ;
let information = ef . get_information ( ) ;
let text_messages = ef . get_text_messages ( ) ;
let empty_folder_number : usize = information . number_of_empty_folders ;
entry_info . set_text ( format! ( " Found {} empty folders. " , empty_folder_number ) . as_str ( ) ) ;
// Create GUI
{
let list_store = scrolled_window_empty_folder_finder
. get_children ( )
. get ( 0 )
. unwrap ( )
. clone ( )
. downcast ::< gtk ::TreeView > ( )
. unwrap ( )
. get_model ( )
. unwrap ( )
. downcast ::< gtk ::ListStore > ( )
. unwrap ( ) ;
list_store . clear ( ) ;
let col_indices = [ 0 , 1 , 2 , 3 ] ;
let hashmap = ef . get_empty_folder_list ( ) ;
for ( name , entry ) in hashmap {
let name : String = name [ .. ( name . len ( ) - 1 ) ] . to_string ( ) ;
let index = name . rfind ( '/' ) . unwrap ( ) ;
let values : [ & dyn ToValue ; 4 ] = [
& ( name [ index + 1 .. ] . to_string ( ) ) ,
& ( name [ .. index ] . to_string ( ) ) ,
2020-10-01 17:53:10 +13:00
& ( NaiveDateTime ::from_timestamp ( entry . modified_date as i64 , 0 ) . to_string ( ) ) ,
2020-09-30 08:17:58 +13:00
& ( MAIN_ROW_COLOR . to_string ( ) ) ,
] ;
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
}
print_text_messages_to_text_view ( & text_messages , & text_view_errors ) ;
2020-09-30 05:44:20 +13:00
}
2020-09-30 08:17:58 +13:00
// Set state
{
* shared_empty_folders_state . borrow_mut ( ) = ef ;
if empty_folder_number > 0 {
buttons_save . show ( ) ;
buttons_delete . show ( ) ;
* shared_buttons . borrow_mut ( ) . get_mut ( " empty_folder " ) . unwrap ( ) . get_mut ( " save " ) . unwrap ( ) = true ;
* shared_buttons . borrow_mut ( ) . get_mut ( " empty_folder " ) . unwrap ( ) . get_mut ( " delete " ) . unwrap ( ) = true ;
} else {
buttons_save . hide ( ) ;
buttons_delete . hide ( ) ;
* shared_buttons . borrow_mut ( ) . get_mut ( " empty_folder " ) . unwrap ( ) . get_mut ( " save " ) . unwrap ( ) = false ;
* shared_buttons . borrow_mut ( ) . get_mut ( " empty_folder " ) . unwrap ( ) . get_mut ( " delete " ) . unwrap ( ) = false ;
}
2020-09-30 05:44:20 +13:00
}
2020-09-22 21:24:55 +12:00
}
2020-09-30 08:17:58 +13:00
e = > panic! ( " Not existent {} " , e ) ,
2020-09-22 21:24:55 +12:00
}
2020-09-30 08:17:58 +13:00
} ) ;
}
// Delete button
{
2020-10-01 03:38:45 +13:00
let scrolled_window_duplicate_finder = scrolled_window_duplicate_finder . clone ( ) ;
2020-10-01 01:47:39 +13:00
let notebook_chooser_tool_children_names = notebook_chooser_tool_children_names . clone ( ) ;
let notebook_chooser_tool = notebook_chooser_tool . clone ( ) ;
2020-10-01 05:22:50 +13:00
let buttons_delete_clone = buttons_delete . clone ( ) ;
let buttons_select = buttons_select . clone ( ) ;
let shared_buttons = shared_buttons . clone ( ) ;
buttons_delete_clone . connect_clicked ( move | _ | match notebook_chooser_tool_children_names . get ( notebook_chooser_tool . get_current_page ( ) . unwrap ( ) as usize ) . unwrap ( ) . as_str ( ) {
2020-09-30 08:17:58 +13:00
" notebook_duplicate_finder_label " = > {
let tree_view = scrolled_window_duplicate_finder . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let selection = tree_view . get_selection ( ) ;
2020-09-10 07:32:23 +12:00
2020-09-30 08:17:58 +13:00
let ( selection_rows , tree_model ) = selection . get_selected_rows ( ) ;
let list_store = tree_model . clone ( ) . downcast ::< gtk ::ListStore > ( ) . unwrap ( ) ;
2020-09-05 07:12:18 +12:00
2020-09-30 08:17:58 +13:00
// let new_tree_model = TreeModel::new(); // TODO - maybe create new model when inserting a new data, because this seems to be not optimal when using thousands of rows
2020-09-22 21:24:55 +12:00
2020-09-30 08:17:58 +13:00
let mut messages : String = " " . to_string ( ) ;
2020-09-24 21:58:59 +12:00
2020-09-30 08:17:58 +13:00
// 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 ( ) {
let name = tree_model . get_value ( & tree_model . get_iter ( & tree_path ) . unwrap ( ) , Columns3Default ::Name as i32 ) . get ::< String > ( ) . unwrap ( ) . unwrap ( ) ;
let path = tree_model . get_value ( & tree_model . get_iter ( & tree_path ) . unwrap ( ) , Columns3Default ::Path as i32 ) . get ::< String > ( ) . unwrap ( ) . unwrap ( ) ;
2020-09-24 21:58:59 +12:00
2020-09-30 08:17:58 +13:00
if fs ::remove_file ( format! ( " {} / {} " , path , name ) ) . is_err ( ) {
messages + = format! ( " Failed to remove file {} / {} because file doesn't exists or you don't have permissions. \n " , path , name ) . as_str ( )
}
list_store . remove ( & list_store . get_iter ( & tree_path ) . unwrap ( ) ) ;
2020-09-30 05:44:20 +13:00
}
2020-09-30 08:17:58 +13:00
text_view_errors . get_buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
selection . unselect_all ( ) ;
2020-10-01 05:22:50 +13:00
buttons_delete . hide ( ) ;
buttons_select . hide ( ) ;
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " delete " ) . unwrap ( ) = false ;
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " select " ) . unwrap ( ) = false ;
2020-09-30 08:17:58 +13:00
}
" scrolled_window_empty_folder_finder " = > {
let tree_view = scrolled_window_empty_folder_finder . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let selection = tree_view . get_selection ( ) ;
2020-09-24 21:58:59 +12:00
2020-09-30 08:17:58 +13:00
let ( selection_rows , tree_model ) = selection . get_selected_rows ( ) ;
let list_store = tree_model . clone ( ) . downcast ::< gtk ::ListStore > ( ) . unwrap ( ) ;
2020-09-25 02:11:59 +12:00
2020-09-30 08:17:58 +13:00
// let new_tree_model = TreeModel::new(); // TODO - maybe create new model when inserting a new data, because this seems to be not optimal when using thousands of rows
2020-09-25 02:11:59 +12:00
2020-09-30 08:17:58 +13:00
let mut messages : String = " " . to_string ( ) ;
2020-09-25 02:11:59 +12:00
2020-09-30 08:17:58 +13:00
// 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 ( ) {
let name = tree_model . get_value ( & tree_model . get_iter ( & tree_path ) . unwrap ( ) , Columns3Default ::Name as i32 ) . get ::< String > ( ) . unwrap ( ) . unwrap ( ) ;
let path = tree_model . get_value ( & tree_model . get_iter ( & tree_path ) . unwrap ( ) , Columns3Default ::Path as i32 ) . get ::< String > ( ) . unwrap ( ) . unwrap ( ) ;
2020-09-26 06:29:09 +12:00
2020-09-30 08:17:58 +13:00
if fs ::remove_dir ( format! ( " {} / {} " , path , name ) ) . is_err ( ) {
messages + = format! ( " Failed to folder {} / {} due lack of permissions, selected dir is not empty or doesn't exists. \n " , path , name ) . as_str ( )
}
list_store . remove ( & list_store . get_iter ( & tree_path ) . unwrap ( ) ) ;
2020-09-30 05:44:20 +13:00
}
2020-09-30 00:50:31 +13:00
2020-09-30 08:17:58 +13:00
text_view_errors . get_buffer ( ) . unwrap ( ) . set_text ( messages . as_str ( ) ) ;
selection . unselect_all ( ) ;
}
e = > panic! ( " Not existent {} " , e ) ,
2020-10-01 01:47:39 +13:00
} ) ;
}
// Select button
{
let notebook_chooser_tool_children_names = notebook_chooser_tool_children_names . clone ( ) ;
let notebook_chooser_tool = notebook_chooser_tool . clone ( ) ;
2020-10-01 03:38:45 +13:00
let buttons_select_clone = buttons_select . clone ( ) ;
let popover_select = popover_select . clone ( ) ;
buttons_select_clone . connect_clicked ( move | _ | match notebook_chooser_tool_children_names . get ( notebook_chooser_tool . get_current_page ( ) . unwrap ( ) as usize ) . unwrap ( ) . as_str ( ) {
2020-10-01 01:47:39 +13:00
" notebook_duplicate_finder_label " = > {
2020-10-01 03:38:45 +13:00
// Only popup popup
popover_select . set_relative_to ( Some ( & buttons_select ) ) ;
popover_select . popup ( ) ;
2020-10-01 01:47:39 +13:00
}
" scrolled_window_empty_folder_finder " = > {
// Do nothing
}
e = > panic! ( " Not existent {} " , e ) ,
} ) ;
}
// Save button
{
let buttons_save_clone = buttons_save . clone ( ) ;
buttons_save_clone . connect_clicked ( move | _ | match notebook_chooser_tool_children_names . get ( notebook_chooser_tool . get_current_page ( ) . unwrap ( ) as usize ) . unwrap ( ) . as_str ( ) {
" notebook_duplicate_finder_label " = > {
let file_name = " results_duplicates.txt " ;
let mut df = shared_duplication_state . borrow_mut ( ) ;
df . save_results_to_file ( file_name ) ;
entry_info . set_text ( format! ( " Saved results to file {} " , file_name ) . as_str ( ) ) ;
// Set state
{
buttons_save . hide ( ) ;
* shared_buttons . borrow_mut ( ) . get_mut ( " duplicate " ) . unwrap ( ) . get_mut ( " save " ) . unwrap ( ) = false ;
}
}
" scrolled_window_empty_folder_finder " = > {
let file_name = " results_empty_folder.txt " ;
let mut ef = shared_empty_folders_state . borrow_mut ( ) ;
ef . save_results_to_file ( file_name ) ;
entry_info . set_text ( format! ( " Saved results to file {} " , file_name ) . as_str ( ) ) ;
// Set state
{
2020-10-01 03:38:45 +13:00
buttons_save . hide ( ) ;
* shared_buttons . borrow_mut ( ) . get_mut ( " empty_folder " ) . unwrap ( ) . get_mut ( " save " ) . unwrap ( ) = false ;
2020-10-01 01:47:39 +13:00
}
}
e = > panic! ( " Not existent {} " , e ) ,
2020-09-30 08:17:58 +13:00
} ) ;
}
}
2020-10-01 03:38:45 +13:00
// Popover Buttons
{
// Select all button
{
let scrolled_window_duplicate_finder = scrolled_window_duplicate_finder . clone ( ) ;
let popover_select = popover_select . clone ( ) ;
buttons_popover_select_all . connect_clicked ( move | _ | {
let tree_view = scrolled_window_duplicate_finder . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let selection = tree_view . get_selection ( ) ;
selection . select_all ( ) ;
popover_select . popdown ( ) ;
} ) ;
}
// Unselect all button
{
2020-10-01 05:22:50 +13:00
let scrolled_window_duplicate_finder = scrolled_window_duplicate_finder . clone ( ) ;
let popover_select = popover_select . clone ( ) ;
2020-10-01 03:38:45 +13:00
buttons_popover_unselect_all . connect_clicked ( move | _ | {
let tree_view = scrolled_window_duplicate_finder . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let selection = tree_view . get_selection ( ) ;
selection . unselect_all ( ) ;
popover_select . popdown ( ) ;
} ) ;
}
2020-10-01 05:22:50 +13:00
// Reverse selection
{
// let scrolled_window_duplicate_finder = scrolled_window_duplicate_finder.clone();
// let popover_select = popover_select.clone();
buttons_popover_reverse . connect_clicked ( move | _ | {
let tree_view = scrolled_window_duplicate_finder . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let selection = tree_view . get_selection ( ) ;
let ( vector_tree_path , tree_model ) = selection . get_selected_rows ( ) ;
if vector_tree_path . is_empty ( ) {
selection . select_all ( ) ;
} else {
let tree_iter_all = tree_model . get_iter_first ( ) . unwrap ( ) ; // Never should be available button where there is no available records
2020-10-01 17:53:10 +13:00
2020-10-01 05:22:50 +13:00
let mut current_path_index = 0 ;
let mut tree_iter_selected : TreeIter ;
loop {
if current_path_index > = vector_tree_path . len ( ) {
selection . select_iter ( & tree_iter_all ) ;
} else {
tree_iter_selected = tree_model . get_iter ( vector_tree_path . get ( current_path_index ) . unwrap ( ) ) . unwrap ( ) ;
if tree_model . get_path ( & tree_iter_all ) . unwrap ( ) = = tree_model . get_path ( & tree_iter_selected ) . unwrap ( ) {
selection . unselect_iter ( & tree_iter_selected ) ;
current_path_index + = 1 ;
} else {
selection . select_iter ( & tree_iter_all ) ;
}
}
if ! tree_model . iter_next ( & tree_iter_all ) {
break ;
}
}
}
popover_select . popdown ( ) ;
} ) ;
}
2020-10-01 17:53:10 +13:00
// // All except oldest
// {
// // let scrolled_window_duplicate_finder = scrolled_window_duplicate_finder.clone();
// // let popover_select = popover_select.clone();
// buttons_popover_reverse.connect_clicked(move |_| {
// let tree_view = scrolled_window_duplicate_finder.get_children().get(0).unwrap().clone().downcast::<gtk::TreeView>().unwrap();
// let selection = tree_view.get_selection();
//
// let (vector_tree_path, tree_model) = selection.get_selected_rows();
//
// {
// let tree_iter_all = tree_model.get_iter_first().unwrap(); // Never should be available button where there is no available records
//
// let mut current_path_index = 0;
// let mut tree_iter_selected: TreeIter;
//
// let color = tree_model.get_value(&tree_model.get_iter(tree_path).unwrap(), Columns3Default::Color as i32).get::<String>().unwrap().unwrap();
//
// loop {
// let array_to_have: Vec<SystemTime> = Vec::new();
// let oldest_index : Option<int> = None;
//
// loop {
// if color == HEADER_ROW_COLOR {
// break;
// }
//
//
//
// if current_path_index >= vector_tree_path.len() {
// selection.select_iter(&tree_iter_all);
// } else {
// tree_iter_selected = tree_model.get_iter(vector_tree_path.get(current_path_index).unwrap()).unwrap();
// if tree_model.get_path(&tree_iter_all).unwrap() == tree_model.get_path(&tree_iter_selected).unwrap() {
// selection.unselect_iter(&tree_iter_selected);
// current_path_index += 1;
// } else {
// selection.select_iter(&tree_iter_all);
// }
// }
// if !tree_model.iter_next(&tree_iter_all) {
// break;
// }
// }
// if arry
// }
// }
//
// popover_select.popdown();
// });
// }
2020-10-01 03:38:45 +13:00
}
2020-09-30 08:17:58 +13:00
// Upper Notepad
{
2020-09-30 10:00:15 +13:00
// Add included directory
{
let scrolled_window_included_directories = scrolled_window_included_directories . clone ( ) ;
let main_window = main_window . clone ( ) ;
buttons_add_included_directory . connect_clicked ( move | _ | {
let chooser = gtk ::FileChooserDialog ::with_buttons (
Option ::from ( " Folders to include " ) ,
Option ::from ( & main_window ) ,
gtk ::FileChooserAction ::SelectFolder ,
& [ ( " Ok " , gtk ::ResponseType ::Ok ) , ( " Close " , gtk ::ResponseType ::Cancel ) ] ,
) ;
chooser . show_all ( ) ;
let response_type = chooser . run ( ) ;
if response_type = = gtk ::ResponseType ::Ok {
let folder = chooser . get_filename ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ;
let tree_view = scrolled_window_included_directories . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let list_store = tree_view . get_model ( ) . unwrap ( ) . downcast ::< gtk ::ListStore > ( ) . unwrap ( ) ;
let col_indices = [ 0 , 1 ] ;
let values : [ & dyn ToValue ; 2 ] = [ & folder , & ( MAIN_ROW_COLOR . to_string ( ) ) ] ;
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
}
chooser . close ( ) ;
} ) ;
}
2020-09-30 08:17:58 +13:00
// Add excluded directory
2020-09-30 10:00:15 +13:00
{
let scrolled_window_excluded_directories = scrolled_window_excluded_directories . clone ( ) ;
let main_window = main_window . clone ( ) ;
buttons_add_excluded_directory . connect_clicked ( move | _ | {
let chooser = gtk ::FileChooserDialog ::with_buttons (
Option ::from ( " Folders to exclude " ) ,
Option ::from ( & main_window ) ,
gtk ::FileChooserAction ::SelectFolder ,
& [ ( " Ok " , gtk ::ResponseType ::Ok ) , ( " Close " , gtk ::ResponseType ::Cancel ) ] ,
) ;
chooser . show_all ( ) ;
let response_type = chooser . run ( ) ;
if response_type = = gtk ::ResponseType ::Ok {
let folder = chooser . get_filename ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ;
let tree_view = scrolled_window_excluded_directories . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let list_store = tree_view . get_model ( ) . unwrap ( ) . downcast ::< gtk ::ListStore > ( ) . unwrap ( ) ;
let col_indices = [ 0 , 1 ] ;
let values : [ & dyn ToValue ; 2 ] = [ & folder , & ( MAIN_ROW_COLOR . to_string ( ) ) ] ;
list_store . set ( & list_store . append ( ) , & col_indices , & values ) ;
}
chooser . close ( ) ;
} ) ;
}
// Remove Excluded Folder
{
//let scrolled_window_excluded_directories = scrolled_window_excluded_directories.clone();
buttons_remove_excluded_directory . connect_clicked ( move | _ | {
let tree_view = scrolled_window_excluded_directories . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let list_store = tree_view . get_model ( ) . unwrap ( ) . downcast ::< gtk ::ListStore > ( ) . unwrap ( ) ;
let selection = tree_view . get_selection ( ) ;
let ( _ , tree_iter ) = match selection . get_selected ( ) {
Some ( t ) = > t ,
None = > {
return ;
}
} ;
list_store . remove ( & tree_iter ) ;
} ) ;
}
// Remove Included Folder
{
//let scrolled_window_included_directories = scrolled_window_included_directories.clone();
buttons_remove_included_directory . connect_clicked ( move | _ | {
let tree_view = scrolled_window_included_directories . get_children ( ) . get ( 0 ) . unwrap ( ) . clone ( ) . downcast ::< gtk ::TreeView > ( ) . unwrap ( ) ;
let list_store = tree_view . get_model ( ) . unwrap ( ) . downcast ::< gtk ::ListStore > ( ) . unwrap ( ) ;
let selection = tree_view . get_selection ( ) ;
let ( _ , tree_iter ) = match selection . get_selected ( ) {
Some ( t ) = > t ,
None = > {
return ;
}
} ;
list_store . remove ( & tree_iter ) ;
} ) ;
}
2020-09-30 05:44:20 +13:00
}
2020-09-30 00:50:31 +13:00
}
2020-09-30 05:44:20 +13:00
// Quit the program when X in main window was clicked
main_window . connect_delete_event ( | _ , _ | {
gtk ::main_quit ( ) ;
Inhibit ( false )
} ) ;
// We start the gtk main loop.
gtk ::main ( ) ;
2020-09-26 06:29:09 +12:00
}