mp3splt-gtk
split_files.c
Go to the documentation of this file.
00001 /**********************************************************
00002  *
00003  * mp3splt-gtk -- utility based on mp3splt,
00004  *                for mp3/ogg splitting without decoding
00005  *
00006  * Copyright: (C) 2005-2011 Alexandru Munteanu
00007  * Contact: io_fx@yahoo.fr
00008  *
00009  * http://mp3splt.sourceforge.net/
00010  *
00011  *********************************************************/
00012 
00013 /**********************************************************
00014  *
00015  * This program is free software; you can redistribute it and/or
00016  * modify it under the terms of the GNU General Public License
00017  * as published by the Free Software Foundation; either version 2
00018  * of the License, or (at your option) any later version.
00019  *
00020  * This program is distributed in the hope that it will be useful,
00021  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  * GNU General Public License for more details.
00024  *
00025  * You should have received a copy of the GNU General Public License
00026  * along with this program; if not, write to the Free Software
00027  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
00028  * USA.
00029  *
00030  *********************************************************/
00031 
00032 /*!********************************************************
00033  * \file 
00034  * The split tab
00035  *
00036  * file that handles the split files tab from the main 
00037  * window
00038  **********************************************************/
00039 
00040 #include <gtk/gtk.h>
00041 #include <glib/gi18n.h>
00042 #include <string.h>
00043 #include <glib.h>
00044 #include <glib/gstdio.h>
00045 
00046 #include "util.h"
00047 #include "player.h"
00048 #include "player_tab.h"
00049 #include "split_files.h"
00050 #include "utilities.h"
00051 #include "main_win.h"
00052 
00054 GtkWidget *split_tree;
00055 
00057 gint split_table_number = 0;
00058 
00060 GtkWidget *split_handle_box;
00062 GtkWidget *queue_files_button;
00064 GtkWidget *remove_file_button;
00066 GtkWidget *remove_all_files_button;
00067 
00068 extern gint selected_player;
00069 extern gint split_files;
00070 extern gboolean timer_active;
00071 
00073 enum
00074 {
00075   COL_NAME,
00076   COL_FILENAME,
00077   SPLIT_COLUMNS
00078 };
00079 
00081 GtkTreeModel *create_split_model()
00082 {
00083   GtkListStore *model;
00084 
00085   model = gtk_list_store_new(SPLIT_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
00086 
00087   return GTK_TREE_MODEL (model);
00088 }
00089 
00091 GtkTreeView *create_split_files_tree()
00092 {
00093   GtkTreeView *tree_view;
00094   GtkTreeModel *model;
00095   //create the model
00096   model = (GtkTreeModel *)create_split_model();
00097   //create the tree view
00098   tree_view = (GtkTreeView *)
00099     gtk_tree_view_new_with_model (model);
00100 
00101   return tree_view;
00102 }
00103 
00105 void create_split_columns (GtkTreeView *tree_view)
00106 {
00107   GtkCellRendererText *renderer =
00108     GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
00109   g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_NAME));
00110   GtkTreeViewColumn *name_column = gtk_tree_view_column_new_with_attributes 
00111     (_("Filename"), GTK_CELL_RENDERER(renderer), "text", COL_NAME, NULL);
00112 
00113   //appends columns to the list of columns of tree_view
00114   gtk_tree_view_insert_column(GTK_TREE_VIEW(tree_view),
00115       GTK_TREE_VIEW_COLUMN(name_column),COL_NAME);
00116 
00117   gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 0.5);
00118   gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(name_column),
00119       GTK_TREE_VIEW_COLUMN_AUTOSIZE);
00120   gtk_tree_view_column_set_resizable(name_column, TRUE);
00121 }
00122 
00124 void remove_all_split_rows ()
00125 {
00126   GtkTreeIter iter;
00127   GtkTreeView *tree_view = 
00128     (GtkTreeView *)split_tree;
00129   GtkTreeModel *model;
00130 
00131   model = gtk_tree_view_get_model(tree_view);
00132 
00133   //while we still have rows in the table
00134   while (split_table_number > 0)
00135     {
00136       gtk_tree_model_get_iter_first(model, &iter);
00137       gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
00138       //remove values from the splitpoint array
00139       split_table_number--;
00140     }
00141 }
00142 
00147 guchar *get_real_name_from_filename(guchar *filename)
00148 {
00149   while (strchr((gchar *) filename, G_DIR_SEPARATOR)!=NULL)
00150     filename = (guchar *)strchr((gchar *)filename, G_DIR_SEPARATOR) + 1;
00151 
00152   return filename;
00153 }
00154 
00156 void add_split_row(const gchar *name)
00157 {
00158   GtkTreeIter iter;
00159   GtkTreeView *tree_view = (GtkTreeView *)split_tree;
00160   GtkTreeModel *model;
00161 
00162   model = gtk_tree_view_get_model(tree_view);
00163   gtk_list_store_append (GTK_LIST_STORE (model), &iter);
00164       
00165   //sets text in the minute, second and milisecond column
00166   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
00167       COL_NAME,get_real_name_from_filename((guchar *)name),
00168       COL_FILENAME,name, -1);
00169   //add 1 to the row number of the table
00170   split_table_number++;
00171 }
00172 
00174 gchar *get_filename_from_split_files(gint number)
00175 {
00176   gchar *filename = NULL;
00177   GtkTreeIter iter;
00178   GtkTreeModel *model;
00179   GtkTreePath *path = NULL;
00180   
00181   //get the model
00182   model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
00183   
00184   path = gtk_tree_path_new_from_indices (number-1 ,-1);
00185   //get the iter correspondig to the path
00186   if(gtk_tree_model_get_iter(model, &iter, path))
00187   {
00188     gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
00189   }
00190   gtk_tree_path_free(path);
00191   
00192   return filename;
00193 }
00194 
00196 void queue_files_button_event( GtkWidget *widget,
00197                                gpointer   data )
00198 {
00199   //if not connected to player, we connect to player
00200   if (!timer_active)
00201     {
00202       connect_button_event(NULL,NULL);
00203     }
00204   
00205   //our file list
00206   GList *file_list = NULL;
00207   
00208   //the name of the file that we put in the queue
00209   gchar *filename;
00210   
00211   GtkTreeIter iter;
00212   GtkTreeModel *model;
00213   GtkTreePath *path = NULL;
00214   
00215   //get the model
00216   model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
00217   
00218   gint number = split_files;
00219   //put the split filenames in a g_list
00220   while(number >= 0)
00221   {
00222     path = gtk_tree_path_new_from_indices (number ,-1);
00223     //get the iter correspondig to the path
00224     if(gtk_tree_model_get_iter(model, &iter, path))
00225     {
00226       gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
00227 
00228       //add it to the queue file
00229       file_list = g_list_append(file_list, strdup(filename));
00230       g_free(filename);
00231     }
00232     gtk_tree_path_free(path);
00233     number--;
00234   }
00235   
00236   if (file_list != NULL)
00237   {
00238     player_add_files(file_list);
00239   }
00240 
00241   //free memory
00242   g_list_foreach(file_list, (GFunc)g_free, NULL);
00243   g_list_free(file_list);
00244 }
00245 
00247 void remove_file_button_event(GtkWidget *widget, gpointer data)
00248 {
00249   GtkTreeIter iter;
00250   GtkTreeModel *model;
00251   GtkTreePath *path;
00252   GList *selected_list = NULL;
00253   GList *current_element = NULL;
00254   GtkTreeSelection *selection;
00255   
00256   //get the model
00257   model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
00258   //get the selection
00259   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(split_tree));
00260   //get selected rows
00261   selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
00262   
00263   //the name of the file that we have clicked on
00264   gchar *filename;
00265   
00266   //while the list is not empty and we have numbers in the table
00267   //(splitnumber >0)
00268   while (g_list_length(selected_list) > 0)
00269   {
00270     //get the last element
00271     current_element = g_list_last(selected_list);
00272     path = current_element->data;
00273     //get the iter correspondig to the path
00274     gtk_tree_model_get_iter(model, &iter, path);
00275     gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
00276     g_remove(filename);
00277     //remove the path from the selected list
00278     gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
00279     selected_list = g_list_remove(selected_list, path);
00280     //remove 1 to the row number of the table
00281     split_table_number--;
00282 
00283     //free memory
00284     gtk_tree_path_free(path);
00285     g_free(filename);
00286   }
00287   
00288   if (split_table_number == 0)
00289   {
00290     gtk_widget_set_sensitive(queue_files_button, FALSE);
00291     gtk_widget_set_sensitive(remove_all_files_button, FALSE);
00292   }
00293   
00294   gtk_widget_set_sensitive(remove_file_button,FALSE);
00295   
00296   //we free the selected elements
00297   g_list_foreach (selected_list, 
00298                   (GFunc)gtk_tree_path_free, NULL);
00299   g_list_free (selected_list);  
00300 }
00301 
00303 void remove_all_files_button_event(GtkWidget *widget,
00304                                    gpointer data)
00305 {
00306   GtkTreeIter iter;
00307   GtkTreeModel *model;
00308   
00309   model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
00310   
00311   //filename to erase
00312   gchar *filename;
00313   //for all the splitnumbers
00314   while (split_table_number > 0)
00315   {
00316     gtk_tree_model_get_iter_first(model, &iter);
00317     gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
00318     g_remove(filename);
00319     gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
00320     split_table_number--;
00321     g_free(filename);
00322   }
00323   
00324   gtk_widget_set_sensitive(remove_all_files_button,FALSE);
00325   gtk_widget_set_sensitive(remove_file_button,FALSE);
00326   gtk_widget_set_sensitive(queue_files_button,FALSE);
00327 }
00328 
00330 GtkWidget *create_queue_buttons_hbox()
00331 {
00332   //our horizontal box
00333   GtkWidget *hbox;
00334   hbox = gtk_hbox_new(FALSE,0);
00335 
00336   //button for queueing all files
00337   queue_files_button = (GtkWidget *)
00338     create_cool_button(GTK_STOCK_UNINDENT, 
00339                        _("_Queue files to player"),FALSE);
00340   gtk_box_pack_start (GTK_BOX (hbox),
00341                       queue_files_button, TRUE, FALSE, 5);
00342   gtk_widget_set_sensitive(queue_files_button, FALSE);
00343   g_signal_connect (G_OBJECT (queue_files_button), "clicked",
00344                     G_CALLBACK (queue_files_button_event), NULL);
00345   
00346   //button for removing a file
00347   remove_file_button = (GtkWidget *)
00348     create_cool_button(GTK_STOCK_DELETE,
00349                        _("_Delete selected files"),FALSE);
00350   gtk_box_pack_start (GTK_BOX (hbox),
00351                       remove_file_button, TRUE, FALSE, 5);
00352   gtk_widget_set_sensitive(remove_file_button,FALSE);
00353   g_signal_connect (G_OBJECT (remove_file_button), "clicked",
00354                     G_CALLBACK (remove_file_button_event), NULL);
00355   
00356   //button for removing a file
00357   remove_all_files_button = (GtkWidget *)
00358     create_cool_button(GTK_STOCK_DELETE,
00359                        _("D_elete all files"),FALSE);
00360   gtk_box_pack_start (GTK_BOX (hbox),
00361                       remove_all_files_button, TRUE, FALSE, 5);
00362   gtk_widget_set_sensitive(remove_all_files_button,FALSE);
00363   g_signal_connect (G_OBJECT (remove_all_files_button), "clicked",
00364                     G_CALLBACK (remove_all_files_button_event), NULL);
00365   
00366   return hbox;
00367 }
00368 
00370 void split_tree_row_activated(GtkTreeView *tree_view, GtkTreePath *arg1,
00371     GtkTreeViewColumn *arg2, gpointer data)
00372 {
00373   GtkTreeIter iter;
00374   GtkTreeModel *model;
00375   GList *selected_list = NULL;
00376   GList *current_element = NULL;
00377   GtkTreeSelection *selection;
00378   GtkTreePath *path;
00379 
00380   //get the model
00381   model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
00382   //get the selection
00383   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
00384   //get selected rows
00385   selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
00386 
00387   //get the last element
00388   current_element = g_list_first(selected_list);
00389   path = current_element->data;
00390   //get the iter correspondig to the path
00391   gtk_tree_model_get_iter(model, &iter, path);
00392   //the name of the file that we have clicked on
00393   gchar *filename = NULL;
00394 
00395   gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
00396 
00397   //connecting to player
00398   connect_button_event (NULL, NULL);
00399   //set the entry with the current filename
00400   change_current_filename(filename);
00401   //starts playing, 0 means start playing
00402   connect_to_player_with_song(0);
00403 
00404   //free memory
00405   gtk_tree_path_free(path);
00406   if (filename)
00407   {
00408     g_free(filename);
00409     filename = NULL;
00410   }
00411 }
00412 
00414 void split_selection_changed(GtkTreeSelection *selec,
00415                              gpointer data)
00416 {
00417   GtkTreeModel *model;
00418   GtkTreeSelection *selection;
00419   GList *selected_list = NULL;
00420   
00421   //get the model
00422   model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
00423   //get the selection
00424   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(split_tree));
00425   //get selected rows
00426   selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
00427 
00428   if (g_list_length(selected_list) > 0)
00429     {
00430       gtk_widget_set_sensitive(remove_file_button,TRUE);
00431     }
00432 }
00433 
00435 void close_split_popup_window_event( GtkWidget *window,
00436                                     gpointer data )
00437 {
00438   GtkWidget *window_child;
00439 
00440   window_child = gtk_bin_get_child(GTK_BIN(window));
00441 
00442   gtk_widget_reparent(GTK_WIDGET(window_child), 
00443                       GTK_WIDGET(split_handle_box));
00444 
00445   gtk_widget_destroy(window);
00446 }
00447 
00449 void handle_split_detached_event (GtkHandleBox *handlebox,
00450                                      GtkWidget *widget,
00451                                      gpointer data)
00452 {
00453   //new window
00454   GtkWidget *window;
00455 
00456   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00457 
00458   gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window));
00459 
00460   g_signal_connect (G_OBJECT (window), "delete_event",
00461                     G_CALLBACK (close_split_popup_window_event),
00462                     NULL);
00463 
00464   gtk_widget_show(GTK_WIDGET(window));
00465 }
00466 
00468 GtkWidget *create_split_files()
00469 {
00470   //our vertical box
00471   GtkWidget *vbox;
00472   vbox = gtk_vbox_new(FALSE,0);
00473 
00474   /* handle box for detaching */
00475   split_handle_box = gtk_handle_box_new();
00476   gtk_container_add(GTK_CONTAINER (split_handle_box), 
00477                     GTK_WIDGET(vbox));
00478   //handle event
00479   g_signal_connect(split_handle_box, "child-detached",
00480                    G_CALLBACK(handle_split_detached_event),
00481                    NULL);
00482 
00483   // scrolled window and the tree 
00484   //create the tree and add it to the scrolled window
00485   split_tree = (GtkWidget *)
00486     create_split_files_tree();
00487   //scrolled window for the tree
00488   GtkWidget *scrolled_window;
00489   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
00490   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
00491   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
00492                                   GTK_POLICY_AUTOMATIC,
00493                                   GTK_POLICY_AUTOMATIC);
00494   gtk_box_pack_start (GTK_BOX (vbox),
00495                       scrolled_window, TRUE, TRUE, 0);
00496   //create columns
00497   create_split_columns (GTK_TREE_VIEW(split_tree));
00498   //add the tree to the scrolled window
00499   gtk_container_add (GTK_CONTAINER (scrolled_window), 
00500                      GTK_WIDGET(split_tree));
00501   g_signal_connect (G_OBJECT (split_tree), "row-activated",
00502                     G_CALLBACK (split_tree_row_activated), NULL);
00503   
00504   //selection for the tree
00505   GtkWidget *split_tree_selection;
00506   split_tree_selection = (GtkWidget *)
00507     gtk_tree_view_get_selection(GTK_TREE_VIEW(split_tree));
00508   g_signal_connect (G_OBJECT (split_tree_selection), "changed",
00509                     G_CALLBACK (split_selection_changed), NULL);
00510   gtk_tree_selection_set_mode(GTK_TREE_SELECTION(split_tree_selection),
00511                               GTK_SELECTION_MULTIPLE);
00512   
00513   // horizontal box with queue buttons
00514   GtkWidget *queue_buttons_hbox;
00515   queue_buttons_hbox = 
00516     (GtkWidget *)create_queue_buttons_hbox();
00517   gtk_box_pack_start (GTK_BOX (vbox),
00518                       queue_buttons_hbox, FALSE, FALSE, 5);
00519   
00520   return split_handle_box;
00521 }