1 /*************************************************************************/
2 /* Copyright (C) 2007-2009 sujith <m.sujith@gmail.com>                   */
3 /* Copyright (C) 2009-2015 matias <mati86dl@gmail.com>                   */
4 /*                                                                       */
5 /* This program is free software: you can redistribute it and/or modify  */
6 /* it under the terms of the GNU General Public License as published by  */
7 /* the Free Software Foundation, either version 3 of the License, or     */
8 /* (at your option) any later version.                                   */
9 /*                                                                       */
10 /* This program is distributed in the hope that it will be useful,       */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of        */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
13 /* GNU General Public License for more details.                          */
14 /*                                                                       */
15 /* You should have received a copy of the GNU General Public License     */
16 /* along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17 /*************************************************************************/
18 
19 #if HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 
23 #include "pragha.h"
24 
25 #if defined(GETTEXT_PACKAGE)
26 #include <glib/gi18n-lib.h>
27 #else
28 #include <glib/gi18n.h>
29 #endif
30 
31 #include <glib.h>
32 #include <locale.h> /* require LC_ALL */
33 #include <libintl.h>
34 #include <tag_c.h>
35 
36 #include "pragha-hig.h"
37 #include "pragha-window.h"
38 #include "pragha-playback.h"
39 #include "pragha-musicobject-mgmt.h"
40 #include "pragha-menubar.h"
41 #include "pragha-file-utils.h"
42 #include "pragha-utils.h"
43 #include "pragha-music-enum.h"
44 #include "pragha-playlists-mgmt.h"
45 
46 #ifdef G_OS_WIN32
47 #include "../win32/win32dep.h"
48 #endif
49 
50 gint debug_level;
51 #ifdef DEBUG
52 GThread *pragha_main_thread = NULL;
53 #endif
54 
55 struct _PraghaApplication {
56 	GtkApplication base_instance;
57 
58 	/* Main window and icon */
59 
60 	GtkWidget         *mainwindow;
61 
62 	/* Main stuff */
63 
64 	PraghaBackend     *backend;
65 	PraghaPreferences *preferences;
66 	PraghaDatabase    *cdbase;
67 	PraghaArtCache    *art_cache;
68 	PraghaMusicEnum   *enum_map;
69 
70 	PraghaScanner     *scanner;
71 
72 	PreferencesDialog *setting_dialog;
73 
74 	/* Main widgets */
75 
76 	GtkUIManager      *menu_ui_manager;
77 	GtkBuilder        *menu_ui;
78 	PraghaToolbar     *toolbar;
79 	GtkWidget         *infobox;
80 	GtkWidget         *pane1;
81 	GtkWidget         *pane2;
82 	PraghaSidebar     *sidebar1;
83 	PraghaSidebar     *sidebar2;
84 	PraghaLibraryPane *library;
85 	PraghaPlaylist    *playlist;
86 	PraghaStatusbar   *statusbar;
87 
88 	PraghaStatusIcon  *status_icon;
89 
90 	GBinding          *sidebar2_binding;
91 
92 #ifdef HAVE_LIBPEAS
93 	PraghaPluginsEngine *plugins_engine;
94 #endif
95 };
96 
97 G_DEFINE_TYPE (PraghaApplication, pragha_application, GTK_TYPE_APPLICATION);
98 
99 /*
100  * Some calbacks..
101  */
102 
103 /* Handler for the 'Open' item in the File menu */
104 
105 static void
pragha_open_files_dialog_close_button_cb(GtkWidget * widget,gpointer data)106 pragha_open_files_dialog_close_button_cb (GtkWidget *widget, gpointer data)
107 {
108     gtk_widget_destroy(GTK_WIDGET(data));
109 }
110 
111 static void
pragha_open_files_dialog_add_button_cb(GtkWidget * widget,gpointer data)112 pragha_open_files_dialog_add_button_cb (GtkWidget *widget, gpointer data)
113 {
114 	PraghaPlaylist *playlist;
115 	GSList *files = NULL, *l;
116 	gboolean add_recursively;
117 	GList *mlist = NULL;
118 
119 	GtkWidget *window = g_object_get_data(data, "window");
120 	GtkWidget *chooser = g_object_get_data(data, "chooser");
121 	GtkWidget *toggle = g_object_get_data(data, "toggle-button");
122 	PraghaApplication *pragha = g_object_get_data(data, "pragha");
123 
124 	PraghaPreferences *preferences = pragha_application_get_preferences (pragha);
125 
126 	add_recursively = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle));
127 	pragha_preferences_set_add_recursively (preferences, add_recursively);
128 
129 	gchar *last_folder = gtk_file_chooser_get_current_folder ((GtkFileChooser *) chooser);
130 	pragha_preferences_set_last_folder (preferences, last_folder);
131 	g_free (last_folder);
132 
133 	files = gtk_file_chooser_get_filenames((GtkFileChooser *) chooser);
134 
135 	gtk_widget_destroy(window);
136 
137 	if (files) {
138 		for (l = files; l != NULL; l = l->next) {
139 			mlist = append_mobj_list_from_unknown_filename(mlist, l->data);
140 		}
141 		g_slist_free_full(files, g_free);
142 
143 		playlist = pragha_application_get_playlist (pragha);
144 		pragha_playlist_append_mobj_list (playlist, mlist);
145 		g_list_free (mlist);
146 	}
147 }
148 
149 static gboolean
pragha_open_files_dialog_keypress(GtkWidget * dialog,GdkEventKey * event,gpointer data)150 pragha_open_files_dialog_keypress (GtkWidget   *dialog,
151                                    GdkEventKey *event,
152                                    gpointer     data)
153 {
154     if (event->keyval == GDK_KEY_Escape) {
155         gtk_widget_destroy(dialog);
156         return TRUE;
157     }
158     return FALSE;
159 }
160 
161 void
pragha_application_open_files(PraghaApplication * pragha)162 pragha_application_open_files (PraghaApplication *pragha)
163 {
164 	PraghaPreferences *preferences;
165 	GtkWidget *window, *hbox, *vbox, *chooser, *bbox, *toggle, *close_button, *add_button;
166 	gpointer storage;
167 	gint i = 0;
168 	GtkFileFilter *media_filter, *playlist_filter, *all_filter;
169 	const gchar *last_folder = NULL;
170 
171 	/* Create a file chooser dialog */
172 
173 	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
174 
175 	gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG);
176 	gtk_window_set_title(GTK_WINDOW(window), (_("Select a file to play")));
177 	gtk_window_set_default_size(GTK_WINDOW(window), 700, 450);
178 	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
179 	gtk_container_set_border_width(GTK_CONTAINER(window), 10);
180 
181 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
182 
183 	gtk_container_add(GTK_CONTAINER(window), vbox);
184 
185 	chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_OPEN);
186 
187 	/* Set various properties */
188 
189 	gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(chooser), TRUE);
190 
191 	preferences = pragha_application_get_preferences (pragha);
192 	last_folder = pragha_preferences_get_last_folder (preferences);
193 	if (string_is_not_empty(last_folder))
194 		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), last_folder);
195 
196 	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
197 
198 	toggle = gtk_check_button_new_with_label(_("Add files recursively"));
199 	if(pragha_preferences_get_add_recursively (preferences))
200 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle), TRUE);
201 
202 	bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
203 	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
204 	gtk_box_set_spacing(GTK_BOX(bbox), 6);
205 
206 	close_button = gtk_button_new_with_mnemonic (_("_Cancel"));
207 	add_button = gtk_button_new_with_mnemonic (_("_Add"));
208 	gtk_container_add(GTK_CONTAINER(bbox), close_button);
209 	gtk_container_add(GTK_CONTAINER(bbox), add_button);
210 
211 	gtk_box_pack_start(GTK_BOX(hbox), toggle, TRUE, TRUE, 3);
212 	gtk_box_pack_end(GTK_BOX(hbox), bbox, FALSE, FALSE, 3);
213 
214 	gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
215 	gtk_box_pack_end(GTK_BOX(vbox), chooser, TRUE, TRUE, 3);
216 
217 	/* Create file filters  */
218 
219 	media_filter = gtk_file_filter_new();
220 	gtk_file_filter_set_name(GTK_FILE_FILTER(media_filter), _("Supported media"));
221 
222 	while (mime_wav[i])
223 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
224 		                              mime_wav[i++]);
225 	i = 0;
226 	while (mime_mpeg[i])
227 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
228 		                              mime_mpeg[i++]);
229 	i = 0;
230 	while (mime_flac[i])
231 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
232 		                              mime_flac[i++]);
233 	i = 0;
234 	while (mime_ogg[i])
235 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
236 		                              mime_ogg[i++]);
237 
238 	i = 0;
239 	while (mime_asf[i])
240 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
241 		                              mime_asf[i++]);
242 	i = 0;
243 	while (mime_mp4[i])
244 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
245 		                              mime_mp4[i++]);
246 	i = 0;
247 	while (mime_ape[i])
248 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
249 		                              mime_ape[i++]);
250 	i = 0;
251 	while (mime_tracker[i])
252 	 gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
253 		                              mime_tracker[i++]);
254 
255 	#ifdef HAVE_PLPARSER
256 	i = 0;
257 	while (mime_playlist[i])
258 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
259 		                              mime_playlist[i++]);
260 	i = 0;
261 	while (mime_dual[i])
262 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(media_filter),
263 		                              mime_dual[i++]);
264 	#else
265 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(media_filter), "*.m3u");
266 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(media_filter), "*.M3U");
267 
268 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(media_filter), "*.pls");
269 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(media_filter), "*.PLS");
270 
271 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(media_filter), "*.xspf");
272 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(media_filter), "*.XSPF");
273 
274 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(media_filter), "*.wax");
275 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(media_filter), "*.WAX");
276 	#endif
277 
278 	playlist_filter = gtk_file_filter_new();
279 
280 	#ifdef HAVE_PLPARSER
281 	i = 0;
282 	while (mime_playlist[i])
283 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(playlist_filter),
284 		                              mime_playlist[i++]);
285 	i = 0;
286 	while (mime_dual[i])
287 		gtk_file_filter_add_mime_type(GTK_FILE_FILTER(playlist_filter),
288 		                              mime_dual[i++]);
289 	#else
290 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(playlist_filter), "*.m3u");
291 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(playlist_filter), "*.M3U");
292 
293 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(playlist_filter), "*.pls");
294 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(playlist_filter), "*.PLS");
295 
296 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(playlist_filter), "*.xspf");
297 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(playlist_filter), "*.XSPF");
298 
299 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(playlist_filter), "*.wax");
300 	gtk_file_filter_add_pattern(GTK_FILE_FILTER(playlist_filter), "*.WAX");
301 	#endif
302 
303 	gtk_file_filter_set_name(GTK_FILE_FILTER(playlist_filter), _("Playlists"));
304 
305 	all_filter = gtk_file_filter_new ();
306 	gtk_file_filter_set_name (GTK_FILE_FILTER(all_filter), _("All files"));
307 	gtk_file_filter_add_pattern (GTK_FILE_FILTER(all_filter), "*");
308 
309 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser),
310 	                             GTK_FILE_FILTER(media_filter));
311 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser),
312 	                             GTK_FILE_FILTER(playlist_filter));
313 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(chooser),
314 	                             GTK_FILE_FILTER(all_filter));
315 
316 	gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(chooser),
317 	                            GTK_FILE_FILTER(media_filter));
318 
319 	storage = g_object_new(G_TYPE_OBJECT, NULL);
320 	g_object_set_data(storage, "window", window);
321 	g_object_set_data(storage, "chooser", chooser);
322 	g_object_set_data(storage, "toggle-button", toggle);
323 	g_object_set_data(storage, "pragha", pragha);
324 
325 	g_signal_connect (add_button, "clicked",
326 	                  G_CALLBACK(pragha_open_files_dialog_add_button_cb), storage);
327 	g_signal_connect (chooser, "file-activated",
328 	                  G_CALLBACK(pragha_open_files_dialog_add_button_cb), storage);
329 	g_signal_connect (close_button, "clicked",
330 	                  G_CALLBACK(pragha_open_files_dialog_close_button_cb), window);
331 	g_signal_connect (window, "destroy",
332 	                  G_CALLBACK(gtk_widget_destroy), window);
333 	g_signal_connect (window, "key-press-event",
334 	                  G_CALLBACK(pragha_open_files_dialog_keypress), NULL);
335 
336 	gtk_window_set_transient_for(GTK_WINDOW (window), GTK_WINDOW(pragha_application_get_window(pragha)));
337 	gtk_window_set_destroy_with_parent (GTK_WINDOW (window), TRUE);
338 
339 	gtk_widget_show_all(window);
340 }
341 
342 /* Build a dialog to get a new playlist name */
343 
344 static char *
totem_open_location_set_from_clipboard(GtkWidget * open_location)345 totem_open_location_set_from_clipboard (GtkWidget *open_location)
346 {
347 	GtkClipboard *clipboard;
348 	gchar *clipboard_content;
349 
350 	/* Initialize the clipboard and get its content */
351 	clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (open_location)), GDK_SELECTION_CLIPBOARD);
352 	clipboard_content = gtk_clipboard_wait_for_text (clipboard);
353 
354 	/* Check clipboard for "://". If it exists, return it */
355 	if (clipboard_content != NULL && strcmp (clipboard_content, "") != 0)
356 	{
357 		if (g_strrstr (clipboard_content, "://") != NULL)
358 			return clipboard_content;
359 	}
360 
361 	g_free (clipboard_content);
362 	return NULL;
363 }
364 
365 void
pragha_application_add_location(PraghaApplication * pragha)366 pragha_application_add_location (PraghaApplication *pragha)
367 {
368 	PraghaPlaylist *playlist;
369 	PraghaDatabase *cdbase;
370 	PraghaMusicobject *mobj;
371 	GtkWidget *dialog, *table, *uri_entry, *label_name, *name_entry;
372 	const gchar *uri = NULL, *name = NULL;
373 	gchar *clipboard_location = NULL, *real_name = NULL;
374 	GSList *list = NULL, *i = NULL;
375 	GList *mlist = NULL;
376 	guint row = 0;
377 	gint result;
378 
379 	/* Create dialog window */
380 
381 	table = pragha_hig_workarea_table_new ();
382 	pragha_hig_workarea_table_add_section_title(table, &row, _("Enter the URL of an internet radio stream"));
383 
384 	uri_entry = gtk_entry_new();
385 	gtk_entry_set_max_length(GTK_ENTRY(uri_entry), 255);
386 
387 	pragha_hig_workarea_table_add_wide_control (table, &row, uri_entry);
388 
389 	label_name = gtk_label_new_with_mnemonic(_("Give it a name to save"));
390 	name_entry = gtk_entry_new();
391 	gtk_entry_set_max_length(GTK_ENTRY(name_entry), 255);
392 
393 	pragha_hig_workarea_table_add_row (table, &row, label_name, name_entry);
394 
395 	/* Get item from clipboard to fill GtkEntry */
396 	clipboard_location = totem_open_location_set_from_clipboard (uri_entry);
397 	if (clipboard_location != NULL && strcmp (clipboard_location, "") != 0) {
398 		gtk_entry_set_text (GTK_ENTRY(uri_entry), clipboard_location);
399 		g_free (clipboard_location);
400 	}
401 
402 	dialog = gtk_dialog_new_with_buttons (_("Add a location"),
403 	                                      GTK_WINDOW(pragha_application_get_window(pragha)),
404 	                                      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
405 	                                      _("_Cancel"), GTK_RESPONSE_CANCEL,
406 	                                      _("_Ok"), GTK_RESPONSE_ACCEPT,
407 	                                      NULL);
408 
409 	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
410 
411 	gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), table);
412 
413 	gtk_window_set_default_size(GTK_WINDOW (dialog), 450, -1);
414 
415 	gtk_entry_set_activates_default (GTK_ENTRY(uri_entry), TRUE);
416 	gtk_entry_set_activates_default (GTK_ENTRY(name_entry), TRUE);
417 
418 	gtk_widget_show_all(dialog);
419 
420 	result = gtk_dialog_run(GTK_DIALOG(dialog));
421 	switch(result) {
422 	case GTK_RESPONSE_ACCEPT:
423 		if (gtk_entry_get_text_length (GTK_ENTRY(uri_entry)))
424 			uri = gtk_entry_get_text(GTK_ENTRY(uri_entry));
425 
426 		playlist = pragha_application_get_playlist (pragha);
427 
428 		if (string_is_not_empty(uri)) {
429 			if (gtk_entry_get_text_length (GTK_ENTRY(name_entry)))
430 				name = gtk_entry_get_text(GTK_ENTRY(name_entry));
431 
432 			#ifdef HAVE_PLPARSER
433 			list = pragha_totem_pl_parser_parse_from_uri (uri);
434 			#else
435 			list = g_slist_append (list, g_strdup(uri));
436 			#endif
437 
438 			for (i = list; i != NULL; i = i->next) {
439 				if (string_is_not_empty(name))
440 					real_name = new_radio (playlist, i->data, name);
441 
442 				mobj = new_musicobject_from_location (i->data, real_name);
443 				mlist = g_list_append(mlist, mobj);
444 
445 				if (real_name) {
446 					g_free (real_name);
447 					real_name = NULL;
448 				}
449 				g_free(i->data);
450 			}
451 			g_slist_free(list);
452 
453 			/* Append playlist and save on database */
454 
455 			pragha_playlist_append_mobj_list (playlist, mlist);
456 			g_list_free(mlist);
457 
458 			cdbase = pragha_application_get_database (pragha);
459 			pragha_database_change_playlists_done (cdbase);
460 		}
461 		break;
462 	case GTK_RESPONSE_CANCEL:
463 		break;
464 	default:
465 		break;
466 	}
467 	gtk_widget_destroy(dialog);
468 
469 	return;
470 }
471 
472 /* Handler for 'Add All' action in the Tools menu */
473 
474 void
pragha_application_append_entery_libary(PraghaApplication * pragha)475 pragha_application_append_entery_libary (PraghaApplication *pragha)
476 {
477 	PraghaPlaylist *playlist;
478 	PraghaDatabase *cdbase;
479 	GList *list = NULL;
480 	PraghaMusicobject *mobj;
481 
482 	/* Query and insert entries */
483 
484 	set_watch_cursor (pragha_application_get_window(pragha));
485 
486 	cdbase = pragha_application_get_database (pragha);
487 
488 	const gchar *sql = "SELECT id FROM LOCATION";
489 	PraghaPreparedStatement *statement = pragha_database_create_statement (cdbase, sql);
490 
491 	while (pragha_prepared_statement_step (statement)) {
492 		gint location_id = pragha_prepared_statement_get_int (statement, 0);
493 		mobj = new_musicobject_from_db (cdbase, location_id);
494 
495 		if (G_LIKELY(mobj))
496 			list = g_list_prepend (list, mobj);
497 		else
498 			g_warning ("Unable to retrieve details for"
499 			            " location_id : %d",
500 			            location_id);
501 
502 		pragha_process_gtk_events ();
503 	}
504 
505 	pragha_prepared_statement_free (statement);
506 
507 	remove_watch_cursor (pragha_application_get_window(pragha));
508 
509 	if (list) {
510 		list = g_list_reverse(list);
511 		playlist = pragha_application_get_playlist (pragha);
512 		pragha_playlist_append_mobj_list (playlist, list);
513 		g_list_free(list);
514 	}
515 }
516 
517 /* Handler for the 'About' action in the Help menu */
518 
519 void
pragha_application_about_dialog(PraghaApplication * pragha)520 pragha_application_about_dialog (PraghaApplication *pragha)
521 {
522 	GtkWidget *mainwindow;
523 
524 	mainwindow = pragha_application_get_window (pragha);
525 
526 	const gchar *authors[] = {
527 		"sujith ( m.sujith@gmail.com )",
528 		"matias ( mati86dl@gmail.com )",
529 		NULL};
530 
531 	gtk_show_about_dialog(GTK_WINDOW(mainwindow),
532 	                      "logo-icon-name", "pragha",
533 	                      "authors", authors,
534 	                      "translator-credits", _("translator-credits"),
535 	                      "comments", "A lightweight GTK+ music player",
536 	                      "copyright", "(C) 2007-2009 Sujith\n(C) 2009-2015 Matias",
537 	                      "license-type", GTK_LICENSE_GPL_3_0,
538 	                      "name", PACKAGE_NAME,
539 	                      "version", PACKAGE_VERSION,
540 	                      NULL);
541 }
542 
543 static void
pragha_library_pane_append_tracks(PraghaLibraryPane * library,PraghaApplication * pragha)544 pragha_library_pane_append_tracks (PraghaLibraryPane *library, PraghaApplication *pragha)
545 {
546 	GList *list = NULL;
547 	list = pragha_library_pane_get_mobj_list (library);
548 	if (list) {
549 		pragha_playlist_append_mobj_list (pragha->playlist,
550 			                              list);
551 		g_list_free(list);
552 	}
553 }
554 
555 static void
pragha_library_pane_replace_tracks(PraghaLibraryPane * library,PraghaApplication * pragha)556 pragha_library_pane_replace_tracks (PraghaLibraryPane *library, PraghaApplication *pragha)
557 {
558 	GList *list = NULL;
559 	list = pragha_library_pane_get_mobj_list (library);
560 	if (list) {
561 		pragha_playlist_remove_all (pragha->playlist);
562 
563 		pragha_playlist_append_mobj_list (pragha->playlist,
564 			                              list);
565 		g_list_free(list);
566 	}
567 }
568 
569 static void
pragha_library_pane_replace_tracks_and_play(PraghaLibraryPane * library,PraghaApplication * pragha)570 pragha_library_pane_replace_tracks_and_play (PraghaLibraryPane *library, PraghaApplication *pragha)
571 {
572 	GList *list = NULL;
573 	list = pragha_library_pane_get_mobj_list (library);
574 	if (list) {
575 		pragha_playlist_remove_all (pragha->playlist);
576 
577 		pragha_playlist_append_mobj_list (pragha->playlist,
578 			                              list);
579 
580 		if (pragha_backend_get_state (pragha->backend) != ST_STOPPED)
581 			pragha_playback_next_track(pragha);
582 		else
583 			pragha_playback_play_pause_resume(pragha);
584 
585 		g_list_free(list);
586 	}
587 }
588 
589 static void
pragha_playlist_update_change_tags(PraghaPlaylist * playlist,gint changed,PraghaMusicobject * mobj,PraghaApplication * pragha)590 pragha_playlist_update_change_tags (PraghaPlaylist *playlist, gint changed, PraghaMusicobject *mobj, PraghaApplication *pragha)
591 {
592 	PraghaBackend *backend;
593 	PraghaToolbar *toolbar;
594 	PraghaMusicobject *cmobj = NULL;
595 
596 	backend = pragha_application_get_backend (pragha);
597 
598 	if(pragha_backend_get_state (backend) != ST_STOPPED) {
599 		cmobj = pragha_backend_get_musicobject (backend);
600 		pragha_update_musicobject_change_tag (cmobj, changed, mobj);
601 
602 		toolbar = pragha_application_get_toolbar (pragha);
603 		pragha_toolbar_set_title (toolbar, cmobj);
604 	}
605 }
606 
607 static void
pragha_playlist_update_statusbar_playtime(PraghaPlaylist * playlist,PraghaApplication * pragha)608 pragha_playlist_update_statusbar_playtime (PraghaPlaylist *playlist, PraghaApplication *pragha)
609 {
610 	PraghaStatusbar *statusbar;
611 	gint total_playtime = 0, no_tracks = 0;
612 	gchar *str, *tot_str;
613 
614 	if(pragha_playlist_is_changing(playlist))
615 		return;
616 
617 	total_playtime = pragha_playlist_get_total_playtime (playlist);
618 	no_tracks = pragha_playlist_get_no_tracks (playlist);
619 
620 	tot_str = convert_length_str(total_playtime);
621 	str = g_strdup_printf("%i %s - %s",
622 	                      no_tracks,
623 	                      ngettext("Track", "Tracks", no_tracks),
624 	                      tot_str);
625 
626 	CDEBUG(DBG_VERBOSE, "Updating status bar with new playtime: %s", tot_str);
627 
628 	statusbar = pragha_application_get_statusbar (pragha);
629 	pragha_statusbar_set_main_text(statusbar, str);
630 
631 	g_free(tot_str);
632 	g_free(str);
633 }
634 
635 static void
pragha_art_cache_changed_handler(PraghaArtCache * cache,PraghaApplication * pragha)636 pragha_art_cache_changed_handler (PraghaArtCache *cache, PraghaApplication *pragha)
637 {
638 	PraghaBackend *backend;
639 	PraghaToolbar *toolbar;
640 	PraghaMusicobject *mobj = NULL;
641 	gchar *album_art_path = NULL;
642 	const gchar *artist = NULL, *album = NULL;
643 
644 	backend = pragha_application_get_backend (pragha);
645 	if (pragha_backend_get_state (backend) != ST_STOPPED) {
646 		mobj = pragha_backend_get_musicobject (backend);
647 
648 		artist = pragha_musicobject_get_artist (mobj);
649 		album = pragha_musicobject_get_album (mobj);
650 
651 		album_art_path = pragha_art_cache_get_uri (cache, artist, album);
652 
653 		if (album_art_path) {
654 			toolbar = pragha_application_get_toolbar (pragha);
655 			pragha_toolbar_set_image_album_art (toolbar, album_art_path);
656 			g_free (album_art_path);
657 		}
658 	}
659 }
660 
661 static void
pragha_libary_list_changed_cb(PraghaPreferences * preferences,PraghaApplication * pragha)662 pragha_libary_list_changed_cb (PraghaPreferences *preferences, PraghaApplication *pragha)
663 {
664 	GtkWidget *infobar = create_info_bar_update_music (pragha);
665 	pragha_window_add_widget_to_infobox (pragha, infobar);
666 }
667 
668 static void
pragha_need_restart_cb(PraghaPreferences * preferences,PraghaApplication * pragha)669 pragha_need_restart_cb (PraghaPreferences *preferences, PraghaApplication *pragha)
670 {
671 	GtkWidget *infobar = pragha_info_bar_need_restart (pragha);
672 	pragha_window_add_widget_to_infobox (pragha, infobar);
673 }
674 
675 #if GTK_CHECK_VERSION (3, 12, 0)
676 static void
pragha_system_titlebar_changed_cb(PraghaPreferences * preferences,GParamSpec * pspec,PraghaApplication * pragha)677 pragha_system_titlebar_changed_cb (PraghaPreferences *preferences, GParamSpec *pspec, PraghaApplication *pragha)
678 {
679 	PraghaToolbar *toolbar;
680 	GtkWidget *window, *parent, *menubar;
681 	GtkAction *action;
682 
683 	window = pragha_application_get_window (pragha);
684 	toolbar = pragha_application_get_toolbar (pragha);
685 	menubar = pragha_application_get_menubar (pragha);
686 	g_object_ref(toolbar);
687 
688 	parent  = gtk_widget_get_parent (GTK_WIDGET(menubar));
689 
690 	if (pragha_preferences_get_system_titlebar (preferences)) {
691 		gtk_widget_hide(GTK_WIDGET(window));
692 
693 		action = pragha_application_get_menu_action (pragha,
694 			"/Menubar/ViewMenu/Fullscreen");
695 		gtk_action_set_sensitive (GTK_ACTION (action), TRUE);
696 
697 		action = pragha_application_get_menu_action (pragha,
698 			"/Menubar/ViewMenu/Playback controls below");
699 		gtk_action_set_sensitive (GTK_ACTION (action), TRUE);
700 
701 		gtk_window_set_titlebar (GTK_WINDOW (window), NULL);
702 		gtk_window_set_title (GTK_WINDOW(window), _("Pragha Music Player"));
703 
704 		gtk_box_pack_start (GTK_BOX(parent), GTK_WIDGET(toolbar),
705 		                    FALSE, FALSE, 0);
706 		gtk_box_reorder_child(GTK_BOX(parent), GTK_WIDGET(toolbar), 1);
707 
708 		pragha_toolbar_set_style(toolbar, TRUE);
709 
710 		gtk_widget_show(GTK_WIDGET(window));
711 
712 	}
713 	else {
714 		gtk_widget_hide(GTK_WIDGET(window));
715 
716 		pragha_preferences_set_controls_below(preferences, FALSE);
717 
718 		action = pragha_application_get_menu_action (pragha,
719 			"/Menubar/ViewMenu/Fullscreen");
720 		gtk_action_set_sensitive (GTK_ACTION (action), FALSE);
721 
722 		action = pragha_application_get_menu_action (pragha,
723 			"/Menubar/ViewMenu/Playback controls below");
724 		gtk_action_set_sensitive (GTK_ACTION (action), FALSE);
725 
726 		gtk_container_remove (GTK_CONTAINER(parent), GTK_WIDGET(toolbar));
727 		gtk_window_set_titlebar (GTK_WINDOW (window), GTK_WIDGET(toolbar));
728 
729 		pragha_toolbar_set_style(toolbar, FALSE);
730 
731 		gtk_widget_show(GTK_WIDGET(window));
732 	}
733 	g_object_unref(toolbar);
734 }
735 #endif
736 
737 
738 static void
pragha_enum_map_removed_handler(PraghaMusicEnum * enum_map,gint enum_removed,PraghaApplication * pragha)739 pragha_enum_map_removed_handler (PraghaMusicEnum *enum_map, gint enum_removed, PraghaApplication *pragha)
740 {
741 	pragha_playlist_crop_music_type (pragha->playlist, enum_removed);
742 }
743 
744 /*
745  * Some public actions.
746  */
747 
748 PraghaPreferences *
pragha_application_get_preferences(PraghaApplication * pragha)749 pragha_application_get_preferences (PraghaApplication *pragha)
750 {
751 	return pragha->preferences;
752 }
753 
754 PraghaDatabase *
pragha_application_get_database(PraghaApplication * pragha)755 pragha_application_get_database (PraghaApplication *pragha)
756 {
757 	return pragha->cdbase;
758 }
759 
760 PraghaArtCache *
pragha_application_get_art_cache(PraghaApplication * pragha)761 pragha_application_get_art_cache (PraghaApplication *pragha)
762 {
763 	return pragha->art_cache;
764 }
765 
766 PraghaBackend *
pragha_application_get_backend(PraghaApplication * pragha)767 pragha_application_get_backend (PraghaApplication *pragha)
768 {
769 	return pragha->backend;
770 }
771 
772 #ifdef HAVE_LIBPEAS
773 PraghaPluginsEngine *
pragha_application_get_plugins_engine(PraghaApplication * pragha)774 pragha_application_get_plugins_engine (PraghaApplication *pragha)
775 {
776 	return pragha->plugins_engine;
777 }
778 #endif
779 
780 PraghaScanner *
pragha_application_get_scanner(PraghaApplication * pragha)781 pragha_application_get_scanner (PraghaApplication *pragha)
782 {
783 	return pragha->scanner;
784 }
785 
786 GtkWidget *
pragha_application_get_window(PraghaApplication * pragha)787 pragha_application_get_window (PraghaApplication *pragha)
788 {
789 	return pragha->mainwindow;
790 }
791 
792 PraghaPlaylist *
pragha_application_get_playlist(PraghaApplication * pragha)793 pragha_application_get_playlist (PraghaApplication *pragha)
794 {
795 	return pragha->playlist;
796 }
797 
798 PraghaLibraryPane *
pragha_application_get_library(PraghaApplication * pragha)799 pragha_application_get_library (PraghaApplication *pragha)
800 {
801 	return pragha->library;
802 }
803 
804 PreferencesDialog *
pragha_application_get_preferences_dialog(PraghaApplication * pragha)805 pragha_application_get_preferences_dialog (PraghaApplication *pragha)
806 {
807 	return pragha->setting_dialog;
808 }
809 
810 PraghaToolbar *
pragha_application_get_toolbar(PraghaApplication * pragha)811 pragha_application_get_toolbar (PraghaApplication *pragha)
812 {
813 	return pragha->toolbar;
814 }
815 
816 PraghaSidebar *
pragha_application_get_first_sidebar(PraghaApplication * pragha)817 pragha_application_get_first_sidebar (PraghaApplication *pragha)
818 {
819 	return pragha->sidebar1;
820 }
821 
822 PraghaSidebar *
pragha_application_get_second_sidebar(PraghaApplication * pragha)823 pragha_application_get_second_sidebar (PraghaApplication *pragha)
824 {
825 	return pragha->sidebar2;
826 }
827 
828 PraghaStatusbar *
pragha_application_get_statusbar(PraghaApplication * pragha)829 pragha_application_get_statusbar (PraghaApplication *pragha)
830 {
831 	return pragha->statusbar;
832 }
833 
834 PraghaStatusIcon *
pragha_application_get_status_icon(PraghaApplication * pragha)835 pragha_application_get_status_icon (PraghaApplication *pragha)
836 {
837 	return pragha->status_icon;
838 }
839 
840 GtkBuilder *
pragha_application_get_menu_ui(PraghaApplication * pragha)841 pragha_application_get_menu_ui (PraghaApplication *pragha)
842 {
843 	return pragha->menu_ui;
844 }
845 
846 GtkUIManager *
pragha_application_get_menu_ui_manager(PraghaApplication * pragha)847 pragha_application_get_menu_ui_manager (PraghaApplication *pragha)
848 {
849 	return pragha->menu_ui_manager;
850 }
851 
852 GtkAction *
pragha_application_get_menu_action(PraghaApplication * pragha,const gchar * path)853 pragha_application_get_menu_action (PraghaApplication *pragha, const gchar *path)
854 {
855 	GtkUIManager *ui_manager = pragha_application_get_menu_ui_manager (pragha);
856 
857 	return gtk_ui_manager_get_action (ui_manager, path);
858 }
859 
860 GtkWidget *
pragha_application_get_menu_action_widget(PraghaApplication * pragha,const gchar * path)861 pragha_application_get_menu_action_widget (PraghaApplication *pragha, const gchar *path)
862 {
863 	GtkUIManager *ui_manager = pragha_application_get_menu_ui_manager (pragha);
864 
865 	return gtk_ui_manager_get_widget (ui_manager, path);
866 }
867 
868 GtkWidget *
pragha_application_get_menubar(PraghaApplication * pragha)869 pragha_application_get_menubar (PraghaApplication *pragha)
870 {
871 	GtkUIManager *ui_manager = pragha_application_get_menu_ui_manager (pragha);
872 
873 	return gtk_ui_manager_get_widget (ui_manager, "/Menubar");
874 }
875 
876 GtkWidget *
pragha_application_get_infobox_container(PraghaApplication * pragha)877 pragha_application_get_infobox_container (PraghaApplication *pragha)
878 {
879 	return pragha->infobox;
880 }
881 
882 GtkWidget *
pragha_application_get_first_pane(PraghaApplication * pragha)883 pragha_application_get_first_pane (PraghaApplication *pragha)
884 {
885 	return pragha->pane1;
886 }
887 
888 GtkWidget *
pragha_application_get_second_pane(PraghaApplication * pragha)889 pragha_application_get_second_pane (PraghaApplication *pragha)
890 {
891 	return pragha->pane2;
892 }
893 
894 gboolean
pragha_application_is_first_run(PraghaApplication * pragha)895 pragha_application_is_first_run (PraghaApplication *pragha)
896 {
897 	return string_is_empty (pragha_preferences_get_installed_version (pragha->preferences));
898 }
899 
900 static void
pragha_application_construct_window(PraghaApplication * pragha)901 pragha_application_construct_window (PraghaApplication *pragha)
902 {
903 	/* Main window */
904 
905 	pragha->mainwindow = gtk_application_window_new (GTK_APPLICATION (pragha));
906 
907 	gtk_window_set_icon_name (GTK_WINDOW(pragha->mainwindow), "pragha");
908 
909 
910 	/* Get all widgets instances */
911 
912 	pragha->menu_ui_manager = pragha_menubar_new ();
913 	pragha->menu_ui = pragha_gmenu_toolbar_new (pragha);
914 	pragha->toolbar = pragha_toolbar_new ();
915 	pragha->infobox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
916 	pragha->pane1 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
917 	pragha->pane2 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
918 	pragha->sidebar1 = pragha_sidebar_new ();
919 	pragha->sidebar2 = pragha_sidebar_new ();
920 	pragha->library = pragha_library_pane_new ();
921 	pragha->playlist = pragha_playlist_new ();
922 	pragha->statusbar = pragha_statusbar_get ();
923 	pragha->scanner = pragha_scanner_new();
924 
925 	pragha->status_icon = pragha_status_icon_new (pragha);
926 
927 	pragha_menubar_connect_signals (pragha->menu_ui_manager, pragha);
928 
929 	/* Contruct the window. */
930 
931 	pragha_window_new (pragha);
932 
933 	gtk_window_set_title (GTK_WINDOW(pragha->mainwindow),
934 	                      _("Pragha Music Player"));
935 }
936 
937 static void
pragha_application_dispose(GObject * object)938 pragha_application_dispose (GObject *object)
939 {
940 	PraghaApplication *pragha = PRAGHA_APPLICATION (object);
941 
942 	CDEBUG(DBG_INFO, "Cleaning up");
943 
944 #ifdef HAVE_LIBPEAS
945 	if (pragha->plugins_engine) {
946 		g_object_unref (pragha->plugins_engine);
947 		pragha->plugins_engine = NULL;
948 	}
949 #endif
950 	if (pragha->setting_dialog) {
951 		pragha_preferences_dialog_free (pragha->setting_dialog);
952 		pragha->setting_dialog = NULL;
953 	}
954 	if (pragha->backend) {
955 		g_object_unref (pragha->backend);
956 		pragha->backend = NULL;
957 	}
958 	if (pragha->art_cache) {
959 		g_object_unref (pragha->art_cache);
960 		pragha->art_cache = NULL;
961 	}
962 	if (pragha->enum_map) {
963 		g_object_unref (pragha->enum_map);
964 		pragha->enum_map = NULL;
965 	}
966 	if (pragha->scanner) {
967 		pragha_scanner_free (pragha->scanner);
968 		pragha->scanner = NULL;
969 	}
970 	if (pragha->menu_ui_manager) {
971 		g_object_unref (pragha->menu_ui_manager);
972 		pragha->menu_ui_manager = NULL;
973 	}
974 
975 	/* Save Preferences and database. */
976 
977 	if (pragha->preferences) {
978 		g_object_unref (pragha->preferences);
979 		pragha->preferences = NULL;
980 	}
981 	if (pragha->cdbase) {
982 		g_object_unref (pragha->cdbase);
983 		pragha->cdbase = NULL;
984 	}
985 
986 	G_OBJECT_CLASS (pragha_application_parent_class)->dispose (object);
987 }
988 
989 static void
pragha_application_startup(GApplication * application)990 pragha_application_startup (GApplication *application)
991 {
992 	PraghaToolbar *toolbar;
993 	PraghaPlaylist *playlist;
994 	const gchar *version = NULL;
995 	const gchar *desktop = NULL;
996 
997 	const GBindingFlags binding_flags =
998 		G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL;
999 
1000 	PraghaApplication *pragha = PRAGHA_APPLICATION (application);
1001 
1002 	G_APPLICATION_CLASS (pragha_application_parent_class)->startup (application);
1003 
1004 	/* Allocate memory for simple structures */
1005 
1006 	pragha->preferences = pragha_preferences_get();
1007 
1008 	pragha->cdbase = pragha_database_get();
1009 	if (pragha_database_start_successfully(pragha->cdbase) == FALSE) {
1010 		g_error("Unable to init music dbase");
1011 	}
1012 
1013 	version = pragha_preferences_get_installed_version (pragha->preferences);
1014 	if (string_is_not_empty (version) && (g_ascii_strcasecmp (version, "1.3.1") < 0)) {
1015 		pragha_database_compatibilize_version (pragha->cdbase);
1016 	}
1017 
1018 	pragha->enum_map = pragha_music_enum_get ();
1019 	g_signal_connect (pragha->enum_map, "enum-removed",
1020 	                  G_CALLBACK(pragha_enum_map_removed_handler), pragha);
1021 
1022 #ifdef HAVE_LIBPEAS
1023 	pragha->plugins_engine = pragha_plugins_engine_new (G_OBJECT(pragha));
1024 #endif
1025 
1026 	pragha->art_cache = pragha_art_cache_get ();
1027 	g_signal_connect (pragha->art_cache, "cache-changed",
1028 	                  G_CALLBACK(pragha_art_cache_changed_handler), pragha);
1029 
1030 	pragha->backend = pragha_backend_new ();
1031 
1032 	g_signal_connect (pragha->backend, "finished",
1033 	                  G_CALLBACK(pragha_backend_finished_song), pragha);
1034 	g_signal_connect (pragha->backend, "tags-changed",
1035 	                  G_CALLBACK(pragha_backend_tags_changed), pragha);
1036 
1037 	g_signal_connect (pragha->backend, "error",
1038 	                 G_CALLBACK(gui_backend_error_show_dialog_cb), pragha);
1039 	g_signal_connect (pragha->backend, "error",
1040 	                  G_CALLBACK(gui_backend_error_update_current_playlist_cb), pragha);
1041 	g_signal_connect (pragha->backend, "notify::state",
1042 	                  G_CALLBACK (pragha_menubar_update_playback_state_cb), pragha);
1043 
1044 	/*
1045 	 * Collect widgets and construct the window.
1046 	 */
1047 
1048 	pragha_application_construct_window (pragha);
1049 
1050 	/* Connect Signals and Bindings. */
1051 
1052 	toolbar = pragha->toolbar;
1053 	g_signal_connect_swapped (toolbar, "prev",
1054 	                          G_CALLBACK(pragha_playback_prev_track), pragha);
1055 	g_signal_connect_swapped (toolbar, "play",
1056 	                          G_CALLBACK(pragha_playback_play_pause_resume), pragha);
1057 	g_signal_connect_swapped (toolbar, "stop",
1058 	                          G_CALLBACK(pragha_playback_stop), pragha);
1059 	g_signal_connect_swapped (toolbar, "next",
1060 	                          G_CALLBACK(pragha_playback_next_track), pragha);
1061 	g_signal_connect (toolbar, "unfull-activated",
1062 	                  G_CALLBACK(pragha_window_unfullscreen), pragha);
1063 	g_signal_connect (toolbar, "album-art-activated",
1064 	                  G_CALLBACK(pragha_playback_show_current_album_art), pragha);
1065 	g_signal_connect_swapped (toolbar, "track-info-activated",
1066 	                          G_CALLBACK(pragha_playback_edit_current_track), pragha);
1067 	g_signal_connect (toolbar, "track-progress-activated",
1068 	                  G_CALLBACK(pragha_playback_seek_fraction), pragha);
1069 
1070 	playlist = pragha->playlist;
1071 	g_signal_connect (playlist, "playlist-set-track",
1072 	                  G_CALLBACK(pragha_playback_set_playlist_track), pragha);
1073 	g_signal_connect (playlist, "playlist-change-tags",
1074 	                  G_CALLBACK(pragha_playlist_update_change_tags), pragha);
1075 	g_signal_connect (playlist, "playlist-changed",
1076 	                  G_CALLBACK(pragha_playlist_update_statusbar_playtime), pragha);
1077 	pragha_playlist_update_statusbar_playtime (playlist, pragha);
1078 
1079 	g_signal_connect (pragha->library, "library-append-playlist",
1080 	                  G_CALLBACK(pragha_library_pane_append_tracks), pragha);
1081 	g_signal_connect (pragha->library, "library-replace-playlist",
1082 	                  G_CALLBACK(pragha_library_pane_replace_tracks), pragha);
1083 	g_signal_connect (pragha->library, "library-replace-playlist-and-play",
1084 	                  G_CALLBACK(pragha_library_pane_replace_tracks_and_play), pragha);
1085 
1086 	g_signal_connect (G_OBJECT(pragha->mainwindow), "window-state-event",
1087 	                  G_CALLBACK(pragha_toolbar_window_state_event), toolbar);
1088 	g_signal_connect (G_OBJECT(toolbar), "notify::timer-remaining-mode",
1089 	                  G_CALLBACK(pragha_toolbar_show_ramaning_time_cb), pragha->backend);
1090 
1091 	g_signal_connect (pragha->backend, "notify::state",
1092 	                  G_CALLBACK(pragha_toolbar_playback_state_cb), toolbar);
1093 	g_signal_connect (pragha->backend, "tick",
1094 	                 G_CALLBACK(pragha_toolbar_update_playback_progress), toolbar);
1095 	g_signal_connect (pragha->backend, "buffering",
1096 	                  G_CALLBACK(pragha_toolbar_update_buffering_cb), toolbar);
1097 
1098 	g_signal_connect (pragha->backend, "notify::state",
1099 	                  G_CALLBACK (update_current_playlist_view_playback_state_cb), pragha->playlist);
1100 
1101 	g_object_bind_property (pragha->backend, "volume",
1102 	                        toolbar, "volume",
1103 	                        binding_flags);
1104 
1105 	g_object_bind_property (pragha->preferences, "timer-remaining-mode",
1106 	                        toolbar, "timer-remaining-mode",
1107 	                        binding_flags);
1108 
1109 	g_signal_connect (pragha->preferences, "LibraryChanged",
1110 	                  G_CALLBACK (pragha_libary_list_changed_cb), pragha);
1111 	g_signal_connect (pragha->preferences, "NeedRestart",
1112 	                  G_CALLBACK (pragha_need_restart_cb), pragha);
1113 
1114 #if GTK_CHECK_VERSION (3, 12, 0)
1115 	g_signal_connect (pragha->preferences, "notify::system-titlebar",
1116 	                  G_CALLBACK (pragha_system_titlebar_changed_cb), pragha);
1117 #endif
1118 
1119 	pragha->sidebar2_binding =
1120 		g_object_bind_property (pragha->preferences, "secondary-lateral-panel",
1121 		                        pragha->sidebar2, "visible",
1122 		                        binding_flags);
1123 
1124 	pragha->setting_dialog = pragha_preferences_dialog_new (pragha->mainwindow);
1125 
1126 	#ifdef HAVE_LIBPEAS
1127 	gboolean sidebar2_visible = // FIXME: Hack to allow hide sidebar when init.
1128 		pragha_preferences_get_secondary_lateral_panel(pragha->preferences);
1129 
1130 	pragha_plugins_engine_startup (pragha->plugins_engine);
1131 
1132 	pragha_preferences_set_secondary_lateral_panel(pragha->preferences,
1133 	                                               sidebar2_visible);
1134 	#endif
1135 
1136 	/* If first run and the desktop is gnome adapts style. */
1137 
1138 	if (pragha_application_is_first_run (pragha)) {
1139 		desktop = g_getenv ("XDG_CURRENT_DESKTOP");
1140 		if (desktop && (g_strcmp0(desktop, "GNOME") == 0) &&
1141 			gdk_screen_is_composited (gdk_screen_get_default())) {
1142 			pragha_preferences_set_system_titlebar (pragha->preferences, FALSE);
1143 			pragha_preferences_set_toolbar_size (pragha->preferences, GTK_ICON_SIZE_SMALL_TOOLBAR);
1144 			pragha_preferences_set_show_menubar (pragha->preferences, FALSE);
1145 		}
1146 	}
1147 
1148 	/* Forse update menubar and toolbar playback actions */
1149 
1150 	pragha_menubar_update_playback_state_cb (pragha->backend, NULL, pragha);
1151 	pragha_toolbar_playback_state_cb (pragha->backend, NULL, pragha->toolbar);
1152 
1153 	/* Finally fill the library and the playlist */
1154 
1155 	pragha_init_gui_state (pragha);
1156 }
1157 
1158 static void
pragha_application_shutdown(GApplication * application)1159 pragha_application_shutdown (GApplication *application)
1160 {
1161 	PraghaApplication *pragha = PRAGHA_APPLICATION (application);
1162 
1163 	CDEBUG(DBG_INFO, "Pragha shutdown: Saving curret state.");
1164 
1165 	if (pragha_preferences_get_restore_playlist (pragha->preferences))
1166 		pragha_playlist_save_playlist_state (pragha->playlist);
1167 
1168 	pragha_window_save_settings (pragha);
1169 
1170 	pragha_playback_stop (pragha);
1171 
1172 	/* Shutdown plugins can hide sidebar before save settings. */
1173 	if (pragha->sidebar2_binding) {
1174 		g_object_unref (pragha->sidebar2_binding);
1175 		pragha->sidebar2_binding = NULL;
1176 	}
1177 
1178 #ifdef HAVE_LIBPEAS
1179 	pragha_plugins_engine_shutdown (pragha->plugins_engine);
1180 #endif
1181 
1182 	gtk_widget_destroy (pragha->mainwindow);
1183 
1184 	G_APPLICATION_CLASS (pragha_application_parent_class)->shutdown (application);
1185 }
1186 
1187 static void
pragha_application_activate(GApplication * application)1188 pragha_application_activate (GApplication *application)
1189 {
1190 	PraghaApplication *pragha = PRAGHA_APPLICATION (application);
1191 
1192 	CDEBUG(DBG_INFO, G_STRFUNC);
1193 
1194 	gtk_window_present (GTK_WINDOW (pragha->mainwindow));
1195 }
1196 
1197 static void
pragha_application_open(GApplication * application,GFile ** files,gint n_files,const gchar * hint)1198 pragha_application_open (GApplication *application, GFile **files, gint n_files, const gchar *hint)
1199 {
1200 	PraghaApplication *pragha = PRAGHA_APPLICATION (application);
1201 	gint i;
1202 	GList *mlist = NULL;
1203 
1204 	for (i = 0; i < n_files; i++) {
1205 		gchar *path = g_file_get_path (files[i]);
1206 		mlist = append_mobj_list_from_unknown_filename (mlist, path);
1207 		g_free (path);
1208 	}
1209 
1210 	if (mlist) {
1211 		pragha_playlist_append_mobj_list (pragha->playlist, mlist);
1212 		g_list_free (mlist);
1213 	}
1214 
1215 	gtk_window_present (GTK_WINDOW (pragha->mainwindow));
1216 }
1217 
1218 static int
pragha_application_command_line(GApplication * application,GApplicationCommandLine * command_line)1219 pragha_application_command_line (GApplication *application, GApplicationCommandLine *command_line)
1220 {
1221 	PraghaApplication *pragha = PRAGHA_APPLICATION (application);
1222 	int ret = 0;
1223 	gint argc;
1224 
1225 	gchar **argv = g_application_command_line_get_arguments (command_line, &argc);
1226 
1227 	if (argc <= 1) {
1228 		pragha_application_activate (application);
1229 		goto exit;
1230 	}
1231 
1232 	ret = handle_command_line (pragha, command_line, argc, argv);
1233 
1234 exit:
1235 	g_strfreev (argv);
1236 
1237 	return ret;
1238 }
1239 
1240 //it's used for --help and --version
1241 static gboolean
pragha_application_local_command_line(GApplication * application,gchar *** arguments,int * exit_status)1242 pragha_application_local_command_line (GApplication *application, gchar ***arguments, int *exit_status)
1243 {
1244 	PraghaApplication *pragha = PRAGHA_APPLICATION (application);
1245 
1246 	gchar **argv = *arguments;
1247 	gint argc = g_strv_length (argv);
1248 
1249 	*exit_status = handle_command_line (pragha, NULL, argc, argv);
1250 
1251 	return FALSE;
1252 }
1253 
1254 void
pragha_application_quit(PraghaApplication * pragha)1255 pragha_application_quit (PraghaApplication *pragha)
1256 {
1257 	g_application_quit (G_APPLICATION (pragha));
1258 }
1259 
1260 static void
pragha_application_class_init(PraghaApplicationClass * class)1261 pragha_application_class_init (PraghaApplicationClass *class)
1262 {
1263 	GObjectClass *object_class = G_OBJECT_CLASS (class);
1264 	GApplicationClass *application_class = G_APPLICATION_CLASS (class);
1265 
1266 	object_class->dispose = pragha_application_dispose;
1267 
1268 	application_class->startup = pragha_application_startup;
1269 	application_class->shutdown = pragha_application_shutdown;
1270 	application_class->activate = pragha_application_activate;
1271 	application_class->open = pragha_application_open;
1272 	application_class->command_line = pragha_application_command_line;
1273 	application_class->local_command_line = pragha_application_local_command_line;
1274 }
1275 
1276 static void
pragha_application_init(PraghaApplication * pragha)1277 pragha_application_init (PraghaApplication *pragha)
1278 {
1279 }
1280 
1281 PraghaApplication *
pragha_application_new()1282 pragha_application_new ()
1283 {
1284 	return g_object_new (PRAGHA_TYPE_APPLICATION,
1285 	                     "application-id", "org.pragha",
1286 	                     "flags", G_APPLICATION_HANDLES_COMMAND_LINE | G_APPLICATION_HANDLES_OPEN,
1287 	                     NULL);
1288 }
1289 
main(gint argc,gchar * argv[])1290 gint main(gint argc, gchar *argv[])
1291 {
1292 	PraghaApplication *pragha;
1293 	int status;
1294 #ifdef DEBUG
1295 	g_print ("debug enabled\n");
1296 	pragha_main_thread = g_thread_self ();
1297 #endif
1298 	debug_level = 0;
1299 
1300 	/* setup translation domain */
1301 	setlocale (LC_ALL, "");
1302 	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
1303 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1304 	textdomain (GETTEXT_PACKAGE);
1305 
1306 	/* Force unicode to taglib. */
1307 	taglib_set_strings_unicode(TRUE);
1308 	taglib_set_string_management_enabled(FALSE);
1309 
1310 	/* Setup application name and pulseaudio role */
1311 	g_set_application_name(_("Pragha Music Player"));
1312 	g_setenv("PULSE_PROP_media.role", "audio", TRUE);
1313 
1314 	pragha = pragha_application_new ();
1315 	status = g_application_run (G_APPLICATION (pragha), argc, argv);
1316 	g_object_run_dispose (G_OBJECT (pragha));
1317 	g_object_unref (pragha);
1318 
1319 	return status;
1320 }
1321