mp3splt-gtk

- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

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-2013 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 ui_state *ui;
43
44 static gpointer split_collected_files(ui_state *ui);
45 static gboolean collect_files_to_split(ui_state *ui);
46
47 void split_action(ui_state *ui)
48 {
49 set_is_splitting_safe(TRUE, ui);
50 if (!collect_files_to_split(ui))
51 {
52 set_is_splitting_safe(FALSE, ui);
53 return;
54 }
55 set_is_splitting_safe(FALSE, ui);
56
57 create_thread((GThreadFunc)split_collected_files, ui);
58 }
59
60 static gboolean collect_files_to_split(ui_state *ui)
61 {
62 //clean
63 GPtrArray *files_to_split = ui->files_to_split;
64 if (files_to_split && files_to_split->len > 0)
65 {
66 gint length = files_to_split->len;
67 gint i = 0;
68 for (i = 0;i < length;i++)
69 {
70 g_free(g_ptr_array_index(files_to_split, i));
71 }
72 g_ptr_array_free(ui->files_to_split, TRUE);
73 }
74 ui->files_to_split = g_ptr_array_new();
75
76 //collect
77 if (get_split_file_mode_safe(ui) == FILE_MODE_SINGLE)
78 {
79 g_ptr_array_add(ui->files_to_split, g_strdup(get_input_filename(ui->gui)));
80 }
81 else if (ui->infos->multiple_files_tree_number > 0)
82 {
83 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(ui->gui->multiple_files_tree));
84 gint row_number = 0;
85 while (row_number < ui->infos->multiple_files_tree_number)
86 {
87 GtkTreePath *path = gtk_tree_path_new_from_indices(row_number ,-1);
88
89 GtkTreeIter iter;
90 gtk_tree_model_get_iter(model, &iter, path);
91
92 gchar *filename = NULL;
93 gtk_tree_model_get(model, &iter, MULTIPLE_COL_FILENAME, &filename, -1);
94
95 g_ptr_array_add(ui->files_to_split, filename);
96
97 row_number++;
98 }
99 }
100 else
101 {
102 put_status_message(_(" error: no files found in batch mode"), ui);
103 return FALSE;
104 }
105
106 return TRUE;
107 }
108
109 static gboolean split_collected_files_end(ui_with_err *ui_err)
110 {
111 gint err = ui_err->err;
112 ui_state *ui = ui_err->ui;
113
114 gtk_widget_set_sensitive(ui->gui->cancel_button, FALSE);
115
116 if (err >= 0)
117 {
118 gtk_progress_bar_set_fraction(ui->gui->percent_progress_bar, 1.0);
119 gtk_progress_bar_set_text(ui->gui->percent_progress_bar, _(" finished"));
120 }
121
122 set_is_splitting_safe(FALSE, ui);
123
124 set_process_in_progress_and_wait_safe(FALSE, ui_err->ui);
125
126 g_free(ui_err);
127
128 return FALSE;
129 }
130
131 static gint get_stop_split_safe(ui_state *ui)
132 {
133 lock_mutex(&ui->variables_mutex);
134 gint stop_split = ui->status->stop_split;
135 unlock_mutex(&ui->variables_mutex);
136 return stop_split;
137 }
138
140 static gpointer split_collected_files(ui_state *ui)
141 {
142 set_process_in_progress_and_wait_safe(TRUE, ui);
143
144 enter_threads();
145
146 gtk_widget_set_sensitive(ui->gui->cancel_button, TRUE);
147
148 put_options_from_preferences(ui);
149
150 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_DEFAULT);
151 if (!get_checked_output_radio_box(ui))
152 {
153 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_FORMAT);
154 }
155
156 exit_threads();
157
158 gint split_file_mode = get_split_file_mode_safe(ui);
159
160 lock_mutex(&ui->variables_mutex);
161 mp3splt_set_path_of_split(ui->mp3splt_state, get_output_directory(ui));
162 unlock_mutex(&ui->variables_mutex);
163
164 enter_threads();
165 remove_all_split_rows(ui);
166 exit_threads();
167
168 gint err = mp3splt_erase_all_splitpoints(ui->mp3splt_state);
169 err = mp3splt_erase_all_tags(ui->mp3splt_state);
170
171 gint split_mode = mp3splt_get_int_option(ui->mp3splt_state, SPLT_OPT_SPLIT_MODE, &err);
172 print_status_bar_confirmation_in_idle(err, ui);
173
174 enter_threads();
175 gchar *format = strdup(gtk_entry_get_text(GTK_ENTRY(ui->gui->output_entry)));
176 exit_threads();
177
178 err = mp3splt_set_oformat(ui->mp3splt_state, format);
179
180 if (format)
181 {
182 free(format);
183 format = NULL;
184 }
185
186 if (mp3splt_get_int_option(ui->mp3splt_state, SPLT_OPT_SPLIT_MODE, &err) == SPLT_OPTION_NORMAL_MODE &&
187 split_file_mode == FILE_MODE_SINGLE)
188 {
189 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, SPLT_OUTPUT_CUSTOM);
190 }
191
192 if (split_mode == SPLT_OPTION_NORMAL_MODE)
193 {
194 enter_threads();
195 put_splitpoints_and_tags_in_mp3splt_state(ui->mp3splt_state, ui);
196
197 err = mp3splt_remove_tags_of_skippoints(ui->mp3splt_state);
198 print_status_bar_confirmation_in_idle(err, ui);
199 exit_threads();
200 }
201
202 err = SPLT_OK;
203 gint output_filenames = mp3splt_get_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, &err);
204
205 //files_to_split will not have a read/write issue because the 'splitting' boolean, which does not
206 //allow us to modify it while we read it here - no mutex needed
207 GPtrArray *files_to_split = ui->files_to_split;
208 gint length = files_to_split->len;
209 gint i = 0;
210 for (i = 0;i < length;i++)
211 {
212 gchar *filename = g_ptr_array_index(files_to_split, i);
213
214 enter_threads();
215 print_processing_file(filename, ui);
216 exit_threads();
217
218 mp3splt_set_filename_to_split(ui->mp3splt_state, filename);
219
220 gint err = mp3splt_split(ui->mp3splt_state);
221 print_status_bar_confirmation_in_idle(err, ui);
222
223 err = mp3splt_erase_all_tags(ui->mp3splt_state);
224 print_status_bar_confirmation_in_idle(err, ui);
225
226 err = mp3splt_erase_all_splitpoints(ui->mp3splt_state);
227 print_status_bar_confirmation_in_idle(err, ui);
228
229 if (get_stop_split_safe(ui))
230 {
231 set_stop_split_safe(FALSE, ui);
232 break;
233 }
234 }
235
236 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_OUTPUT_FILENAMES, output_filenames);
237
238 ui_with_err *ui_err = g_malloc0(sizeof(ui_with_err));
239 ui_err->err = err;
240 ui_err->ui = ui;
241
242 gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)split_collected_files_end, ui_err, NULL);
243
244 return NULL;
245 }
246
247 GThread *create_thread(GThreadFunc func, ui_state *ui)
248 {
249 mp3splt_set_int_option(ui->mp3splt_state, SPLT_OPT_DEBUG_MODE, ui->infos->debug_is_active);
250 return g_thread_create(func, ui, TRUE, NULL);
251 }
252
253 GThread *create_thread_with_fname(GThreadFunc func, ui_with_fname *ui_fname)
254 {
255 mp3splt_set_int_option(ui_fname->ui->mp3splt_state, SPLT_OPT_DEBUG_MODE, ui_fname->ui->infos->debug_is_active);
256 return g_thread_create(func, ui_fname, TRUE, NULL);
257 }
258
259 void enter_threads()
260 {
261 gdk_threads_enter();
262 }
263
264 void exit_threads()
265 {
266 gdk_threads_leave();
267 }
268
269 gboolean exit_application(GtkWidget *widget, GdkEvent *event, gpointer data)
270 {
271 ui_state *ui = (ui_state *)data;
272
273 ui_save_preferences(NULL, ui);
274
275 if (get_is_splitting_safe(ui))
276 {
277 lmanager_stop_split(ui);
278 put_status_message(_(" info: stopping the split process before exiting"), ui);
279 }
280
281 if (player_is_running(ui))
282 {
283 player_quit(ui);
284 }
285
286 gtk_main_quit();
287
288 return FALSE;
289 }
290
291 void exit_application_bis(GtkWidget *widget, gpointer data)
292 {
293 exit_application(widget, NULL, data);
294 }
295
296 static gboolean sigint_called = FALSE;
297 static void sigint_handler(gint sig)
298 {
299 if (!sigint_called)
300 {
301 sigint_called = TRUE;
302 exit_application(NULL, NULL, ui);
303 }
304 }
305
306 #ifndef __WIN32__
307 static void sigpipe_handler(gint sig)
308 {
309 if (player_is_running(ui) &&
310 ui->infos->selected_player == PLAYER_SNACKAMP)
311 {
312 disconnect_snackamp(ui);
313 }
314 }
315 #endif
316
317 static void register_application_signals()
318 {
319 signal(SIGINT, sigint_handler);
320 #ifndef __WIN32__
321 signal(SIGPIPE, sigpipe_handler);
322 #endif
323 }
324
325 static void init_i18n_and_plugin_paths(gchar *argv[], ui_state *ui)
326 {
327 setlocale(LC_ALL, "");
328 textdomain("mp3splt-gtk");
329
330 #ifdef __WIN32__
331 char mp3splt_uninstall_file[2048] = { '\0' };
332 DWORD dwType, dwSize = sizeof(mp3splt_uninstall_file) - 1;
333 SHGetValue(HKEY_LOCAL_MACHINE,
334 TEXT("SOFTWARE\\mp3splt-gtk"),
335 TEXT("UninstallString"),
336 &dwType,
337 mp3splt_uninstall_file,
338 &dwSize);
339
340 gchar *end = strrchr(mp3splt_uninstall_file, SPLT_DIRCHAR);
341 if (end) { *end = '\0'; }
342
343 gchar *executable_dir = NULL;
344 gchar *executable = strdup(argv[0]);
345
346 end = strrchr(executable, SPLT_DIRCHAR);
347 if (end)
348 {
349 *end = '\0';
350 executable_dir = executable;
351 }
352 else
353 {
354 if (mp3splt_uninstall_file[0] != '\0')
355 {
356 executable_dir = mp3splt_uninstall_file;
357 }
358 }
359
360 bindtextdomain(LIBMP3SPLT_WITH_SONAME, "translations");
361 bindtextdomain("mp3splt-gtk", "translations");
362 #else
363 bindtextdomain("mp3splt-gtk", LOCALEDIR);
364 #endif
365 bind_textdomain_codeset("mp3splt-gtk", "UTF-8");
366
367 #ifdef __WIN32__
368 if (executable != NULL)
369 {
370 if (executable[0] != '\0')
371 {
372 g_setenv("GST_PLUGIN_PATH", ".\\", TRUE);
373 mp3splt_append_plugins_scan_dir(ui->mp3splt_state, executable);
374 _chdir(executable);
375 }
376 }
377 #endif
378 }
379
380 static void parse_command_line_options(gint argc, gchar * argv[], ui_state *ui)
381 {
382 opterr = 0;
383 int option;
384 while ((option = getopt(argc, argv, "d:")) != -1)
385 {
386 switch (option)
387 {
388 case 'd':
389 fprintf(stdout, _("Setting the output directory to %s.\n"), optarg);
390 set_output_directory_and_update_ui((gchar *)optarg, ui);
391 #ifdef __WIN32__
392 mkdir(optarg);
393 #else
394 mkdir(optarg, 0777);
395 #endif
396 if (!directory_exists(optarg))
397 {
398 ui_fail(ui, "Error: The specified output directory is inaccessible!\n");
399 }
400 break;
401 case '?':
402 if (optopt == 'd')
403 ui_fail(ui, _("Option -%c requires an argument.\n"), optopt);
404 else if (isprint(optopt))
405 ui_fail(ui, _("Unknown option `-%c'.\n"), optopt, NULL);
406 else
407 ui_fail(ui, _("Unknown option character `\\x%x'.\n"), optopt);
408 break;
409 default:
410 ui_fail(ui, NULL);
411 }
412 }
413
414 if (optind == argc)
415 {
416 return;
417 }
418
419 if (!file_exists(argv[optind]))
420 {
421 ui_fail(ui, _("Cannot open input file %s\n"), argv[optind]);
422 }
423
424 #ifndef __WIN32__
425 char *input_filename = realpath(argv[optind], NULL);
426 import_file(input_filename, ui);
427 free(input_filename);
428 #else
429 import_file(argv[optind], ui);
430 #endif
431 }
432
433 #ifdef __WIN32__
434 static void set_language_env_variable_from_preferences()
436 {
437 GKeyFile *key_file = g_key_file_new();
438 gchar *filename = get_preferences_filename();
439
440 g_key_file_load_from_file(key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
441
442 if (filename)
443 {
444 g_free(filename);
445 filename = NULL;
446 }
447
448 gchar *lang = g_key_file_get_string(key_file, "general", "language", NULL);
449
450 gchar lang_env[32] = { '\0' };
451 g_snprintf(lang_env, 32, "LANG=%s", lang);
452 putenv(lang_env);
453
454 g_free(lang);
455 g_key_file_free(key_file);
456 }
457 #endif
458
482 gint main(gint argc, gchar *argv[], gchar **envp)
483 {
484 ui = ui_state_new();
485
486 g_thread_init(NULL);
487 gdk_threads_init();
488
489 register_application_signals();
490 init_i18n_and_plugin_paths(argv, ui);
491
492 gtk_init(&argc, &argv);
493
494 lmanager_init_and_find_plugins(ui);
495
496 #ifdef __WIN32__
497 set_language_env_variable_from_preferences();
498 #endif
499
500 create_application(ui);
501
502 import_cue_file_from_the_configuration_directory(ui);
503
504 parse_command_line_options(argc, argv, ui);
505
506 enter_threads();
507 gtk_main();
508 exit_threads();
509
510 gint return_code = ui->return_code;
511 ui_state_free(ui);
512
513 return return_code;
514 }
515
get_preferences_filename
gchar * get_preferences_filename()
Get the name of the preferences file.
Definition: preferences_manager.c:190
put_splitpoints_and_tags_in_mp3splt_state
void put_splitpoints_and_tags_in_mp3splt_state(splt_state *state, ui_state *ui)
puts the splitpoints into the state
Definition: splitpoints_window.c:2166
get_input_filename
gchar * get_input_filename(gui_state *gui)
Get the name of the input file.
Definition: main_window.c:76
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
ui_with_fname
Definition: ui_types.h:509
file_exists
gint file_exists(const gchar *fname)
check if specified file exists
Definition: utilities.c:62
print_processing_file
void print_processing_file(gchar *filename, ui_state *ui)
Issues the message &quot;Processing file &lt;filename&gt;&quot; into the message bar.
Definition: utilities.c:82
get_output_directory
gchar * get_output_directory(ui_state *ui)
Get the name of the output directory.
Definition: preferences_window.c:189
ui_state
Definition: ui_types.h:485
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:264
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
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
put_options_from_preferences
void put_options_from_preferences(ui_state *ui)
Update the ui-&gt;mp3splt_state structure.
Definition: options_manager.c:76
ui_with_err
Definition: ui_types.h:504
import_file
void import_file(gchar *filename, ui_state *ui)
Handles the import of an input file (audio or splitpoint)
Definition: import.c:86
main
gint main(gint argc, gchar *argv[], gchar **envp)
The traditional C main function.
Definition: mp3splt-gtk.c:482
directory_exists
gint directory_exists(const gchar *directory)
check if specified directory exists
Definition: utilities.c:44