mp3splt-gtk
multiple_files_window.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 "multiple_files_window.h"
41 
42 #define MY_GTK_RESPONSE 200
43 
44 static gboolean file_exists_in_multiple_files_table(const gchar *filename, ui_state *ui);
45 
47 static GtkTreeModel *create_multiple_files_model()
48 {
49  GtkListStore *model =
50  gtk_list_store_new(MULTIPLE_FILES_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
51  return GTK_TREE_MODEL(model);
52 }
53 
54 static GtkTreeView *create_multiple_files_tree()
55 {
56  return GTK_TREE_VIEW(gtk_tree_view_new_with_model(create_multiple_files_model()));
57 }
58 
59 static void create_multiple_files_columns(GtkTreeView *multiple_files_tree)
60 {
61  GtkCellRendererText *renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
62  GtkTreeViewColumn *filename_column = gtk_tree_view_column_new_with_attributes
63  (_("Complete filename"), GTK_CELL_RENDERER(renderer), "text", MULTIPLE_COL_FILENAME, NULL);
64  gtk_tree_view_insert_column(multiple_files_tree,
65  GTK_TREE_VIEW_COLUMN(filename_column), MULTIPLE_COL_FILENAME);
66 
67  gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(filename_column), 0.5);
68  gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(filename_column),
69  GTK_TREE_VIEW_COLUMN_AUTOSIZE);
70  gtk_tree_view_column_set_sort_column_id(filename_column, MULTIPLE_COL_FILENAME);
71 }
72 
73 static void multiple_files_open_button_event(GtkWidget *widget, gpointer data)
74 {
75  gtk_dialog_response(GTK_DIALOG(data), MY_GTK_RESPONSE);
76 }
77 
78 void multiple_files_add_button_event(GtkWidget *widget, ui_state *ui)
79 {
80  GtkWidget *file_chooser = gtk_file_chooser_dialog_new(_("Choose files or directories"),
81  NULL,
82  GTK_FILE_CHOOSER_ACTION_OPEN,
83  GTK_STOCK_CANCEL,
84  GTK_RESPONSE_CANCEL,
85  NULL);
86 
87  wh_set_browser_directory_handler(ui, file_chooser);
88 
89  GtkWidget *button = gtk_dialog_add_button(GTK_DIALOG(file_chooser),
90  GTK_STOCK_ADD, MY_GTK_RESPONSE);
91  gtk_button_set_use_stock(GTK_BUTTON(button), TRUE);
92  g_signal_connect(G_OBJECT(button), "clicked",
93  G_CALLBACK(multiple_files_open_button_event), file_chooser);
94  g_signal_connect(G_OBJECT(file_chooser), "file-activated",
95  G_CALLBACK(multiple_files_open_button_event), file_chooser);
96 
97  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(file_chooser), TRUE);
98 
99  //mp3 & ogg filter
100  GtkFileFilter *our_filter = gtk_file_filter_new();
101  gtk_file_filter_set_name(our_filter, _("mp3 and ogg files (*.mp3 *.ogg)"));
102  gtk_file_filter_add_pattern(our_filter, "*.mp3");
103  gtk_file_filter_add_pattern(our_filter, "*.MP3");
104  gtk_file_filter_add_pattern(our_filter, "*.ogg");
105  gtk_file_filter_add_pattern(our_filter, "*.OGG");
106  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), our_filter);
107  //mp3 filter
108  our_filter = gtk_file_filter_new();
109  gtk_file_filter_set_name(our_filter, _("mp3 files (*.mp3)"));
110  gtk_file_filter_add_pattern(our_filter, "*.mp3");
111  gtk_file_filter_add_pattern(our_filter, "*.MP3");
112  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), our_filter);
113  //ogg filter
114  our_filter = gtk_file_filter_new();
115  gtk_file_filter_set_name(our_filter, _("ogg files (*.ogg)"));
116  gtk_file_filter_add_pattern(our_filter, "*.ogg");
117  gtk_file_filter_add_pattern(our_filter, "*.OGG");
118  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), our_filter);
119 
120  //all files filter
121  our_filter = gtk_file_filter_new();
122  gtk_file_filter_set_name(our_filter, _("All Files"));
123  gtk_file_filter_add_pattern(our_filter, "*");
124  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), our_filter);
125 
126  if (gtk_dialog_run(GTK_DIALOG(file_chooser)) == MY_GTK_RESPONSE)
127  {
128  GSList *files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(file_chooser));
129  if (!files)
130  {
131  gtk_widget_destroy(file_chooser);
132  return;
133  }
134 
135  import_files_to_batch_and_free(files, ui);
136  }
137 
138  gtk_widget_destroy(file_chooser);
139 }
140 
141 void multiple_files_add_filename(const gchar *filename, ui_state *ui)
142 {
143  if (file_exists_in_multiple_files_table(filename, ui))
144  {
145  return;
146  }
147 
148  GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->multiple_files_tree);
149 
150  GtkTreeIter iter;
151  gtk_list_store_append(GTK_LIST_STORE(model), &iter);
152  gtk_list_store_set(GTK_LIST_STORE(model), &iter, MULTIPLE_COL_FILENAME, filename, -1);
153 
154  ui->infos->multiple_files_tree_number++;
155 }
156 
157 static gboolean file_exists_in_multiple_files_table(const gchar *filename, ui_state *ui)
158 {
159  if (filename == NULL)
160  {
161  return;
162  }
163 
164  GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->multiple_files_tree);
165 
166  GtkTreeIter iter;
167  if (!gtk_tree_model_get_iter_first(model, &iter))
168  {
169  return FALSE;
170  }
171 
172  while (TRUE)
173  {
174  gchar *fname = NULL;
175  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
176  MULTIPLE_COL_FILENAME, &fname, -1);
177 
178  if (strcmp(filename, fname) == 0)
179  {
180  g_free(fname);
181  return TRUE;
182  }
183 
184  g_free(fname);
185 
186  if (!gtk_tree_model_iter_next(model, &iter))
187  {
188  break;
189  }
190  }
191 
192  return FALSE;
193 }
194 
195 static void multiple_files_remove_button_event(GtkWidget *widget, ui_state *ui)
196 {
197  GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->multiple_files_tree);
198  GtkTreeSelection *selection = gtk_tree_view_get_selection(ui->gui->multiple_files_tree);
199  GList *selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
200 
201  while (g_list_length(selected_list) > 0)
202  {
203  GList *current_element = g_list_last(selected_list);
204  GtkTreePath *path = current_element->data;
205  GtkTreeIter iter;
206  gtk_tree_model_get_iter(model, &iter, path);
207 
208  gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
209  selected_list = g_list_remove(selected_list, path);
210  ui->infos->multiple_files_tree_number--;
211 
212  gtk_tree_path_free(path);
213  }
214 
215  if (ui->infos->multiple_files_tree_number == 0)
216  {
217  gtk_widget_set_sensitive(ui->gui->multiple_files_remove_all_files_button, FALSE);
218  }
219 
220  gtk_widget_set_sensitive(ui->gui->multiple_files_remove_file_button,FALSE);
221 
222  g_list_foreach(selected_list, (GFunc)gtk_tree_path_free, NULL);
223  g_list_free(selected_list);
224 }
225 
226 static void multiple_files_remove_all_button_event(GtkWidget *widget, ui_state *ui)
227 {
228  GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->multiple_files_tree);
229  while (ui->infos->multiple_files_tree_number > 0)
230  {
231  GtkTreeIter iter;
232  gtk_tree_model_get_iter_first(model, &iter);
233  gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
234  ui->infos->multiple_files_tree_number--;
235  }
236 
237  gtk_widget_set_sensitive(ui->gui->multiple_files_remove_all_files_button, FALSE);
238  gtk_widget_set_sensitive(ui->gui->multiple_files_remove_file_button, FALSE);
239 }
240 
241 void batch_file_mode_split_button_event(GtkWidget *widget, ui_state *ui)
242 {
243  set_split_file_mode_safe(FILE_MODE_MULTIPLE, ui);
244  split_button_event(widget, ui);
245 }
246 
247 static GtkWidget *create_multiple_files_buttons_hbox(ui_state *ui)
248 {
249  GtkWidget *hbox = wh_hbox_new();
250 
251  //button for adding file(s)
252  GtkWidget *multiple_files_add_button =
253  wh_create_cool_button(GTK_STOCK_DIRECTORY, _("_Add files or directories"), FALSE);
254  gtk_box_pack_start(GTK_BOX(hbox), multiple_files_add_button, FALSE, FALSE, 5);
255  gtk_widget_set_sensitive(multiple_files_add_button, TRUE);
256  g_signal_connect(G_OBJECT(multiple_files_add_button), "clicked",
257  G_CALLBACK(multiple_files_add_button_event), ui);
258 
259  //button for removing a file
260  GtkWidget *multiple_files_remove_file_button =
261  wh_create_cool_button(GTK_STOCK_REMOVE, _("_Remove selected"),FALSE);
262  ui->gui->multiple_files_remove_file_button = multiple_files_remove_file_button;
263  gtk_box_pack_start(GTK_BOX(hbox),
264  multiple_files_remove_file_button, FALSE, FALSE, 5);
265  gtk_widget_set_sensitive(multiple_files_remove_file_button, FALSE);
266  g_signal_connect(G_OBJECT(multiple_files_remove_file_button), "clicked",
267  G_CALLBACK(multiple_files_remove_button_event), ui);
268 
269  //button for removing a file
270  GtkWidget *multiple_files_remove_all_files_button =
271  wh_create_cool_button(GTK_STOCK_CLEAR, _("R_emove all"),FALSE);
272  ui->gui->multiple_files_remove_all_files_button = multiple_files_remove_all_files_button;
273  gtk_box_pack_start(GTK_BOX(hbox), multiple_files_remove_all_files_button,
274  FALSE, FALSE, 5);
275  gtk_widget_set_sensitive(multiple_files_remove_all_files_button, FALSE);
276  g_signal_connect(G_OBJECT(multiple_files_remove_all_files_button), "clicked",
277  G_CALLBACK(multiple_files_remove_all_button_event), ui);
278 
279  GtkWidget *split_button = wh_create_cool_button(GTK_STOCK_EXECUTE,_("Batch split !"), FALSE);
280  g_signal_connect(G_OBJECT(split_button), "clicked",
281  G_CALLBACK(batch_file_mode_split_button_event), ui);
282  gtk_box_pack_end(GTK_BOX(hbox), split_button, FALSE, FALSE, 4);
283 
284  return hbox;
285 }
286 
287 static void multiple_files_selection_changed(GtkTreeSelection *selec, ui_state *ui)
288 {
289  GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->multiple_files_tree);
290  GtkTreeSelection *selection = gtk_tree_view_get_selection(ui->gui->multiple_files_tree);
291  GList *selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
292 
293  if (g_list_length(selected_list) > 0)
294  {
295  gtk_widget_set_sensitive(ui->gui->multiple_files_remove_file_button, TRUE);
296  }
297  else
298  {
299  gtk_widget_set_sensitive(ui->gui->multiple_files_remove_file_button, FALSE);
300  }
301 }
302 
303 GtkWidget *create_multiple_files_component(ui_state *ui)
304 {
305  GtkWidget *vbox = wh_vbox_new();
306 
307  GtkTreeView *multiple_files_tree = create_multiple_files_tree();
308  dnd_add_drag_data_received_to_widget(GTK_WIDGET(multiple_files_tree), DND_BATCH_MODE_AUDIO_FILES, ui);
309  ui->gui->multiple_files_tree = multiple_files_tree;
310 
311  GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
312  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
313  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_window),
314  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
315  gtk_box_pack_end(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 2);
316 
317  //create columns
318  create_multiple_files_columns(multiple_files_tree);
319 
320  //add the tree to the scrolled window
321  gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(multiple_files_tree));
322 
323  //selection for the tree
324  GtkTreeSelection *multiple_files_tree_selection = gtk_tree_view_get_selection(multiple_files_tree);
325  g_signal_connect(G_OBJECT(multiple_files_tree_selection), "changed",
326  G_CALLBACK(multiple_files_selection_changed), ui);
327  gtk_tree_selection_set_mode(GTK_TREE_SELECTION(multiple_files_tree_selection),
328  GTK_SELECTION_MULTIPLE);
329 
330  GtkWidget *buttons_hbox = create_multiple_files_buttons_hbox(ui);
331  gtk_box_pack_start(GTK_BOX(vbox), buttons_hbox, FALSE, FALSE, 2);
332 
333  return vbox;
334 }
335