mp3splt-gtk
split_files.c
Go to the documentation of this file.
1 /**********************************************************
2  *
3  * mp3splt-gtk -- utility based on mp3splt,
4  * for mp3/ogg splitting without decoding
5  *
6  * Copyright: (C) 2005-2012 Alexandru Munteanu
7  * Contact: io_fx@yahoo.fr
8  *
9  * http://mp3splt.sourceforge.net/
10  *
11  *********************************************************/
12 
13 /**********************************************************
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28  * USA.
29  *
30  *********************************************************/
31 
32 /*!********************************************************
33  * \file
34  * The split tab
35  *
36  * file that handles the split files tab from the main
37  * window
38  **********************************************************/
39 
40 #include <gtk/gtk.h>
41 #include <glib/gi18n.h>
42 #include <string.h>
43 #include <glib.h>
44 #include <glib/gstdio.h>
45 
46 #include "util.h"
47 #include "player.h"
48 #include "player_tab.h"
49 #include "split_files.h"
50 #include "utilities.h"
51 #include "main_win.h"
52 
54 GtkWidget *split_tree;
55 
58 
60 GtkWidget *split_handle_box;
62 GtkWidget *queue_files_button;
64 GtkWidget *remove_file_button;
67 
68 extern gint selected_player;
69 extern gint split_files;
70 extern gboolean timer_active;
71 
73 enum
74 {
75  COL_NAME,
76  COL_FILENAME,
77  SPLIT_COLUMNS
78 };
79 
81 GtkTreeModel *create_split_model()
82 {
83  GtkListStore *model;
84 
85  model = gtk_list_store_new(SPLIT_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
86 
87  return GTK_TREE_MODEL (model);
88 }
89 
92 {
93  GtkTreeView *tree_view;
94  GtkTreeModel *model;
95  //create the model
96  model = (GtkTreeModel *)create_split_model();
97  //create the tree view
98  tree_view = (GtkTreeView *)
99  gtk_tree_view_new_with_model (model);
100 
101  return tree_view;
102 }
103 
105 void create_split_columns (GtkTreeView *tree_view)
106 {
107  GtkCellRendererText *renderer =
108  GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
109  g_object_set_data(G_OBJECT(renderer), "col", GINT_TO_POINTER(COL_NAME));
110  GtkTreeViewColumn *name_column = gtk_tree_view_column_new_with_attributes
111  (_("Filename"), GTK_CELL_RENDERER(renderer), "text", COL_NAME, NULL);
112 
113  //appends columns to the list of columns of tree_view
114  gtk_tree_view_insert_column(GTK_TREE_VIEW(tree_view),
115  GTK_TREE_VIEW_COLUMN(name_column),COL_NAME);
116 
117  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 0.5);
118  gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(name_column),
119  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
120  gtk_tree_view_column_set_resizable(name_column, TRUE);
121 }
122 
125 {
126  GtkTreeIter iter;
127  GtkTreeView *tree_view =
128  (GtkTreeView *)split_tree;
129  GtkTreeModel *model;
130 
131  model = gtk_tree_view_get_model(tree_view);
132 
133  //while we still have rows in the table
134  while (split_table_number > 0)
135  {
136  gtk_tree_model_get_iter_first(model, &iter);
137  gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
138  //remove values from the splitpoint array
140  }
141 }
142 
147 guchar *get_real_name_from_filename(guchar *filename)
148 {
149  while (strchr((gchar *) filename, G_DIR_SEPARATOR)!=NULL)
150  filename = (guchar *)strchr((gchar *)filename, G_DIR_SEPARATOR) + 1;
151 
152  return filename;
153 }
154 
156 void add_split_row(const gchar *name)
157 {
158  GtkTreeIter iter;
159  GtkTreeView *tree_view = (GtkTreeView *)split_tree;
160  GtkTreeModel *model;
161 
162  model = gtk_tree_view_get_model(tree_view);
163  gtk_list_store_append (GTK_LIST_STORE (model), &iter);
164 
165  //sets text in the minute, second and milisecond column
166  gtk_list_store_set (GTK_LIST_STORE (model), &iter,
167  COL_NAME,get_real_name_from_filename((guchar *)name),
168  COL_FILENAME,name, -1);
169  //add 1 to the row number of the table
171 }
172 
174 gchar *get_filename_from_split_files(gint number)
175 {
176  gchar *filename = NULL;
177  GtkTreeIter iter;
178  GtkTreeModel *model;
179  GtkTreePath *path = NULL;
180 
181  //get the model
182  model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
183 
184  path = gtk_tree_path_new_from_indices (number-1 ,-1);
185  //get the iter correspondig to the path
186  if(gtk_tree_model_get_iter(model, &iter, path))
187  {
188  gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
189  }
190  gtk_tree_path_free(path);
191 
192  return filename;
193 }
194 
196 void queue_files_button_event( GtkWidget *widget,
197  gpointer data )
198 {
199  //if not connected to player, we connect to player
200  if (!timer_active)
201  {
202  connect_button_event(NULL,NULL);
203  }
204 
205  //our file list
206  GList *file_list = NULL;
207 
208  //the name of the file that we put in the queue
209  gchar *filename;
210 
211  GtkTreeIter iter;
212  GtkTreeModel *model;
213  GtkTreePath *path = NULL;
214 
215  //get the model
216  model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
217 
218  gint number = split_files;
219  //put the split filenames in a g_list
220  while(number >= 0)
221  {
222  path = gtk_tree_path_new_from_indices (number ,-1);
223  //get the iter correspondig to the path
224  if(gtk_tree_model_get_iter(model, &iter, path))
225  {
226  gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
227 
228  //add it to the queue file
229  file_list = g_list_append(file_list, strdup(filename));
230  g_free(filename);
231  }
232  gtk_tree_path_free(path);
233  number--;
234  }
235 
236  if (file_list != NULL)
237  {
238  player_add_files(file_list);
239  }
240 
241  //free memory
242  g_list_foreach(file_list, (GFunc)g_free, NULL);
243  g_list_free(file_list);
244 }
245 
247 void remove_file_button_event(GtkWidget *widget, gpointer data)
248 {
249  GtkTreeIter iter;
250  GtkTreeModel *model;
251  GtkTreePath *path;
252  GList *selected_list = NULL;
253  GList *current_element = NULL;
254  GtkTreeSelection *selection;
255 
256  //get the model
257  model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
258  //get the selection
259  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(split_tree));
260  //get selected rows
261  selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
262 
263  //the name of the file that we have clicked on
264  gchar *filename;
265 
266  //while the list is not empty and we have numbers in the table
267  //(splitnumber >0)
268  while (g_list_length(selected_list) > 0)
269  {
270  //get the last element
271  current_element = g_list_last(selected_list);
272  path = current_element->data;
273  //get the iter correspondig to the path
274  gtk_tree_model_get_iter(model, &iter, path);
275  gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
276  g_remove(filename);
277  //remove the path from the selected list
278  gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
279  selected_list = g_list_remove(selected_list, path);
280  //remove 1 to the row number of the table
282 
283  //free memory
284  gtk_tree_path_free(path);
285  g_free(filename);
286  }
287 
288  if (split_table_number == 0)
289  {
290  gtk_widget_set_sensitive(queue_files_button, FALSE);
291  gtk_widget_set_sensitive(remove_all_files_button, FALSE);
292  }
293 
294  gtk_widget_set_sensitive(remove_file_button,FALSE);
295 
296  //we free the selected elements
297  g_list_foreach (selected_list,
298  (GFunc)gtk_tree_path_free, NULL);
299  g_list_free (selected_list);
300 }
301 
303 void remove_all_files_button_event(GtkWidget *widget,
304  gpointer data)
305 {
306  GtkTreeIter iter;
307  GtkTreeModel *model;
308 
309  model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
310 
311  //filename to erase
312  gchar *filename;
313  //for all the splitnumbers
314  while (split_table_number > 0)
315  {
316  gtk_tree_model_get_iter_first(model, &iter);
317  gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
318  g_remove(filename);
319  gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
321  g_free(filename);
322  }
323 
324  gtk_widget_set_sensitive(remove_all_files_button,FALSE);
325  gtk_widget_set_sensitive(remove_file_button,FALSE);
326  gtk_widget_set_sensitive(queue_files_button,FALSE);
327 }
328 
331 {
332  //our horizontal box
333  GtkWidget *hbox;
334  hbox = gtk_hbox_new(FALSE,0);
335 
336  //button for queueing all files
337  queue_files_button = (GtkWidget *)
338  create_cool_button(GTK_STOCK_UNINDENT,
339  _("_Queue files to player"),FALSE);
340  gtk_box_pack_start (GTK_BOX (hbox),
341  queue_files_button, FALSE, FALSE, 5);
342  gtk_widget_set_sensitive(queue_files_button, FALSE);
343  g_signal_connect (G_OBJECT (queue_files_button), "clicked",
344  G_CALLBACK (queue_files_button_event), NULL);
345 
346  //button for removing a file
347  remove_file_button = (GtkWidget *)
348  create_cool_button(GTK_STOCK_DELETE,
349  _("_Delete selected files"),FALSE);
350  gtk_box_pack_start (GTK_BOX (hbox),
351  remove_file_button, FALSE, FALSE, 5);
352  gtk_widget_set_sensitive(remove_file_button,FALSE);
353  g_signal_connect (G_OBJECT (remove_file_button), "clicked",
354  G_CALLBACK (remove_file_button_event), NULL);
355 
356  //button for removing a file
357  remove_all_files_button = (GtkWidget *)
358  create_cool_button(GTK_STOCK_DELETE,
359  _("D_elete all files"),FALSE);
360  gtk_box_pack_start (GTK_BOX (hbox),
361  remove_all_files_button, FALSE, FALSE, 5);
362  gtk_widget_set_sensitive(remove_all_files_button,FALSE);
363  g_signal_connect (G_OBJECT (remove_all_files_button), "clicked",
364  G_CALLBACK (remove_all_files_button_event), NULL);
365 
366  return hbox;
367 }
368 
370 void split_tree_row_activated(GtkTreeView *tree_view, GtkTreePath *arg1,
371  GtkTreeViewColumn *arg2, gpointer data)
372 {
373  GtkTreeIter iter;
374  GtkTreeModel *model;
375  GList *selected_list = NULL;
376  GList *current_element = NULL;
377  GtkTreeSelection *selection;
378  GtkTreePath *path;
379 
380  //get the model
381  model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
382  //get the selection
383  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
384  //get selected rows
385  selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
386 
387  //get the last element
388  current_element = g_list_first(selected_list);
389  path = current_element->data;
390  //get the iter correspondig to the path
391  gtk_tree_model_get_iter(model, &iter, path);
392  //the name of the file that we have clicked on
393  gchar *filename = NULL;
394 
395  gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
396 
397  //connecting to player
398  connect_button_event (NULL, NULL);
399  //set the entry with the current filename
400  change_current_filename(filename);
401  //starts playing, 0 means start playing
403 
404  //free memory
405  gtk_tree_path_free(path);
406  if (filename)
407  {
408  g_free(filename);
409  filename = NULL;
410  }
411 }
412 
414 void split_selection_changed(GtkTreeSelection *selec,
415  gpointer data)
416 {
417  GtkTreeModel *model;
418  GtkTreeSelection *selection;
419  GList *selected_list = NULL;
420 
421  //get the model
422  model = gtk_tree_view_get_model(GTK_TREE_VIEW(split_tree));
423  //get the selection
424  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(split_tree));
425  //get selected rows
426  selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
427 
428  if (g_list_length(selected_list) > 0)
429  {
430  gtk_widget_set_sensitive(remove_file_button,TRUE);
431  }
432 }
433 
435 void close_split_popup_window_event( GtkWidget *window,
436  gpointer data )
437 {
438  GtkWidget *window_child;
439 
440  window_child = gtk_bin_get_child(GTK_BIN(window));
441 
442  gtk_widget_reparent(GTK_WIDGET(window_child),
443  GTK_WIDGET(split_handle_box));
444 
445  gtk_widget_destroy(window);
446 }
447 
449 void handle_split_detached_event (GtkHandleBox *handlebox,
450  GtkWidget *widget,
451  gpointer data)
452 {
453  //new window
454  GtkWidget *window;
455 
456  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
457 
458  gtk_widget_reparent(GTK_WIDGET(widget), GTK_WIDGET(window));
459 
460  g_signal_connect (G_OBJECT (window), "delete_event",
461  G_CALLBACK (close_split_popup_window_event),
462  NULL);
463 
464  gtk_widget_show(GTK_WIDGET(window));
465 }
466 
468 GtkWidget *create_split_files()
469 {
470  //our vertical box
471  GtkWidget *vbox;
472  vbox = gtk_vbox_new(FALSE,0);
473 
474  /* handle box for detaching */
475  split_handle_box = gtk_handle_box_new();
476  gtk_container_add(GTK_CONTAINER (split_handle_box),
477  GTK_WIDGET(vbox));
478  //handle event
479  g_signal_connect(split_handle_box, "child-detached",
480  G_CALLBACK(handle_split_detached_event),
481  NULL);
482 
483  // scrolled window and the tree
484  //create the tree and add it to the scrolled window
485  split_tree = (GtkWidget *)
487  //scrolled window for the tree
488  GtkWidget *scrolled_window;
489  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
490  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
491  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
492  GTK_POLICY_AUTOMATIC,
493  GTK_POLICY_AUTOMATIC);
494  gtk_box_pack_start (GTK_BOX (vbox),
495  scrolled_window, TRUE, TRUE, 0);
496  //create columns
497  create_split_columns (GTK_TREE_VIEW(split_tree));
498  //add the tree to the scrolled window
499  gtk_container_add (GTK_CONTAINER (scrolled_window),
500  GTK_WIDGET(split_tree));
501  g_signal_connect (G_OBJECT (split_tree), "row-activated",
502  G_CALLBACK (split_tree_row_activated), NULL);
503 
504  //selection for the tree
505  GtkWidget *split_tree_selection;
506  split_tree_selection = (GtkWidget *)
507  gtk_tree_view_get_selection(GTK_TREE_VIEW(split_tree));
508  g_signal_connect (G_OBJECT (split_tree_selection), "changed",
509  G_CALLBACK (split_selection_changed), NULL);
510  gtk_tree_selection_set_mode(GTK_TREE_SELECTION(split_tree_selection),
511  GTK_SELECTION_MULTIPLE);
512 
513  // horizontal box with queue buttons
514  GtkWidget *queue_buttons_hbox;
515  queue_buttons_hbox =
516  (GtkWidget *)create_queue_buttons_hbox();
517  gtk_box_pack_start (GTK_BOX (vbox),
518  queue_buttons_hbox, FALSE, FALSE, 2);
519 
520  return split_handle_box;
521 }