Move sidebar state to sidebar code.
[gmpc.git] / src / playlist3.c
blob05672f67cdec0284a8897b03fa244533b9c1c6cd
1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2011 Qball Cow <qball@gmpclient.org>
3 * Project homepage: http://gmpclient.org/
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 2 of the License, or
8 * (at your option) any later version.
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.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <gtk/gtk.h>
21 #include <gdk/gdkkeysyms.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <config.h>
25 #include "main.h"
26 #include "plugin.h"
27 #include "misc.h"
28 #include "playlist3.h"
29 #include "preferences.h"
30 #include "revision.h"
31 #include "gmpc-metaimage.h"
32 #include "gmpc-extras.h"
33 #include "GUI/cmd.h"
34 #include "GUI/status_icon.h"
35 #include "GUI/title_header.h"
36 #include "GUI/control_window.h"
38 #define ALBUM_SIZE_SMALL 42
39 #define ALBUM_SIZE_LARGE 42
41 #define LOG_DOMAIN "Playlist"
43 /* Drag and drop Target table */
44 static GtkTargetEntry target_table[] =
46 {(gchar *) "x-url/http", 0, 0},
47 {(gchar *) "_NETSCAPE_URL", 0, 1},
48 {(gchar *) "text/uri-list", 0, 2},
49 {(gchar *) "audio/*", 0, 3},
50 {(gchar *) "audio/x-scpls", 0, 4},
51 {(gchar *) "internal-drop", 0, 99}
54 GtkWidget *metaimage_album_art = NULL;
55 GtkWidget *metaimage_artist_art = NULL;
56 GmpcFavoritesButton *favorites_button = NULL;
58 GtkCellRenderer *sidebar_text = NULL;
59 /**
60 * Widgets used in the header.
61 * and the new progresbar
63 static GtkWidget *new_pb = NULL;
65 /**
66 * Indicates the zoom level and the previous zoom level.
68 int pl3_zoom = PLAYLIST_NO_ZOOM;
69 int pl3_old_zoom = PLAYLIST_NO_ZOOM;
71 static void playlist_zoom_level_changed(void);
72 void playlist_zoom_in(void);
73 void playlist_zoom_out(void);
76 void pl3_pb_seek_event(GtkWidget * pb, guint seek_time, gpointer user_data);
78 void set_browser_format(void);
79 void set_playlist_format(void);
81 gboolean playlist_player_volume_changed(GtkWidget * vol_but, int new_vol);
83 /* Glade declarations, otherwise these would be static */
84 void about_window(void);
85 int pl3_cat_tree_button_press_event(GtkTreeView *, GdkEventButton *);
86 int pl3_cat_tree_button_release_event(GtkTreeView *, GdkEventButton *);
88 void cur_song_center_enable_tb(GtkToggleButton *);
89 void show_cover_case_tb(GtkToggleButton * but);
90 void save_possize_enable_tb(GtkToggleButton *);
91 void playlist_menu_repeat_changed(GtkToggleAction *);
92 void playlist_menu_single_mode_changed(GtkToggleAction * );
93 void playlist_menu_consume_changed(GtkToggleAction * );
95 void playlist_menu_random_changed(GtkToggleAction *);
96 void playlist_menu_artist_image_changed(GtkToggleAction *);
97 void hide_on_close_enable_tb(GtkToggleButton * but);
98 gboolean pl3_close(void);
99 static void pl3_update_profiles_menu(GmpcProfiles * prof, const int changed, const int col, const gchar * id);
100 gboolean playlist3_enter_notify_event(GtkWidget * wid, GdkEventCrossing * event, gpointer data);
101 gboolean playlist3_leave_notify_event(GtkWidget * wid, GdkEventCrossing * event, gpointer data);
103 static void pl3_profiles_changed(GmpcProfiles * prof, const int changed, const int col, const gchar * id);
104 static void playlist3_server_output_changed(GtkWidget * item, gpointer data);
105 static void playlist3_fill_server_menu(void);
106 void playlist3_server_update_db(void);
108 void easy_command_help_window(void);
110 void pl3_style_set_event(GtkWidget *widget, GtkStyle *previous_style, gpointer user_data);
112 void pl3_sidebar_plugins_init(void);
114 /* Old category browser style */
115 static int old_type = -1;
117 /* interface description */
118 GtkBuilder *pl3_xml = NULL;
119 /* category treeview-store */
120 GtkTreeModel *pl3_tree = NULL;
122 /* size */
123 static GtkAllocation pl3_wsize = { 0, 0, 0, 0 };
125 static int pl3_hidden = TRUE;
127 static void playlist_status_changed(MpdObj * mi, ChangedStatusType what, void *userdata);
129 /* Playlist "Plugin" */
130 static void playlist_pref_construct(GtkWidget * container);
131 static void playlist_pref_destroy(GtkWidget * container);
133 static GtkBuilder *playlist_pref_xml = NULL;
135 void ck_search_as_you_type(GtkToggleButton * but);
138 /* Get the type of the selected row..
139 * -1 means no row selected
141 int pl3_cat_get_selected_browser(void)
143 return old_type;
150 * Extras for better integration
153 void init_extra_playlist_state(void);
154 void enable_extra_playlist(GtkToggleAction *action);
156 /**************************************************
157 * Category Tree
159 static void pl3_initialize_tree(void)
161 int i;
162 GtkTreePath *path;
163 GtkTreeSelection *sel;
164 GtkWidget *cat_tree = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "cat_tree"));
166 INIT_TIC_TAC()
168 path = gtk_tree_path_new_from_string("0");
169 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk_builder_get_object(pl3_xml, "cat_tree")));
170 TEC("Get selection");
171 for (i = 0; i < num_plugins; i++)
173 if (gmpc_plugin_is_browser(plugins[i]))
175 if (gmpc_plugin_get_enabled(plugins[i]))
177 gmpc_plugin_browser_add(plugins[i], cat_tree);
180 TEC("setup %s", gmpc_plugin_get_name(plugins[i]))
183 gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtk_builder_get_object(pl3_xml, "cat_tree")), path, NULL, FALSE);
184 TEC("set cursor");
185 gtk_tree_path_free(path);
186 TEC("finish set");
191 * Function to handle a change in category.
193 static void pl3_cat_sel_changed(GtkTreeSelection * selec, gpointer * userdata)
195 GtkTreeView *tree = (GtkTreeView *) gtk_builder_get_object(pl3_xml, "cat_tree");
196 GtkTreeModel *model = gtk_tree_view_get_model(tree);
197 GtkTreeIter iter;
198 GtkWidget *container = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "browser_container"));
199 if (!model)
200 return;
201 if (gtk_tree_selection_get_selected(selec, &model, &iter))
203 gint type;
205 gtk_tree_model_get(model, &iter, PL3_CAT_TYPE, &type, -1);
209 * Start switching side view (if type changed )
211 if (old_type != -1)
213 gmpc_plugin_browser_unselected(plugins[plugin_get_pos(old_type)], container);
215 old_type = -1;
216 if(type > -1)
218 /** if type changed give a selected signal */
219 if ((old_type != type))
221 gmpc_plugin_browser_selected(plugins[plugin_get_pos(type)], container);
226 * update old value, so get_selected_category is correct before calling selection_changed
228 old_type = type;
230 } else
232 if (old_type != -1)
234 gmpc_plugin_browser_unselected(plugins[plugin_get_pos(old_type)], container);
236 old_type = -1;
237 gtk_tree_model_get_iter_first(model, &iter);
238 gtk_tree_selection_select_iter(selec, &iter);
240 pl3_option_menu_activate();
244 /* handle right mouse clicks on the cat tree view */
245 /* gonna be a big function*/
246 int pl3_cat_tree_button_press_event(GtkTreeView * tree, GdkEventButton * event)
248 GtkTreeSelection *sel = gtk_tree_view_get_selection(tree);
249 if (event->button != 3 || gtk_tree_selection_count_selected_rows(sel) < 2 || !mpd_check_connected(connection))
251 return FALSE;
253 return TRUE;
258 void pl3_option_menu_activate(void)
261 GtkWidget *tree = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "cat_tree"));
262 int i;
263 gint type = pl3_cat_get_selected_browser();
264 int menu_items = 0;
265 GdkEventButton *event = NULL;
266 GtkWidget *menu = NULL;
267 GtkUIManager *ui = GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml, "uimanager1"));
268 GtkMenuItem *m_item = GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui, "/menubartest/menu_option"));
270 //gtk_menu_item_set_submenu(m_item, NULL);
272 if (!mpd_check_connected(connection) || type == -1)
273 return;
275 menu = gtk_menu_new();
277 for (i = 0; i < num_plugins; i++)
279 if (gmpc_plugin_is_browser(plugins[i]))
281 menu_items += gmpc_plugin_browser_cat_right_mouse_menu(plugins[i], menu, type, tree, event);
284 if (menu_items)
286 gtk_widget_show_all(menu);
287 gtk_menu_item_set_submenu(m_item, menu);
288 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_option")), TRUE);
289 } else
291 g_object_ref_sink(menu);
292 g_object_unref(menu);
293 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_option")), FALSE);
299 int pl3_cat_tree_button_release_event(GtkTreeView * tree, GdkEventButton * event)
301 int i;
302 gint type = pl3_cat_get_selected_browser();
303 int menu_items = 0;
304 GtkWidget *menu = NULL;
305 if (type == -1 || !mpd_check_connected(connection) || event->button != 3)
307 /* no selections, or no usefull one.. so propagate the signal */
308 return FALSE;
311 menu = gtk_menu_new();
313 for (i = 0; i < num_plugins; i++)
315 if (gmpc_plugin_is_browser(plugins[i]))
317 menu_items += gmpc_plugin_browser_cat_right_mouse_menu(plugins[i], menu, type, GTK_WIDGET(tree), event);
321 if (menu_items)
323 gtk_widget_show_all(menu);
324 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
325 /*event->button */ 0, event->time);
326 } else
328 g_object_ref_sink(menu);
329 g_object_unref(menu);
331 return TRUE;
334 void pl3_sidebar_plugins_init(void)
336 int i;
337 for (i = 0; i < num_plugins; i++)
339 // This is implicitely done inside sidebar_init
340 // if (gmpc_plugin_is_sidebar(plugins[i]))
342 gmpc_plugin_sidebar_init(plugins[i]);
347 /**********************************************************
348 * MISC
350 static GtkWidget *control_window = NULL;
351 static gboolean pl3_win_state_event(GtkWidget * window, GdkEventWindowState * event, gpointer data)
353 GtkWidget *vbox1 = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "vbox1"));
354 GtkWidget *p = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "alignment1"));
355 GtkWidget *h = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hbox1"));
356 GtkWidget *b = (GTK_WIDGET(gtk_builder_get_object(pl3_xml, "menubartest")));
357 if (((event->new_window_state) & GDK_WINDOW_STATE_FULLSCREEN))
359 if(control_window == NULL) {
360 control_window = create_control_window(window);
361 gtk_box_pack_start(GTK_BOX(vbox1), control_window, FALSE, FALSE, 0);
363 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "sidebar")));
364 gtk_widget_hide(p);
365 gtk_widget_hide(h);
366 gtk_widget_hide(b);
367 } else if ((event->changed_mask) & GDK_WINDOW_STATE_FULLSCREEN)
369 control_window_destroy(control_window);
370 control_window = NULL;
371 playlist_zoom_level_changed();
372 gtk_widget_show(p);
373 gtk_widget_show(h);
374 gtk_widget_show(b);
376 return FALSE;
380 gboolean pl3_window_is_fullscreen(void)
382 GtkWidget *win = playlist3_get_window();
383 GdkWindowState state = 0;
384 if (win->window)
385 state = gdk_window_get_state(win->window);
386 return (state & GDK_WINDOW_STATE_FULLSCREEN) ? TRUE : FALSE;
390 void pl3_window_fullscreen(void)
392 GtkWidget *win = playlist3_get_window();
394 if (pl3_zoom < PLAYLIST_MINI)
396 if (pl3_window_is_fullscreen())
398 gtk_window_unfullscreen(GTK_WINDOW(win));
399 } else
401 gtk_window_fullscreen(GTK_WINDOW(win));
407 int pl3_window_key_press_event(GtkWidget * mw, GdkEventKey * event)
409 int i = 0;
410 gint type = pl3_cat_get_selected_browser();
412 * Following key's are only valid when connected
414 if (!mpd_check_connected(connection))
416 return FALSE;
418 for (i = 0; i < num_plugins; i++)
420 if (gmpc_plugin_is_browser(plugins[i]))
422 gmpc_plugin_browser_key_press_event(plugins[i], mw, event, type);
425 if((event->state&GDK_MOD1_MASK) > 0)
427 guint kev = event->keyval;
428 if(kev >= GDK_KEY_0 && kev <= GDK_KEY_9)
430 int index = 0;
431 GtkTreeIter iter;
432 kev-=GDK_KEY_0;
433 if (gtk_tree_model_get_iter_first(pl3_tree, &iter))
435 if(kev == 0) kev+=10;
437 gint type =0 ;
438 gtk_tree_model_get(pl3_tree, &iter, PL3_CAT_TYPE, &type, -1);
439 if(type >= 0) index++;
440 if(index == kev && type >= 0)
442 GtkWidget *cat_tree = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "cat_tree"));
443 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(cat_tree));
445 // if this is allready selected, do +10. this allows us to go up to 20 browsers.
446 if(type == old_type && gtk_tree_selection_iter_is_selected(select, &iter)) {
447 kev+=10;
448 }else{
449 gtk_tree_selection_select_iter(select, &iter);
450 return;
453 }while(gtk_tree_model_iter_next(pl3_tree, &iter));
458 /* don't propagate */
459 return FALSE;
463 * Close the playlist and save position/size
465 gboolean pl3_close(void)
467 /* only save when window is PLAYLIST_SMALL or NO ZOOM */
468 if (pl3_xml != NULL)
470 GtkWidget *window = playlist3_get_window();
471 int maximized = FALSE;
472 if (window->window)
474 GdkWindowState state = gdk_window_get_state(window->window);
475 maximized = ((state & GDK_WINDOW_STATE_MAXIMIZED) > 0);
477 cfg_set_single_value_as_int(config, "playlist", "maximized", maximized);
479 gtk_window_get_position(GTK_WINDOW(window), &pl3_wsize.x, &pl3_wsize.y);
481 cfg_set_single_value_as_int(config, "playlist", "xpos", pl3_wsize.x);
482 cfg_set_single_value_as_int(config, "playlist", "ypos", pl3_wsize.y);
484 if (pl3_zoom <= PLAYLIST_SMALL)
486 gtk_window_get_size(GTK_WINDOW(window), &pl3_wsize.width, &pl3_wsize.height);
487 g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "pl3_close: save size: %i %i\n", pl3_wsize.width, pl3_wsize.height);
488 cfg_set_single_value_as_int(config, "playlist", "width", pl3_wsize.width);
489 cfg_set_single_value_as_int(config, "playlist", "height", pl3_wsize.height);
493 if (cfg_get_single_value_as_int_with_default(config, "playlist", "hide-on-close", FALSE))
495 if (tray_icon2_get_available())
497 pl3_toggle_hidden();
498 return TRUE;
500 gtk_window_iconify(GTK_WINDOW(playlist3_get_window()));
501 return TRUE;
505 * Quit the program
507 main_quit();
508 return TRUE;
513 * Hide the playlist.
514 * Before hiding save current size and position
516 int pl3_hide(void)
518 GtkWidget *pl3_win = playlist3_get_window();
519 if (!tray_icon2_get_available())
521 gtk_window_iconify(GTK_WINDOW(pl3_win));
522 return 1;
524 if (pl3_xml != NULL && !pl3_hidden)
526 GtkWidget *window = playlist3_get_window();
527 int maximized = FALSE;
528 if (window->window)
530 GdkWindowState state = gdk_window_get_state(window->window);
531 maximized = ((state & GDK_WINDOW_STATE_MAXIMIZED) > 0);
533 cfg_set_single_value_as_int(config, "playlist", "maximized", maximized);
534 /** Save position
536 gtk_window_get_position(GTK_WINDOW(pl3_win), &pl3_wsize.x, &pl3_wsize.y);
537 cfg_set_single_value_as_int(config, "playlist", "xpos", pl3_wsize.x);
538 cfg_set_single_value_as_int(config, "playlist", "ypos", pl3_wsize.y);
539 /* save size, only when in SMALL or no zoom mode
541 if (pl3_zoom <= PLAYLIST_SMALL)
543 gtk_window_get_size(GTK_WINDOW(pl3_win), &pl3_wsize.width, &pl3_wsize.height);
544 g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "pl3_hide: save size: %i %i\n", pl3_wsize.width, pl3_wsize.height);
545 cfg_set_single_value_as_int(config, "playlist", "width", pl3_wsize.width);
546 cfg_set_single_value_as_int(config, "playlist", "height", pl3_wsize.height);
548 gtk_widget_hide(pl3_win);
549 pl3_hidden = TRUE;
551 #ifdef HAVE_APP_INDICATOR
552 tray_icon2_update_menu();
553 #endif
554 return TRUE;
558 /* create the playlist view
559 * This is done only once, for the rest its hidden, but still there
561 static void pl3_show_and_position_window(void)
563 GtkWidget *pl3_win;
564 if (!pl3_xml)
565 return;
566 pl3_win = playlist3_get_window();
567 if (pl3_wsize.x > 0 || pl3_wsize.y > 0)
569 gtk_window_move(GTK_WINDOW(pl3_win), pl3_wsize.x, pl3_wsize.y);
571 if (pl3_wsize.height > 0 && pl3_wsize.width > 0)
573 g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "restore size %i %i\n", pl3_wsize.width, pl3_wsize.height);
574 gtk_window_resize(GTK_WINDOW(pl3_win), pl3_wsize.width, pl3_wsize.height);
576 gtk_widget_show(pl3_win);
577 gtk_window_present(GTK_WINDOW(pl3_win));
582 gboolean playlist3_window_is_hidden(void)
584 return pl3_hidden;
588 void pl3_toggle_hidden(void)
590 if (pl3_hidden)
592 create_playlist3();
593 } else
595 pl3_hide();
600 static void playlist3_source_drag_data_recieved(GtkWidget * widget,
601 GdkDragContext * context,
602 gint x,
603 gint y, GtkSelectionData * data, guint info, guint time_recieved)
605 if (info != 99)
607 int found = 0;
608 const gchar *url_data = (gchar *) data->data;
609 int i;
610 if (url_data)
613 gchar **url = g_uri_list_extract_uris(url_data);
614 for (i = 0; url && url[i]; i++)
616 gchar *scheme = g_uri_parse_scheme(url[i]);
617 /* Don't add lines withouth an actual scheme. */
618 if (scheme)
620 gchar *fu = g_uri_unescape_string(url[i], NULL);
621 url_start_real(fu);
622 g_free(fu);
623 g_free(scheme);
626 if (url)
627 g_strfreev(url);
630 gtk_drag_finish(context, found, FALSE, time_recieved);
631 } else
633 MpdData *mdata;
634 gchar **stripped;
635 int i;
636 guchar *odata = gtk_selection_data_get_text(data);
637 stripped = g_strsplit((gchar *) odata, "\n", 0);
638 g_free(odata);
639 if (context->action == GDK_ACTION_MOVE)
641 mpd_playlist_clear(connection);
643 mpd_database_search_start(connection, TRUE);
644 for (i = 0; stripped && stripped[i]; i++)
646 gchar **request = g_strsplit(stripped[i], ":", 2);
647 mpd_database_search_add_constraint(connection, mpd_misc_get_tag_by_name(request[0]), request[1]);
648 g_strfreev(request);
650 mdata = mpd_database_search_commit(connection);
651 for (; mdata; mdata = mpd_data_get_next(mdata))
653 mpd_playlist_queue_add(connection, mdata->song->file);
655 mpd_playlist_queue_commit(connection);
656 if (context->action == GDK_ACTION_MOVE)
658 mpd_player_play(connection);
661 g_strfreev(stripped);
662 gtk_drag_finish(context, TRUE, FALSE, time_recieved);
668 * Progresbar
670 void pl3_pb_seek_event(GtkWidget * pb, guint seek_time, gpointer user_data)
672 mpd_player_seek(connection, (int)seek_time);
677 static void about_dialog_activate(GtkWidget * dialog, const gchar * uri, gpointer data)
679 open_uri(uri);
683 /***
684 * Handle a connect/Disconnect
686 static void playlist_connection_changed(MpdObj * mi, int connect, gpointer data)
688 GtkWidget *pl3_win = playlist3_get_window();
689 /* Set menu items */
690 if (connect)
692 char **handlers;
693 gboolean found = FALSE;
694 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "vbox_playlist_player")), TRUE);
695 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hpaned1-hbox")), TRUE);
697 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDConnect")), FALSE);
698 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDDisconnect")), TRUE);
699 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPassword")), TRUE);
700 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_view")), TRUE);
701 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_option")), TRUE);
703 /* Check if MPD supports 'file://' (so local files). */
704 /* TODO: make this a separate function */
705 handlers = mpd_server_get_url_handlers(connection);
706 if (handlers)
708 int i=0;
709 for(; !found && handlers != NULL && handlers[i] != NULL; i++) {
710 if(g_utf8_collate(handlers[i], "file://") == 0) {
711 found = TRUE;
714 g_strfreev(handlers);
716 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "open_local_file")), found);
717 } else
719 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "vbox_playlist_player")), FALSE);
720 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hpaned1-hbox")), FALSE);
722 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDConnect")), TRUE);
723 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDDisconnect")), FALSE);
724 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPassword")), FALSE);
725 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_view")), FALSE);
726 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_option")), FALSE);
727 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "open_local_file")), FALSE);
729 /** Set back to the current borwser, and update window title */
730 if (connect)
732 gchar *string = NULL;
733 GtkTreeIter iter;
734 GtkTreeSelection *selec = gtk_tree_view_get_selection((GtkTreeView *) gtk_builder_get_object(pl3_xml,
735 "cat_tree"));
736 GtkTreeModel *model = GTK_TREE_MODEL(pl3_tree);
737 if (gtk_tree_model_get_iter_first(model, &iter))
739 gtk_tree_selection_select_iter(selec, &iter);
741 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles) > 1)
743 gchar *id = gmpc_profiles_get_current(gmpc_profiles);
744 if (id)
746 string =
747 g_strdup_printf("[%s] %s - %s %s", gmpc_profiles_get_name(gmpc_profiles, id), _("GMPC"),
748 _("Connected to"), mpd_get_hostname(mi));
749 g_free(id);
752 if (!string)
753 string = g_strdup_printf("%s - %s %s", _("GMPC"), _("Connected to"), mpd_get_hostname(mi));
754 gtk_window_set_title(GTK_WINDOW(pl3_win), string);
755 g_free(string);
756 } else
758 gchar *string = NULL;
760 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles) > 1)
762 gchar *id = gmpc_profiles_get_current(gmpc_profiles);
763 if (id)
765 string =
766 g_strdup_printf("[%s] %s - %s", gmpc_profiles_get_name(gmpc_profiles, id), _("GMPC"),
767 _("Disconnected"));
768 g_free(id);
771 if (!string)
772 string = g_strdup_printf("%s - %s", _("GMPC"), _("Disconnected"));
773 gtk_window_set_title(GTK_WINDOW(pl3_win), string);
774 g_free(string);
778 * make the playlist update itself
780 playlist_status_changed(connection,
781 MPD_CST_STATE | MPD_CST_SONGID | MPD_CST_NEXTSONG |
782 MPD_CST_ELAPSED_TIME | MPD_CST_VOLUME |
783 MPD_CST_REPEAT | MPD_CST_RANDOM | MPD_CST_PERMISSION
784 | MPD_CST_SINGLE_MODE | MPD_CST_CONSUME_MODE | MPD_CST_UPDATING, NULL);
787 * Also need updating
789 pl3_option_menu_activate();
790 pl3_tool_menu_update();
792 playlist3_fill_server_menu();
795 * update interface
796 * items that are caused by the plugin.
798 pl3_update_go_menu();
802 void pl3_style_set_event( GtkWidget *widget,
803 GtkStyle *previous_style,
804 gpointer user_data)
806 if (cfg_get_single_value_as_int_with_default(config, "Default", "use-dark-style-header", TRUE))
808 gtk_rc_parse_string("widget \"*header*\" style \"dark\"");
811 gboolean pl3_cat_select_function(GtkTreeSelection *select, GtkTreeModel *model, GtkTreePath *path, gboolean cur_select, gpointer data)
813 GtkTreeIter iter;
814 if(gtk_tree_model_get_iter(model, &iter, path))
816 gint type =0 ;
817 gtk_tree_model_get(model, &iter, PL3_CAT_TYPE, &type, -1);
818 if(type >= 0) return TRUE;
820 return FALSE;
822 void create_playlist3(void)
824 GtkWidget *pb,*ali;
825 GtkCellRenderer *renderer;
826 GtkWidget *tree;
827 GtkTreeSelection *sel;
828 GtkTreeViewColumn *column = NULL;
829 gchar *path = NULL;
830 GtkTreeIter iter;
831 GError *error = NULL;
832 INIT_TIC_TAC();
833 /* indicate that the playlist is not hidden */
834 pl3_hidden = FALSE;
837 * If the playlist already exists,
838 * It is probably coming from a hidden state,
839 * so re-position the window
841 if (pl3_xml != NULL)
843 pl3_show_and_position_window();
844 return;
847 /** Ambiance / Radiance theme "dark" header */
848 if (cfg_get_single_value_as_int_with_default(config, "Default", "use-dark-style-header", TRUE))
850 gtk_rc_parse_string("widget \"*header*\" style \"dark\"");
853 /** use background color for the sidebar treeview cells */
854 gtk_rc_parse_string (
855 "style \"sidebar-treeview\"\n"
856 "{\n"
857 " GtkTreeView::odd-row-color = @bg_color\n"
858 " GtkTreeView::even-row-color = @bg_color\n"
859 "}\n"
860 "widget \"*.sidebar.*\" style \"sidebar-treeview\"");
862 /** menubar */
863 gtk_rc_parse_string (
864 "style \"menubar-style\"\n"
865 "{\n"
866 " GtkMenuBar::shadow-type = none\n"
867 "}\n"
868 "widget \"*.menubar\" style \"menubar-style\"\n");
870 /* initial, setting the url hook */
871 gtk_about_dialog_set_url_hook((GtkAboutDialogActivateLinkFunc) about_dialog_activate, NULL, NULL);
872 TEC("Setup dialog url hook")
873 /* load gui desciption */
874 path = gmpc_get_full_glade_path("playlist3.ui");
875 TEC("get path")
876 pl3_xml = gtk_builder_new();
877 TEC("create builder")
878 if(gtk_builder_add_from_file(pl3_xml, path,&error) == 0)
881 * Check if the file is loaded, if not then show an error message and abort the program
882 if (pl3_xml == NULL)
885 g_log(LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Failed to open playlist3.glade: %s\n", error->message);
886 abort();
888 g_free(path);
889 TEC("Load builder file")
891 /* create tree store for the "category" view */
892 if (pl3_tree == NULL)
894 GType types[] =
896 G_TYPE_INT, /* row type, see free_type struct */
897 G_TYPE_STRING, /* display name */
898 G_TYPE_STRING, /* full path and stuff for backend */
899 G_TYPE_STRING, /* icon id */
900 G_TYPE_INT, /* ordering */
901 G_TYPE_INT
903 /* song id, song title */
904 pl3_tree = (GtkTreeModel *) gmpc_tools_liststore_sort_new();
905 gtk_list_store_set_column_types(GTK_LIST_STORE(pl3_tree), PL3_CAT_NROWS, types);
907 TEC("Setup pl3_tree")
909 GtkTreeIter iter;
911 playlist3_insert_browser(&iter, PL3_CAT_BROWSER_LIBRARY);
912 gtk_list_store_set(GTK_LIST_STORE(pl3_tree), &iter,
913 PL3_CAT_TYPE,-1, PL3_CAT_TITLE, _("Library"),PL3_CAT_BOLD, PANGO_WEIGHT_ULTRABOLD,-1);
915 playlist3_insert_browser(&iter, PL3_CAT_BROWSER_ONLINE_MEDIA);
916 gtk_list_store_set(GTK_LIST_STORE(pl3_tree), &iter,
917 PL3_CAT_TYPE,-1, PL3_CAT_TITLE, _("Online Media"),PL3_CAT_BOLD, PANGO_WEIGHT_ULTRABOLD,-1);
919 playlist3_insert_browser(&iter, PL3_CAT_BROWSER_MISC);
920 gtk_list_store_set(GTK_LIST_STORE(pl3_tree), &iter,
921 PL3_CAT_TYPE,-1, PL3_CAT_TITLE, _("Misc."),PL3_CAT_BOLD, PANGO_WEIGHT_ULTRABOLD,-1);
925 tree = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "cat_tree"));
926 gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)),
927 pl3_cat_select_function, pl3_tree, NULL);
929 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(pl3_tree));
930 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
931 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(sel), GTK_SELECTION_BROWSE);
932 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(tree), TRUE);
934 sidebar_text = renderer = my_cell_renderer_new();//gtk_cell_renderer_pixbuf_new();
935 g_object_set(G_OBJECT(renderer), "xalign", 0.5,NULL);
936 column = gtk_tree_view_column_new();
937 gtk_tree_view_column_pack_start(column, renderer, FALSE);
938 g_object_set(G_OBJECT(renderer), "stock-size", GTK_ICON_SIZE_MENU, NULL);
940 int w, h;
941 if (gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &w, &h))
943 g_object_set(G_OBJECT(renderer), "height", h+10, NULL);
944 g_object_set(G_OBJECT(renderer), "image-width", w,NULL);
947 gtk_tree_view_column_set_attributes(column, renderer,
948 "icon-name", PL3_CAT_ICON_ID,
949 "text", PL3_CAT_TITLE,
950 "weight", PL3_CAT_BOLD, NULL);
951 g_object_set(renderer, "weight-set", TRUE, NULL);
953 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
954 gtk_tree_view_set_search_column(GTK_TREE_VIEW(tree), PL3_CAT_TITLE);
955 g_signal_connect_after(G_OBJECT(sel), "changed", G_CALLBACK(pl3_cat_sel_changed), NULL);
957 TEC("setup cat_tree");
959 /* initialize the category view */
960 pl3_initialize_tree();
962 TEC("Init category tree")
963 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "vbox_playlist_player")));
966 * The new progress bar
968 pb = (GtkWidget *) gtk_builder_get_object(pl3_xml, "hbox_progress");
969 gtk_widget_show(pb);
970 g_signal_connect(G_OBJECT(pb), "seek-event", G_CALLBACK(pl3_pb_seek_event), NULL);
972 new_pb = pb;
974 TEC("Init progress bar")
975 /* Make sure change is applied */
977 playlist3_new_header();
979 pl3_sidebar_plugins_init();
981 TEC("Init header")
982 if (!cfg_get_single_value_as_int_with_default(config, "Interface", "hide-favorites-icon", FALSE))
984 favorites_button = gmpc_favorites_button_new();
985 ali = gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
986 gtk_container_add(GTK_CONTAINER(ali), GTK_WIDGET(favorites_button));
987 gtk_box_pack_start(GTK_BOX(gtk_builder_get_object(pl3_xml, "hbox10")), GTK_WIDGET(ali), FALSE, FALSE, 0);
988 gtk_widget_show_all(GTK_WIDGET(ali));
989 TEC("Init fav icon")
991 playlist_status_changed(connection,
992 MPD_CST_STATE | MPD_CST_SONGID | MPD_CST_NEXTSONG |
993 MPD_CST_ELAPSED_TIME | MPD_CST_VOLUME |
994 MPD_CST_REPEAT | MPD_CST_RANDOM | MPD_CST_PERMISSION
995 | MPD_CST_SINGLE_MODE | MPD_CST_CONSUME_MODE, NULL);
996 g_signal_connect(G_OBJECT(gtk_builder_get_object(pl3_xml, "volume_button")),
997 "value_changed", G_CALLBACK(playlist_player_volume_changed), NULL);
999 TEC("Signal setup")
1001 /* Restore values from config */
1002 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION
1003 (gtk_builder_get_object
1004 (pl3_xml, "ViewShowArtistImage")),
1005 cfg_get_single_value_as_int_with_default
1006 (config, "playlist", "cover-image-enable", 0));
1008 /* connect signals that are defined in the gui description */
1009 gtk_builder_connect_signals(pl3_xml,NULL);
1011 TEC("connect signals")
1013 /* select the current playlist */
1014 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pl3_tree), &iter))
1016 gtk_tree_selection_select_iter(sel, &iter);
1019 TEC("Select view")
1021 * Insert new custom widget
1023 metaimage_album_art = gmpc_metaimage_new(META_ALBUM_ART);
1025 /* Hide when requested. */
1026 if (cfg_get_single_value_as_int_with_default(config, "Interface", "hide-album-art", FALSE))
1028 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_album_art), FALSE);
1030 gtk_box_pack_start(GTK_BOX
1031 (gtk_builder_get_object(pl3_xml, "hbox_playlist_player")), metaimage_album_art, FALSE, TRUE, 0);
1033 gtk_box_reorder_child(GTK_BOX
1034 (gtk_builder_get_object(pl3_xml, "hbox_playlist_player")), metaimage_album_art, 0);
1035 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_album_art), ALBUM_SIZE_LARGE);
1036 gmpc_metaimage_set_no_cover_icon(GMPC_METAIMAGE(metaimage_album_art), (char *)"gmpc");
1037 gmpc_metaimage_set_connection(GMPC_METAIMAGE(metaimage_album_art), connection);
1038 /** make sure size is updated */
1039 gmpc_metaimage_set_cover_na(GMPC_METAIMAGE(metaimage_album_art));
1041 metaimage_artist_art = gmpc_metaimage_new(META_ARTIST_ART);
1042 gtk_container_add(GTK_CONTAINER(gtk_builder_get_object(pl3_xml, "sidebar_artist_image_alignment")), metaimage_artist_art);
1044 gmpc_metaimage_set_no_cover_icon(GMPC_METAIMAGE(metaimage_artist_art), (char *)"no-artist");
1045 gmpc_metaimage_set_loading_cover_icon(GMPC_METAIMAGE(metaimage_artist_art), (char *)"fetching-artist");
1046 gmpc_metaimage_set_connection(GMPC_METAIMAGE(metaimage_artist_art), connection);
1047 if (!cfg_get_single_value_as_int_with_default(config, "playlist", "cover-image-enable", FALSE))
1049 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art), FALSE);
1051 gmpc_metaimage_set_squared(GMPC_METAIMAGE(metaimage_artist_art), FALSE);
1052 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_artist_art), 145);
1054 TEC("Setup metaimages")
1055 /* restore the window's position and size, if the user wants this. */
1056 if (cfg_get_single_value_as_int_with_default(config, "playlist", "savepossize", 1))
1058 int maximized = cfg_get_single_value_as_int_with_default(config, "playlist", "maximized", 0);
1059 /* Load values from config file */
1060 pl3_wsize.x = cfg_get_single_value_as_int_with_default(config, "playlist", "xpos", 0);
1061 pl3_wsize.y = cfg_get_single_value_as_int_with_default(config, "playlist", "ypos", 0);
1062 pl3_wsize.width = cfg_get_single_value_as_int_with_default(config, "playlist", "width", 0);
1063 pl3_wsize.height = cfg_get_single_value_as_int_with_default(config, "playlist", "height", 0);
1064 TEC("get settings")
1065 /* restore location + position */
1066 /*pl3_show_and_position_window(); */
1068 if (pl3_wsize.x > 0 || pl3_wsize.y > 0)
1070 gtk_window_move(GTK_WINDOW(playlist3_get_window()), pl3_wsize.x, pl3_wsize.y);
1072 TEC("move window settings")
1073 if (pl3_wsize.height > 0 && pl3_wsize.width > 0)
1075 g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "restore size %i %i\n", pl3_wsize.width, pl3_wsize.height);
1076 gtk_window_resize(GTK_WINDOW(playlist3_get_window()), pl3_wsize.width, pl3_wsize.height);
1078 TEC("resize window settings")
1079 /* restore pane position */
1080 gtk_widget_set_size_request(GTK_WIDGET(gtk_builder_get_object(pl3_xml,"sidebar")), 150,-1);
1082 TEC("set pane window settings")
1083 if (maximized)
1084 gtk_window_maximize(GTK_WINDOW(playlist3_get_window()));
1085 TEC("maximize pane window settings")
1087 * restore zoom level
1090 gtk_widget_show(playlist3_get_window());
1091 TEC("Show window")
1092 pl3_zoom = cfg_get_single_value_as_int_with_default(config, "playlist", "zoomlevel", PLAYLIST_NO_ZOOM);
1093 playlist_zoom_level_changed();
1094 TEC("zoom level")
1096 #ifdef HAVE_APP_INDICATOR
1097 tray_icon2_update_menu();
1098 #endif
1100 TEC("Restore state")
1101 pl3_update_go_menu();
1102 TEC("Go menu")
1103 /* make it update itself */
1104 pl3_update_profiles_menu(gmpc_profiles, PROFILE_ADDED, -1, NULL);
1105 g_signal_connect(G_OBJECT(gmpc_profiles), "changed", G_CALLBACK(pl3_update_profiles_menu), NULL);
1106 g_signal_connect(G_OBJECT(gmpc_profiles), "changed", G_CALLBACK(pl3_profiles_changed), NULL);
1108 TEC("Update profiles")
1110 * Set as drag destination
1112 gtk_drag_dest_set(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hbox_playlist_player")),
1113 GTK_DEST_DEFAULT_ALL,
1114 target_table, 6, GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_DEFAULT | GDK_ACTION_MOVE);
1115 g_signal_connect(G_OBJECT
1116 (gtk_builder_get_object(pl3_xml, "hbox_playlist_player")),
1117 "drag_data_received", GTK_SIGNAL_FUNC(playlist3_source_drag_data_recieved), NULL);
1119 TEC("setup drag")
1123 playlist_connection_changed(connection, FALSE, NULL);
1125 g_signal_connect(G_OBJECT(playlist3_get_window()), "window-state-event", G_CALLBACK(pl3_win_state_event), NULL);
1127 TEC("signal connn changed")
1129 g_signal_connect(G_OBJECT(playlist3_get_window()), "style-set", G_CALLBACK(pl3_style_set_event), NULL);
1132 * Add status icons
1134 main_window_init_default_status_icons();
1135 main_window_update_status_icons();
1137 TEC("Update status icon")
1138 /* Update extra */
1139 init_extra_playlist_state();
1140 TEC("Setup extra playlist")
1145 * Helper functions
1147 GtkListStore *playlist3_get_category_tree_store(void)
1149 if (pl3_xml == NULL)
1150 return NULL;
1151 return GTK_LIST_STORE(pl3_tree);
1155 GtkTreeView *playlist3_get_category_tree_view(void)
1157 if (pl3_xml == NULL)
1158 return NULL;
1159 return (GtkTreeView *) gtk_builder_get_object(pl3_xml, "cat_tree");
1162 GtkWidget* playlist3_get_widget_by_id(const char *id) {
1163 return (GtkWidget *) gtk_builder_get_object(pl3_xml, id);
1167 /****************************************************************************************
1168 * PREFERENCES *
1169 ****************************************************************************************/
1170 /* prototyping for glade */
1171 void ck_stop_on_exit_toggled_cb(GtkToggleButton * but, gpointer data);
1172 void ck_show_tooltip_enable_tb(GtkToggleButton * but);
1174 G_MODULE_EXPORT void show_cover_case_tb(GtkToggleButton * but)
1176 int bool1 = gtk_toggle_button_get_active(but);
1177 cfg_set_single_value_as_int(config, "metaimage", "addcase", bool1);
1178 gmpc_meta_watcher_force_reload(gmw);
1182 G_MODULE_EXPORT void ck_stop_on_exit_toggled_cb(GtkToggleButton * but, gpointer data)
1184 int bool1 = gtk_toggle_button_get_active(but);
1185 cfg_set_single_value_as_int(config, "connection", "stop-on-exit", bool1);
1189 G_MODULE_EXPORT void hide_on_close_enable_tb(GtkToggleButton * but)
1191 int bool1 = gtk_toggle_button_get_active(but);
1192 cfg_set_single_value_as_int(config, "playlist", "hide-on-close", bool1);
1196 G_MODULE_EXPORT void cur_song_center_enable_tb(GtkToggleButton * but)
1198 int bool1 = gtk_toggle_button_get_active(but);
1199 cfg_set_single_value_as_int(config, "playlist", "st_cur_song", bool1);
1203 G_MODULE_EXPORT void save_possize_enable_tb(GtkToggleButton * but)
1205 int bool1 = gtk_toggle_button_get_active(but);
1206 cfg_set_single_value_as_int(config, "playlist", "savepossize", bool1);
1210 G_MODULE_EXPORT void ck_show_tooltip_enable_tb(GtkToggleButton * but)
1212 int bool1 = gtk_toggle_button_get_active(but);
1213 cfg_set_single_value_as_int(config, "GmpcTreeView", "show-tooltip", bool1);
1217 G_MODULE_EXPORT void ck_search_as_you_type(GtkToggleButton * but)
1219 int bool1 = gtk_toggle_button_get_active(but);
1220 cfg_set_single_value_as_int(config, "general", "search-as-you-type", bool1);
1224 static void playlist_pref_destroy(GtkWidget * container)
1226 if (playlist_pref_xml)
1228 GtkWidget *vbox = (GtkWidget *) gtk_builder_get_object(playlist_pref_xml,
1229 "playlist-vbox");
1230 gtk_container_remove(GTK_CONTAINER(container), vbox);
1231 g_object_unref(playlist_pref_xml);
1232 playlist_pref_xml = NULL;
1237 void playlist_pref_construct(GtkWidget * container)
1239 GError *error = NULL;
1240 gchar *path = gmpc_get_full_glade_path("preferences-playlist.ui");
1241 playlist_pref_xml = gtk_builder_new();
1243 gtk_builder_add_from_file(playlist_pref_xml, path, &error);
1244 if(error) {
1245 g_warning("Failed to open builder file: %s", error->message);
1246 g_error_free(error);
1247 return;
1249 if (playlist_pref_xml)
1251 GtkWidget *vbox = (GtkWidget *) gtk_builder_get_object(playlist_pref_xml,
1252 "playlist-vbox");
1253 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1254 (gtk_builder_get_object
1255 (playlist_pref_xml, "ck_ps")),
1256 cfg_get_single_value_as_int_with_default(config, "playlist", "st_cur_song", 0));
1257 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1258 (gtk_builder_get_object
1259 (playlist_pref_xml, "ck_possize")),
1260 cfg_get_single_value_as_int_with_default(config, "playlist", "savepossize", 1));
1261 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1262 (gtk_builder_get_object
1263 (playlist_pref_xml, "ck_hide_on_close")),
1264 cfg_get_single_value_as_int_with_default(config, "playlist", "hide-on-close", 0));
1266 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1267 (gtk_builder_get_object
1268 (playlist_pref_xml, "ck_stop_on_exit")),
1269 cfg_get_single_value_as_int_with_default(config, "connection", "stop-on-exit", 0));
1271 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1272 (gtk_builder_get_object
1273 (playlist_pref_xml, "ck_cover_case")),
1274 cfg_get_single_value_as_int_with_default(config, "metaimage", "addcase", TRUE));
1276 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1277 (gtk_builder_get_object
1278 (playlist_pref_xml, "ck_show_tooltip")),
1279 cfg_get_single_value_as_int_with_default
1280 (config, "GmpcTreeView", "show-tooltip", TRUE));
1282 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1283 (gtk_builder_get_object
1284 (playlist_pref_xml, "ck_search_as_you_type")),
1285 cfg_get_single_value_as_int_with_default(config, "general", "search-as-you-type",
1286 0));
1287 gtk_container_add(GTK_CONTAINER(container), vbox);
1288 gtk_widget_show_all(vbox);
1289 gtk_builder_connect_signals(playlist_pref_xml, NULL);
1291 g_free(path);
1296 * Menu Callback functions
1299 void playlist_menu_repeat_changed(GtkToggleAction * action)
1301 int active = gtk_toggle_action_get_active(action);
1302 if (active != mpd_player_get_repeat(connection))
1304 mpd_player_set_repeat(connection, active);
1309 void playlist_menu_random_changed(GtkToggleAction *action)
1311 int active = gtk_toggle_action_get_active(action);
1312 if (active != mpd_player_get_random(connection))
1314 mpd_player_set_random(connection, active);
1319 void playlist_menu_single_mode_changed(GtkToggleAction * action)
1321 int active = gtk_toggle_action_get_active(action);
1322 if (active != mpd_player_get_single(connection))
1324 mpd_player_set_single(connection, active);
1329 void playlist_menu_consume_changed(GtkToggleAction * action)
1331 int active = gtk_toggle_action_get_active(action);
1332 if (active != mpd_player_get_consume(connection))
1334 mpd_player_set_consume(connection, active);
1340 * This is artist image
1341 * FIXME: Rename
1343 void playlist_menu_artist_image_changed(GtkToggleAction *ta)
1345 int active = gtk_toggle_action_get_active(ta);
1346 cfg_set_single_value_as_int(config, "playlist", "cover-image-enable", active);
1347 if(pl3_zoom < PLAYLIST_SMALL)
1349 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art), active);
1350 if (active)
1351 gtk_widget_show(metaimage_artist_art);
1356 /***
1357 * Zooming functions
1359 void playlist_zoom_out(void)
1361 /* Do not change zoom level when fullscreen */
1362 if(pl3_window_is_fullscreen())
1363 return;
1364 if ((pl3_zoom + 1) >= PLAYLIST_ZOOM_LEVELS)
1365 return;
1366 pl3_old_zoom = pl3_zoom;
1367 pl3_zoom++;
1368 playlist_zoom_level_changed();
1372 void playlist_zoom_in(void)
1374 /* Do not change zoom level when fullscreen */
1375 if(pl3_window_is_fullscreen())
1376 return;
1377 if (pl3_zoom <= PLAYLIST_NO_ZOOM)
1378 return;
1379 pl3_old_zoom = pl3_zoom;
1380 pl3_zoom--;
1381 playlist_zoom_level_changed();
1386 * FIXME: Needs propper grouping and cleaning up
1388 static void playlist_zoom_level_changed(void)
1390 GtkWidget *pl3_win = playlist3_get_window();
1391 printf("playlist3 zoom level changed\n");
1393 if (pl3_old_zoom <= PLAYLIST_SMALL)
1395 gtk_window_get_size(GTK_WINDOW(pl3_win), &pl3_wsize.width, &pl3_wsize.height);
1396 cfg_set_single_value_as_int(config, "playlist", "width", pl3_wsize.width);
1397 cfg_set_single_value_as_int(config, "playlist", "height", pl3_wsize.height);
1398 g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "save size: %i %i\n", pl3_wsize.width, pl3_wsize.height);
1401 if (pl3_old_zoom == PLAYLIST_MINI && pl3_zoom != PLAYLIST_MINI)
1403 GtkWidget *box =GTK_WIDGET(gtk_builder_get_object(pl3_xml, "pl3_button_control_box"));
1404 GtkWidget *top = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hbox10"));
1405 GtkWidget *vtop = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "vbox_playlist_player"));
1406 /* add my own reference */
1407 g_object_ref(box);
1408 gtk_container_remove(GTK_CONTAINER(vtop), box);
1409 gtk_box_pack_end(GTK_BOX(top), box, FALSE, TRUE, 0);
1410 gtk_box_reorder_child(GTK_BOX(top), box, 0);
1411 /* release my reference */
1412 g_object_unref(box);
1413 gtk_widget_show(box);
1414 gmpc_progress_set_hide_text(GMPC_PROGRESS(new_pb), FALSE);
1416 /* Album image only if enabled. */
1417 if(metaimage_album_art != NULL)
1419 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_album_art), ALBUM_SIZE_LARGE);
1420 gmpc_metaimage_reload_image(GMPC_METAIMAGE(metaimage_album_art));
1424 if (pl3_old_zoom != PLAYLIST_MINI && pl3_zoom == PLAYLIST_MINI)
1426 GtkWidget *box =GTK_WIDGET(gtk_builder_get_object(pl3_xml, "pl3_button_control_box"));
1427 GtkWidget *top = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hbox10"));
1428 GtkWidget *vtop = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "vbox_playlist_player"));
1429 /* add my own reference */
1430 g_object_ref(box);
1431 gtk_container_remove(GTK_CONTAINER(top), box);
1432 gtk_box_pack_end(GTK_BOX(vtop), box, FALSE, TRUE, 3);
1433 /* release my reference */
1434 g_object_unref(box);
1435 gtk_widget_show(box);
1437 gmpc_progress_set_hide_text(GMPC_PROGRESS(new_pb), TRUE);
1439 /* Album image only if enabled. */
1440 if(metaimage_album_art != NULL)
1442 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_album_art), ALBUM_SIZE_SMALL);
1443 gmpc_metaimage_reload_image(GMPC_METAIMAGE(metaimage_album_art));
1448 /* Show full view */
1449 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hpaned1-hbox")));
1450 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hbox1")));
1451 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hbox10")));
1452 /** Menu Bar */
1453 /** BUTTON BOX */
1454 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "pl3_button_control_box")));
1456 gtk_window_set_resizable(GTK_WINDOW(pl3_win), TRUE);
1457 if (pl3_wsize.width > 0 && pl3_wsize.height > 0 && pl3_old_zoom == PLAYLIST_MINI)
1459 g_log(LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "restore size %i %i\n", pl3_wsize.width, pl3_wsize.height);
1460 gtk_window_resize(GTK_WINDOW(pl3_win), pl3_wsize.width, pl3_wsize.height);
1462 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "sidebar")));
1464 if (cfg_get_single_value_as_int_with_default(config, "playlist", "cover-image-enable", FALSE))
1466 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art), TRUE);
1467 gtk_widget_show(metaimage_artist_art);
1469 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_go")),TRUE);
1470 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_option")),TRUE);
1472 gboolean st_shown;
1473 g_object_get(G_OBJECT(sidebar_text), "show_text", &st_shown, NULL);
1474 if(!st_shown)
1476 /* restore pane position */
1477 g_object_set(sidebar_text, "show_text", TRUE, NULL);
1478 gtk_widget_set_size_request(GTK_WIDGET(gtk_builder_get_object(pl3_xml,"sidebar")), 150,-1);
1479 gmpc_sidebar_plugins_update_state(GMPC_PLUGIN_SIDEBAR_STATE_FULL);
1482 /* Now start hiding */
1483 switch (pl3_zoom)
1485 case PLAYLIST_NO_ZOOM:
1486 break;
1487 case PLAYLIST_MINI:
1488 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "hpaned1-hbox")));
1489 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_option")),FALSE);
1490 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_go")),FALSE);
1491 if (pl3_win->window)
1493 if (gdk_window_get_state(pl3_win->window) & GDK_WINDOW_STATE_MAXIMIZED)
1495 gtk_window_unmaximize(GTK_WINDOW(pl3_win));
1498 if (gdk_window_get_state(pl3_win->window) & GDK_WINDOW_STATE_FULLSCREEN)
1500 gtk_window_unfullscreen(GTK_WINDOW(pl3_win));
1503 gtk_window_set_resizable(GTK_WINDOW(pl3_win), FALSE);
1505 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml, "sidebar")));
1506 break;
1507 case PLAYLIST_SMALL:
1508 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art), FALSE);
1509 if(st_shown) {
1510 g_object_set(sidebar_text, "show_text", FALSE, NULL);
1511 gtk_widget_set_size_request(GTK_WIDGET(gtk_builder_get_object(pl3_xml,"sidebar")), 32,-1);
1512 gmpc_sidebar_plugins_update_state(GMPC_PLUGIN_SIDEBAR_STATE_COLLAPSED);
1514 gtk_widget_grab_focus(pl3_win);
1515 default:
1516 break;
1518 /** Save zoom level
1520 cfg_set_single_value_as_int(config, "playlist", "zoomlevel", pl3_zoom);
1525 * Update the window to status changes in mpd
1527 static void playlist_status_changed(MpdObj * mi, ChangedStatusType what, void *userdata)
1529 char buffer[1024];
1530 GtkWidget *pl3_win = playlist3_get_window();
1532 * if the window isn't there yet, return
1534 if (!pl3_xml)
1535 return;
1536 control_window_status_update(mi, what, control_window);
1538 * Player state changed
1540 if (what & MPD_CST_STATE)
1542 mpd_Song *song = mpd_playlist_get_current_song(connection);
1543 int state = mpd_player_get_state(mi);
1544 switch (state)
1546 case MPD_PLAYER_PLAY:
1548 gchar *markup = cfg_get_single_value_as_string_with_default(config,
1549 "playlist", /* Category */
1550 "window-markup",/* Key */
1551 /* default value */
1552 "[%title% - &[%artist%]]|%name%|%shortfile%"
1555 * Update the image in the menu
1557 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPlayPause")), "gtk-media-pause");
1558 gtk_image_set_from_stock(GTK_IMAGE
1559 (gtk_builder_get_object
1560 (pl3_xml, "play_button_image")), "gtk-media-pause",
1561 GTK_ICON_SIZE_MENU);
1564 * Update window title
1566 mpd_song_markup(buffer, 1024, markup, mpd_playlist_get_current_song(connection));
1568 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles) > 1)
1570 gchar *id = gmpc_profiles_get_current(gmpc_profiles);
1571 if (id)
1573 gchar *string = g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles,
1574 id), buffer);
1575 gtk_window_set_title(GTK_WINDOW(pl3_win), string);
1576 g_free(id);
1577 g_free(string);
1579 } else
1580 gtk_window_set_title(GTK_WINDOW(pl3_win), buffer);
1582 g_free(markup);
1583 break;
1585 case MPD_PLAYER_PAUSE:
1587 gchar *markup = cfg_get_single_value_as_string_with_default(config,
1588 "playlist", /* Category */
1589 "window-markup",/* Key */
1590 /* default value */
1591 "[%title% - &[%artist%]]|%name%|%shortfile%"
1593 /** Update menu and button images */
1595 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPlayPause")), "gtk-media-play");
1596 gtk_image_set_from_stock(GTK_IMAGE
1597 (gtk_builder_get_object
1598 (pl3_xml, "play_button_image")), "gtk-media-play",
1599 GTK_ICON_SIZE_MENU);
1601 * Set paused in Window string
1603 mpd_song_markup(buffer, 1024 - strlen(_("paused") - 4),
1604 markup, mpd_playlist_get_current_song(connection));
1605 /* Append translated paused */
1606 strcat(buffer, " (");
1607 strcat(buffer, _("paused"));
1608 strcat(buffer, ")");
1610 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles) > 1)
1612 gchar *id = gmpc_profiles_get_current(gmpc_profiles);
1613 if (id)
1615 gchar *string = g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles,
1616 id), buffer);
1617 gtk_window_set_title(GTK_WINDOW(pl3_win), string);
1618 g_free(id);
1619 g_free(string);
1621 } else
1622 gtk_window_set_title(GTK_WINDOW(pl3_win), buffer);
1623 g_free(markup);
1624 break;
1626 default:
1627 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPlayPause")), "gtk-media-play");
1628 /* Make sure it's reset correctly */
1629 gmpc_progress_set_time(GMPC_PROGRESS(new_pb), 0, 0);
1631 gtk_image_set_from_stock(GTK_IMAGE
1632 (gtk_builder_get_object
1633 (pl3_xml, "play_button_image")), "gtk-media-play",
1634 GTK_ICON_SIZE_MENU);
1635 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles) > 1)
1637 gchar *id = gmpc_profiles_get_current(gmpc_profiles);
1638 if (id)
1640 gchar *string = g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles,
1641 id), _("GMPC"));
1642 gtk_window_set_title(GTK_WINDOW(pl3_win), string);
1643 g_free(id);
1644 g_free(string);
1646 } else
1647 gtk_window_set_title(GTK_WINDOW(pl3_win), _("GMPC"));
1649 playlist3_update_header();
1651 if(favorites_button != NULL)
1653 if (state == MPD_PLAYER_PLAY || state == MPD_PLAYER_PAUSE)
1655 gmpc_favorites_button_set_song(favorites_button, song);
1656 } else
1658 gmpc_favorites_button_set_song(favorites_button, NULL);
1663 * Handle song change or Playlist change
1664 * Anything that can change metadta
1666 if (what & MPD_CST_SONGID || what & MPD_CST_SONGPOS || what & MPD_CST_PLAYLIST)
1668 playlist3_update_header();
1669 /* make is update markups and stuff */
1670 playlist_status_changed(mi, MPD_CST_STATE, NULL);
1673 * set repeat buttons in menu correct
1675 if (what & MPD_CST_REPEAT)
1677 if (mpd_check_connected(connection))
1679 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml, "MPDRepeat")),
1680 mpd_player_get_repeat(connection));
1684 if (what & MPD_CST_RANDOM)
1686 if (mpd_check_connected(connection))
1688 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml, "MPDRandom")),
1689 mpd_player_get_random(connection));
1692 if (what & (MPD_CST_RANDOM | MPD_CST_REPEAT | MPD_CST_SINGLE_MODE | MPD_CST_CONSUME_MODE))
1694 main_window_update_status_icons();
1696 if (what & MPD_CST_SINGLE_MODE)
1698 if (mpd_check_connected(connection))
1700 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml, "MPDSingleMode")),
1701 mpd_player_get_single(connection));
1705 if (what & MPD_CST_CONSUME_MODE)
1707 if (mpd_check_connected(connection))
1709 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml, "MPDConsumeMode")),
1710 mpd_player_get_consume(connection));
1713 if (what & MPD_CST_ELAPSED_TIME)
1715 if (mpd_check_connected(connection))
1717 int totalTime = mpd_status_get_total_song_time(connection);
1718 int elapsedTime = mpd_status_get_elapsed_song_time(connection);
1719 gmpc_progress_set_time(GMPC_PROGRESS(new_pb), totalTime, elapsedTime);
1720 } else
1723 gmpc_progress_set_time(GMPC_PROGRESS(new_pb), 0, 0);
1726 if (what & MPD_CST_PERMISSION)
1728 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDSingleMode")),
1730 mpd_check_connected(connection) &&
1731 mpd_server_check_command_allowed(connection, "single") == MPD_SERVER_COMMAND_ALLOWED
1734 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDConsumeMode")),
1736 mpd_check_connected(connection) &&
1737 mpd_server_check_command_allowed(connection, "consume") == MPD_SERVER_COMMAND_ALLOWED
1740 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPlayPause")),
1742 mpd_check_connected(connection) &&
1743 mpd_server_check_command_allowed(connection, "play") == MPD_SERVER_COMMAND_ALLOWED
1746 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDNext")),
1748 mpd_check_connected(connection) &&
1749 mpd_server_check_command_allowed(connection, "next") == MPD_SERVER_COMMAND_ALLOWED
1752 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPrevious")),
1754 mpd_check_connected(connection) &&
1755 mpd_server_check_command_allowed(connection, "previous") == MPD_SERVER_COMMAND_ALLOWED
1758 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDStop")),
1760 mpd_check_connected(connection) &&
1761 mpd_server_check_command_allowed(connection, "stop") == MPD_SERVER_COMMAND_ALLOWED
1764 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDRepeat")),
1766 mpd_check_connected(connection) &&
1767 mpd_server_check_command_allowed(connection, "repeat") == MPD_SERVER_COMMAND_ALLOWED
1770 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDRandom")),
1772 mpd_check_connected(connection)&&
1773 mpd_server_check_command_allowed(connection, "random") == MPD_SERVER_COMMAND_ALLOWED
1776 /* Also update volume stuff */
1777 what = what|MPD_CST_VOLUME;
1780 if (what & MPD_CST_VOLUME)
1782 GtkWidget *volume_button = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "volume_button"));
1783 //gtk_scale_button_get_value(GTK_SCALE_BUTTON(volume_button)) * 100;
1784 int volume = gmpc_widgets_volume_get_volume_level(GMPC_WIDGETS_VOLUME(volume_button));
1785 int new_volume = mpd_status_get_volume(connection);
1786 if (new_volume >= 0 &&
1787 mpd_server_check_command_allowed(connection, "setvol") == MPD_SERVER_COMMAND_ALLOWED
1790 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDMuted")),
1791 TRUE
1793 gtk_widget_set_sensitive(volume_button, TRUE);
1794 /* don't do anything if nothing is changed */
1795 if (new_volume != volume)
1797 gmpc_widgets_volume_set_volume_level(GMPC_WIDGETS_VOLUME(volume_button), new_volume );
1799 } else
1801 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDMuted")),
1802 FALSE
1804 gtk_widget_set_sensitive(volume_button, FALSE);
1807 if (what & MPD_CST_SERVER_ERROR)
1809 gchar *error = mpd_status_get_mpd_error(mi);
1810 if (error)
1812 gchar *mes = g_markup_printf_escaped("%s: '%s'",
1813 _("MPD Reported the following error"),
1814 error);
1815 playlist3_show_error_message(mes, ERROR_WARNING);
1816 g_free(mes);
1817 g_free(error);
1820 if (what & MPD_CST_OUTPUT)
1822 playlist3_fill_server_menu();
1824 if (what & MPD_CST_NEXTSONG)
1827 GtkWidget *next_button = GTK_WIDGET(gtk_builder_get_object(pl3_xml, "next_button"));
1828 if (next_button)
1830 int i = mpd_player_get_next_song_id(mi);
1831 if (i >= 0)
1833 mpd_Song *song = mpd_playlist_get_song(mi, i);
1834 if (song)
1836 mpd_song_markup(buffer, 1024, "[%title% - &[%artist%]]|%shortfile%", song);
1837 gtk_widget_set_tooltip_text(next_button, buffer);
1838 mpd_freeSong(song);
1839 } else
1840 gtk_widget_set_tooltip_text(next_button, "");
1841 } else
1842 gtk_widget_set_tooltip_text(next_button, "");
1847 gboolean playlist_player_volume_changed(GtkWidget * vol_but, int new_vol)
1849 int volume = new_vol; //gtk_scale_button_get_value(GTK_SCALE_BUTTON(vol_but)) * 100;
1850 int new_volume = mpd_status_get_volume(connection);
1851 if (new_volume >= 0 && new_volume != volume)
1853 mpd_status_set_volume(connection, volume);
1854 return FALSE;
1856 return FALSE;
1860 void about_window(void)
1862 gchar *path = gmpc_get_full_glade_path("aboutdialog.ui");
1863 GtkBuilder *xml = gtk_builder_new();
1864 GtkWidget *dialog = NULL;
1865 gtk_builder_add_from_file(xml, path, NULL);
1866 dialog = (GtkWidget *) gtk_builder_get_object(xml, "aboutdialog");
1868 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(playlist3_get_window()));
1869 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
1870 g_free(path);
1872 if (strlen(revision))
1874 path = g_strdup_printf("%s\nRevision: %s", VERSION, revision);
1875 } else
1877 path = g_strdup_printf("%s\n%s\n", VERSION, GMPC_TAGLINE);
1879 gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), GMPC_COPYRIGHT);
1880 gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(dialog), _("Gnome Music Player Client"));
1881 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), GMPC_WEBSITE);
1882 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), path);
1884 g_free(path);
1885 gtk_widget_show(dialog);
1886 gtk_dialog_run(GTK_DIALOG(dialog));
1887 gtk_widget_destroy(dialog);
1888 g_object_unref(xml);
1892 /****************************************************
1893 * Interface stuff
1895 void pl3_update_go_menu(void)
1897 int i = 0;
1898 int items = 0;
1899 GtkWidget *menu = NULL;
1900 GtkAccelGroup *group = playlist3_get_accel_group();
1901 GtkUIManager *ui = GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml, "uimanager1"));
1902 GtkMenuItem *m_item = GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui, "/menubartest/menu_go"));
1903 /***
1904 * Remove any old menu
1906 gtk_menu_item_set_submenu(m_item, NULL);
1908 * Create a new menu
1910 menu = gtk_menu_new();
1911 gtk_menu_set_accel_group(GTK_MENU(menu), group);
1912 if (mpd_check_connected(connection))
1914 for (i = 0; i < num_plugins; i++)
1916 if (gmpc_plugin_is_browser(plugins[i]))
1918 items += gmpc_plugin_browser_add_go_menu(plugins[i], menu);
1924 * Attach menu
1926 if (items)
1928 gtk_widget_show_all(menu);
1929 gtk_menu_item_set_submenu(m_item, menu);
1930 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_go")), TRUE);
1931 } else
1933 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_go")), FALSE);
1934 g_object_ref_sink(menu);
1935 g_object_unref(menu);
1940 static void pl3_profile_selected(GtkRadioMenuItem * radio, gpointer data)
1942 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(radio)))
1944 gchar *uid = g_object_get_data(G_OBJECT(radio), "uid");
1945 if (!uid)
1947 return;
1949 connection_set_current_profile(uid);
1950 if (mpd_check_connected(connection))
1952 mpd_disconnect(connection);
1953 connect_to_mpd();
1959 static void pl3_profiles_changed(GmpcProfiles * prof, const int changed, const int col, const gchar * id)
1961 if (!mpd_check_connected(connection))
1963 playlist_connection_changed(connection, 0, NULL);
1968 static void pl3_update_profiles_menu(GmpcProfiles * prof, const int changed, const int col, const gchar * id)
1970 int items = 0;
1971 GtkWidget *menu = NULL;
1972 gchar *current = gmpc_profiles_get_current(gmpc_profiles);
1973 GList *iter, *mult;
1974 GtkUIManager *ui = GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml, "uimanager1"));
1975 GtkMenuItem *m_item = GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui, "/menubartest/menu_music/menu_profiles"));
1976 /* check if there is anything changed that is important for us. */
1978 if (changed == PROFILE_COL_CHANGED && col != PROFILE_COL_NAME)
1980 g_free(current);
1981 return;
1983 /***
1984 * Remove any old menu
1986 gtk_menu_item_set_submenu(m_item, NULL);
1988 * Create a new menu
1990 menu = gtk_menu_new();
1992 mult = gmpc_profiles_get_profiles_ids(gmpc_profiles);
1993 if (mult)
1995 GSList *group = NULL;
1996 iter = mult;
1999 /** Get profile name */
2000 const gchar *value = gmpc_profiles_get_name(gmpc_profiles, (char *)iter->data);
2001 GtkWidget *item = gtk_radio_menu_item_new_with_label(group, value);
2002 /* get new group */
2003 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item));
2004 /* add to the menu */
2005 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2007 /* check the current profile */
2008 if (!strcmp((char *)(iter->data), current))
2010 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
2014 * Attach click handler
2016 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(pl3_profile_selected), NULL);
2018 /** Attach the uid to the handler */
2019 value = g_strdup((char *)(iter->data));
2020 g_object_set_data_full(G_OBJECT(item), "uid", (gpointer) value, g_free);
2022 items++;
2023 } while ((iter = g_list_next(iter)));
2024 g_list_foreach(mult, (GFunc) g_free, NULL);
2025 g_list_free(mult);
2030 * Attach menu
2032 if (items)
2034 gtk_widget_show_all(menu);
2035 gtk_menu_item_set_submenu(m_item , menu);
2036 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_profiles")), TRUE);
2037 } else
2039 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_profiles")), FALSE);
2040 g_object_ref_sink(menu);
2041 g_object_unref(menu);
2043 g_free(current);
2047 static void playlist3_server_output_changed(GtkWidget * item, gpointer data)
2049 int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "id"));
2050 int state = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
2051 mpd_server_set_output_device(connection, id, state);
2056 void playlist3_server_update_db(void)
2058 mpd_database_update_dir(connection, "/");
2062 static GList *server_menu_items = NULL;
2063 static void playlist3_fill_server_menu(void)
2065 GtkUIManager *ui = GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml, "uimanager1"));
2066 GtkMenuItem *m_item = GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui, "/menubartest/menu_server"));
2067 /** Clear old items */
2068 if(server_menu_items != NULL)
2070 g_list_foreach(server_menu_items, (GFunc)gtk_widget_destroy, NULL);
2071 g_list_free(server_menu_items);
2072 server_menu_items = NULL;
2075 /* if connected fill with items */
2076 if (mpd_check_connected(connection))
2078 GtkWidget *menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(m_item));
2079 GtkWidget *menu_item = NULL;
2080 int i = 0;
2081 MpdData *data = NULL;
2083 data = mpd_server_get_output_devices(connection);
2084 if(data)
2086 menu_item = gtk_separator_menu_item_new();
2087 server_menu_items = g_list_append(server_menu_items, menu_item);
2088 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
2090 for (; data; data = mpd_data_get_next(data))
2092 menu_item = gtk_check_menu_item_new_with_label(data->output_dev->name);
2093 server_menu_items = g_list_append(server_menu_items, menu_item);
2094 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), data->output_dev->enabled ? TRUE : FALSE);
2095 gtk_widget_add_accelerator(menu_item, "activate",
2096 gtk_ui_manager_get_accel_group(GTK_UI_MANAGER(ui)),
2097 GDK_1 + i, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
2099 g_signal_connect(G_OBJECT(menu_item), "toggled", G_CALLBACK(playlist3_server_output_changed), NULL);
2100 g_object_set_data(G_OBJECT(menu_item), "id", GINT_TO_POINTER(data->output_dev->id));
2101 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
2102 i++;
2104 gtk_widget_show_all(menu);
2105 /* Server Menu Item */
2106 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_server")), TRUE);
2107 } else
2109 /* Server Menu Item */
2110 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_server")), FALSE);
2116 * new header
2118 /* glue code */
2120 extern GmpcBrowsersMetadata *browsers_metadata;
2122 void info2_activate(void)
2124 GtkTreeView *tree = (GtkTreeView *) gtk_builder_get_object(pl3_xml, "cat_tree");
2125 gmpc_browsers_metadata_select_browser(browsers_metadata, tree);
2129 void info2_fill_song_view(mpd_Song * song)
2131 info2_activate();
2132 gmpc_browsers_metadata_set_song(browsers_metadata, song);
2136 void info2_fill_artist_view(const gchar * artist)
2138 info2_activate();
2139 gmpc_browsers_metadata_set_artist(browsers_metadata, artist);
2143 void info2_fill_album_view(const gchar * artist, const gchar * album)
2145 info2_activate();
2146 gmpc_browsers_metadata_set_album(browsers_metadata, artist, album);
2150 void playlist3_insert_browser(GtkTreeIter * iter, gint position)
2152 GtkTreeIter it, *sib = NULL;
2153 gint pos = 0;
2154 GtkTreeModel *model = GTK_TREE_MODEL(pl3_tree);
2155 if (gtk_tree_model_get_iter_first(model, &it))
2159 gtk_tree_model_get(model, &it, PL3_CAT_ORDER, &pos, -1);
2160 if (position <= pos)
2161 sib = &it;
2162 } while (sib == NULL && gtk_tree_model_iter_next(model, &it));
2164 gtk_list_store_insert_before(GTK_LIST_STORE(pl3_tree), iter, sib);
2165 gtk_list_store_set(GTK_LIST_STORE(pl3_tree), iter, PL3_CAT_ORDER, position, PL3_CAT_BOLD, PANGO_WEIGHT_NORMAL, -1);
2170 * Category editing
2173 void playlist3_destroy(void)
2175 GtkWidget *win = playlist3_get_window();
2176 if(server_menu_items) g_list_free(server_menu_items);
2177 gtk_widget_destroy(win);
2178 g_object_unref(pl3_xml);
2181 GtkWidget *playlist3_get_window(void)
2183 return GTK_WIDGET(gtk_builder_get_object(pl3_xml, "pl3_win"));
2187 /***
2188 * Help menu
2190 /* Make glade happy */
2191 void url_visit_website(void);
2192 void url_getting_help(void);
2194 void url_visit_website(void)
2196 open_uri(GMPC_WEBSITE);
2200 void url_getting_help(void)
2202 open_uri(GMPC_BUGTRACKER);
2206 gmpcPrefPlugin playlist_gpp =
2208 .construct = playlist_pref_construct,
2209 .destroy = playlist_pref_destroy
2212 gmpcPlugin playlist_plug =
2214 .name = N_("Interface"),
2215 .version = {1, 1, 1},
2216 .plugin_type = GMPC_INTERNALL,
2217 .mpd_status_changed = &playlist_status_changed,
2218 .mpd_connection_changed = &playlist_connection_changed,
2219 .pref = &playlist_gpp,
2224 * Tool menu
2227 void pl3_tool_menu_update(void)
2229 int i;
2230 int menu_items = 0;
2231 GtkWidget *menu = NULL;
2232 GtkAccelGroup *group = gtk_accel_group_new();
2233 GtkUIManager *ui = GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml, "uimanager1"));
2234 GtkMenuItem *m_item = GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui, "/menubartest/menu_tool"));
2235 gtk_menu_item_set_submenu(m_item, NULL);
2236 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_tool")), FALSE);
2237 if (!mpd_check_connected(connection))
2238 return;
2240 menu = gtk_menu_new();
2241 gtk_menu_set_accel_group(GTK_MENU(menu), group);
2242 g_object_unref(group);
2243 gtk_window_add_accel_group(GTK_WINDOW(playlist3_get_window()), group);
2244 for (i = 0; i < num_plugins; i++)
2246 menu_items += gmpc_plugin_tool_menu_integration(plugins[i], GTK_MENU(menu));
2248 if (menu_items)
2250 gtk_widget_show_all(menu);
2251 gtk_menu_item_set_submenu(m_item, menu);
2252 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml, "menu_tool")), TRUE);
2253 } else
2255 g_object_ref_sink(menu);
2256 g_object_unref(menu);
2261 void easy_command_help_window(void)
2263 if (gmpc_easy_command)
2264 gmpc_easy_command_help_window(gmpc_easy_command, NULL);
2270 * Extra wrappings for menu
2272 extern gmpcPlugin extraplaylist_plugin;
2273 void enable_extra_playlist(GtkToggleAction *action)
2275 gboolean state = gtk_toggle_action_get_active(action);
2276 if(extraplaylist_plugin.set_enabled)
2278 if(extraplaylist_plugin.get_enabled() != state)
2280 extraplaylist_plugin.set_enabled(state);
2283 preferences_window_update();
2287 void init_extra_playlist_state(void)
2289 GtkToggleAction *action = GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml, "ViewExtraPlaylist"));
2290 if(extraplaylist_plugin.get_enabled)
2292 gtk_toggle_action_set_active(action, extraplaylist_plugin.get_enabled());
2296 GtkAccelGroup *playlist3_get_accel_group(void)
2298 static GtkAccelGroup *group = NULL;
2299 if(group == NULL) {
2300 group = gtk_accel_group_new();
2301 gtk_window_add_accel_group(GTK_WINDOW(playlist3_get_window()), group);
2303 return group;
2306 void open_local_file(void)
2308 char **handlers;
2309 gboolean found = FALSE;
2310 if(!mpd_check_connected(connection))
2311 return;
2313 /* Check if MPD supports 'file://' (so local files). */
2314 handlers = mpd_server_get_url_handlers(connection);
2315 if (handlers)
2317 int i=0;
2318 for(; !found && handlers != NULL && handlers[i] != NULL; i++) {
2319 if(g_utf8_collate(handlers[i], "file://") == 0) {
2320 found = TRUE;
2323 g_strfreev(handlers);
2325 /* error message or file open */
2326 if(!found) {
2327 /* Message not found */
2328 GtkWidget *gmd = gtk_message_dialog_new(
2329 (GtkWindow*)playlist3_get_window(),
2330 GTK_DIALOG_MODAL,
2331 GTK_MESSAGE_ERROR,
2332 GTK_BUTTONS_CLOSE,
2334 "To playback local files, you need to be connected "
2335 "using unix socket.\n"
2336 "See the MPD website for more information."
2339 gtk_dialog_run(GTK_DIALOG(gmd));
2340 gtk_widget_destroy(GTK_WIDGET(gmd));
2341 }else {
2342 GtkWidget *fmd = gtk_file_chooser_dialog_new(
2343 "Select a local file",
2344 (GtkWindow*)playlist3_get_window(),
2345 GTK_FILE_CHOOSER_ACTION_OPEN,
2346 GTK_STOCK_CLOSE,
2347 GTK_RESPONSE_CLOSE,
2348 GTK_STOCK_OPEN,
2349 GTK_RESPONSE_OK,
2350 NULL);
2351 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(fmd), TRUE);
2352 switch(gtk_dialog_run(GTK_DIALOG(fmd)))
2354 case GTK_RESPONSE_OK:
2356 GSList *iter;
2357 GSList *uris = gtk_file_chooser_get_uris(GTK_FILE_CHOOSER(fmd));
2358 for(iter = uris;
2359 iter != NULL;
2360 iter = g_slist_next(iter))
2362 char *uri = g_uri_unescape_string(iter->data,NULL);
2363 url_start_real(uri);
2364 g_free(uri);
2366 g_slist_foreach (uris, (GFunc) g_free, NULL);
2367 g_slist_free (uris);
2368 break;
2370 default:
2371 break;
2373 gtk_widget_destroy(GTK_WIDGET(fmd));
2377 void show_user_manual(void);
2378 void show_user_manual(void)
2380 open_help("ghelp:gmpc");
2383 GmpcPluginSidebarState playlist3_get_sidebar_state(void)
2385 gboolean st_shown;
2386 g_object_get(G_OBJECT(sidebar_text), "show_text", &st_shown, NULL);
2387 return st_shown? GMPC_PLUGIN_SIDEBAR_STATE_FULL:GMPC_PLUGIN_SIDEBAR_STATE_COLLAPSED;
2389 /* vim: set noexpandtab ts=4 sw=4 sts=4 tw=80: */