/* $Id: sort.c,v 1.2 2000/01/30 19:50:22 benediktroth Exp $ */ #include #include #include #include #include #include #include #include #include "yamt.h" #include "sort.h" GtkWidget *sort_box_new( ) { GtkWidget *box; GtkWidget *sort_directory_frame; GtkWidget *sort_directory_table; GtkWidget *sort_directory_source_label; GtkWidget *sort_directory_target_label; GtkWidget *sort_button_select_source; GtkWidget *sort_button_select_target; GtkWidget *hbox; GtkWidget *sort_task_frame; GtkWidget *sort_task_table; GtkWidget *sort_format_frame; GtkWidget *sort_format_table; GtkWidget *sort_level1_label; GtkWidget *sort_level2_label; GtkWidget *sort_buttons_box; GtkWidget *sort_buttons_quit; GtkWidget *sort_buttons_start; /* The box it which everything is put */ box = gtk_vbox_new( FALSE, 0); /* Frame for directory */ sort_directory_frame = gtk_frame_new( NULL ); gtk_box_pack_start( GTK_BOX (box), sort_directory_frame, TRUE, FALSE, 0 ); gtk_widget_show( sort_directory_frame ); /* Table for directory */ sort_directory_table = gtk_table_new( 2, 2, TRUE); gtk_table_set_row_spacings( GTK_TABLE (sort_directory_table), 5); gtk_container_set_border_width( GTK_CONTAINER (sort_directory_table), 5); gtk_container_add( GTK_CONTAINER (sort_directory_frame), sort_directory_table ); gtk_widget_show( sort_directory_table ); /* The Source Directory */ sort_directory_source_label=gtk_label_new( _("Source Directory: ") ); gtk_table_attach_defaults( GTK_TABLE (sort_directory_table), sort_directory_source_label, 0, 1, 0, 1); gtk_widget_show( sort_directory_source_label ); sort_directory_source=gtk_label_new( _("[no dir selected]") ); gtk_table_attach_defaults( GTK_TABLE (sort_directory_table), sort_directory_source, 1, 2, 0, 1); gtk_widget_show( sort_directory_source ); /* The select button */ sort_button_select_source = gnome_stock_or_ordinary_button( GNOME_STOCK_PIXMAP_OPEN ); gtk_signal_connect( GTK_OBJECT (sort_button_select_source), "clicked", GTK_SIGNAL_FUNC (sort_directory_select), _("Select Directory") ); gtk_table_attach_defaults( GTK_TABLE (sort_directory_table), sort_button_select_source, 2, 3, 0, 1); gtk_widget_show( sort_button_select_source ); /* The Target (Root) Directory */ sort_directory_target_label=gtk_label_new( _("Target Directory: ") ); gtk_table_attach_defaults( GTK_TABLE (sort_directory_table), sort_directory_target_label, 0, 1, 1, 2); gtk_widget_show( sort_directory_target_label ); sort_directory_target=gtk_label_new( _("[no dir selected]") ); gtk_table_attach_defaults( GTK_TABLE (sort_directory_table), sort_directory_target, 1, 2, 1, 2); gtk_widget_show( sort_directory_target ); /* The select button */ sort_button_select_target = gnome_stock_or_ordinary_button( GNOME_STOCK_PIXMAP_OPEN ); gtk_signal_connect( GTK_OBJECT (sort_button_select_target), "clicked", GTK_SIGNAL_FUNC (sort_directory_select2), _("Select Directory") ); gtk_table_attach_defaults( GTK_TABLE (sort_directory_table), sort_button_select_target, 2, 3, 1, 2); gtk_widget_show( sort_button_select_target ); /* The recursive button */ sort_button_recursive = gtk_check_button_new_with_label( _("Recurse Subdirs") ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON (sort_button_recursive), FALSE ); gtk_table_attach_defaults( GTK_TABLE (sort_directory_table), sort_button_recursive, 1, 2, 2, 3); gtk_widget_show( sort_button_recursive ); /* ******************************************* */ hbox = gtk_hbox_new( FALSE, 10 ); gtk_box_pack_start( GTK_BOX(box), hbox, FALSE, TRUE, 0 ); gtk_widget_show( hbox ); /* ------------------------------ */ /* The Task frame */ sort_task_frame = gtk_frame_new( NULL ); gtk_frame_set_label( GTK_FRAME (sort_task_frame), _("Task") ); gtk_box_pack_start( GTK_BOX (hbox), sort_task_frame, TRUE, TRUE, 0 ); gtk_widget_show( sort_task_frame ); /* Table */ sort_task_table = gtk_table_new( 2, 1, TRUE); gtk_container_add( GTK_CONTAINER (sort_task_frame), sort_task_table ); gtk_widget_show( sort_task_table ); /* Sort */ sort_task_sort = gtk_radio_button_new_with_label( NULL, _("Sort") ); gtk_signal_connect( GTK_OBJECT(sort_task_sort), "clicked", GTK_SIGNAL_FUNC(sort_task_switched), NULL ); gtk_table_attach_defaults( GTK_TABLE (sort_task_table), sort_task_sort, 0, 1, 0, 1); gtk_widget_show(sort_task_sort); /* Unsort */ sort_task_unsort = gtk_radio_button_new_with_label( gtk_radio_button_group( GTK_RADIO_BUTTON(sort_task_sort)), _("Unsort") ); gtk_signal_connect( GTK_OBJECT(sort_task_unsort), "clicked", GTK_SIGNAL_FUNC(sort_task_switched), NULL ); gtk_table_attach_defaults( GTK_TABLE (sort_task_table), sort_task_unsort, 0, 1, 1, 2); gtk_widget_show(sort_task_unsort); /* ------------------------------ */ /* The format frame */ sort_format_frame = gtk_frame_new( NULL ); gtk_frame_set_label( GTK_FRAME (sort_format_frame), _("Format") ); gtk_box_pack_start( GTK_BOX (hbox), sort_format_frame, TRUE, TRUE, 0 ); gtk_widget_show( sort_format_frame ); /* Table */ sort_format_table = gtk_table_new( 2, 3, FALSE); gtk_container_add( GTK_CONTAINER (sort_format_frame), sort_format_table ); gtk_widget_show( sort_format_table ); /* Label for level 1 */ sort_level1_label = gtk_label_new( _("Level 1:") ); gtk_table_attach_defaults( GTK_TABLE (sort_format_table), sort_level1_label, 0, 1, 0, 1); gtk_widget_show( sort_level1_label ); /* Create a new combo box */ sort_level1 = gtk_combo_new(); gtk_entry_set_editable( GTK_ENTRY (GTK_COMBO(sort_level1)->entry), FALSE); /* Create the CList */ if ( !sort_level1_list ) { sort_level1_list = g_list_append( sort_level1_list, _("Artist") ); sort_level1_list = g_list_append( sort_level1_list, _("Album") ); sort_level1_list = g_list_append( sort_level1_list, _("Year") ); sort_level1_list = g_list_append( sort_level1_list, _("Genre") ); sort_level1_list = g_list_append( sort_level1_list, _("Comment") ); sort_level1_list = g_list_append( sort_level1_list, _("Title") ); } /* Connect the combo and the list */ gtk_combo_set_popdown_strings( GTK_COMBO(sort_level1), sort_level1_list); gtk_table_attach_defaults( GTK_TABLE (sort_format_table), sort_level1, 1, 2, 0, 1); gtk_widget_show( sort_level1 ); /* Label for level 2 */ sort_level2_label = gtk_label_new( _("Level 2:") ); gtk_table_attach_defaults( GTK_TABLE (sort_format_table), sort_level2_label, 0, 1, 2, 3); gtk_widget_show( sort_level2_label); /* Create a new combo box */ sort_level2 = gtk_combo_new(); gtk_entry_set_editable( GTK_ENTRY (GTK_COMBO(sort_level2)->entry), FALSE); /* Create the CList */ if ( !sort_level2_list ) { sort_level2_list = g_list_append( sort_level2_list, _("Album") ); sort_level2_list = g_list_append( sort_level2_list, _("Artist") ); sort_level2_list = g_list_append( sort_level2_list, _("Year") ); sort_level2_list = g_list_append( sort_level2_list, _("Genre") ); sort_level2_list = g_list_append( sort_level2_list, _("Comment") ); sort_level2_list = g_list_append( sort_level2_list, _("Title") ); } /* Connect the combo and the list */ gtk_combo_set_popdown_strings( GTK_COMBO(sort_level2), sort_level2_list); gtk_table_attach_defaults( GTK_TABLE (sort_format_table), sort_level2, 1, 2, 2, 3); gtk_widget_show( sort_level2 ); /* The Box for the buttons */ sort_buttons_box = gtk_hbox_new( TRUE, 10); gtk_container_set_border_width( GTK_CONTAINER (sort_buttons_box), 3); gtk_box_pack_start( GTK_BOX (box), sort_buttons_box, TRUE, FALSE, 0 ); gtk_widget_show( sort_buttons_box ); /* The Buttons */ sort_buttons_start = gnome_stock_or_ordinary_button( GNOME_STOCK_PIXMAP_EXEC ); gtk_signal_connect( GTK_OBJECT (sort_buttons_start), "clicked", GTK_SIGNAL_FUNC (sort_start), NULL ); gtk_box_pack_start( GTK_BOX (sort_buttons_box), sort_buttons_start, TRUE, TRUE, 0 ); gtk_widget_show( sort_buttons_start ); sort_buttons_quit = gnome_stock_or_ordinary_button( GNOME_STOCK_PIXMAP_QUIT ); gtk_signal_connect( GTK_OBJECT (sort_buttons_quit), "clicked", GTK_SIGNAL_FUNC (gtk_exit), NULL ); gtk_box_pack_start( GTK_BOX (sort_buttons_box), sort_buttons_quit, TRUE, TRUE, 0 ); gtk_widget_show( sort_buttons_quit ); return(box); } void sort_load_properties( void ) { gtk_label_set_text( GTK_LABEL (sort_directory_source), prop_mp3_dir ); } void sort_task_switched( GtkWidget *widget, gpointer *data ) { gboolean active; active = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(sort_task_sort) ); if( active ) { gtk_widget_set_sensitive( GTK_WIDGET(sort_level1), TRUE ); gtk_widget_set_sensitive( GTK_WIDGET(sort_level2), TRUE ); } else { gtk_widget_set_sensitive( GTK_WIDGET(sort_level1), FALSE ); gtk_widget_set_sensitive( GTK_WIDGET(sort_level2), FALSE ); } } void sort_directory_select( void ) { GtkWidget *filew; gchar *buffer; gtk_label_get( GTK_LABEL (sort_directory_source), &buffer ); filew = gtk_file_selection_new( _("Select a Directory") ); gtk_file_selection_set_filename( GTK_FILE_SELECTION (filew), buffer ); gtk_signal_connect( GTK_OBJECT (filew), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroy), filew); /* Connect the ok buton to load_file */ gtk_signal_connect( GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button), "clicked", GTK_SIGNAL_FUNC (sort_lf), filew); gtk_signal_connect( GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button), "clicked", GTK_SIGNAL_FUNC (destroy), filew); /* Connect the cancel buton to destroy */ gtk_signal_connect( GTK_OBJECT (GTK_FILE_SELECTION (filew)->cancel_button), "clicked", GTK_SIGNAL_FUNC (destroy), filew); gtk_widget_show(filew); } /* I don't know how to pass the filename directly to load_file so I use this function */ void sort_lf( GtkWidget *widget, GtkFileSelection *file_selection ) { gchar *filename=gtk_file_selection_get_filename( GTK_FILE_SELECTION (file_selection)); sort_directory_load( filename ); } void sort_directory_load( gchar *dirname ) { gtk_label_set_text( GTK_LABEL (sort_directory_source),dirname); /* g_print("dir: %s\n", dirname ); */ } void sort_directory_select2( void ) { GtkWidget *filew; filew = gtk_file_selection_new( _("Select a Directory") ); gtk_file_selection_set_filename( GTK_FILE_SELECTION (filew), prop_mp3_dir ); gtk_signal_connect( GTK_OBJECT (filew), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroy), filew); /* Connect the ok buton to load_file */ gtk_signal_connect( GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button), "clicked", GTK_SIGNAL_FUNC (sort_lf2), filew); gtk_signal_connect( GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button), "clicked", GTK_SIGNAL_FUNC (destroy), filew); /* Connect the cancel buton to destroy */ gtk_signal_connect( GTK_OBJECT (GTK_FILE_SELECTION (filew)->cancel_button), "clicked", GTK_SIGNAL_FUNC (destroy), filew); gtk_widget_show(filew); } /* I don't know how to pass the filename directly to load_file so I use this function */ void sort_lf2( GtkWidget *widget, GtkFileSelection *file_selection ) { gchar *filename=gtk_file_selection_get_filename( GTK_FILE_SELECTION (file_selection)); sort_directory_load2( filename ); } void sort_directory_load2( gchar *dirname ) { gtk_label_set_text( GTK_LABEL (sort_directory_target),dirname); /* g_print("dir: %s\n", dirname ); */ } void sort_start( void ) { gchar *format_level1; gchar *format_level2; gchar *source_directory; gchar *target_directory; gboolean recursive; gboolean sort; gtk_label_get( GTK_LABEL (sort_directory_source), &source_directory ); yamtlog("%s %s", "Sort-(Source-)Directory: ", source_directory); gtk_label_get( GTK_LABEL (sort_directory_target), &target_directory ); if( (strcmp( target_directory, _("[no dir selected]") )) == 0 ) { target_directory = g_strdup( source_directory ); if( target_directory[strlen(target_directory)-1] != '/' ) strcat( target_directory, "/" ); } yamtlog("%s %s", "Sort-(Root-)Directory: ", target_directory ); sort = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(sort_task_sort) ); yamtlog("%s %s", _("Sort: "), sort ? "TRUE" : "FALSE" ); if( sort ) { format_level1 = gtk_entry_get_text( GTK_ENTRY(GTK_COMBO(sort_level1)->entry) ); /* Replace the internationalized string with english */ /* so that id3tag_sort() can use it */ if( !strcmp( format_level1, _("Title") ) ) format_level1 = "Title"; else if( !strcmp( format_level1, _("Artist") ) ) format_level1 = "Artist"; else if( !strcmp( format_level1, _("Album") ) ) format_level1 = "Album"; else if( !strcmp( format_level1, _("Comment") ) ) format_level1 = "Comment"; else if( !strcmp( format_level1, _("Year") ) ) format_level1 = "Year"; else if( !strcmp( format_level1, _("Genre") ) ) format_level1 = "Genre"; yamtlog("%s %s", "Sort-Format Level1: ", format_level1); format_level2 = gtk_entry_get_text( GTK_ENTRY(GTK_COMBO(sort_level2)->entry) ); /* Replace the internationalized string with english */ /* so that id3tag_sort() can use them */ if( !strcmp( format_level2, _("Title") ) ) format_level2 = "Title"; else if( !strcmp( format_level2, _("Artist") ) ) format_level2 = "Artist"; else if( !strcmp( format_level2, _("Album") ) ) format_level2 = "Album"; else if( !strcmp( format_level2, _("Comment") ) ) format_level2 = "Comment"; else if( !strcmp( format_level2, _("Year") ) ) format_level2 = "Year"; else if( !strcmp( format_level2, _("Genre") ) ) format_level2 = "Genre"; yamtlog("%s %s", "Sort-Format Level2: ", format_level2); recursive = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(sort_button_recursive) ); yamtlog("%s %s", _("Sort-Recursive: "), recursive ? "TRUE" : "FALSE" ); sort_go( target_directory, source_directory, 0 , recursive, format_level1, format_level2); } else { /* move files */ unsort_go( target_directory, source_directory, 0 , 1 ); /* delete dirs */ unsort_go2( source_directory ); } } void sort_go( gchar *rootdir, gchar *dir, gint depth, gboolean recursive, gchar *format_level1, gchar *format_level2 ) { DIR *dp; struct dirent *entry; struct stat statbuf; if( (dp = opendir(dir))==NULL ) { yamtlog("%s %s", _("ERROR while opening "), dir); gnome_error_dialog( _("Could not open directory!") ); return; } while( (entry = readdir(dp)) != NULL ) { chdir(dir); lstat( entry->d_name, &statbuf); if( S_ISDIR(statbuf.st_mode)) /* If it's a directory */ { /* Shall it be recursive ? */ if( recursive == 0 ) continue; /* ignore "." and ".." */ if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 ) continue; /* printf("%*s%s/\n", depth, " ", entry->d_name ); */ /* Recurse but increase the indent level */ sort_go( rootdir, entry->d_name, depth+4, recursive, format_level1, format_level2 ); } else /* If it's not a directory */ { /* printf("%*s%s\n", depth, " ", entry->d_name ); */ id3tag_sort( entry->d_name, rootdir, format_level1, format_level2 ); } } chdir(".."); closedir(dp); } void unsort_go( gchar *rootdir, gchar *dir, gint depth, gboolean recursive ) { DIR *dp; struct dirent *entry; struct stat statbuf; gchar command[80]=""; if( (dp = opendir(dir))==NULL ) { yamtlog("%s %s", _("ERROR while opening "), dir); gnome_error_dialog( _("Could not open directory!") ); return; } while( (entry = readdir(dp)) != NULL ) { chdir(dir); lstat( entry->d_name, &statbuf); if( S_ISDIR(statbuf.st_mode)) /* If it's a directory */ { /* Shall it be recursive ? */ if( recursive == 0 ) continue; /* ignore "." and ".." */ if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 ) continue; printf("%*s%s/\n", depth, " ", entry->d_name ); /* Recurse but increase the indent level */ unsort_go( rootdir, entry->d_name, depth+4, recursive ); } else /* If it's not a directory */ { /* printf("%*s%s\n", depth, " ", entry->d_name ); */ sprintf( command, "mv \"%s\" \"%s%s\"", entry->d_name, rootdir,entry->d_name ); system(command); } } chdir(".."); closedir(dp); } /* Delete all (empty) (sub)dirs */ void unsort_go2( gchar *dir ) { DIR *dp; struct dirent *entry; struct stat statbuf; if( (dp = opendir(dir))==NULL ) { yamtlog("%s %s", _("ERROR while opening "), dir); gnome_error_dialog( _("Could not open directory!") ); return; } while( (entry = readdir(dp)) != NULL ) { update_progress_bar(); chdir(dir); lstat( entry->d_name, &statbuf); if( S_ISDIR(statbuf.st_mode)) /* If it's a directory */ { /* ignore "." and ".." */ if( strcmp(".", entry->d_name) == 0 || strcmp("..", entry->d_name) == 0 ) continue; unsort_go2( entry->d_name ); remove( entry->d_name ); } else /* If it's not a directory */ { continue; } } chdir(".."); closedir(dp); }