mp3splt-gtk: src/mp3splt-gtk.c Source File

mp3splt-gtk 0.9.3.1519

Loading...
Searching...
No Matches
mp3splt-gtk.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-2014 Alexandru Munteanu
7 * Contact: m@ioalex.net
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
28 * USA.
29 *
30 *********************************************************/
31
32/*!********************************************************
33 * \file
34 * The main file,
35 *
36 * this file contains the main() function as well as some
37 * globally used functions.
38 *********************************************************/
39
40#include "mp3splt-gtk.h"
41#include "ui_types.h"
42
43#ifndef __WIN32__
44 #include <langinfo.h>
45#endif
46
47 ui_state *ui;
48
49static gpointer split_collected_files(ui_for_split *ui_fs);
50static gboolean collect_files_to_split(ui_state *ui);
51
52void split_action(ui_state *ui)
53{
54 set_is_splitting_safe(TRUE, ui);
55 if (!collect_files_to_split(ui))
56 {
57 set_is_splitting_safe(FALSE, ui);
58 return;
59 }
60
61 gtk_widget_set_sensitive(ui->gui->cancel_button, TRUE);
62 remove_all_split_rows(ui);
63
64 ui_for_split *ui_fs = build_ui_for_split(ui);
65 ui_fs->pat = get_splitpoints_and_tags_for_mp3splt_state(ui);
66
67 create_thread_and_unref((GThreadFunc)split_collected_files,
68 (gpointer) ui_fs, ui, "split");
69}
70
71static gboolean collect_files_to_split(ui_state *ui)
72{
73 //clean
74 GPtrArray *files_to_split = ui->files_to_split;
75 if (files_to_split && files_to_split->len > 0)
76 {
77 gint length = files_to_split->len;
78 gint i = 0;
79 for (i = 0;i < length;i++)
80 {
81 g_free(g_ptr_array_index(files_to_split, i));
82 }
83 g_ptr_array_free(ui->files_to_split, TRUE);
84 }
85 ui->files_to_split = g_ptr_array_new();
86
87 //collect
88 if (get_split_file_mode(ui) == FILE_MODE_SINGLE)
89 {
90 g_ptr_array_add(ui->files_to_split, g_strdup(get_input_filename(ui->gui)));
91 }
92 else if (ui->infos->multiple_files_tree_number > 0)
93 {
94 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(ui->gui->multiple_files_tree));
95 gint row_number = 0;
96 while (row_number < ui->infos->multiple_files_tree_number)
97 {
98 GtkTreePath *path = gtk_tree_path_new_from_indices(row_number ,-1);
99
100 GtkTreeIter iter;
101 gtk_tree_model_get_iter(model, &iter, path);
102
103 gchar *filename = NULL;
104 gtk_tree_model_get(model, &iter, MULTIPLE_COL_FILENAME, &filename, -1);
105
106 g_ptr_array_add(ui->files_to_split, filename);
107
108 row_number++;
109 }
110 }
111 else
112 {
113 put_status_message(_(" error: no files found in batch mode"), ui);
114 return FALSE;
115 }
116
117 return TRUE;
118}
119
120static gboolean split_collected_files_end(ui_with_err *ui_err)
121{
122 gint err = ui_err->err;
123 ui_state *ui = ui_err->ui;
124
125 gtk_widget_set_sensitive(ui->gui->cancel_button, FALSE);
126
127 if (err >= 0)
128 {
129 gtk_progress_bar_set_fraction(ui->gui->percent_progress_bar, 1.0);
130 gtk_progress_bar_set_text(ui->gui->percent_progress_bar, _(" finished"));
131 }
132
133 set_is_splitting_safe(FALSE, ui);
134
135 set_process_in_progress_and_wait_safe(FALSE, ui_err->ui);
136
137 g_free(ui_err);
138
139 return FALSE;
140}
141
142static gint get_stop_split_safe(ui_state *ui)
143{
144 lock_mutex(&ui->variables_mutex);
145 gint stop_split = ui->status->stop_split;
146 unlock_mutex(&ui->variables_mutex);
147 return stop_split;
148}
149
151static gpointer split_collected_files(ui_for_split *ui_fs)
152{
153 ui_state *ui = ui_fs->ui;
154
155 set_process_in_progress_and_wait_safe(TRUE, ui);
156
157 put_options_from_preferences(ui_fs);
158
159 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_DEFAULT);
160 if (!ui_fs->is_checked_output_radio_box)
161 {
162 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_FORMAT);
163 }
164
165 mp3splt_set_path_of_split(ui->mp3splt_state, ui_fs->output_directory);
166
167 gint err = mp3splt_erase_all_splitpoints(ui->mp3splt_state);
168 err = mp3splt_erase_all_tags(ui->mp3splt_state);
169
170 gint split_mode = mp3splt_get_int_option(ui->mp3splt_state, SPLT_OPT_SPLIT_MODE, &err);
171 print_status_bar_confirmation_in_idle(err, ui);
172
173 err = mp3splt_set_oformat(ui->mp3splt_state, ui_fs->output_format);
174
175 if (mp3splt_get_int_option(ui->mp3splt_state, SPLT_OPT_SPLIT_MODE, &err) == SPLT_OPTION_NORMAL_MODE &&
176 ui_fs->split_file_mode == FILE_MODE_SINGLE)
177 {
178 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_CUSTOM);
179 }
180
181 if (split_mode == SPLT_OPTION_NORMAL_MODE)
182 {
183 gint i = 0;
184 for (i = 0;i < ui_fs->pat->splitpoints->len; i++)
185 {
186 splt_point *point = g_ptr_array_index(ui_fs->pat->splitpoints, i);
187 mp3splt_append_splitpoint(ui->mp3splt_state, point);
188 splt_tags *tags = g_ptr_array_index(ui_fs->pat->tags, i);
189 mp3splt_append_tags(ui->mp3splt_state, tags);
190 }
191
192 err = mp3splt_remove_tags_of_skippoints(ui->mp3splt_state);
193 print_status_bar_confirmation_in_idle(err, ui);
194 }
195
196 gint selected_split_mode = ui_fs->selected_split_mode;
197 gboolean is_single_file_mode = FALSE;
198 if (ui_fs->split_file_mode == FILE_MODE_SINGLE)
199 {
200 is_single_file_mode = TRUE;
201 }
202
203 //files_to_split will not have a read/write issue because the 'splitting' boolean, which does not
204 //allow us to modify it while we read it here - no mutex needed
205 GPtrArray *files_to_split = ui->files_to_split;
206 gint length = files_to_split->len;
207 gint i = 0;
208 for (i = 0;i < length;i++)
209 {
210 gint output_filenames = mp3splt_get_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, &err);
211
212 gchar *filename = g_ptr_array_index(files_to_split, i);
213
214 print_processing_file(filename, ui);
215
216 mp3splt_set_filename_to_split(ui->mp3splt_state, filename);
217
218 if (!is_single_file_mode)
219 {
220 if (selected_split_mode == SELECTED_SPLIT_INTERNAL_SHEET)
221 {
222 err = mp3splt_import(ui->mp3splt_state, PLUGIN_INTERNAL_IMPORT, filename);
223 print_status_bar_confirmation_in_idle(err, ui);
224 if (err < 0) { continue; }
225 }
226 else if ((selected_split_mode == SELECTED_SPLIT_CUE_FILE) ||
227 (selected_split_mode == SELECTED_SPLIT_CDDB_FILE))
228 {
229 gchar *cue_or_cddb = g_strdup(filename);
230 gchar *last_ext = g_strrstr(cue_or_cddb, ".");
231 *last_ext = '\0';
232
233 GString *cue_or_cddb_file = g_string_new(cue_or_cddb);
234 g_free(cue_or_cddb);
235
236 if (selected_split_mode == SELECTED_SPLIT_CUE_FILE) {
237 g_string_append(cue_or_cddb_file, ".cue");
238 err = mp3splt_import(ui->mp3splt_state, CUE_IMPORT, cue_or_cddb_file->str);
239
240 if (err >= 0) {
241 splt_point *splitpoint = mp3splt_point_new(LONG_MAX, NULL);
242 err = mp3splt_append_splitpoint(ui->mp3splt_state, splitpoint);
243 }
244 }
245 else
246 {
247 g_string_append(cue_or_cddb_file, ".cddb");
248 err = mp3splt_import(ui->mp3splt_state, CDDB_IMPORT, cue_or_cddb_file->str);
249 }
250
251 print_status_bar_confirmation_in_idle(err, ui);
252 g_string_free(cue_or_cddb_file, SPLT_TRUE);
253 if (err < 0) { continue; }
254
255 //set to custom because when importing the .cue & .cddb, output filenames are already set
256 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_CUSTOM);
257 }
258 }
259
260 err = mp3splt_split(ui->mp3splt_state);
261 print_status_bar_confirmation_in_idle(err, ui);
262
263 err = mp3splt_erase_all_tags(ui->mp3splt_state);
264 print_status_bar_confirmation_in_idle(err, ui);
265
266 err = mp3splt_erase_all_splitpoints(ui->mp3splt_state);
267 print_status_bar_confirmation_in_idle(err, ui);
268
269 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, output_filenames);
270
271 if (get_stop_split_safe(ui))
272 {
273 set_stop_split_safe(FALSE, ui);
274 break;
275 }
276 }
277
278 free_ui_for_split(ui_fs);
279
280 ui_with_err *ui_err = g_malloc0(sizeof(ui_with_err));
281 ui_err->err = err;
282 ui_err->ui = ui;
283
284 add_idle(G_PRIORITY_HIGH_IDLE, (GSourceFunc)split_collected_files_end, ui_err, NULL);
285
286 return NULL;
287}
288
289static gpointer thread_wrapper_function(gpointer data)
290{
291 ui_with_data *ui_wd = (ui_with_data *) data;
292 ui_state *ui = ui_wd->ui;
293
294 set_process_in_progress_and_wait_safe(TRUE, ui);
295
296 //some general options
297 if (ui_wd->filename_to_split != NULL)
298 {
299 mp3splt_set_filename_to_split(ui->mp3splt_state, ui_wd->filename_to_split);
300 }
301
302 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_DEBUG_MODE, ui->infos->debug_is_active);
303 if (ui_wd->is_checked_output_radio_box)
304 {
305 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_FORMAT);
306 }
307 else
308 {
309 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_DEFAULT);
310 }
311
312 set_process_in_progress_and_wait_safe(FALSE, ui);
313
314 gpointer returned_value = ui_wd->thread(ui_wd->data);
315
316 if (ui_wd->filename_to_split) { g_free(ui_wd->filename_to_split); }
317 g_free(ui_wd);
318
319 return returned_value;
320}
321
322GThread *create_thread(GThreadFunc func, gpointer data, ui_state *ui, const char *name)
323{
324 ui_with_data *ui_wd = g_malloc0(sizeof(ui_with_data));
325 ui_wd->ui = ui;
326 ui_wd->data = data;
327 ui_wd->thread = func;
328 ui_wd->is_checked_output_radio_box = get_checked_output_radio_box(ui);
329 gchar *input_filename = get_input_filename(ui->gui);
330 if (input_filename != NULL)
331 {
332 ui_wd->filename_to_split = g_strdup(input_filename);
333 }
334 return g_thread_new(name, thread_wrapper_function, ui_wd);
335}
336
337void create_thread_and_unref(GThreadFunc func, gpointer data, ui_state *ui, const char *name)
338{
339 g_thread_unref(create_thread(func, data, ui, name));
340}
341
342void add_idle(gint priority, GSourceFunc function, gpointer data, GDestroyNotify notify)
343{
344 gdk_threads_add_idle_full(priority, function, data, notify);
345}
346
347gboolean exit_application(GtkWidget *widget, GdkEvent *event, gpointer data)
348{
349 ui_state *ui = (ui_state *)data;
350
351 ui_save_preferences(NULL, ui);
352
353 if (get_is_splitting_safe(ui))
354 {
355 lmanager_stop_split(ui);
356 put_status_message(_(" info: stopping the split process before exiting"), ui);
357 }
358
359 if (player_is_running(ui))
360 {
361 player_quit(ui);
362 }
363
364 g_application_quit(G_APPLICATION(ui->gui->application));
365
366 return FALSE;
367}
368
369static gboolean sigint_called = FALSE;
370static void sigint_handler(gint sig)
371{
372 if (!sigint_called)
373 {
374 sigint_called = TRUE;
375 exit_application(NULL, NULL, ui);
376 }
377}
378
379#ifndef __WIN32__
380static void sigpipe_handler(gint sig)
381{
382 if (player_is_running(ui) &&
383 ui->infos->selected_player == PLAYER_SNACKAMP)
384 {
385 disconnect_snackamp(ui);
386 }
387}
388#endif
389
390static void register_application_signals()
391{
392 signal(SIGINT, sigint_handler);
393#ifndef __WIN32__
394 signal(SIGPIPE, sigpipe_handler);
395#endif
396}
397
398static void init_i18n_and_plugin_paths(gchar *argv[], ui_state *ui)
399{
400 setlocale(LC_ALL, "");
401 textdomain("mp3splt-gtk");
402
403#ifdef __WIN32__
404 char mp3splt_uninstall_file[2048] = { '\0' };
405 DWORD dwType, dwSize = sizeof(mp3splt_uninstall_file) - 1;
406 SHGetValue(HKEY_LOCAL_MACHINE,
407 TEXT("SOFTWARE\\mp3splt-gtk"),
408 TEXT("UninstallString"),
409 &dwType,
410 mp3splt_uninstall_file,
411 &dwSize);
412
413 gchar *end = strrchr(mp3splt_uninstall_file, SPLT_DIRCHAR);
414 if (end) { *end = '\0'; }
415
416 gchar *executable_dir = NULL;
417 gchar *executable = strdup(argv[0]);
418
419 end = strrchr(executable, SPLT_DIRCHAR);
420 if (end)
421 {
422 *end = '\0';
423 executable_dir = executable;
424 }
425 else
426 {
427 if (mp3splt_uninstall_file[0] != '\0')
428 {
429 executable_dir = mp3splt_uninstall_file;
430 }
431 }
432
433 bindtextdomain(LIBMP3SPLT_WITH_SONAME, "translations");
434 bindtextdomain("mp3splt-gtk", "translations");
435 bind_textdomain_codeset("mp3splt-gtk", "UTF-8");
436#else
437 bindtextdomain("mp3splt-gtk", LOCALEDIR);
438 bind_textdomain_codeset("mp3splt-gtk", nl_langinfo(CODESET));
439#endif
440
441#ifdef __WIN32__
442 if (executable != NULL)
443 {
444 if (executable[0] != '\0')
445 {
446 g_setenv("GST_PLUGIN_PATH", ".\\", TRUE);
447 mp3splt_append_plugins_scan_dir(ui->mp3splt_state, executable);
448 _chdir(executable);
449 }
450 }
451#endif
452}
453
454#ifdef __WIN32__
456static void set_language_env_variable_from_preferences()
457{
458 GKeyFile *key_file = g_key_file_new();
459 gchar *filename = get_preferences_filename();
460
461 g_key_file_load_from_file(key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
462
463 if (filename)
464 {
465 g_free(filename);
466 filename = NULL;
467 }
468
469 gchar *lang = g_key_file_get_string(key_file, "general", "language", NULL);
470
471 gchar lang_env[32] = { '\0' };
472 g_snprintf(lang_env, 32, "LANG=%s", lang);
473 putenv(lang_env);
474
475 g_free(lang);
476 g_key_file_free(key_file);
477}
478#endif
479
503gint main(gint argc, gchar **argv, gchar **envp)
504{
505 ui = ui_state_new();
506
507 ui->argc = argc;
508 ui->argv = argv;
509
510 register_application_signals();
511 init_i18n_and_plugin_paths(argv, ui);
512
513 gtk_init(&argc, &argv);
514
515 lmanager_init_and_find_plugins(ui);
516
517#ifdef __WIN32__
518 set_language_env_variable_from_preferences();
519#endif
520
521 create_application(ui);
522 int application_code =
523 g_application_run(G_APPLICATION(ui->gui->application), argc, argv);
524
525 gint return_code = ui->return_code;
526 ui_state_free(ui);
527
528 if (application_code != 0)
529 {
530 return application_code;
531 }
532
533 return return_code;
534}
535
get_input_filename
gchar * get_input_filename(gui_state *gui)
Get the name of the input file.
Definition main_window.c:73
put_status_message
void put_status_message(const gchar *text, ui_state *ui)
Output a info message to the status message bar.
Definition main_window.c:263
main
gint main(gint argc, gchar **argv, gchar **envp)
The traditional C main function.
Definition mp3splt-gtk.c:503
put_options_from_preferences
void put_options_from_preferences(ui_for_split *ui_fs)
Update the ui->mp3splt_state structure.
Definition options_manager.c:189
player_quit
gint player_quit(ui_state *ui)
quits the player
Definition player_control.c:611
player_is_running
gint player_is_running(ui_state *ui)
returns FALSE if the player is not running, else TRUE
Definition player_control.c:95
get_preferences_filename
gchar * get_preferences_filename()
Get the name of the preferences file.
Definition preferences_manager.c:186
get_checked_output_radio_box
gboolean get_checked_output_radio_box(ui_state *ui)
returns the checked output radio box
Definition preferences_window.c:71
disconnect_snackamp
gint disconnect_snackamp(ui_state *ui)
disconnecting with the player possibly returns an error
Definition snackamp_control.c:200
remove_all_split_rows
void remove_all_split_rows(ui_state *ui)
removes all rows from the split files table
Definition split_files_window.c:80
ui_for_split
Definition ui_types.h:571
ui_state
Definition ui_types.h:509
ui_with_data
Definition ui_types.h:537
ui_with_err
Definition ui_types.h:531
print_processing_file
void print_processing_file(gchar *filename, ui_state *ui)
Issues the message "Processing file <filename>" into the message bar.
Definition utilities.c:82