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