1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2012 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.
21 #include <gdk/gdkkeysyms.h>
28 #include "playlist3.h"
29 #include "preferences.h"
31 #include "gmpc-metaimage.h"
32 #include "gmpc-extras.h"
34 #include "GUI/status_icon.h"
35 #include "GUI/title_header.h"
36 #include "GUI/control_window.h"
40 #define LOG_DOMAIN "Playlist"
42 /* Drag and drop Target table */
43 static GtkTargetEntry target_table
[] =
45 {(gchar
*) "x-url/http", 0, 0},
46 {(gchar
*) "_NETSCAPE_URL", 0, 1},
47 {(gchar
*) "text/uri-list", 0, 2},
48 {(gchar
*) "audio/*", 0, 3},
49 {(gchar
*) "audio/x-scpls", 0, 4},
50 {(gchar
*) "internal-drop", 0, 99}
53 GtkWidget
*metaimage_album_art
= NULL
;
54 GtkWidget
*metaimage_artist_art
= NULL
;
55 GmpcFavoritesButton
*favorites_button
= NULL
;
57 GtkCellRenderer
*sidebar_text
= NULL
;
59 * Widgets used in the header.
60 * and the new progresbar
62 static GtkWidget
*new_pb
= NULL
;
65 * Indicates the zoom level and the previous zoom level.
67 int pl3_zoom
= PLAYLIST_NO_ZOOM
;
68 int pl3_old_zoom
= PLAYLIST_NO_ZOOM
;
70 static void playlist_zoom_level_changed(void);
71 void playlist_zoom_in(void);
72 void playlist_zoom_out(void);
75 void pl3_pb_seek_event(GtkWidget
* pb
, guint seek_time
, gpointer user_data
);
77 void set_browser_format(void);
78 void set_playlist_format(void);
80 gboolean
playlist_player_volume_changed(GtkWidget
* vol_but
, double new_vol
);
82 /* Glade declarations, otherwise these would be static */
83 void about_window(void);
84 int pl3_cat_tree_button_press_event(GtkTreeView
*, GdkEventButton
*);
85 int pl3_cat_tree_button_release_event(GtkTreeView
*, GdkEventButton
*);
86 int pl3_window_key_release_event(GtkWidget
* mw
, GdkEventKey
* event
);
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
);
102 gboolean
pl3_window_focus_out_event(GtkWidget
*window
, GdkEventFocus
*event
, gpointer data
);
104 static void pl3_profiles_changed(GmpcProfiles
* prof
, const int changed
, const int col
, const gchar
* id
);
105 static void playlist3_server_output_changed(GtkWidget
* item
, gpointer data
);
106 static void playlist3_fill_server_menu(void);
107 void playlist3_server_update_db(void);
109 void easy_command_help_window(void);
111 void pl3_style_set_event(GtkWidget
*widget
, GtkStyle
*previous_style
, gpointer user_data
);
113 void pl3_sidebar_plugins_init(void);
115 /* Old category browser style */
116 static int old_type
= -1;
118 /* interface description */
119 GtkBuilder
*pl3_xml
= NULL
;
120 /* category treeview-store */
121 GtkTreeModel
*pl3_tree
= NULL
;
124 static GtkAllocation pl3_wsize
= { 0, 0, 0, 0 };
126 static int pl3_hidden
= TRUE
;
128 static void playlist_status_changed(MpdObj
* mi
, ChangedStatusType what
, void *userdata
);
130 /* Playlist "Plugin" */
131 static void playlist_pref_construct(GtkWidget
* container
);
132 static void playlist_pref_destroy(GtkWidget
* container
);
134 static GtkBuilder
*playlist_pref_xml
= NULL
;
136 void ck_search_as_you_type(GtkToggleButton
* but
);
139 /* Get the type of the selected row..
140 * -1 means no row selected
142 int pl3_cat_get_selected_browser(void)
151 * Extras for better integration
154 void init_extra_playlist_state(void);
155 void enable_extra_playlist(GtkToggleAction
*action
);
157 /**************************************************
160 static void pl3_initialize_tree(void)
164 GtkTreeSelection
*sel
;
165 GtkWidget
*cat_tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
169 path
= gtk_tree_path_new_from_string("0");
170 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk_builder_get_object(pl3_xml
, "cat_tree")));
171 TEC("Get selection");
172 for (i
= 0; i
< num_plugins
; i
++)
174 if (gmpc_plugin_is_browser(plugins
[i
]))
176 if (gmpc_plugin_get_enabled(plugins
[i
]))
178 gmpc_plugin_browser_add(plugins
[i
], cat_tree
);
181 TEC("setup %s", gmpc_plugin_get_name(plugins
[i
]))
184 gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtk_builder_get_object(pl3_xml
, "cat_tree")), path
, NULL
, FALSE
);
186 gtk_tree_path_free(path
);
192 * Function to handle a change in category.
194 static void pl3_cat_sel_changed(GtkTreeSelection
* selec
, gpointer
* userdata
)
196 GtkTreeView
*tree
= (GtkTreeView
*) gtk_builder_get_object(pl3_xml
, "cat_tree");
197 GtkTreeModel
*model
= gtk_tree_view_get_model(tree
);
199 GtkWidget
*container
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "browser_container"));
202 if (gtk_tree_selection_get_selected(selec
, &model
, &iter
))
206 gtk_tree_model_get(model
, &iter
, PL3_CAT_TYPE
, &type
, -1);
210 * Start switching side view (if type changed )
214 gmpc_plugin_browser_unselected(plugins
[plugin_get_pos(old_type
)], container
);
219 /** if type changed give a selected signal */
220 if ((old_type
!= type
))
222 gmpc_plugin_browser_selected(plugins
[plugin_get_pos(type
)], container
);
227 * update old value, so get_selected_category is correct before calling selection_changed
235 gmpc_plugin_browser_unselected(plugins
[plugin_get_pos(old_type
)], container
);
238 gtk_tree_model_get_iter_first(model
, &iter
);
239 gtk_tree_selection_select_iter(selec
, &iter
);
241 pl3_option_menu_activate();
245 /* handle right mouse clicks on the cat tree view */
246 /* gonna be a big function*/
247 int pl3_cat_tree_button_press_event(GtkTreeView
* tree
, GdkEventButton
* event
)
249 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(tree
);
250 if (event
->button
!= 3 || gtk_tree_selection_count_selected_rows(sel
) < 2 || !mpd_check_connected(connection
))
259 void pl3_option_menu_activate(void)
262 GtkWidget
*tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
264 gint type
= pl3_cat_get_selected_browser();
266 GdkEventButton
*event
= NULL
;
267 GtkWidget
*menu
= NULL
;
268 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
269 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_option"));
271 //gtk_menu_item_set_submenu(m_item, NULL);
273 if (!mpd_check_connected(connection
) || type
== -1)
276 menu
= gtk_menu_new();
278 for (i
= 0; i
< num_plugins
; i
++)
280 if (gmpc_plugin_is_browser(plugins
[i
]))
282 menu_items
+= gmpc_plugin_browser_cat_right_mouse_menu(plugins
[i
], menu
, type
, tree
, event
);
287 gtk_widget_show_all(menu
);
288 gtk_menu_item_set_submenu(m_item
, menu
);
289 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")), TRUE
);
292 g_object_ref_sink(menu
);
293 g_object_unref(menu
);
294 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")), FALSE
);
300 int pl3_cat_tree_button_release_event(GtkTreeView
* tree
, GdkEventButton
* event
)
303 gint type
= pl3_cat_get_selected_browser();
305 GtkWidget
*menu
= NULL
;
307 if (type
== -1 || !mpd_check_connected(connection
) || event
->button
!= 3)
309 /* no selections, or no usefull one.. so propagate the signal */
313 menu
= gtk_menu_new();
315 for (i
= 0; i
< num_plugins
; i
++)
317 if (gmpc_plugin_is_browser(plugins
[i
]))
319 menu_items
+= gmpc_plugin_browser_cat_right_mouse_menu(plugins
[i
], menu
, type
, GTK_WIDGET(tree
), event
);
325 gtk_widget_show_all(menu
);
326 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
, NULL
, NULL
,
327 /*event->button */ 0, event
->time
);
330 g_object_ref_sink(menu
);
331 g_object_unref(menu
);
336 void pl3_sidebar_plugins_init(void)
339 for (i
= 0; i
< num_plugins
; i
++)
341 // This is implicitely done inside sidebar_init
342 // if (gmpc_plugin_is_sidebar(plugins[i]))
344 gmpc_plugin_sidebar_init(plugins
[i
]);
349 /**********************************************************
352 static GtkWidget
*control_window
= NULL
;
353 static gboolean
pl3_win_state_event(GtkWidget
* window
, GdkEventWindowState
* event
, gpointer data
)
355 GtkWidget
*vbox1
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox1"));
356 GtkWidget
*p
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "alignment1"));
357 GtkWidget
*h
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox1"));
358 GtkWidget
*b
= (GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "menubartest")));
359 if (((event
->new_window_state
) & GDK_WINDOW_STATE_FULLSCREEN
))
361 if(control_window
== NULL
) {
362 control_window
= create_control_window(window
);
363 gtk_box_pack_start(GTK_BOX(vbox1
), control_window
, FALSE
, FALSE
, 0);
365 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "sidebar")));
369 } else if ((event
->changed_mask
) & GDK_WINDOW_STATE_FULLSCREEN
)
371 control_window_destroy(control_window
);
372 control_window
= NULL
;
373 playlist_zoom_level_changed();
382 * This avoids the 'keybinding help' to become sticky when moving the window, or chainging
383 * focus to other window.
385 gboolean
pl3_window_focus_out_event(GtkWidget
*window
, GdkEventFocus
*event
, gpointer data
)
391 gboolean
pl3_window_is_fullscreen(void)
393 GtkWidget
*win
= playlist3_get_window();
394 GdkWindowState state
= 0;
395 if (gtk_widget_get_window(win
))
396 state
= gdk_window_get_state(gtk_widget_get_window(win
));
397 return (state
& GDK_WINDOW_STATE_FULLSCREEN
) ? TRUE
: FALSE
;
401 gboolean
pl3_window_fullscreen(void)
403 GtkWidget
*win
= playlist3_get_window();
405 if (pl3_zoom
< PLAYLIST_MINI
)
407 if (pl3_window_is_fullscreen())
409 gtk_window_unfullscreen(GTK_WINDOW(win
));
412 gtk_window_fullscreen(GTK_WINDOW(win
));
419 int pl3_window_key_release_event(GtkWidget
* mw
, GdkEventKey
* event
)
423 int pl3_window_key_press_event(GtkWidget
* mw
, GdkEventKey
* event
)
426 gint type
= pl3_cat_get_selected_browser();
428 * Following key's are only valid when connected
430 if (!mpd_check_connected(connection
))
434 for (i
= 0; i
< num_plugins
; i
++)
436 if (gmpc_plugin_is_browser(plugins
[i
]))
438 gmpc_plugin_browser_key_press_event(plugins
[i
], mw
, event
, type
);
441 if(event
->keyval
== GDK_KEY_colon
)
446 if((event
->state
&GDK_MOD1_MASK
) > 0)
448 guint kev
= event
->keyval
;
449 if(kev
>= GDK_KEY_0
&& kev
<= GDK_KEY_9
)
454 if (gtk_tree_model_get_iter_first(pl3_tree
, &iter
))
456 if(kev
== 0) kev
+=10;
459 gtk_tree_model_get(pl3_tree
, &iter
, PL3_CAT_TYPE
, &new_type
, -1);
460 if(new_type
>= 0) i_index
++;
461 if(i_index
== kev
&& new_type
>= 0)
463 GtkWidget
*cat_tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
464 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(cat_tree
));
466 // if this is allready selected, do +10. this allows us to go up to 20 browsers.
467 if(new_type
== old_type
&& gtk_tree_selection_iter_is_selected(select
, &iter
)) {
470 gtk_tree_selection_select_iter(select
, &iter
);
474 }while(gtk_tree_model_iter_next(pl3_tree
, &iter
));
479 /* don't propagate */
484 * Close the playlist and save position/size
486 gboolean
pl3_close(void)
488 /* only save when window is PLAYLIST_SMALL or NO ZOOM */
491 GtkWidget
*window
= playlist3_get_window();
492 int maximized
= FALSE
;
493 if (gtk_widget_get_window(window
))
495 GdkWindowState state
= gdk_window_get_state(gtk_widget_get_window(window
));
496 maximized
= ((state
& GDK_WINDOW_STATE_MAXIMIZED
) > 0);
498 cfg_set_single_value_as_int(config
, "playlist", "maximized", maximized
);
500 gtk_window_get_position(GTK_WINDOW(window
), &pl3_wsize
.x
, &pl3_wsize
.y
);
502 cfg_set_single_value_as_int(config
, "playlist", "xpos", pl3_wsize
.x
);
503 cfg_set_single_value_as_int(config
, "playlist", "ypos", pl3_wsize
.y
);
505 if (pl3_zoom
<= PLAYLIST_SMALL
)
507 gtk_window_get_size(GTK_WINDOW(window
), &pl3_wsize
.width
, &pl3_wsize
.height
);
508 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "pl3_close: save size: %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
509 cfg_set_single_value_as_int(config
, "playlist", "width", pl3_wsize
.width
);
510 cfg_set_single_value_as_int(config
, "playlist", "height", pl3_wsize
.height
);
514 if (cfg_get_single_value_as_int_with_default(config
, "playlist", "hide-on-close", FALSE
))
516 if (tray_icon2_get_available())
521 gtk_window_iconify(GTK_WINDOW(playlist3_get_window()));
535 * Before hiding save current size and position
539 GtkWidget
*pl3_win
= playlist3_get_window();
540 if (!tray_icon2_get_available())
542 gtk_window_iconify(GTK_WINDOW(pl3_win
));
545 if (pl3_xml
!= NULL
&& !pl3_hidden
)
547 GtkWidget
*window
= playlist3_get_window();
548 int maximized
= FALSE
;
549 if (gtk_widget_get_window(window
))
551 GdkWindowState state
= gdk_window_get_state(gtk_widget_get_window(window
));
552 maximized
= ((state
& GDK_WINDOW_STATE_MAXIMIZED
) > 0);
554 cfg_set_single_value_as_int(config
, "playlist", "maximized", maximized
);
557 gtk_window_get_position(GTK_WINDOW(pl3_win
), &pl3_wsize
.x
, &pl3_wsize
.y
);
558 cfg_set_single_value_as_int(config
, "playlist", "xpos", pl3_wsize
.x
);
559 cfg_set_single_value_as_int(config
, "playlist", "ypos", pl3_wsize
.y
);
560 /* save size, only when in SMALL or no zoom mode
562 if (pl3_zoom
<= PLAYLIST_SMALL
)
564 gtk_window_get_size(GTK_WINDOW(pl3_win
), &pl3_wsize
.width
, &pl3_wsize
.height
);
565 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "pl3_hide: save size: %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
566 cfg_set_single_value_as_int(config
, "playlist", "width", pl3_wsize
.width
);
567 cfg_set_single_value_as_int(config
, "playlist", "height", pl3_wsize
.height
);
569 gtk_widget_hide(pl3_win
);
572 #ifdef HAVE_APP_INDICATOR
573 tray_icon2_update_menu();
579 /* create the playlist view
580 * This is done only once, for the rest its hidden, but still there
582 void pl3_show_and_position_window(void)
587 pl3_win
= playlist3_get_window();
588 if (pl3_wsize
.x
> 0 || pl3_wsize
.y
> 0)
590 gtk_window_move(GTK_WINDOW(pl3_win
), pl3_wsize
.x
, pl3_wsize
.y
);
592 if (pl3_wsize
.height
> 0 && pl3_wsize
.width
> 0)
594 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "restore size %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
595 gtk_window_resize(GTK_WINDOW(pl3_win
), pl3_wsize
.width
, pl3_wsize
.height
);
597 gtk_widget_show(pl3_win
);
598 gtk_window_present(GTK_WINDOW(pl3_win
));
603 gboolean
playlist3_window_is_hidden(void)
609 void pl3_toggle_hidden(void)
621 static void playlist3_source_drag_data_recieved(GtkWidget
* widget
,
622 GdkDragContext
* context
,
624 gint y
, GtkSelectionData
* data
, guint info
, guint time_recieved
)
629 const guchar
*url_data
= gtk_selection_data_get_data(data
);
634 gchar
**url
= g_uri_list_extract_uris(url_data
);
635 for (i
= 0; url
&& url
[i
]; i
++)
637 gchar
*scheme
= g_uri_parse_scheme(url
[i
]);
638 /* Don't add lines withouth an actual scheme. */
641 gchar
*fu
= g_uri_unescape_string(url
[i
], NULL
);
651 gtk_drag_finish(context
, found
, FALSE
, time_recieved
);
657 guchar
*odata
= gtk_selection_data_get_text(data
);
658 stripped
= g_strsplit((gchar
*) odata
, "\n", 0);
660 if (gdk_drag_context_get_actions(context
)== GDK_ACTION_MOVE
)
662 mpd_playlist_clear(connection
);
664 mpd_database_search_start(connection
, TRUE
);
665 for (i
= 0; stripped
&& stripped
[i
]; i
++)
667 gchar
**request
= g_strsplit(stripped
[i
], ":", 2);
668 mpd_database_search_add_constraint(connection
, mpd_misc_get_tag_by_name(request
[0]), request
[1]);
671 mdata
= mpd_database_search_commit(connection
);
672 for (; mdata
; mdata
= mpd_data_get_next(mdata
))
674 mpd_playlist_queue_add(connection
, mdata
->song
->file
);
676 mpd_playlist_queue_commit(connection
);
677 if (gdk_drag_context_get_actions(context
)== GDK_ACTION_MOVE
)
679 mpd_player_play(connection
);
682 g_strfreev(stripped
);
683 gtk_drag_finish(context
, TRUE
, FALSE
, time_recieved
);
691 void pl3_pb_seek_event(GtkWidget
* pb
, guint seek_time
, gpointer user_data
)
693 mpd_player_seek(connection
, (int)seek_time
);
698 static void about_dialog_activate(GtkWidget
* dialog
, const gchar
* uri
, gpointer data
)
705 * Handle a connect/Disconnect
707 static void playlist_connection_changed(MpdObj
* mi
, int connect
, gpointer data
)
709 GtkWidget
*pl3_win
= playlist3_get_window();
714 gboolean found
= FALSE
;
715 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player")), TRUE
);
716 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hpaned1-hbox")), TRUE
);
718 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDConnect")), FALSE
);
719 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDDisconnect")), TRUE
);
720 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPassword")), TRUE
);
721 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_view")), TRUE
);
722 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")), TRUE
);
724 /* Check if MPD supports 'file://' (so local files). */
725 /* TODO: make this a separate function */
726 handlers
= mpd_server_get_url_handlers(connection
);
730 for(; !found
&& handlers
!= NULL
&& handlers
[i
] != NULL
; i
++) {
731 if(g_utf8_collate(handlers
[i
], "file://") == 0) {
735 g_strfreev(handlers
);
737 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "open_local_file")), found
);
740 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player")), FALSE
);
741 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hpaned1-hbox")), FALSE
);
743 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDConnect")), TRUE
);
744 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDDisconnect")), FALSE
);
745 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPassword")), FALSE
);
746 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_view")), FALSE
);
747 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")), FALSE
);
748 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "open_local_file")), FALSE
);
750 /** Set back to the current borwser, and update window title */
753 gchar
*string
= NULL
;
755 GtkTreeSelection
*selec
= gtk_tree_view_get_selection((GtkTreeView
*) gtk_builder_get_object(pl3_xml
,
757 GtkTreeModel
*model
= GTK_TREE_MODEL(pl3_tree
);
758 if (gtk_tree_model_get_iter_first(model
, &iter
))
760 gtk_tree_selection_select_iter(selec
, &iter
);
762 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
764 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
768 g_strdup_printf("[%s] %s - %s %s", gmpc_profiles_get_name(gmpc_profiles
, id
), _("GMPC"),
769 _("Connected to"), mpd_get_hostname(mi
));
774 string
= g_strdup_printf("%s - %s %s", _("GMPC"), _("Connected to"), mpd_get_hostname(mi
));
775 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
779 gchar
*string
= NULL
;
781 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
783 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
787 g_strdup_printf("[%s] %s - %s", gmpc_profiles_get_name(gmpc_profiles
, id
), _("GMPC"),
793 string
= g_strdup_printf("%s - %s", _("GMPC"), _("Disconnected"));
794 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
799 * make the playlist update itself
801 playlist_status_changed(connection
,
802 MPD_CST_STATE
| MPD_CST_SONGID
| MPD_CST_NEXTSONG
|
803 MPD_CST_ELAPSED_TIME
| MPD_CST_VOLUME
|
804 MPD_CST_REPEAT
| MPD_CST_RANDOM
| MPD_CST_PERMISSION
805 | MPD_CST_SINGLE_MODE
| MPD_CST_CONSUME_MODE
| MPD_CST_UPDATING
, NULL
);
810 pl3_option_menu_activate();
811 pl3_tool_menu_update();
813 playlist3_fill_server_menu();
817 * items that are caused by the plugin.
819 pl3_update_go_menu();
823 void pl3_style_set_event( GtkWidget
*widget
,
824 GtkStyle
*previous_style
,
827 if (cfg_get_single_value_as_int_with_default(config
, "Default", "use-dark-style-header", TRUE
))
829 gtk_rc_parse_string("widget \"*header*\" style \"dark\"");
832 static gboolean
pl3_cat_select_function(GtkTreeSelection
*select
, GtkTreeModel
*model
, GtkTreePath
*path
, gboolean cur_select
, gpointer data
)
835 if(gtk_tree_model_get_iter(model
, &iter
, path
))
838 gtk_tree_model_get(model
, &iter
, PL3_CAT_TYPE
, &type
, -1);
839 if(type
>= 0) return TRUE
;
844 void create_playlist3(void)
847 GtkCellRenderer
*renderer
;
849 GtkTreeSelection
*sel
;
850 GtkTreeViewColumn
*column
= NULL
;
853 GError
*error
= NULL
;
855 /* indicate that the playlist is not hidden */
859 * If the playlist already exists,
860 * It is probably coming from a hidden state,
861 * so re-position the window
865 pl3_show_and_position_window();
873 /** Ambiance / Radiance theme "dark" header */
874 if (cfg_get_single_value_as_int_with_default(config
, "Default", "use-dark-style-header", TRUE
))
876 gtk_rc_parse_string("widget \"*header*\" style \"dark\"");
879 /** use background color for the sidebar treeview cells */
880 gtk_rc_parse_string (
881 "style \"sidebar-treeview\"\n"
883 " GtkTreeView::odd-row-color = @bg_color\n"
884 " GtkTreeView::even-row-color = @bg_color\n"
886 "widget \"*.sidebar.*\" style \"sidebar-treeview\"");
889 gtk_rc_parse_string (
890 "style \"menubar-style\"\n"
892 " GtkMenuBar::shadow-type = none\n"
894 "widget \"*.menubar\" style \"menubar-style\"\n");
896 /* initial, setting the url hook */
898 // gtk_about_dialog_set_url_hook((GtkAboutDialogActivateLinkFunc) about_dialog_activate, NULL, NULL);
899 TEC("Setup dialog url hook")
900 /* load gui desciption */
901 path
= gmpc_get_full_glade_path("playlist3.ui");
903 pl3_xml
= gtk_builder_new();
904 TEC("create builder")
905 if(gtk_builder_add_from_file(pl3_xml
, path
,&error
) == 0)
908 * Check if the file is loaded, if not then show an error message and abort the program
912 g_log(LOG_DOMAIN
, G_LOG_LEVEL_WARNING
, "Failed to open playlist3.glade: %s\n", error
->message
);
920 GtkWidget
*widget
= (GtkWidget
*)gtk_builder_get_object(pl3_xml
, "cat_tree");
921 GtkStyleContext
*ct
= gtk_widget_get_style_context(widget
);
922 gtk_style_context_add_class(ct
, GTK_STYLE_CLASS_SIDEBAR
);
924 TEC("Load builder file")
926 /* create tree store for the "category" view */
927 if (pl3_tree
== NULL
)
931 G_TYPE_INT
, /* row type, see free_type struct */
932 G_TYPE_STRING
, /* display name */
933 G_TYPE_STRING
, /* full path and stuff for backend */
934 G_TYPE_STRING
, /* icon id */
935 G_TYPE_INT
, /* ordering */
936 G_TYPE_INT
, /* Bold */
937 G_TYPE_STRING
, /* stock id */
938 G_TYPE_BOOLEAN
/* Show text */
940 /* song id, song title */
941 pl3_tree
= (GtkTreeModel
*) gmpc_tools_liststore_sort_new();
942 gtk_list_store_set_column_types(GTK_LIST_STORE(pl3_tree
), PL3_CAT_NROWS
, types
);
944 TEC("Setup pl3_tree")
946 tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
947 gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
)),
948 pl3_cat_select_function
, pl3_tree
, NULL
);
950 gtk_tree_view_set_model(GTK_TREE_VIEW(tree
), GTK_TREE_MODEL(pl3_tree
));
951 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
952 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(sel
), GTK_SELECTION_BROWSE
);
953 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(tree
), TRUE
);
954 // Enable tooltip on the treeview.
955 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(tree
), PL3_CAT_TITLE
);
957 sidebar_text
= renderer
= GTK_CELL_RENDERER(my_cell_renderer_new());
958 g_object_set(G_OBJECT(renderer
), "xalign", 0.5,NULL
);
959 column
= gtk_tree_view_column_new();
960 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column
),GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
962 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
963 g_object_set(G_OBJECT(renderer
), "stock-size", GTK_ICON_SIZE_MENU
, NULL
);
966 if (gtk_icon_size_lookup(GTK_ICON_SIZE_MENU
, &w
, &h
))
968 g_object_set(G_OBJECT(renderer
), "height", h
+10, NULL
);
969 g_object_set(G_OBJECT(renderer
), "image-width", w
,NULL
);
972 gtk_tree_view_column_set_attributes(column
, renderer
,
973 "icon-name", PL3_CAT_ICON_ID
,
974 "stock-id", PL3_CAT_STOCK_ID
,
975 "text", PL3_CAT_TITLE
,
976 "weight", PL3_CAT_BOLD
,
977 "show_text", PL3_CAT_SHOW_TEXT
, NULL
);
978 g_object_set(renderer
, "weight-set", TRUE
, NULL
);
980 gtk_tree_view_append_column(GTK_TREE_VIEW(tree
), column
);
981 gtk_tree_view_set_search_column(GTK_TREE_VIEW(tree
), PL3_CAT_TITLE
);
982 g_signal_connect_after(G_OBJECT(sel
), "changed", G_CALLBACK(pl3_cat_sel_changed
), NULL
);
984 TEC("setup cat_tree");
986 /* initialize the category view */
987 pl3_initialize_tree();
989 TEC("Init category tree")
990 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player")));
993 * The new progress bar
995 pb
= (GtkWidget
*) gtk_builder_get_object(pl3_xml
, "hbox_progress");
997 g_signal_connect(G_OBJECT(pb
), "seek-event", G_CALLBACK(pl3_pb_seek_event
), NULL
);
1001 TEC("Init progress bar")
1002 /* Make sure change is applied */
1004 playlist3_new_header();
1006 pl3_sidebar_plugins_init();
1009 if (!cfg_get_single_value_as_int_with_default(config
, "Interface", "hide-favorites-icon", FALSE
))
1011 favorites_button
= gmpc_favorites_button_new();
1012 ali
= gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
1013 gtk_container_add(GTK_CONTAINER(ali
), GTK_WIDGET(favorites_button
));
1014 gtk_box_pack_start(GTK_BOX(gtk_builder_get_object(pl3_xml
, "hbox10")), GTK_WIDGET(ali
), FALSE
, FALSE
, 0);
1015 gtk_widget_show_all(GTK_WIDGET(ali
));
1016 TEC("Init fav icon")
1018 playlist_status_changed(connection
,
1019 MPD_CST_STATE
| MPD_CST_SONGID
| MPD_CST_NEXTSONG
|
1020 MPD_CST_ELAPSED_TIME
| MPD_CST_VOLUME
|
1021 MPD_CST_REPEAT
| MPD_CST_RANDOM
| MPD_CST_PERMISSION
1022 | MPD_CST_SINGLE_MODE
| MPD_CST_CONSUME_MODE
, NULL
);
1023 g_signal_connect(G_OBJECT(gtk_builder_get_object(pl3_xml
, "volume_button")),
1024 "value_changed", G_CALLBACK(playlist_player_volume_changed
), NULL
);
1028 /* Restore values from config */
1029 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION
1030 (gtk_builder_get_object
1031 (pl3_xml
, "ViewShowArtistImage")),
1032 cfg_get_single_value_as_int_with_default
1033 (config
, "playlist", "cover-image-enable", 0));
1035 /* connect signals that are defined in the gui description */
1036 gtk_builder_connect_signals(pl3_xml
,NULL
);
1038 TEC("connect signals")
1040 /* select the current playlist */
1041 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pl3_tree
), &iter
))
1043 gtk_tree_selection_select_iter(sel
, &iter
);
1048 * Insert new custom widget
1050 metaimage_album_art
= gmpc_metaimage_new(META_ALBUM_ART
);
1052 /* Hide when requested. */
1053 if (cfg_get_single_value_as_int_with_default(config
, "Interface", "hide-album-art", FALSE
))
1055 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_album_art
), FALSE
);
1057 gtk_box_pack_start(GTK_BOX
1058 (gtk_builder_get_object(pl3_xml
, "hbox_playlist_player")), metaimage_album_art
, FALSE
, TRUE
, 0);
1060 gtk_box_reorder_child(GTK_BOX
1061 (gtk_builder_get_object(pl3_xml
, "hbox_playlist_player")), metaimage_album_art
, 0);
1062 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_album_art
), ALBUM_SIZE
);
1063 gmpc_metaimage_set_no_cover_icon(GMPC_METAIMAGE(metaimage_album_art
), (char *)"gmpc");
1064 gmpc_metaimage_set_connection(GMPC_METAIMAGE(metaimage_album_art
), connection
);
1065 /** make sure size is updated */
1066 gmpc_metaimage_set_cover_na(GMPC_METAIMAGE(metaimage_album_art
));
1068 metaimage_artist_art
= gmpc_metaimage_new(META_ARTIST_ART
);
1069 gtk_container_add(GTK_CONTAINER(gtk_builder_get_object(pl3_xml
, "sidebar_artist_image_alignment")), metaimage_artist_art
);
1071 gmpc_metaimage_set_no_cover_icon(GMPC_METAIMAGE(metaimage_artist_art
), (char *)"no-artist");
1072 gmpc_metaimage_set_loading_cover_icon(GMPC_METAIMAGE(metaimage_artist_art
), (char *)"fetching-artist");
1073 gmpc_metaimage_set_connection(GMPC_METAIMAGE(metaimage_artist_art
), connection
);
1074 if (!cfg_get_single_value_as_int_with_default(config
, "playlist", "cover-image-enable", FALSE
))
1076 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art
), FALSE
);
1078 gmpc_metaimage_set_squared(GMPC_METAIMAGE(metaimage_artist_art
), FALSE
);
1079 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_artist_art
), 145);
1081 TEC("Setup metaimages")
1082 /* restore the window's position and size, if the user wants this. */
1083 if (cfg_get_single_value_as_int_with_default(config
, "playlist", "savepossize", 1))
1085 int maximized
= cfg_get_single_value_as_int_with_default(config
, "playlist", "maximized", 0);
1086 /* Load values from config file */
1087 pl3_wsize
.x
= cfg_get_single_value_as_int_with_default(config
, "playlist", "xpos", 0);
1088 pl3_wsize
.y
= cfg_get_single_value_as_int_with_default(config
, "playlist", "ypos", 0);
1089 pl3_wsize
.width
= cfg_get_single_value_as_int_with_default(config
, "playlist", "width", 0);
1090 pl3_wsize
.height
= cfg_get_single_value_as_int_with_default(config
, "playlist", "height", 0);
1092 /* restore location + position */
1093 /*pl3_show_and_position_window(); */
1095 if (pl3_wsize
.x
> 0 || pl3_wsize
.y
> 0)
1097 gtk_window_move(GTK_WINDOW(playlist3_get_window()), pl3_wsize
.x
, pl3_wsize
.y
);
1099 TEC("move window settings")
1100 if (pl3_wsize
.height
> 0 && pl3_wsize
.width
> 0)
1102 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "restore size %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
1103 gtk_window_resize(GTK_WINDOW(playlist3_get_window()), pl3_wsize
.width
, pl3_wsize
.height
);
1105 TEC("set pane window settings")
1107 gtk_window_maximize(GTK_WINDOW(playlist3_get_window()));
1108 TEC("maximize pane window settings")
1110 * restore zoom level
1113 gtk_widget_show(playlist3_get_window());
1115 pl3_zoom
= cfg_get_single_value_as_int_with_default(config
, "playlist", "zoomlevel", PLAYLIST_NO_ZOOM
);
1116 playlist_zoom_level_changed();
1119 #ifdef HAVE_APP_INDICATOR
1120 tray_icon2_update_menu();
1123 TEC("Restore state")
1124 pl3_update_go_menu();
1126 /* make it update itself */
1127 pl3_update_profiles_menu(gmpc_profiles
, GMPC_PROFILES_ACTION_ADDED
, -1, NULL
);
1128 g_signal_connect(G_OBJECT(gmpc_profiles
), "changed", G_CALLBACK(pl3_update_profiles_menu
), NULL
);
1129 g_signal_connect(G_OBJECT(gmpc_profiles
), "changed", G_CALLBACK(pl3_profiles_changed
), NULL
);
1131 TEC("Update profiles")
1133 * Set as drag destination
1135 gtk_drag_dest_set(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox_playlist_player")),
1136 GTK_DEST_DEFAULT_ALL
,
1137 target_table
, 6, GDK_ACTION_COPY
| GDK_ACTION_LINK
| GDK_ACTION_DEFAULT
| GDK_ACTION_MOVE
);
1138 g_signal_connect(G_OBJECT
1139 (gtk_builder_get_object(pl3_xml
, "hbox_playlist_player")),
1140 "drag_data_received", G_CALLBACK (playlist3_source_drag_data_recieved
), NULL
);
1146 playlist_connection_changed(connection
, FALSE
, NULL
);
1148 g_signal_connect(G_OBJECT(playlist3_get_window()), "window-state-event", G_CALLBACK(pl3_win_state_event
), NULL
);
1150 TEC("signal connn changed")
1152 g_signal_connect(G_OBJECT(playlist3_get_window()), "style-set", G_CALLBACK(pl3_style_set_event
), NULL
);
1157 main_window_init_default_status_icons();
1158 main_window_update_status_icons();
1160 TEC("Update status icon")
1162 init_extra_playlist_state();
1163 TEC("Setup extra playlist")
1165 // Add window to GtkApplication.
1166 gtk_application_add_window(gmpc_application
, playlist3_get_window());
1173 GtkListStore
*playlist3_get_category_tree_store(void)
1175 if (pl3_xml
== NULL
)
1177 return GTK_LIST_STORE(pl3_tree
);
1181 GtkTreeView
*playlist3_get_category_tree_view(void)
1183 if (pl3_xml
== NULL
)
1185 return (GtkTreeView
*) gtk_builder_get_object(pl3_xml
, "cat_tree");
1188 GtkWidget
* playlist3_get_widget_by_id(const char *id
) {
1189 return (GtkWidget
*) gtk_builder_get_object(pl3_xml
, id
);
1193 /****************************************************************************************
1195 ****************************************************************************************/
1196 /* prototyping for glade */
1197 void ck_stop_on_exit_toggled_cb(GtkToggleButton
* but
, gpointer data
);
1198 void ck_show_tooltip_enable_tb(GtkToggleButton
* but
);
1200 G_MODULE_EXPORT
void show_cover_case_tb(GtkToggleButton
* but
)
1202 int bool1
= gtk_toggle_button_get_active(but
);
1203 cfg_set_single_value_as_int(config
, "metaimage", "addcase", bool1
);
1204 pixbuf_cache_clear();
1205 gmpc_meta_watcher_force_reload_cb(gmw
);
1209 G_MODULE_EXPORT
void ck_stop_on_exit_toggled_cb(GtkToggleButton
* but
, gpointer data
)
1211 int bool1
= gtk_toggle_button_get_active(but
);
1212 cfg_set_single_value_as_int(config
, "connection", "stop-on-exit", bool1
);
1216 G_MODULE_EXPORT
void hide_on_close_enable_tb(GtkToggleButton
* but
)
1218 int bool1
= gtk_toggle_button_get_active(but
);
1219 cfg_set_single_value_as_int(config
, "playlist", "hide-on-close", bool1
);
1223 G_MODULE_EXPORT
void cur_song_center_enable_tb(GtkToggleButton
* but
)
1225 int bool1
= gtk_toggle_button_get_active(but
);
1226 cfg_set_single_value_as_int(config
, "playlist", "st_cur_song", bool1
);
1230 G_MODULE_EXPORT
void save_possize_enable_tb(GtkToggleButton
* but
)
1232 int bool1
= gtk_toggle_button_get_active(but
);
1233 cfg_set_single_value_as_int(config
, "playlist", "savepossize", bool1
);
1237 G_MODULE_EXPORT
void ck_show_tooltip_enable_tb(GtkToggleButton
* but
)
1239 int bool1
= gtk_toggle_button_get_active(but
);
1240 cfg_set_single_value_as_int(config
, "GmpcTreeView", "show-tooltip", bool1
);
1244 G_MODULE_EXPORT
void ck_search_as_you_type(GtkToggleButton
* but
)
1246 int bool1
= gtk_toggle_button_get_active(but
);
1247 cfg_set_single_value_as_int(config
, "general", "search-as-you-type", bool1
);
1251 static void playlist_pref_destroy(GtkWidget
* container
)
1253 if (playlist_pref_xml
)
1255 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(playlist_pref_xml
,
1257 gtk_container_remove(GTK_CONTAINER(container
), vbox
);
1258 g_object_unref(playlist_pref_xml
);
1259 playlist_pref_xml
= NULL
;
1264 void playlist_pref_construct(GtkWidget
* container
)
1266 GError
*error
= NULL
;
1267 gchar
*path
= gmpc_get_full_glade_path("preferences-playlist.ui");
1268 playlist_pref_xml
= gtk_builder_new();
1270 gtk_builder_add_from_file(playlist_pref_xml
, path
, &error
);
1272 g_warning("Failed to open builder file: %s", error
->message
);
1273 g_error_free(error
);
1276 if (playlist_pref_xml
)
1278 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(playlist_pref_xml
,
1280 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1281 (gtk_builder_get_object
1282 (playlist_pref_xml
, "ck_ps")),
1283 cfg_get_single_value_as_int_with_default(config
, "playlist", "st_cur_song", 0));
1284 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1285 (gtk_builder_get_object
1286 (playlist_pref_xml
, "ck_possize")),
1287 cfg_get_single_value_as_int_with_default(config
, "playlist", "savepossize", 1));
1288 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1289 (gtk_builder_get_object
1290 (playlist_pref_xml
, "ck_hide_on_close")),
1291 cfg_get_single_value_as_int_with_default(config
, "playlist", "hide-on-close", 0));
1293 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1294 (gtk_builder_get_object
1295 (playlist_pref_xml
, "ck_stop_on_exit")),
1296 cfg_get_single_value_as_int_with_default(config
, "connection", "stop-on-exit", 0));
1298 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1299 (gtk_builder_get_object
1300 (playlist_pref_xml
, "ck_cover_case")),
1301 cfg_get_single_value_as_int_with_default(config
, "metaimage", "addcase", TRUE
));
1303 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1304 (gtk_builder_get_object
1305 (playlist_pref_xml
, "ck_show_tooltip")),
1306 cfg_get_single_value_as_int_with_default
1307 (config
, "GmpcTreeView", "show-tooltip", TRUE
));
1309 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1310 (gtk_builder_get_object
1311 (playlist_pref_xml
, "ck_search_as_you_type")),
1312 cfg_get_single_value_as_int_with_default(config
, "general", "search-as-you-type",
1314 gtk_container_add(GTK_CONTAINER(container
), vbox
);
1315 gtk_widget_show_all(vbox
);
1316 gtk_builder_connect_signals(playlist_pref_xml
, NULL
);
1323 * Menu Callback functions
1326 void playlist_menu_repeat_changed(GtkToggleAction
* action
)
1328 int active
= gtk_toggle_action_get_active(action
);
1329 if (active
!= mpd_player_get_repeat(connection
))
1331 mpd_player_set_repeat(connection
, active
);
1336 void playlist_menu_random_changed(GtkToggleAction
*action
)
1338 int active
= gtk_toggle_action_get_active(action
);
1339 if (active
!= mpd_player_get_random(connection
))
1341 mpd_player_set_random(connection
, active
);
1346 void playlist_menu_single_mode_changed(GtkToggleAction
* action
)
1348 int active
= gtk_toggle_action_get_active(action
);
1349 if (active
!= mpd_player_get_single(connection
))
1351 mpd_player_set_single(connection
, active
);
1356 void playlist_menu_consume_changed(GtkToggleAction
* action
)
1358 int active
= gtk_toggle_action_get_active(action
);
1359 if (active
!= mpd_player_get_consume(connection
))
1361 mpd_player_set_consume(connection
, active
);
1367 * This is artist image
1370 void playlist_menu_artist_image_changed(GtkToggleAction
*ta
)
1372 int active
= gtk_toggle_action_get_active(ta
);
1373 cfg_set_single_value_as_int(config
, "playlist", "cover-image-enable", active
);
1374 if(pl3_zoom
< PLAYLIST_SMALL
)
1376 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art
), active
);
1378 gtk_widget_show(metaimage_artist_art
);
1386 void playlist_zoom_out(void)
1388 /* Do not change zoom level when fullscreen */
1389 if(pl3_window_is_fullscreen())
1391 if ((pl3_zoom
+ 1) >= PLAYLIST_ZOOM_LEVELS
)
1393 pl3_old_zoom
= pl3_zoom
;
1395 playlist_zoom_level_changed();
1399 void playlist_zoom_in(void)
1401 /* Do not change zoom level when fullscreen */
1402 if(pl3_window_is_fullscreen())
1404 if (pl3_zoom
<= PLAYLIST_NO_ZOOM
)
1406 pl3_old_zoom
= pl3_zoom
;
1408 playlist_zoom_level_changed();
1410 static void update_show_text(gboolean state
)
1412 GtkTreeView
*tree
= (GtkTreeView
*) gtk_builder_get_object(pl3_xml
, "cat_tree");
1413 GtkTreeModel
*model
= gtk_tree_view_get_model(tree
);
1415 if(gtk_tree_model_get_iter_first(model
, &iter
))
1418 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, PL3_CAT_SHOW_TEXT
, state
, -1);
1419 }while(gtk_tree_model_iter_next(model
, &iter
));
1424 * FIXME: Needs propper grouping and cleaning up
1426 static void playlist_zoom_level_changed(void)
1429 GtkWidget
*pl3_win
= playlist3_get_window();
1430 printf("playlist3 zoom level changed\n");
1432 if (pl3_old_zoom
<= PLAYLIST_SMALL
)
1434 gtk_window_get_size(GTK_WINDOW(pl3_win
), &pl3_wsize
.width
, &pl3_wsize
.height
);
1435 cfg_set_single_value_as_int(config
, "playlist", "width", pl3_wsize
.width
);
1436 cfg_set_single_value_as_int(config
, "playlist", "height", pl3_wsize
.height
);
1437 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "save size: %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
1440 if (pl3_old_zoom
== PLAYLIST_MINI
&& pl3_zoom
!= PLAYLIST_MINI
)
1442 GtkWidget
*box
=GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_button_control_box"));
1443 GtkWidget
*top
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox10"));
1444 GtkWidget
*vtop
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player"));
1445 /* add my own reference */
1447 gtk_container_remove(GTK_CONTAINER(vtop
), box
);
1448 gtk_box_pack_end(GTK_BOX(top
), box
, FALSE
, TRUE
, 0);
1449 gtk_box_reorder_child(GTK_BOX(top
), box
, 0);
1450 /* release my reference */
1451 g_object_unref(box
);
1452 gtk_widget_show(box
);
1453 gmpc_progress_set_hide_text(GMPC_PROGRESS(new_pb
), FALSE
);
1455 if (pl3_old_zoom
!= PLAYLIST_MINI
&& pl3_zoom
== PLAYLIST_MINI
)
1457 GtkWidget
*box
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_button_control_box"));
1458 GtkWidget
*top
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox10"));
1459 GtkWidget
*vtop
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player"));
1460 /* add my own reference */
1462 gtk_container_remove(GTK_CONTAINER(top
), box
);
1463 gtk_box_pack_end(GTK_BOX(vtop
), box
, FALSE
, TRUE
, 3);
1464 /* release my reference */
1465 g_object_unref(box
);
1466 gtk_widget_show(box
);
1468 gmpc_progress_set_hide_text(GMPC_PROGRESS(new_pb
), TRUE
);
1471 /* Show full view */
1472 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hpaned1-hbox")));
1473 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox1")));
1474 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox10")));
1477 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_button_control_box")));
1479 gtk_window_set_resizable(GTK_WINDOW(pl3_win
), TRUE
);
1480 if (pl3_wsize
.width
> 0 && pl3_wsize
.height
> 0 && pl3_old_zoom
== PLAYLIST_MINI
)
1482 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "restore size %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
1483 gtk_window_resize(GTK_WINDOW(pl3_win
), pl3_wsize
.width
, pl3_wsize
.height
);
1485 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "sidebar")));
1487 if (cfg_get_single_value_as_int_with_default(config
, "playlist", "cover-image-enable", FALSE
))
1489 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art
), TRUE
);
1490 gtk_widget_show(metaimage_artist_art
);
1492 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_go")),TRUE
);
1493 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")),TRUE
);
1495 update_show_text(TRUE
);
1496 gmpc_sidebar_plugins_update_state(GMPC_PLUGIN_SIDEBAR_STATE_FULL
);
1498 /* Now start hiding */
1501 case PLAYLIST_NO_ZOOM
:
1504 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hpaned1-hbox")));
1505 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")),FALSE
);
1506 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_go")),FALSE
);
1509 if (gdk_window_get_state(gtk_widget_get_window(pl3_win
)) & GDK_WINDOW_STATE_MAXIMIZED
)
1511 gtk_window_unmaximize(GTK_WINDOW(pl3_win
));
1514 if (gdk_window_get_state(gtk_widget_get_window(pl3_win
)) & GDK_WINDOW_STATE_FULLSCREEN
)
1516 gtk_window_unfullscreen(GTK_WINDOW(pl3_win
));
1519 gtk_window_set_resizable(GTK_WINDOW(pl3_win
), FALSE
);
1521 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "sidebar")));
1523 case PLAYLIST_SMALL
:
1524 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art
), FALSE
);
1525 update_show_text(FALSE
);
1526 gmpc_sidebar_plugins_update_state(GMPC_PLUGIN_SIDEBAR_STATE_COLLAPSED
);
1527 gtk_widget_grab_focus(pl3_win
);
1533 cfg_set_single_value_as_int(config
, "playlist", "zoomlevel", pl3_zoom
);
1538 * Update the window to status changes in mpd
1540 static void playlist_status_changed(MpdObj
* mi
, ChangedStatusType what
, void *userdata
)
1543 GtkWidget
*pl3_win
= playlist3_get_window();
1545 * if the window isn't there yet, return
1549 control_window_status_update(mi
, what
, control_window
);
1551 * Player state changed
1553 if (what
& MPD_CST_STATE
)
1555 mpd_Song
*song
= mpd_playlist_get_current_song(connection
);
1556 int state
= mpd_player_get_state(mi
);
1559 case MPD_PLAYER_PLAY
:
1561 gchar
*markup
= cfg_get_single_value_as_string_with_default(config
,
1562 "playlist", /* Category */
1563 "window-markup",/* Key */
1565 "[%title% - &[%artist%]]|%name%|%shortfile%"
1568 * Update the image in the menu
1570 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPlayPause")), "gtk-media-pause");
1571 gtk_image_set_from_stock(GTK_IMAGE
1572 (gtk_builder_get_object
1573 (pl3_xml
, "play_button_image")), "gtk-media-pause",
1574 GTK_ICON_SIZE_MENU
);
1577 * Update window title
1579 mpd_song_markup(buffer
, 1024, markup
, mpd_playlist_get_current_song(connection
));
1581 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
1583 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
1586 gchar
*string
= g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles
,
1588 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
1593 gtk_window_set_title(GTK_WINDOW(pl3_win
), buffer
);
1598 case MPD_PLAYER_PAUSE
:
1600 gchar
*markup
= cfg_get_single_value_as_string_with_default(config
,
1601 "playlist", /* Category */
1602 "window-markup",/* Key */
1604 "[%title% - &[%artist%]]|%name%|%shortfile%"
1606 /** Update menu and button images */
1608 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPlayPause")), "gtk-media-play");
1609 gtk_image_set_from_stock(GTK_IMAGE
1610 (gtk_builder_get_object
1611 (pl3_xml
, "play_button_image")), "gtk-media-play",
1612 GTK_ICON_SIZE_MENU
);
1614 * Set paused in Window string
1616 mpd_song_markup(buffer
, 1024 - strlen(_("paused") - 4),
1617 markup
, mpd_playlist_get_current_song(connection
));
1618 /* Append translated paused */
1619 strcat(buffer
, " (");
1620 strcat(buffer
, _("paused"));
1621 strcat(buffer
, ")");
1623 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
1625 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
1628 gchar
*string
= g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles
,
1630 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
1635 gtk_window_set_title(GTK_WINDOW(pl3_win
), buffer
);
1640 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPlayPause")), "gtk-media-play");
1641 /* Make sure it's reset correctly */
1642 gmpc_progress_set_time(GMPC_PROGRESS(new_pb
), 0, 0);
1644 gtk_image_set_from_stock(GTK_IMAGE
1645 (gtk_builder_get_object
1646 (pl3_xml
, "play_button_image")), "gtk-media-play",
1647 GTK_ICON_SIZE_MENU
);
1648 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
1650 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
1653 gchar
*string
= g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles
,
1655 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
1660 gtk_window_set_title(GTK_WINDOW(pl3_win
), _("GMPC"));
1662 playlist3_update_header();
1664 if(favorites_button
!= NULL
)
1666 if (state
== MPD_PLAYER_PLAY
|| state
== MPD_PLAYER_PAUSE
)
1668 gmpc_favorites_button_set_song(favorites_button
, song
);
1671 gmpc_favorites_button_set_song(favorites_button
, NULL
);
1676 * Handle song change or Playlist change
1677 * Anything that can change metadta
1679 if (what
& MPD_CST_SONGID
|| what
& MPD_CST_SONGPOS
|| what
& MPD_CST_PLAYLIST
)
1681 playlist3_update_header();
1682 /* make is update markups and stuff */
1683 playlist_status_changed(mi
, MPD_CST_STATE
, NULL
);
1686 * set repeat buttons in menu correct
1688 if (what
& MPD_CST_REPEAT
)
1690 if (mpd_check_connected(connection
))
1692 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "MPDRepeat")),
1693 mpd_player_get_repeat(connection
));
1697 if (what
& MPD_CST_RANDOM
)
1699 if (mpd_check_connected(connection
))
1701 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "MPDRandom")),
1702 mpd_player_get_random(connection
));
1705 if (what
& (MPD_CST_RANDOM
| MPD_CST_REPEAT
| MPD_CST_SINGLE_MODE
| MPD_CST_CONSUME_MODE
))
1707 main_window_update_status_icons();
1709 if (what
& MPD_CST_SINGLE_MODE
)
1711 if (mpd_check_connected(connection
))
1713 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "MPDSingleMode")),
1714 mpd_player_get_single(connection
));
1718 if (what
& MPD_CST_CONSUME_MODE
)
1720 if (mpd_check_connected(connection
))
1722 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "MPDConsumeMode")),
1723 mpd_player_get_consume(connection
));
1726 if (what
& MPD_CST_ELAPSED_TIME
)
1728 if (mpd_check_connected(connection
))
1730 int totalTime
= mpd_status_get_total_song_time(connection
);
1731 int elapsedTime
= mpd_status_get_elapsed_song_time(connection
);
1732 gmpc_progress_set_time(GMPC_PROGRESS(new_pb
), totalTime
, elapsedTime
);
1736 gmpc_progress_set_time(GMPC_PROGRESS(new_pb
), 0, 0);
1739 if (what
& MPD_CST_PERMISSION
)
1741 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDSingleMode")),
1743 mpd_check_connected(connection
) &&
1744 mpd_server_check_command_allowed(connection
, "single") == MPD_SERVER_COMMAND_ALLOWED
1747 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDConsumeMode")),
1749 mpd_check_connected(connection
) &&
1750 mpd_server_check_command_allowed(connection
, "consume") == MPD_SERVER_COMMAND_ALLOWED
1753 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPlayPause")),
1755 mpd_check_connected(connection
) &&
1756 mpd_server_check_command_allowed(connection
, "play") == MPD_SERVER_COMMAND_ALLOWED
1759 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDNext")),
1761 mpd_check_connected(connection
) &&
1762 mpd_server_check_command_allowed(connection
, "next") == MPD_SERVER_COMMAND_ALLOWED
1765 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPrevious")),
1767 mpd_check_connected(connection
) &&
1768 mpd_server_check_command_allowed(connection
, "previous") == MPD_SERVER_COMMAND_ALLOWED
1771 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDStop")),
1773 mpd_check_connected(connection
) &&
1774 mpd_server_check_command_allowed(connection
, "stop") == MPD_SERVER_COMMAND_ALLOWED
1777 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDRepeat")),
1779 mpd_check_connected(connection
) &&
1780 mpd_server_check_command_allowed(connection
, "repeat") == MPD_SERVER_COMMAND_ALLOWED
1783 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDRandom")),
1785 mpd_check_connected(connection
)&&
1786 mpd_server_check_command_allowed(connection
, "random") == MPD_SERVER_COMMAND_ALLOWED
1789 /* Also update volume stuff */
1790 what
= what
|MPD_CST_VOLUME
;
1793 if (what
& MPD_CST_VOLUME
)
1795 GtkWidget
*volume_button
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "volume_button"));
1796 int new_volume
= mpd_status_get_volume(connection
);
1797 if (new_volume
>= 0 &&
1798 mpd_server_check_command_allowed(connection
, "setvol") == MPD_SERVER_COMMAND_ALLOWED
1801 int volume
= gtk_scale_button_get_value(GTK_SCALE_BUTTON(volume_button
))/100.0;
1802 gtk_widget_show(GTK_WIDGET(volume_button
));
1803 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDMuted")),
1806 /* don't do anything if nothing is changed */
1807 if (new_volume
!= volume
)
1809 gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume_button
),new_volume
/100.0f
);
1813 gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume_button
),0);
1814 gtk_widget_hide(GTK_WIDGET(volume_button
));
1815 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDMuted")),
1820 if (what
& MPD_CST_SERVER_ERROR
)
1822 gchar
*error
= mpd_status_get_mpd_error(mi
);
1825 gchar
*mes
= g_markup_printf_escaped("%s: '%s'",
1826 _("MPD Reported the following error"),
1828 playlist3_show_error_message(mes
, ERROR_WARNING
);
1833 if (what
& MPD_CST_OUTPUT
)
1835 playlist3_fill_server_menu();
1837 if (what
& MPD_CST_NEXTSONG
)
1840 GtkWidget
*next_button
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "next_button"));
1843 int i
= mpd_player_get_next_song_id(mi
);
1846 mpd_Song
*song
= mpd_playlist_get_song(mi
, i
);
1849 mpd_song_markup(buffer
, 1024, "[%title% - &[%artist%]]|%shortfile%", song
);
1850 gtk_widget_set_tooltip_text(next_button
, buffer
);
1853 gtk_widget_set_tooltip_text(next_button
, "");
1855 gtk_widget_set_tooltip_text(next_button
, "");
1860 gboolean
playlist_player_volume_changed(GtkWidget
* vol_but
, double new_vol
)
1862 int volume
= new_vol
*100; //gtk_scale_button_get_value(GTK_SCALE_BUTTON(vol_but)) * 100;
1863 int new_volume
= mpd_status_get_volume(connection
);
1864 if (new_volume
>= 0 && new_volume
!= volume
)
1866 mpd_status_set_volume(connection
, volume
);
1873 void about_window(void)
1875 gchar
*path
= gmpc_get_full_glade_path("aboutdialog.ui");
1876 GtkBuilder
*xml
= gtk_builder_new();
1877 GtkWidget
*dialog
= NULL
;
1878 gtk_builder_add_from_file(xml
, path
, NULL
);
1879 dialog
= (GtkWidget
*) gtk_builder_get_object(xml
, "aboutdialog");
1881 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(playlist3_get_window()));
1882 gtk_window_set_position(GTK_WINDOW(dialog
), GTK_WIN_POS_CENTER_ON_PARENT
);
1885 if (strlen(revision
))
1887 path
= g_strdup_printf("%s\nRevision: %s", VERSION
, revision
);
1890 path
= g_strdup_printf("%s\n%s\n", VERSION
, GMPC_TAGLINE
);
1892 gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog
), GMPC_COPYRIGHT
);
1893 gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(dialog
), _("Gnome Music Player Client"));
1894 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog
), GMPC_WEBSITE
);
1895 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog
), path
);
1898 gtk_widget_show(dialog
);
1899 gtk_dialog_run(GTK_DIALOG(dialog
));
1900 gtk_widget_destroy(dialog
);
1901 g_object_unref(xml
);
1905 /****************************************************
1908 void pl3_update_go_menu(void)
1912 GtkWidget
*menu
= NULL
;
1913 GtkAccelGroup
*group
= playlist3_get_accel_group();
1914 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
1915 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_go"));
1917 * Remove any old menu
1919 gtk_menu_item_set_submenu(m_item
, NULL
);
1923 menu
= gtk_menu_new();
1924 gtk_menu_set_accel_group(GTK_MENU(menu
), group
);
1925 if (mpd_check_connected(connection
))
1927 for (i
= 0; i
< num_plugins
; i
++)
1929 if (gmpc_plugin_is_browser(plugins
[i
]))
1931 items
+= gmpc_plugin_browser_add_go_menu(plugins
[i
], menu
);
1941 gtk_widget_show_all(menu
);
1942 gtk_menu_item_set_submenu(m_item
, menu
);
1943 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_go")), TRUE
);
1946 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_go")), FALSE
);
1947 g_object_ref_sink(menu
);
1948 g_object_unref(menu
);
1953 static void pl3_profile_selected(GtkRadioMenuItem
* radio
, gpointer data
)
1955 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(radio
)))
1957 gchar
*uid
= g_object_get_data(G_OBJECT(radio
), "uid");
1962 connection_set_current_profile(uid
);
1963 if (mpd_check_connected(connection
))
1965 mpd_disconnect(connection
);
1972 static void pl3_profiles_changed(GmpcProfiles
* prof
, const int changed
, const int col
, const gchar
* id
)
1974 if (!mpd_check_connected(connection
))
1976 playlist_connection_changed(connection
, 0, NULL
);
1981 static void pl3_update_profiles_menu(GmpcProfiles
* prof
, const int changed
, const int col
, const gchar
* id
)
1984 GtkWidget
*menu
= NULL
;
1985 gchar
*current
= gmpc_profiles_get_current(gmpc_profiles
);
1987 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
1988 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_music/menu_profiles"));
1989 /* check if there is anything changed that is important for us. */
1991 if (changed
== GMPC_PROFILES_ACTION_COL_CHANGED
&& col
!= GMPC_PROFILES_COLUMN_NAME
)
1997 * Remove any old menu
1999 gtk_menu_item_set_submenu(m_item
, NULL
);
2003 menu
= gtk_menu_new();
2005 mult
= gmpc_profiles_get_profiles_ids(gmpc_profiles
);
2008 GSList
*group
= NULL
;
2012 /** Get profile name */
2013 const gchar
*value
= gmpc_profiles_get_name(gmpc_profiles
, (char *)iter
->data
);
2014 GtkWidget
*item
= gtk_radio_menu_item_new_with_label(group
, value
);
2016 group
= gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item
));
2017 /* add to the menu */
2018 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
2020 /* check the current profile */
2021 if (!strcmp((char *)(iter
->data
), current
))
2023 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item
), TRUE
);
2027 * Attach click handler
2029 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(pl3_profile_selected
), NULL
);
2031 /** Attach the uid to the handler */
2032 value
= g_strdup((char *)(iter
->data
));
2033 g_object_set_data_full(G_OBJECT(item
), "uid", (gpointer
) value
, g_free
);
2036 } while ((iter
= g_list_next(iter
)));
2046 gtk_widget_show_all(menu
);
2047 gtk_menu_item_set_submenu(m_item
, menu
);
2048 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_profiles")), TRUE
);
2051 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_profiles")), FALSE
);
2052 g_object_ref_sink(menu
);
2053 g_object_unref(menu
);
2059 static void playlist3_server_output_changed(GtkWidget
* item
, gpointer data
)
2061 int id
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item
), "id"));
2062 int state
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item
));
2063 mpd_server_set_output_device(connection
, id
, state
);
2068 void playlist3_server_update_db(void)
2070 mpd_database_update_dir(connection
, "/");
2074 static GList
*server_menu_items
= NULL
;
2075 static void playlist3_fill_server_menu(void)
2077 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
2078 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_server"));
2079 /** Clear old items */
2080 if(server_menu_items
!= NULL
)
2082 g_list_foreach(server_menu_items
, (GFunc
)gtk_widget_destroy
, NULL
);
2083 g_list_free(server_menu_items
);
2084 server_menu_items
= NULL
;
2087 /* if connected fill with items */
2088 if (mpd_check_connected(connection
))
2090 GtkWidget
*menu
= gtk_menu_item_get_submenu(GTK_MENU_ITEM(m_item
));
2091 GtkWidget
*menu_item
= NULL
;
2093 MpdData
*data
= NULL
;
2095 data
= mpd_server_get_output_devices(connection
);
2098 menu_item
= gtk_separator_menu_item_new();
2099 server_menu_items
= g_list_append(server_menu_items
, menu_item
);
2100 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
2102 for (; data
; data
= mpd_data_get_next(data
))
2104 menu_item
= gtk_check_menu_item_new_with_label(data
->output_dev
->name
);
2105 server_menu_items
= g_list_append(server_menu_items
, menu_item
);
2106 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item
), data
->output_dev
->enabled
? TRUE
: FALSE
);
2107 gtk_widget_add_accelerator(menu_item
, "activate",
2108 gtk_ui_manager_get_accel_group(GTK_UI_MANAGER(ui
)),
2109 GDK_KEY_1
+ i
, GDK_CONTROL_MASK
, GTK_ACCEL_VISIBLE
);
2111 g_signal_connect(G_OBJECT(menu_item
), "toggled", G_CALLBACK(playlist3_server_output_changed
), NULL
);
2112 g_object_set_data(G_OBJECT(menu_item
), "id", GINT_TO_POINTER(data
->output_dev
->id
));
2113 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
2116 gtk_widget_show_all(menu
);
2117 /* Server Menu Item */
2118 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_server")), TRUE
);
2121 /* Server Menu Item */
2122 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_server")), FALSE
);
2132 extern GmpcBrowsersMetadata
*browsers_metadata
;
2134 void info2_activate(void)
2136 GtkTreeView
*tree
= (GtkTreeView
*) gtk_builder_get_object(pl3_xml
, "cat_tree");
2137 gmpc_browsers_metadata_select_browser(browsers_metadata
, tree
);
2141 void info2_fill_song_view(mpd_Song
* song
)
2144 gmpc_browsers_metadata_set_song(browsers_metadata
, song
);
2148 void info2_fill_artist_view(const gchar
* artist
)
2151 gmpc_browsers_metadata_set_artist(browsers_metadata
, artist
);
2155 void info2_fill_album_view(const gchar
* artist
, const gchar
* album
)
2158 gmpc_browsers_metadata_set_album(browsers_metadata
, artist
, album
);
2162 void playlist3_insert_browser(GtkTreeIter
* iter
, gint position
)
2164 GtkTreeIter it
, *sib
= NULL
;
2166 GtkTreeModel
*model
= GTK_TREE_MODEL(pl3_tree
);
2167 if (gtk_tree_model_get_iter_first(model
, &it
))
2171 gtk_tree_model_get(model
, &it
, PL3_CAT_ORDER
, &pos
, -1);
2172 if (position
<= pos
)
2174 } while (sib
== NULL
&& gtk_tree_model_iter_next(model
, &it
));
2177 // first check breaks recursion. Do not check for header when adding a header.
2178 // Next check checks if the header is allready there.
2179 if(position
%1000 != 0 && (pos
-pos
%1000) != (position
-position
%1000))
2182 pos
= position
-position
%1000;
2184 if(pos
== PL3_CAT_BROWSER_LIBRARY
)
2186 playlist3_insert_browser(&it
, PL3_CAT_BROWSER_LIBRARY
);
2187 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), &it
,
2188 PL3_CAT_TYPE
,-1, PL3_CAT_TITLE
, _("Library"),PL3_CAT_BOLD
, PANGO_WEIGHT_ULTRABOLD
,-1);
2190 gtk_list_store_insert_after(GTK_LIST_STORE(pl3_tree
), iter
, sib
);
2192 else if (pos
== PL3_CAT_BROWSER_ONLINE_MEDIA
)
2194 playlist3_insert_browser(&it
, PL3_CAT_BROWSER_ONLINE_MEDIA
);
2195 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), &it
,
2196 PL3_CAT_TYPE
,-1, PL3_CAT_TITLE
, _("Online Media"),PL3_CAT_BOLD
, PANGO_WEIGHT_ULTRABOLD
,-1);
2198 gtk_list_store_insert_after(GTK_LIST_STORE(pl3_tree
), iter
, sib
);
2200 else if (pos
== PL3_CAT_BROWSER_MISC
)
2202 playlist3_insert_browser(&it
, PL3_CAT_BROWSER_MISC
);
2203 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), &it
,
2204 PL3_CAT_TYPE
,-1, PL3_CAT_TITLE
, _("Misc."),PL3_CAT_BOLD
, PANGO_WEIGHT_ULTRABOLD
,-1);
2206 gtk_list_store_insert_after(GTK_LIST_STORE(pl3_tree
), iter
, sib
);
2211 gtk_list_store_insert_before(GTK_LIST_STORE(pl3_tree
), iter
, sib
);
2216 gtk_list_store_insert_before(GTK_LIST_STORE(pl3_tree
), iter
, sib
);
2218 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), iter
, PL3_CAT_ORDER
, position
, PL3_CAT_BOLD
, PANGO_WEIGHT_NORMAL
, -1);
2226 void playlist3_destroy(void)
2228 GtkWidget
*win
= playlist3_get_window();
2229 if(server_menu_items
) g_list_free(server_menu_items
);
2230 gtk_widget_destroy(win
);
2231 g_object_unref(pl3_xml
);
2234 GtkWidget
*playlist3_get_window(void)
2236 return GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_win"));
2243 /* Make glade happy */
2244 void url_visit_website(void);
2245 void url_getting_help(void);
2247 void url_visit_website(void)
2249 open_uri(GMPC_WEBSITE
);
2253 void url_getting_help(void)
2255 open_uri(GMPC_BUGTRACKER
);
2259 gmpcPrefPlugin playlist_gpp
=
2261 .construct
= playlist_pref_construct
,
2262 .destroy
= playlist_pref_destroy
2265 gmpcPlugin playlist_plug
=
2267 .name
= N_("Interface"),
2268 .version
= {1, 1, 1},
2269 .plugin_type
= GMPC_INTERNALL
,
2270 .mpd_status_changed
= &playlist_status_changed
,
2271 .mpd_connection_changed
= &playlist_connection_changed
,
2272 .pref
= &playlist_gpp
,
2280 void pl3_tool_menu_update(void)
2284 GtkWidget
*menu
= NULL
;
2285 GtkAccelGroup
*group
= gtk_accel_group_new();
2286 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
2287 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_tool"));
2288 gtk_menu_item_set_submenu(m_item
, NULL
);
2289 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_tool")), FALSE
);
2290 if (!mpd_check_connected(connection
))
2293 menu
= gtk_menu_new();
2294 gtk_menu_set_accel_group(GTK_MENU(menu
), group
);
2295 g_object_unref(group
);
2296 gtk_window_add_accel_group(GTK_WINDOW(playlist3_get_window()), group
);
2297 for (i
= 0; i
< num_plugins
; i
++)
2299 menu_items
+= gmpc_plugin_tool_menu_integration(plugins
[i
], GTK_MENU(menu
));
2303 gtk_widget_show_all(menu
);
2304 gtk_menu_item_set_submenu(m_item
, menu
);
2305 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_tool")), TRUE
);
2308 g_object_ref_sink(menu
);
2309 g_object_unref(menu
);
2314 void easy_command_help_window(void)
2316 if (gmpc_easy_command
)
2317 gmpc_easy_command_help_window(gmpc_easy_command
, NULL
);
2323 * Extra wrappings for menu
2325 extern gmpcPlugin extraplaylist_plugin
;
2326 void enable_extra_playlist(GtkToggleAction
*action
)
2328 gboolean state
= gtk_toggle_action_get_active(action
);
2329 if(extraplaylist_plugin
.set_enabled
)
2331 if(extraplaylist_plugin
.get_enabled() != state
)
2333 extraplaylist_plugin
.set_enabled(state
);
2336 preferences_window_update();
2340 void init_extra_playlist_state(void)
2342 GtkToggleAction
*action
= GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "ViewExtraPlaylist"));
2343 if(extraplaylist_plugin
.get_enabled
)
2345 gtk_toggle_action_set_active(action
, extraplaylist_plugin
.get_enabled());
2349 GtkAccelGroup
*playlist3_get_accel_group(void)
2351 static GtkAccelGroup
*group
= NULL
;
2353 group
= gtk_accel_group_new();
2354 gtk_window_add_accel_group(GTK_WINDOW(playlist3_get_window()), group
);
2359 void open_local_file(void)
2362 gboolean found
= FALSE
;
2363 if(!mpd_check_connected(connection
))
2366 /* Check if MPD supports 'file://' (so local files). */
2367 handlers
= mpd_server_get_url_handlers(connection
);
2371 for(; !found
&& handlers
!= NULL
&& handlers
[i
] != NULL
; i
++) {
2372 if(g_utf8_collate(handlers
[i
], "file://") == 0) {
2376 g_strfreev(handlers
);
2378 /* error message or file open */
2380 /* Message not found */
2381 GtkWidget
*gmd
= gtk_message_dialog_new(
2382 (GtkWindow
*)playlist3_get_window(),
2387 "To playback local files, you need to be connected "
2388 "using unix socket.\n"
2389 "See the MPD website for more information."
2392 gtk_dialog_run(GTK_DIALOG(gmd
));
2393 gtk_widget_destroy(GTK_WIDGET(gmd
));
2395 GtkWidget
*fmd
= gtk_file_chooser_dialog_new(
2396 "Select a local file",
2397 (GtkWindow
*)playlist3_get_window(),
2398 GTK_FILE_CHOOSER_ACTION_OPEN
,
2404 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(fmd
), TRUE
);
2405 switch(gtk_dialog_run(GTK_DIALOG(fmd
)))
2407 case GTK_RESPONSE_OK
:
2410 GSList
*uris
= gtk_file_chooser_get_uris(GTK_FILE_CHOOSER(fmd
));
2413 iter
= g_slist_next(iter
))
2415 char *uri
= g_uri_unescape_string(iter
->data
,NULL
);
2416 url_start_real(uri
);
2419 g_slist_foreach (uris
, (GFunc
) g_free
, NULL
);
2420 g_slist_free (uris
);
2426 gtk_widget_destroy(GTK_WIDGET(fmd
));
2430 void show_user_manual(void);
2431 void show_user_manual(void)
2433 open_help("ghelp:gmpc");
2436 GmpcPluginSidebarState
playlist3_get_sidebar_state(void)
2438 return pl3_zoom
== PLAYLIST_NO_ZOOM
? GMPC_PLUGIN_SIDEBAR_STATE_FULL
:GMPC_PLUGIN_SIDEBAR_STATE_COLLAPSED
;
2440 /* vim: set noexpandtab ts=4 sw=4 sts=4 tw=80: */