mp3splt-gtk
multiple_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  * Batch processing internals
35  *
36  * this file is for management for the the multiple files
37  * mode that currently allows only for batch processing.
38  *********************************************************/
39 
40 #include <gtk/gtk.h>
41 #include <glib/gi18n.h>
42 #include <libmp3splt/mp3splt.h>
43 
44 #include "multiple_files.h"
45 #include "main_win.h"
46 #include "ui_manager.h"
47 #include "widgets_helper.h"
48 
49 extern splt_state *the_state;
50 extern ui_state *ui;
51 
52 GtkWidget *multiple_files_tree = NULL;
53 gint multiple_files_tree_number = 0;
54 
55 GtkWidget *multiple_files_remove_file_button = NULL;
56 GtkWidget *multiple_files_remove_all_files_button = NULL;
57 
58 #define MY_GTK_RESPONSE 200
59 
62 {
63  GtkListStore *model;
64 
65  model = gtk_list_store_new(MULTIPLE_FILES_COLUMNS,
66  G_TYPE_STRING,
67  G_TYPE_STRING);
68 
69  return GTK_TREE_MODEL(model);
70 }
71 
72 GtkTreeView *create_multiple_files_tree()
73 {
74  GtkTreeView *tree_view;
75  GtkTreeModel *model;
76 
77  model = (GtkTreeModel *)create_multiple_files_model();
78  tree_view = (GtkTreeView *)gtk_tree_view_new_with_model(model);
79 
80  return tree_view;
81 }
82 
83 void create_multiple_files_columns(GtkTreeView *tree_view)
84 {
85  GtkCellRendererText *renderer =
86  GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
87  GtkTreeViewColumn *filename_column = gtk_tree_view_column_new_with_attributes
88  (_("Complete filename"), GTK_CELL_RENDERER(renderer),
89  "text", MULTIPLE_COL_FILENAME, NULL);
90  gtk_tree_view_insert_column(GTK_TREE_VIEW(tree_view),
91  GTK_TREE_VIEW_COLUMN(filename_column),MULTIPLE_COL_FILENAME);
92 
93  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(filename_column), 0.5);
94  gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(filename_column),
95  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
96  gtk_tree_view_column_set_sort_column_id(filename_column, MULTIPLE_COL_FILENAME);
97 }
98 
99 void multiple_files_open_button_event(GtkWidget *widget, gpointer data)
100 {
101  gtk_dialog_response(GTK_DIALOG(data), MY_GTK_RESPONSE);
102 }
103 
104 void multiple_files_add_button_event(GtkWidget *widget, gpointer data)
105 {
106  GtkWidget *file_chooser;
107  GtkWidget *our_filter;
108 
109  file_chooser = gtk_file_chooser_dialog_new(_("Choose file or directory"),
110  NULL,
111  GTK_FILE_CHOOSER_ACTION_OPEN,
112  GTK_STOCK_CANCEL,
113  GTK_RESPONSE_CANCEL,
114  NULL);
115 
116  wh_set_browser_directory_handler(ui, file_chooser);
117 
118  GtkWidget *button = gtk_dialog_add_button(GTK_DIALOG(file_chooser),
119  GTK_STOCK_ADD, MY_GTK_RESPONSE);
120  gtk_button_set_use_stock(GTK_BUTTON(button), TRUE);
121  g_signal_connect(G_OBJECT(button), "clicked",
122  G_CALLBACK(multiple_files_open_button_event), file_chooser);
123  g_signal_connect(G_OBJECT(file_chooser), "file-activated",
124  G_CALLBACK(multiple_files_open_button_event), file_chooser);
125 
126  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(file_chooser), TRUE);
127 
128  //mp3 & ogg filter
129  our_filter = (GtkWidget *)gtk_file_filter_new();
130  gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("mp3 and ogg files (*.mp3 *.ogg)"));
131  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.mp3");
132  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.MP3");
133  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.ogg");
134  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.OGG");
135  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
136  //mp3 filter
137  our_filter = (GtkWidget *)gtk_file_filter_new();
138  gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("mp3 files (*.mp3)"));
139  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.mp3");
140  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.MP3");
141  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
142  //ogg filter
143  our_filter = (GtkWidget *)gtk_file_filter_new();
144  gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("ogg files (*.ogg)"));
145  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.ogg");
146  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*.OGG");
147  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
148 
149  //all files filter
150  our_filter = (GtkWidget *)gtk_file_filter_new();
151  gtk_file_filter_set_name (GTK_FILE_FILTER(our_filter), _("All Files"));
152  gtk_file_filter_add_pattern(GTK_FILE_FILTER(our_filter), "*");
153  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), GTK_FILE_FILTER(our_filter));
154 
155  //we push open, ..
156  if (gtk_dialog_run(GTK_DIALOG(file_chooser)) == MY_GTK_RESPONSE)
157  {
158  GSList *files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(file_chooser));
159  if (files)
160  {
161  gchar *filename = NULL;
162 
163  GtkTreeIter iter;
164  GtkTreeModel *model =
165  gtk_tree_view_get_model(GTK_TREE_VIEW(multiple_files_tree));
166 
167  while (files)
168  {
169  filename = files->data;
170 
171  int err = SPLT_OK;
172  int num_of_files_found = 0;
173  char **splt_filenames =
174  mp3splt_find_filenames(the_state, filename, &num_of_files_found, &err);
175 
176  if (splt_filenames)
177  {
178  int i = 0;
179  for (i = 0;i < num_of_files_found;i++)
180  {
181  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
182 
183  gtk_list_store_set (GTK_LIST_STORE(model),
184  &iter,
185  MULTIPLE_COL_FILENAME, splt_filenames[i],
186  -1);
187  multiple_files_tree_number++;
188 
189  if (splt_filenames[i])
190  {
191  free(splt_filenames[i]);
192  splt_filenames[i] = NULL;
193  }
194  }
195 
196  free(splt_filenames);
197  splt_filenames = NULL;
198  }
199 
200  g_free(filename);
201  filename = NULL;
202 
203  files = g_slist_next(files);
204  }
205  g_slist_free(files);
206 
207  if (multiple_files_tree_number > 0)
208  {
209  gtk_widget_set_sensitive(multiple_files_remove_all_files_button, TRUE);
210  }
211  }
212  }
213 
214  gtk_widget_destroy(file_chooser);
215 }
216 
217 void multiple_files_remove_button_event(GtkWidget *widget, gpointer data)
218 {
219  GtkTreeIter iter;
220  GtkTreeModel *model;
221  GtkTreePath *path;
222  GList *selected_list = NULL;
223  GList *current_element = NULL;
224  GtkTreeSelection *selection;
225 
226  model = gtk_tree_view_get_model(GTK_TREE_VIEW(multiple_files_tree));
227  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(multiple_files_tree));
228  selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
229 
230  //the name of the file that we have clicked on
231  gchar *filename = NULL;
232 
233  while (g_list_length(selected_list) > 0)
234  {
235  //get the last element
236  current_element = g_list_last(selected_list);
237  path = current_element->data;
238  //get the iter correspondig to the path
239  gtk_tree_model_get_iter(model, &iter, path);
240  gtk_tree_model_get(model, &iter, MULTIPLE_COL_FILENAME, &filename, -1);
241  //remove the path from the selected list
242  gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
243  selected_list = g_list_remove(selected_list, path);
244  multiple_files_tree_number--;
245 
246  //free memory
247  gtk_tree_path_free(path);
248  g_free(filename);
249  }
250 
251  if (multiple_files_tree_number == 0)
252  {
253  gtk_widget_set_sensitive(multiple_files_remove_all_files_button, FALSE);
254  }
255 
256  gtk_widget_set_sensitive(multiple_files_remove_file_button,FALSE);
257 
258  //free the selected elements
259  g_list_foreach(selected_list, (GFunc)gtk_tree_path_free, NULL);
260  g_list_free(selected_list);
261 }
262 
263 void multiple_files_remove_all_button_event(GtkWidget *widget, gpointer data)
264 {
265  GtkTreeIter iter;
266  GtkTreeModel *model;
267 
268  model = gtk_tree_view_get_model(GTK_TREE_VIEW(multiple_files_tree));
269 
270  //filename to erase
271  gchar *filename = NULL;
272  //for all the splitnumbers
273  while (multiple_files_tree_number > 0)
274  {
275  gtk_tree_model_get_iter_first(model, &iter);
276  gtk_tree_model_get(model, &iter, MULTIPLE_COL_FILENAME, &filename, -1);
277  gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
278  multiple_files_tree_number--;
279  g_free(filename);
280  }
281 
282  gtk_widget_set_sensitive(multiple_files_remove_all_files_button,FALSE);
283  gtk_widget_set_sensitive(multiple_files_remove_file_button,FALSE);
284 }
285 
286 GtkWidget *create_multiple_files_buttons_hbox()
287 {
288  GtkWidget *hbox = gtk_hbox_new(FALSE,0);
289 
290  //button for adding file(s)
291  GtkWidget *multiple_files_add_button = (GtkWidget *)
292  create_cool_button(GTK_STOCK_ADD, _("_Add files"), FALSE);
293  gtk_box_pack_start(GTK_BOX(hbox), multiple_files_add_button, FALSE, FALSE, 5);
294  gtk_widget_set_sensitive(multiple_files_add_button, TRUE);
295  g_signal_connect(G_OBJECT(multiple_files_add_button), "clicked",
296  G_CALLBACK(multiple_files_add_button_event), NULL);
297 
298  //button for removing a file
299  multiple_files_remove_file_button = (GtkWidget *)
300  create_cool_button(GTK_STOCK_DELETE, _("_Remove selected entries"),FALSE);
301  gtk_box_pack_start(GTK_BOX(hbox),
302  multiple_files_remove_file_button, FALSE, FALSE, 5);
303  gtk_widget_set_sensitive(multiple_files_remove_file_button,FALSE);
304  g_signal_connect(G_OBJECT(multiple_files_remove_file_button), "clicked",
305  G_CALLBACK(multiple_files_remove_button_event), NULL);
306 
307  //button for removing a file
308  multiple_files_remove_all_files_button = (GtkWidget *)
309  create_cool_button(GTK_STOCK_DELETE, _("R_emove all entries"),FALSE);
310  gtk_box_pack_start(GTK_BOX(hbox), multiple_files_remove_all_files_button,
311  FALSE, FALSE, 5);
312  gtk_widget_set_sensitive(multiple_files_remove_all_files_button,FALSE);
313  g_signal_connect(G_OBJECT(multiple_files_remove_all_files_button), "clicked",
314  G_CALLBACK(multiple_files_remove_all_button_event), NULL);
315 
316  return hbox;
317 }
318 
319 void multiple_files_selection_changed(GtkTreeSelection *selec, gpointer data)
320 {
321  GtkTreeModel *model;
322  GtkTreeSelection *selection;
323  GList *selected_list = NULL;
324 
325  model = gtk_tree_view_get_model(GTK_TREE_VIEW(multiple_files_tree));
326  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(multiple_files_tree));
327  selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
328 
329  if (g_list_length(selected_list) > 0)
330  {
331  gtk_widget_set_sensitive(multiple_files_remove_file_button,TRUE);
332  }
333  else
334  {
335  gtk_widget_set_sensitive(multiple_files_remove_file_button,FALSE);
336  }
337 }
338 
339 GtkWidget *create_multiple_files_component()
340 {
341  GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
342 
343  multiple_files_tree = (GtkWidget *)create_multiple_files_tree();
344 
345  GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
346  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
347  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window),
348  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
349  gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
350 
351  //create columns
352  create_multiple_files_columns(GTK_TREE_VIEW(multiple_files_tree));
353 
354  //add the tree to the scrolled window
355  gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(multiple_files_tree));
356 
357  //selection for the tree
358  GtkWidget *multiple_files_tree_selection = (GtkWidget *)
359  gtk_tree_view_get_selection(GTK_TREE_VIEW(multiple_files_tree));
360  g_signal_connect(G_OBJECT(multiple_files_tree_selection), "changed",
361  G_CALLBACK(multiple_files_selection_changed), NULL);
362  gtk_tree_selection_set_mode(GTK_TREE_SELECTION(multiple_files_tree_selection),
363  GTK_SELECTION_MULTIPLE);
364 
365  //bottom horizontal box with buttons
366  GtkWidget *buttons_hbox = (GtkWidget *)create_multiple_files_buttons_hbox();
367  gtk_box_pack_start(GTK_BOX(vbox), buttons_hbox, FALSE, FALSE, 2);
368 
369  return vbox;
370 }
371