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.
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"
39 #define SIDEBAR_SMALL 32
41 #define SIDEBAR_LARGE -1
44 #define GDK_KEY_0 GDK_0
48 #define GDK_KEY_1 GDK_1
52 #define GDK_KEY_2 GDK_2
57 #define GDK_KEY_3 GDK_3
61 #define GDK_KEY_4 GDK_4
66 #define GDK_KEY_5 GDK_5
71 #define GDK_KEY_6 GDK_6
76 #define GDK_KEY_7 GDK_7
81 #define GDK_KEY_8 GDK_8
86 #define GDK_KEY_9 GDK_9
91 #define ALBUM_SIZE_SMALL 42
92 #define ALBUM_SIZE_LARGE 42
94 #define LOG_DOMAIN "Playlist"
96 /* Drag and drop Target table */
97 static GtkTargetEntry target_table
[] =
99 {(gchar
*) "x-url/http", 0, 0},
100 {(gchar
*) "_NETSCAPE_URL", 0, 1},
101 {(gchar
*) "text/uri-list", 0, 2},
102 {(gchar
*) "audio/*", 0, 3},
103 {(gchar
*) "audio/x-scpls", 0, 4},
104 {(gchar
*) "internal-drop", 0, 99}
107 GtkWidget
*metaimage_album_art
= NULL
;
108 GtkWidget
*metaimage_artist_art
= NULL
;
109 GmpcFavoritesButton
*favorites_button
= NULL
;
111 GtkCellRenderer
*sidebar_text
= NULL
;
113 * Widgets used in the header.
114 * and the new progresbar
116 static GtkWidget
*new_pb
= NULL
;
119 * Indicates the zoom level and the previous zoom level.
121 int pl3_zoom
= PLAYLIST_NO_ZOOM
;
122 int pl3_old_zoom
= PLAYLIST_NO_ZOOM
;
124 static void playlist_zoom_level_changed(void);
125 void playlist_zoom_in(void);
126 void playlist_zoom_out(void);
129 void pl3_pb_seek_event(GtkWidget
* pb
, guint seek_time
, gpointer user_data
);
131 void set_browser_format(void);
132 void set_playlist_format(void);
134 gboolean
playlist_player_volume_changed(GtkWidget
* vol_but
, int new_vol
);
136 /* Glade declarations, otherwise these would be static */
137 void about_window(void);
138 int pl3_cat_tree_button_press_event(GtkTreeView
*, GdkEventButton
*);
139 int pl3_cat_tree_button_release_event(GtkTreeView
*, GdkEventButton
*);
141 void cur_song_center_enable_tb(GtkToggleButton
*);
142 void show_cover_case_tb(GtkToggleButton
* but
);
143 void save_possize_enable_tb(GtkToggleButton
*);
144 void playlist_menu_repeat_changed(GtkToggleAction
*);
145 void playlist_menu_single_mode_changed(GtkToggleAction
* );
146 void playlist_menu_consume_changed(GtkToggleAction
* );
148 void playlist_menu_random_changed(GtkToggleAction
*);
149 void playlist_menu_artist_image_changed(GtkToggleAction
*);
150 void hide_on_close_enable_tb(GtkToggleButton
* but
);
151 gboolean
pl3_close(void);
152 static void pl3_update_profiles_menu(GmpcProfiles
* prof
, const int changed
, const int col
, const gchar
* id
);
153 gboolean
playlist3_enter_notify_event(GtkWidget
* wid
, GdkEventCrossing
* event
, gpointer data
);
154 gboolean
playlist3_leave_notify_event(GtkWidget
* wid
, GdkEventCrossing
* event
, gpointer data
);
155 gboolean
pl3_window_focus_out_event(GtkWidget
*window
, GdkEventFocus
*event
, gpointer data
);
157 static void pl3_profiles_changed(GmpcProfiles
* prof
, const int changed
, const int col
, const gchar
* id
);
158 static void playlist3_server_output_changed(GtkWidget
* item
, gpointer data
);
159 static void playlist3_fill_server_menu(void);
160 void playlist3_server_update_db(void);
162 void easy_command_help_window(void);
164 void pl3_style_set_event(GtkWidget
*widget
, GtkStyle
*previous_style
, gpointer user_data
);
166 void pl3_sidebar_plugins_init(void);
168 /* Old category browser style */
169 static int old_type
= -1;
171 /* interface description */
172 GtkBuilder
*pl3_xml
= NULL
;
173 /* category treeview-store */
174 GtkTreeModel
*pl3_tree
= NULL
;
177 static GtkAllocation pl3_wsize
= { 0, 0, 0, 0 };
179 static int pl3_hidden
= TRUE
;
181 static void playlist_status_changed(MpdObj
* mi
, ChangedStatusType what
, void *userdata
);
183 /* Playlist "Plugin" */
184 static void playlist_pref_construct(GtkWidget
* container
);
185 static void playlist_pref_destroy(GtkWidget
* container
);
187 static GtkBuilder
*playlist_pref_xml
= NULL
;
189 void ck_search_as_you_type(GtkToggleButton
* but
);
192 /* Get the type of the selected row..
193 * -1 means no row selected
195 int pl3_cat_get_selected_browser(void)
204 * Extras for better integration
207 void init_extra_playlist_state(void);
208 void enable_extra_playlist(GtkToggleAction
*action
);
210 /**************************************************
213 static void pl3_initialize_tree(void)
217 GtkTreeSelection
*sel
;
218 GtkWidget
*cat_tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
222 path
= gtk_tree_path_new_from_string("0");
223 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk_builder_get_object(pl3_xml
, "cat_tree")));
224 TEC("Get selection");
225 for (i
= 0; i
< num_plugins
; i
++)
227 if (gmpc_plugin_is_browser(plugins
[i
]))
229 if (gmpc_plugin_get_enabled(plugins
[i
]))
231 gmpc_plugin_browser_add(plugins
[i
], cat_tree
);
234 TEC("setup %s", gmpc_plugin_get_name(plugins
[i
]))
237 gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtk_builder_get_object(pl3_xml
, "cat_tree")), path
, NULL
, FALSE
);
239 gtk_tree_path_free(path
);
245 * Function to handle a change in category.
247 static void pl3_cat_sel_changed(GtkTreeSelection
* selec
, gpointer
* userdata
)
249 GtkTreeView
*tree
= (GtkTreeView
*) gtk_builder_get_object(pl3_xml
, "cat_tree");
250 GtkTreeModel
*model
= gtk_tree_view_get_model(tree
);
252 GtkWidget
*container
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "browser_container"));
255 if (gtk_tree_selection_get_selected(selec
, &model
, &iter
))
259 gtk_tree_model_get(model
, &iter
, PL3_CAT_TYPE
, &type
, -1);
263 * Start switching side view (if type changed )
267 gmpc_plugin_browser_unselected(plugins
[plugin_get_pos(old_type
)], container
);
272 /** if type changed give a selected signal */
273 if ((old_type
!= type
))
275 gmpc_plugin_browser_selected(plugins
[plugin_get_pos(type
)], container
);
280 * update old value, so get_selected_category is correct before calling selection_changed
288 gmpc_plugin_browser_unselected(plugins
[plugin_get_pos(old_type
)], container
);
291 gtk_tree_model_get_iter_first(model
, &iter
);
292 gtk_tree_selection_select_iter(selec
, &iter
);
294 pl3_option_menu_activate();
298 /* handle right mouse clicks on the cat tree view */
299 /* gonna be a big function*/
300 int pl3_cat_tree_button_press_event(GtkTreeView
* tree
, GdkEventButton
* event
)
302 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(tree
);
303 if (event
->button
!= 3 || gtk_tree_selection_count_selected_rows(sel
) < 2 || !mpd_check_connected(connection
))
312 void pl3_option_menu_activate(void)
315 GtkWidget
*tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
317 gint type
= pl3_cat_get_selected_browser();
319 GdkEventButton
*event
= NULL
;
320 GtkWidget
*menu
= NULL
;
321 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
322 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_option"));
324 //gtk_menu_item_set_submenu(m_item, NULL);
326 if (!mpd_check_connected(connection
) || type
== -1)
329 menu
= gtk_menu_new();
331 for (i
= 0; i
< num_plugins
; i
++)
333 if (gmpc_plugin_is_browser(plugins
[i
]))
335 menu_items
+= gmpc_plugin_browser_cat_right_mouse_menu(plugins
[i
], menu
, type
, tree
, event
);
340 gtk_widget_show_all(menu
);
341 gtk_menu_item_set_submenu(m_item
, menu
);
342 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")), TRUE
);
345 g_object_ref_sink(menu
);
346 g_object_unref(menu
);
347 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")), FALSE
);
353 int pl3_cat_tree_button_release_event(GtkTreeView
* tree
, GdkEventButton
* event
)
356 gint type
= pl3_cat_get_selected_browser();
358 GtkWidget
*menu
= NULL
;
360 if (type
== -1 || !mpd_check_connected(connection
) || event
->button
!= 3)
362 /* no selections, or no usefull one.. so propagate the signal */
366 menu
= gtk_menu_new();
368 for (i
= 0; i
< num_plugins
; i
++)
370 if (gmpc_plugin_is_browser(plugins
[i
]))
372 menu_items
+= gmpc_plugin_browser_cat_right_mouse_menu(plugins
[i
], menu
, type
, GTK_WIDGET(tree
), event
);
378 gtk_widget_show_all(menu
);
379 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
, NULL
, NULL
,
380 /*event->button */ 0, event
->time
);
383 g_object_ref_sink(menu
);
384 g_object_unref(menu
);
389 void pl3_sidebar_plugins_init(void)
392 for (i
= 0; i
< num_plugins
; i
++)
394 // This is implicitely done inside sidebar_init
395 // if (gmpc_plugin_is_sidebar(plugins[i]))
397 gmpc_plugin_sidebar_init(plugins
[i
]);
402 /**********************************************************
405 static GtkWidget
*control_window
= NULL
;
406 static gboolean
pl3_win_state_event(GtkWidget
* window
, GdkEventWindowState
* event
, gpointer data
)
408 GtkWidget
*vbox1
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox1"));
409 GtkWidget
*p
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "alignment1"));
410 GtkWidget
*h
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox1"));
411 GtkWidget
*b
= (GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "menubartest")));
412 if (((event
->new_window_state
) & GDK_WINDOW_STATE_FULLSCREEN
))
414 if(control_window
== NULL
) {
415 control_window
= create_control_window(window
);
416 gtk_box_pack_start(GTK_BOX(vbox1
), control_window
, FALSE
, FALSE
, 0);
418 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "sidebar")));
422 } else if ((event
->changed_mask
) & GDK_WINDOW_STATE_FULLSCREEN
)
424 control_window_destroy(control_window
);
425 control_window
= NULL
;
426 playlist_zoom_level_changed();
434 gboolean alt_button_pressed
= FALSE
;
436 * This avoids the 'keybinding help' to become sticky when moving the window, or chainging
437 * focus to other window.
439 gboolean
pl3_window_focus_out_event(GtkWidget
*window
, GdkEventFocus
*event
, gpointer data
)
441 if(alt_button_pressed
)
443 GtkWidget
*tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
444 alt_button_pressed
= FALSE
;
445 gtk_widget_queue_draw(GTK_WIDGET(tree
));
447 GmpcToolsBindingOverlayNotify
*p
= gtk_builder_get_object(pl3_xml
, "binding_overlay_notify");
448 gmpc_tools_binding_overlay_notify_key_released(p
,GDK_MOD1_MASK
|GDK_CONTROL_MASK
);
453 gboolean
pl3_window_is_fullscreen(void)
455 GtkWidget
*win
= playlist3_get_window();
456 GdkWindowState state
= 0;
458 state
= gdk_window_get_state(win
->window
);
459 return (state
& GDK_WINDOW_STATE_FULLSCREEN
) ? TRUE
: FALSE
;
463 void pl3_window_fullscreen(void)
465 GtkWidget
*win
= playlist3_get_window();
467 if (pl3_zoom
< PLAYLIST_MINI
)
469 if (pl3_window_is_fullscreen())
471 gtk_window_unfullscreen(GTK_WINDOW(win
));
474 gtk_window_fullscreen(GTK_WINDOW(win
));
480 int pl3_window_key_release_event(GtkWidget
* mw
, GdkEventKey
* event
)
482 if(event
->keyval
== GDK_KEY_Alt_L
|| event
->keyval
== GDK_KEY_Alt_R
|| event
->keyval
== GDK_KEY_Meta_L
|| event
->keyval
== GDK_KEY_Meta_R
) {
483 GtkWidget
*tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
484 alt_button_pressed
= FALSE
;
485 gtk_widget_queue_draw(GTK_WIDGET(tree
));
486 GmpcToolsBindingOverlayNotify
*p
= gtk_builder_get_object(pl3_xml
, "binding_overlay_notify");
487 gmpc_tools_binding_overlay_notify_key_released(p
,GDK_MOD1_MASK
);
489 if(event
->keyval
== GDK_KEY_Control_L
|| event
->keyval
== GDK_KEY_Control_R
) {
490 GmpcToolsBindingOverlayNotify
*p
= gtk_builder_get_object(pl3_xml
, "binding_overlay_notify");
491 gmpc_tools_binding_overlay_notify_key_released(p
,GDK_CONTROL_MASK
);
495 int pl3_window_key_press_event(GtkWidget
* mw
, GdkEventKey
* event
)
498 gint type
= pl3_cat_get_selected_browser();
499 if(event
->keyval
== GDK_KEY_Alt_L
|| event
->keyval
== GDK_KEY_Alt_R
) {
500 GtkWidget
*tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
501 alt_button_pressed
= TRUE
;
502 gtk_widget_queue_draw(GTK_WIDGET(tree
));
503 GmpcToolsBindingOverlayNotify
*p
= gtk_builder_get_object(pl3_xml
, "binding_overlay_notify");
504 gmpc_tools_binding_overlay_notify_key_pressed(p
,GDK_MOD1_MASK
);
506 if(event
->keyval
== GDK_KEY_Control_L
|| event
->keyval
== GDK_KEY_Control_R
)
508 GmpcToolsBindingOverlayNotify
*p
= gtk_builder_get_object(pl3_xml
, "binding_overlay_notify");
509 gmpc_tools_binding_overlay_notify_key_pressed(p
,GDK_CONTROL_MASK
);
512 * Following key's are only valid when connected
514 if (!mpd_check_connected(connection
))
518 for (i
= 0; i
< num_plugins
; i
++)
520 if (gmpc_plugin_is_browser(plugins
[i
]))
522 gmpc_plugin_browser_key_press_event(plugins
[i
], mw
, event
, type
);
525 if((event
->state
&GDK_MOD1_MASK
) > 0)
527 guint kev
= event
->keyval
;
528 if(kev
>= GDK_KEY_0
&& kev
<= GDK_KEY_9
)
533 if (gtk_tree_model_get_iter_first(pl3_tree
, &iter
))
535 if(kev
== 0) kev
+=10;
538 gtk_tree_model_get(pl3_tree
, &iter
, PL3_CAT_TYPE
, &type
, -1);
539 if(type
>= 0) index
++;
540 if(index
== kev
&& type
>= 0)
542 GtkWidget
*cat_tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
543 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(cat_tree
));
545 // if this is allready selected, do +10. this allows us to go up to 20 browsers.
546 if(type
== old_type
&& gtk_tree_selection_iter_is_selected(select
, &iter
)) {
549 gtk_tree_selection_select_iter(select
, &iter
);
553 }while(gtk_tree_model_iter_next(pl3_tree
, &iter
));
558 /* don't propagate */
563 * Close the playlist and save position/size
565 gboolean
pl3_close(void)
567 /* only save when window is PLAYLIST_SMALL or NO ZOOM */
570 GtkWidget
*window
= playlist3_get_window();
571 int maximized
= FALSE
;
574 GdkWindowState state
= gdk_window_get_state(window
->window
);
575 maximized
= ((state
& GDK_WINDOW_STATE_MAXIMIZED
) > 0);
577 cfg_set_single_value_as_int(config
, "playlist", "maximized", maximized
);
579 gtk_window_get_position(GTK_WINDOW(window
), &pl3_wsize
.x
, &pl3_wsize
.y
);
581 cfg_set_single_value_as_int(config
, "playlist", "xpos", pl3_wsize
.x
);
582 cfg_set_single_value_as_int(config
, "playlist", "ypos", pl3_wsize
.y
);
584 if (pl3_zoom
<= PLAYLIST_SMALL
)
586 gtk_window_get_size(GTK_WINDOW(window
), &pl3_wsize
.width
, &pl3_wsize
.height
);
587 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "pl3_close: save size: %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
588 cfg_set_single_value_as_int(config
, "playlist", "width", pl3_wsize
.width
);
589 cfg_set_single_value_as_int(config
, "playlist", "height", pl3_wsize
.height
);
593 if (cfg_get_single_value_as_int_with_default(config
, "playlist", "hide-on-close", FALSE
))
595 if (tray_icon2_get_available())
600 gtk_window_iconify(GTK_WINDOW(playlist3_get_window()));
614 * Before hiding save current size and position
618 GtkWidget
*pl3_win
= playlist3_get_window();
619 if (!tray_icon2_get_available())
621 gtk_window_iconify(GTK_WINDOW(pl3_win
));
624 if (pl3_xml
!= NULL
&& !pl3_hidden
)
626 GtkWidget
*window
= playlist3_get_window();
627 int maximized
= FALSE
;
630 GdkWindowState state
= gdk_window_get_state(window
->window
);
631 maximized
= ((state
& GDK_WINDOW_STATE_MAXIMIZED
) > 0);
633 cfg_set_single_value_as_int(config
, "playlist", "maximized", maximized
);
636 gtk_window_get_position(GTK_WINDOW(pl3_win
), &pl3_wsize
.x
, &pl3_wsize
.y
);
637 cfg_set_single_value_as_int(config
, "playlist", "xpos", pl3_wsize
.x
);
638 cfg_set_single_value_as_int(config
, "playlist", "ypos", pl3_wsize
.y
);
639 /* save size, only when in SMALL or no zoom mode
641 if (pl3_zoom
<= PLAYLIST_SMALL
)
643 gtk_window_get_size(GTK_WINDOW(pl3_win
), &pl3_wsize
.width
, &pl3_wsize
.height
);
644 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "pl3_hide: save size: %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
645 cfg_set_single_value_as_int(config
, "playlist", "width", pl3_wsize
.width
);
646 cfg_set_single_value_as_int(config
, "playlist", "height", pl3_wsize
.height
);
648 gtk_widget_hide(pl3_win
);
651 #ifdef HAVE_APP_INDICATOR
652 tray_icon2_update_menu();
658 /* create the playlist view
659 * This is done only once, for the rest its hidden, but still there
661 static void pl3_show_and_position_window(void)
666 pl3_win
= playlist3_get_window();
667 if (pl3_wsize
.x
> 0 || pl3_wsize
.y
> 0)
669 gtk_window_move(GTK_WINDOW(pl3_win
), pl3_wsize
.x
, pl3_wsize
.y
);
671 if (pl3_wsize
.height
> 0 && pl3_wsize
.width
> 0)
673 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "restore size %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
674 gtk_window_resize(GTK_WINDOW(pl3_win
), pl3_wsize
.width
, pl3_wsize
.height
);
676 gtk_widget_show(pl3_win
);
677 gtk_window_present(GTK_WINDOW(pl3_win
));
682 gboolean
playlist3_window_is_hidden(void)
688 void pl3_toggle_hidden(void)
700 static void playlist3_source_drag_data_recieved(GtkWidget
* widget
,
701 GdkDragContext
* context
,
703 gint y
, GtkSelectionData
* data
, guint info
, guint time_recieved
)
708 const gchar
*url_data
= (gchar
*) data
->data
;
713 gchar
**url
= g_uri_list_extract_uris(url_data
);
714 for (i
= 0; url
&& url
[i
]; i
++)
716 gchar
*scheme
= g_uri_parse_scheme(url
[i
]);
717 /* Don't add lines withouth an actual scheme. */
720 gchar
*fu
= g_uri_unescape_string(url
[i
], NULL
);
730 gtk_drag_finish(context
, found
, FALSE
, time_recieved
);
736 guchar
*odata
= gtk_selection_data_get_text(data
);
737 stripped
= g_strsplit((gchar
*) odata
, "\n", 0);
739 if (context
->action
== GDK_ACTION_MOVE
)
741 mpd_playlist_clear(connection
);
743 mpd_database_search_start(connection
, TRUE
);
744 for (i
= 0; stripped
&& stripped
[i
]; i
++)
746 gchar
**request
= g_strsplit(stripped
[i
], ":", 2);
747 mpd_database_search_add_constraint(connection
, mpd_misc_get_tag_by_name(request
[0]), request
[1]);
750 mdata
= mpd_database_search_commit(connection
);
751 for (; mdata
; mdata
= mpd_data_get_next(mdata
))
753 mpd_playlist_queue_add(connection
, mdata
->song
->file
);
755 mpd_playlist_queue_commit(connection
);
756 if (context
->action
== GDK_ACTION_MOVE
)
758 mpd_player_play(connection
);
761 g_strfreev(stripped
);
762 gtk_drag_finish(context
, TRUE
, FALSE
, time_recieved
);
770 void pl3_pb_seek_event(GtkWidget
* pb
, guint seek_time
, gpointer user_data
)
772 mpd_player_seek(connection
, (int)seek_time
);
777 static void about_dialog_activate(GtkWidget
* dialog
, const gchar
* uri
, gpointer data
)
784 * Handle a connect/Disconnect
786 static void playlist_connection_changed(MpdObj
* mi
, int connect
, gpointer data
)
788 GtkWidget
*pl3_win
= playlist3_get_window();
793 gboolean found
= FALSE
;
794 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player")), TRUE
);
795 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hpaned1-hbox")), TRUE
);
797 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDConnect")), FALSE
);
798 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDDisconnect")), TRUE
);
799 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPassword")), TRUE
);
800 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_view")), TRUE
);
801 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")), TRUE
);
803 /* Check if MPD supports 'file://' (so local files). */
804 /* TODO: make this a separate function */
805 handlers
= mpd_server_get_url_handlers(connection
);
809 for(; !found
&& handlers
!= NULL
&& handlers
[i
] != NULL
; i
++) {
810 if(g_utf8_collate(handlers
[i
], "file://") == 0) {
814 g_strfreev(handlers
);
816 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "open_local_file")), found
);
819 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player")), FALSE
);
820 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hpaned1-hbox")), FALSE
);
822 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDConnect")), TRUE
);
823 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDDisconnect")), FALSE
);
824 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPassword")), FALSE
);
825 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_view")), FALSE
);
826 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")), FALSE
);
827 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "open_local_file")), FALSE
);
829 /** Set back to the current borwser, and update window title */
832 gchar
*string
= NULL
;
834 GtkTreeSelection
*selec
= gtk_tree_view_get_selection((GtkTreeView
*) gtk_builder_get_object(pl3_xml
,
836 GtkTreeModel
*model
= GTK_TREE_MODEL(pl3_tree
);
837 if (gtk_tree_model_get_iter_first(model
, &iter
))
839 gtk_tree_selection_select_iter(selec
, &iter
);
841 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
843 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
847 g_strdup_printf("[%s] %s - %s %s", gmpc_profiles_get_name(gmpc_profiles
, id
), _("GMPC"),
848 _("Connected to"), mpd_get_hostname(mi
));
853 string
= g_strdup_printf("%s - %s %s", _("GMPC"), _("Connected to"), mpd_get_hostname(mi
));
854 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
858 gchar
*string
= NULL
;
860 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
862 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
866 g_strdup_printf("[%s] %s - %s", gmpc_profiles_get_name(gmpc_profiles
, id
), _("GMPC"),
872 string
= g_strdup_printf("%s - %s", _("GMPC"), _("Disconnected"));
873 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
878 * make the playlist update itself
880 playlist_status_changed(connection
,
881 MPD_CST_STATE
| MPD_CST_SONGID
| MPD_CST_NEXTSONG
|
882 MPD_CST_ELAPSED_TIME
| MPD_CST_VOLUME
|
883 MPD_CST_REPEAT
| MPD_CST_RANDOM
| MPD_CST_PERMISSION
884 | MPD_CST_SINGLE_MODE
| MPD_CST_CONSUME_MODE
| MPD_CST_UPDATING
, NULL
);
889 pl3_option_menu_activate();
890 pl3_tool_menu_update();
892 playlist3_fill_server_menu();
896 * items that are caused by the plugin.
898 pl3_update_go_menu();
902 void pl3_style_set_event( GtkWidget
*widget
,
903 GtkStyle
*previous_style
,
906 if (cfg_get_single_value_as_int_with_default(config
, "Default", "use-dark-style-header", TRUE
))
908 gtk_rc_parse_string("widget \"*header*\" style \"dark\"");
911 gboolean
pl3_cat_select_function(GtkTreeSelection
*select
, GtkTreeModel
*model
, GtkTreePath
*path
, gboolean cur_select
, gpointer data
)
914 if(gtk_tree_model_get_iter(model
, &iter
, path
))
917 gtk_tree_model_get(model
, &iter
, PL3_CAT_TYPE
, &type
, -1);
918 if(type
>= 0) return TRUE
;
922 void pl3_sidebar_text_get_key_number( GtkTreeViewColumn
*column
,
923 GtkCellRenderer
*renderer
,
930 GtkTreePath
*pa1
= gtk_tree_model_get_path(model
, d_iter
);
931 if(!alt_button_pressed
) {
932 g_object_set(G_OBJECT(renderer
), "show-number", FALSE
, NULL
);
935 if (gtk_tree_model_get_iter_first(pl3_tree
, &iter
))
939 gtk_tree_model_get(pl3_tree
, &iter
, PL3_CAT_TYPE
, &type
, -1);
940 if(type
>= 0) number
++;
943 GtkTreePath
*pa2
= gtk_tree_model_get_path(model
, &iter
);
944 if(gtk_tree_path_compare(pa2
, pa1
) == 0){
945 g_object_set(G_OBJECT(renderer
), "number", number
%10, NULL
);
946 g_object_set(G_OBJECT(renderer
), "show-number", TRUE
, NULL
);
947 gtk_tree_path_free(pa2
);
948 gtk_tree_path_free(pa1
);
951 gtk_tree_path_free(pa2
);
953 }while(gtk_tree_model_iter_next(pl3_tree
, &iter
));
955 gtk_tree_path_free(pa1
);
956 g_object_set(G_OBJECT(renderer
), "number", number
, NULL
);
957 g_object_set(G_OBJECT(renderer
), "show-number", FALSE
, NULL
);
960 void create_playlist3(void)
963 GtkCellRenderer
*renderer
;
965 GtkTreeSelection
*sel
;
966 GtkTreeViewColumn
*column
= NULL
;
969 GError
*error
= NULL
;
971 /* indicate that the playlist is not hidden */
975 * If the playlist already exists,
976 * It is probably coming from a hidden state,
977 * so re-position the window
981 pl3_show_and_position_window();
985 /** Ambiance / Radiance theme "dark" header */
986 if (cfg_get_single_value_as_int_with_default(config
, "Default", "use-dark-style-header", TRUE
))
988 gtk_rc_parse_string("widget \"*header*\" style \"dark\"");
991 /** use background color for the sidebar treeview cells */
992 gtk_rc_parse_string (
993 "style \"sidebar-treeview\"\n"
995 " GtkTreeView::odd-row-color = @bg_color\n"
996 " GtkTreeView::even-row-color = @bg_color\n"
998 "widget \"*.sidebar.*\" style \"sidebar-treeview\"");
1001 gtk_rc_parse_string (
1002 "style \"menubar-style\"\n"
1004 " GtkMenuBar::shadow-type = none\n"
1006 "widget \"*.menubar\" style \"menubar-style\"\n");
1008 /* initial, setting the url hook */
1009 gtk_about_dialog_set_url_hook((GtkAboutDialogActivateLinkFunc
) about_dialog_activate
, NULL
, NULL
);
1010 TEC("Setup dialog url hook")
1011 /* load gui desciption */
1012 path
= gmpc_get_full_glade_path("playlist3.ui");
1014 pl3_xml
= gtk_builder_new();
1015 TEC("create builder")
1016 if(gtk_builder_add_from_file(pl3_xml
, path
,&error
) == 0)
1019 * Check if the file is loaded, if not then show an error message and abort the program
1020 if (pl3_xml == NULL)
1023 g_log(LOG_DOMAIN
, G_LOG_LEVEL_WARNING
, "Failed to open playlist3.glade: %s\n", error
->message
);
1027 TEC("Load builder file")
1029 /* create tree store for the "category" view */
1030 if (pl3_tree
== NULL
)
1034 G_TYPE_INT
, /* row type, see free_type struct */
1035 G_TYPE_STRING
, /* display name */
1036 G_TYPE_STRING
, /* full path and stuff for backend */
1037 G_TYPE_STRING
, /* icon id */
1038 G_TYPE_INT
, /* ordering */
1039 G_TYPE_INT
, /* Bold */
1040 G_TYPE_STRING
/* stock id */
1042 /* song id, song title */
1043 pl3_tree
= (GtkTreeModel
*) gmpc_tools_liststore_sort_new();
1044 gtk_list_store_set_column_types(GTK_LIST_STORE(pl3_tree
), PL3_CAT_NROWS
, types
);
1046 TEC("Setup pl3_tree")
1050 playlist3_insert_browser(&iter
, PL3_CAT_BROWSER_LIBRARY
);
1051 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), &iter
,
1052 PL3_CAT_TYPE
,-1, PL3_CAT_TITLE
, _("Library"),PL3_CAT_BOLD
, PANGO_WEIGHT_ULTRABOLD
,-1);
1054 playlist3_insert_browser(&iter
, PL3_CAT_BROWSER_ONLINE_MEDIA
);
1055 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), &iter
,
1056 PL3_CAT_TYPE
,-1, PL3_CAT_TITLE
, _("Online Media"),PL3_CAT_BOLD
, PANGO_WEIGHT_ULTRABOLD
,-1);
1058 playlist3_insert_browser(&iter
, PL3_CAT_BROWSER_MISC
);
1059 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), &iter
,
1060 PL3_CAT_TYPE
,-1, PL3_CAT_TITLE
, _("Misc."),PL3_CAT_BOLD
, PANGO_WEIGHT_ULTRABOLD
,-1);
1064 tree
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "cat_tree"));
1065 gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
)),
1066 pl3_cat_select_function
, pl3_tree
, NULL
);
1068 gtk_tree_view_set_model(GTK_TREE_VIEW(tree
), GTK_TREE_MODEL(pl3_tree
));
1069 sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
1070 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(sel
), GTK_SELECTION_BROWSE
);
1071 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(tree
), TRUE
);
1072 // Enable tooltip on the treeview.
1073 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(tree
), PL3_CAT_TITLE
);
1075 sidebar_text
= renderer
= my_cell_renderer_new();//gtk_cell_renderer_pixbuf_new();
1076 g_object_set(G_OBJECT(renderer
), "xalign", 0.5,NULL
);
1077 column
= gtk_tree_view_column_new();
1080 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
1081 gtk_tree_view_column_set_cell_data_func(column
, sidebar_text
, pl3_sidebar_text_get_key_number
, NULL
, NULL
);
1082 g_object_set(G_OBJECT(renderer
), "stock-size", GTK_ICON_SIZE_MENU
, NULL
);
1085 if (gtk_icon_size_lookup(GTK_ICON_SIZE_MENU
, &w
, &h
))
1087 g_object_set(G_OBJECT(renderer
), "height", h
+10, NULL
);
1088 g_object_set(G_OBJECT(renderer
), "image-width", w
,NULL
);
1091 gtk_tree_view_column_set_attributes(column
, renderer
,
1092 "icon-name", PL3_CAT_ICON_ID
,
1093 "stock-id", PL3_CAT_STOCK_ID
,
1094 "text", PL3_CAT_TITLE
,
1095 "weight", PL3_CAT_BOLD
, NULL
);
1096 g_object_set(renderer
, "weight-set", TRUE
, NULL
);
1098 gtk_tree_view_append_column(GTK_TREE_VIEW(tree
), column
);
1099 gtk_tree_view_set_search_column(GTK_TREE_VIEW(tree
), PL3_CAT_TITLE
);
1100 g_signal_connect_after(G_OBJECT(sel
), "changed", G_CALLBACK(pl3_cat_sel_changed
), NULL
);
1102 TEC("setup cat_tree");
1104 /* initialize the category view */
1105 pl3_initialize_tree();
1107 TEC("Init category tree")
1108 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player")));
1111 * The new progress bar
1113 pb
= (GtkWidget
*) gtk_builder_get_object(pl3_xml
, "hbox_progress");
1114 gtk_widget_show(pb
);
1115 g_signal_connect(G_OBJECT(pb
), "seek-event", G_CALLBACK(pl3_pb_seek_event
), NULL
);
1119 TEC("Init progress bar")
1120 /* Make sure change is applied */
1122 playlist3_new_header();
1124 pl3_sidebar_plugins_init();
1127 if (!cfg_get_single_value_as_int_with_default(config
, "Interface", "hide-favorites-icon", FALSE
))
1129 favorites_button
= gmpc_favorites_button_new();
1130 ali
= gtk_alignment_new(0.0, 0.5, 0.0, 0.0);
1131 gtk_container_add(GTK_CONTAINER(ali
), GTK_WIDGET(favorites_button
));
1132 gtk_box_pack_start(GTK_BOX(gtk_builder_get_object(pl3_xml
, "hbox10")), GTK_WIDGET(ali
), FALSE
, FALSE
, 0);
1133 gtk_widget_show_all(GTK_WIDGET(ali
));
1134 TEC("Init fav icon")
1136 playlist_status_changed(connection
,
1137 MPD_CST_STATE
| MPD_CST_SONGID
| MPD_CST_NEXTSONG
|
1138 MPD_CST_ELAPSED_TIME
| MPD_CST_VOLUME
|
1139 MPD_CST_REPEAT
| MPD_CST_RANDOM
| MPD_CST_PERMISSION
1140 | MPD_CST_SINGLE_MODE
| MPD_CST_CONSUME_MODE
, NULL
);
1141 g_signal_connect(G_OBJECT(gtk_builder_get_object(pl3_xml
, "volume_button")),
1142 "value_changed", G_CALLBACK(playlist_player_volume_changed
), NULL
);
1146 /* Restore values from config */
1147 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION
1148 (gtk_builder_get_object
1149 (pl3_xml
, "ViewShowArtistImage")),
1150 cfg_get_single_value_as_int_with_default
1151 (config
, "playlist", "cover-image-enable", 0));
1153 /* connect signals that are defined in the gui description */
1154 gtk_builder_connect_signals(pl3_xml
,NULL
);
1156 TEC("connect signals")
1158 /* select the current playlist */
1159 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pl3_tree
), &iter
))
1161 gtk_tree_selection_select_iter(sel
, &iter
);
1166 * Insert new custom widget
1168 metaimage_album_art
= gmpc_metaimage_new(META_ALBUM_ART
);
1170 /* Hide when requested. */
1171 if (cfg_get_single_value_as_int_with_default(config
, "Interface", "hide-album-art", FALSE
))
1173 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_album_art
), FALSE
);
1175 gtk_box_pack_start(GTK_BOX
1176 (gtk_builder_get_object(pl3_xml
, "hbox_playlist_player")), metaimage_album_art
, FALSE
, TRUE
, 0);
1178 gtk_box_reorder_child(GTK_BOX
1179 (gtk_builder_get_object(pl3_xml
, "hbox_playlist_player")), metaimage_album_art
, 0);
1180 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_album_art
), ALBUM_SIZE_LARGE
);
1181 gmpc_metaimage_set_no_cover_icon(GMPC_METAIMAGE(metaimage_album_art
), (char *)"gmpc");
1182 gmpc_metaimage_set_connection(GMPC_METAIMAGE(metaimage_album_art
), connection
);
1183 /** make sure size is updated */
1184 gmpc_metaimage_set_cover_na(GMPC_METAIMAGE(metaimage_album_art
));
1186 metaimage_artist_art
= gmpc_metaimage_new(META_ARTIST_ART
);
1187 gtk_container_add(GTK_CONTAINER(gtk_builder_get_object(pl3_xml
, "sidebar_artist_image_alignment")), metaimage_artist_art
);
1189 gmpc_metaimage_set_no_cover_icon(GMPC_METAIMAGE(metaimage_artist_art
), (char *)"no-artist");
1190 gmpc_metaimage_set_loading_cover_icon(GMPC_METAIMAGE(metaimage_artist_art
), (char *)"fetching-artist");
1191 gmpc_metaimage_set_connection(GMPC_METAIMAGE(metaimage_artist_art
), connection
);
1192 if (!cfg_get_single_value_as_int_with_default(config
, "playlist", "cover-image-enable", FALSE
))
1194 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art
), FALSE
);
1196 gmpc_metaimage_set_squared(GMPC_METAIMAGE(metaimage_artist_art
), FALSE
);
1197 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_artist_art
), 145);
1199 TEC("Setup metaimages")
1200 /* restore the window's position and size, if the user wants this. */
1201 if (cfg_get_single_value_as_int_with_default(config
, "playlist", "savepossize", 1))
1203 int maximized
= cfg_get_single_value_as_int_with_default(config
, "playlist", "maximized", 0);
1204 /* Load values from config file */
1205 pl3_wsize
.x
= cfg_get_single_value_as_int_with_default(config
, "playlist", "xpos", 0);
1206 pl3_wsize
.y
= cfg_get_single_value_as_int_with_default(config
, "playlist", "ypos", 0);
1207 pl3_wsize
.width
= cfg_get_single_value_as_int_with_default(config
, "playlist", "width", 0);
1208 pl3_wsize
.height
= cfg_get_single_value_as_int_with_default(config
, "playlist", "height", 0);
1210 /* restore location + position */
1211 /*pl3_show_and_position_window(); */
1213 if (pl3_wsize
.x
> 0 || pl3_wsize
.y
> 0)
1215 gtk_window_move(GTK_WINDOW(playlist3_get_window()), pl3_wsize
.x
, pl3_wsize
.y
);
1217 TEC("move window settings")
1218 if (pl3_wsize
.height
> 0 && pl3_wsize
.width
> 0)
1220 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "restore size %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
1221 gtk_window_resize(GTK_WINDOW(playlist3_get_window()), pl3_wsize
.width
, pl3_wsize
.height
);
1223 TEC("resize window settings")
1224 /* restore pane position */
1225 gtk_widget_set_size_request(GTK_WIDGET(gtk_builder_get_object(pl3_xml
,"sidebar")),
1227 TEC("set pane window settings")
1229 gtk_window_maximize(GTK_WINDOW(playlist3_get_window()));
1230 TEC("maximize pane window settings")
1232 * restore zoom level
1235 gtk_widget_show(playlist3_get_window());
1237 pl3_zoom
= cfg_get_single_value_as_int_with_default(config
, "playlist", "zoomlevel", PLAYLIST_NO_ZOOM
);
1238 playlist_zoom_level_changed();
1241 #ifdef HAVE_APP_INDICATOR
1242 tray_icon2_update_menu();
1245 TEC("Restore state")
1246 pl3_update_go_menu();
1248 /* make it update itself */
1249 pl3_update_profiles_menu(gmpc_profiles
, PROFILE_ADDED
, -1, NULL
);
1250 g_signal_connect(G_OBJECT(gmpc_profiles
), "changed", G_CALLBACK(pl3_update_profiles_menu
), NULL
);
1251 g_signal_connect(G_OBJECT(gmpc_profiles
), "changed", G_CALLBACK(pl3_profiles_changed
), NULL
);
1253 TEC("Update profiles")
1255 * Set as drag destination
1257 gtk_drag_dest_set(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox_playlist_player")),
1258 GTK_DEST_DEFAULT_ALL
,
1259 target_table
, 6, GDK_ACTION_COPY
| GDK_ACTION_LINK
| GDK_ACTION_DEFAULT
| GDK_ACTION_MOVE
);
1260 g_signal_connect(G_OBJECT
1261 (gtk_builder_get_object(pl3_xml
, "hbox_playlist_player")),
1262 "drag_data_received", GTK_SIGNAL_FUNC(playlist3_source_drag_data_recieved
), NULL
);
1268 playlist_connection_changed(connection
, FALSE
, NULL
);
1270 g_signal_connect(G_OBJECT(playlist3_get_window()), "window-state-event", G_CALLBACK(pl3_win_state_event
), NULL
);
1272 TEC("signal connn changed")
1274 g_signal_connect(G_OBJECT(playlist3_get_window()), "style-set", G_CALLBACK(pl3_style_set_event
), NULL
);
1279 main_window_init_default_status_icons();
1280 main_window_update_status_icons();
1282 TEC("Update status icon")
1284 init_extra_playlist_state();
1285 TEC("Setup extra playlist")
1292 GtkListStore
*playlist3_get_category_tree_store(void)
1294 if (pl3_xml
== NULL
)
1296 return GTK_LIST_STORE(pl3_tree
);
1300 GtkTreeView
*playlist3_get_category_tree_view(void)
1302 if (pl3_xml
== NULL
)
1304 return (GtkTreeView
*) gtk_builder_get_object(pl3_xml
, "cat_tree");
1307 GtkWidget
* playlist3_get_widget_by_id(const char *id
) {
1308 return (GtkWidget
*) gtk_builder_get_object(pl3_xml
, id
);
1312 /****************************************************************************************
1314 ****************************************************************************************/
1315 /* prototyping for glade */
1316 void ck_stop_on_exit_toggled_cb(GtkToggleButton
* but
, gpointer data
);
1317 void ck_show_tooltip_enable_tb(GtkToggleButton
* but
);
1319 G_MODULE_EXPORT
void show_cover_case_tb(GtkToggleButton
* but
)
1321 int bool1
= gtk_toggle_button_get_active(but
);
1322 cfg_set_single_value_as_int(config
, "metaimage", "addcase", bool1
);
1323 gmpc_meta_watcher_force_reload(gmw
);
1327 G_MODULE_EXPORT
void ck_stop_on_exit_toggled_cb(GtkToggleButton
* but
, gpointer data
)
1329 int bool1
= gtk_toggle_button_get_active(but
);
1330 cfg_set_single_value_as_int(config
, "connection", "stop-on-exit", bool1
);
1334 G_MODULE_EXPORT
void hide_on_close_enable_tb(GtkToggleButton
* but
)
1336 int bool1
= gtk_toggle_button_get_active(but
);
1337 cfg_set_single_value_as_int(config
, "playlist", "hide-on-close", bool1
);
1341 G_MODULE_EXPORT
void cur_song_center_enable_tb(GtkToggleButton
* but
)
1343 int bool1
= gtk_toggle_button_get_active(but
);
1344 cfg_set_single_value_as_int(config
, "playlist", "st_cur_song", bool1
);
1348 G_MODULE_EXPORT
void save_possize_enable_tb(GtkToggleButton
* but
)
1350 int bool1
= gtk_toggle_button_get_active(but
);
1351 cfg_set_single_value_as_int(config
, "playlist", "savepossize", bool1
);
1355 G_MODULE_EXPORT
void ck_show_tooltip_enable_tb(GtkToggleButton
* but
)
1357 int bool1
= gtk_toggle_button_get_active(but
);
1358 cfg_set_single_value_as_int(config
, "GmpcTreeView", "show-tooltip", bool1
);
1362 G_MODULE_EXPORT
void ck_search_as_you_type(GtkToggleButton
* but
)
1364 int bool1
= gtk_toggle_button_get_active(but
);
1365 cfg_set_single_value_as_int(config
, "general", "search-as-you-type", bool1
);
1369 static void playlist_pref_destroy(GtkWidget
* container
)
1371 if (playlist_pref_xml
)
1373 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(playlist_pref_xml
,
1375 gtk_container_remove(GTK_CONTAINER(container
), vbox
);
1376 g_object_unref(playlist_pref_xml
);
1377 playlist_pref_xml
= NULL
;
1382 void playlist_pref_construct(GtkWidget
* container
)
1384 GError
*error
= NULL
;
1385 gchar
*path
= gmpc_get_full_glade_path("preferences-playlist.ui");
1386 playlist_pref_xml
= gtk_builder_new();
1388 gtk_builder_add_from_file(playlist_pref_xml
, path
, &error
);
1390 g_warning("Failed to open builder file: %s", error
->message
);
1391 g_error_free(error
);
1394 if (playlist_pref_xml
)
1396 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(playlist_pref_xml
,
1398 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1399 (gtk_builder_get_object
1400 (playlist_pref_xml
, "ck_ps")),
1401 cfg_get_single_value_as_int_with_default(config
, "playlist", "st_cur_song", 0));
1402 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1403 (gtk_builder_get_object
1404 (playlist_pref_xml
, "ck_possize")),
1405 cfg_get_single_value_as_int_with_default(config
, "playlist", "savepossize", 1));
1406 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1407 (gtk_builder_get_object
1408 (playlist_pref_xml
, "ck_hide_on_close")),
1409 cfg_get_single_value_as_int_with_default(config
, "playlist", "hide-on-close", 0));
1411 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1412 (gtk_builder_get_object
1413 (playlist_pref_xml
, "ck_stop_on_exit")),
1414 cfg_get_single_value_as_int_with_default(config
, "connection", "stop-on-exit", 0));
1416 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1417 (gtk_builder_get_object
1418 (playlist_pref_xml
, "ck_cover_case")),
1419 cfg_get_single_value_as_int_with_default(config
, "metaimage", "addcase", TRUE
));
1421 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1422 (gtk_builder_get_object
1423 (playlist_pref_xml
, "ck_show_tooltip")),
1424 cfg_get_single_value_as_int_with_default
1425 (config
, "GmpcTreeView", "show-tooltip", TRUE
));
1427 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1428 (gtk_builder_get_object
1429 (playlist_pref_xml
, "ck_search_as_you_type")),
1430 cfg_get_single_value_as_int_with_default(config
, "general", "search-as-you-type",
1432 gtk_container_add(GTK_CONTAINER(container
), vbox
);
1433 gtk_widget_show_all(vbox
);
1434 gtk_builder_connect_signals(playlist_pref_xml
, NULL
);
1441 * Menu Callback functions
1444 void playlist_menu_repeat_changed(GtkToggleAction
* action
)
1446 int active
= gtk_toggle_action_get_active(action
);
1447 if (active
!= mpd_player_get_repeat(connection
))
1449 mpd_player_set_repeat(connection
, active
);
1454 void playlist_menu_random_changed(GtkToggleAction
*action
)
1456 int active
= gtk_toggle_action_get_active(action
);
1457 if (active
!= mpd_player_get_random(connection
))
1459 mpd_player_set_random(connection
, active
);
1464 void playlist_menu_single_mode_changed(GtkToggleAction
* action
)
1466 int active
= gtk_toggle_action_get_active(action
);
1467 if (active
!= mpd_player_get_single(connection
))
1469 mpd_player_set_single(connection
, active
);
1474 void playlist_menu_consume_changed(GtkToggleAction
* action
)
1476 int active
= gtk_toggle_action_get_active(action
);
1477 if (active
!= mpd_player_get_consume(connection
))
1479 mpd_player_set_consume(connection
, active
);
1485 * This is artist image
1488 void playlist_menu_artist_image_changed(GtkToggleAction
*ta
)
1490 int active
= gtk_toggle_action_get_active(ta
);
1491 cfg_set_single_value_as_int(config
, "playlist", "cover-image-enable", active
);
1492 if(pl3_zoom
< PLAYLIST_SMALL
)
1494 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art
), active
);
1496 gtk_widget_show(metaimage_artist_art
);
1504 void playlist_zoom_out(void)
1506 /* Do not change zoom level when fullscreen */
1507 if(pl3_window_is_fullscreen())
1509 if ((pl3_zoom
+ 1) >= PLAYLIST_ZOOM_LEVELS
)
1511 pl3_old_zoom
= pl3_zoom
;
1513 playlist_zoom_level_changed();
1517 void playlist_zoom_in(void)
1519 /* Do not change zoom level when fullscreen */
1520 if(pl3_window_is_fullscreen())
1522 if (pl3_zoom
<= PLAYLIST_NO_ZOOM
)
1524 pl3_old_zoom
= pl3_zoom
;
1526 playlist_zoom_level_changed();
1531 * FIXME: Needs propper grouping and cleaning up
1533 static void playlist_zoom_level_changed(void)
1535 GtkWidget
*pl3_win
= playlist3_get_window();
1536 printf("playlist3 zoom level changed\n");
1538 if (pl3_old_zoom
<= PLAYLIST_SMALL
)
1540 gtk_window_get_size(GTK_WINDOW(pl3_win
), &pl3_wsize
.width
, &pl3_wsize
.height
);
1541 cfg_set_single_value_as_int(config
, "playlist", "width", pl3_wsize
.width
);
1542 cfg_set_single_value_as_int(config
, "playlist", "height", pl3_wsize
.height
);
1543 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "save size: %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
1546 if (pl3_old_zoom
== PLAYLIST_MINI
&& pl3_zoom
!= PLAYLIST_MINI
)
1548 GtkWidget
*box
=GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_button_control_box"));
1549 GtkWidget
*top
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox10"));
1550 GtkWidget
*vtop
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player"));
1551 /* add my own reference */
1553 gtk_container_remove(GTK_CONTAINER(vtop
), box
);
1554 gtk_box_pack_end(GTK_BOX(top
), box
, FALSE
, TRUE
, 0);
1555 gtk_box_reorder_child(GTK_BOX(top
), box
, 0);
1556 /* release my reference */
1557 g_object_unref(box
);
1558 gtk_widget_show(box
);
1559 gmpc_progress_set_hide_text(GMPC_PROGRESS(new_pb
), FALSE
);
1561 /* Album image only if enabled. */
1562 if(metaimage_album_art
!= NULL
)
1564 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_album_art
), ALBUM_SIZE_LARGE
);
1565 gmpc_metaimage_reload_image(GMPC_METAIMAGE(metaimage_album_art
));
1569 if (pl3_old_zoom
!= PLAYLIST_MINI
&& pl3_zoom
== PLAYLIST_MINI
)
1571 GtkWidget
*box
=GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_button_control_box"));
1572 GtkWidget
*top
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox10"));
1573 GtkWidget
*vtop
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "vbox_playlist_player"));
1574 /* add my own reference */
1576 gtk_container_remove(GTK_CONTAINER(top
), box
);
1577 gtk_box_pack_end(GTK_BOX(vtop
), box
, FALSE
, TRUE
, 3);
1578 /* release my reference */
1579 g_object_unref(box
);
1580 gtk_widget_show(box
);
1582 gmpc_progress_set_hide_text(GMPC_PROGRESS(new_pb
), TRUE
);
1584 /* Album image only if enabled. */
1585 if(metaimage_album_art
!= NULL
)
1587 gmpc_metaimage_set_size(GMPC_METAIMAGE(metaimage_album_art
), ALBUM_SIZE_SMALL
);
1588 gmpc_metaimage_reload_image(GMPC_METAIMAGE(metaimage_album_art
));
1593 /* Show full view */
1594 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hpaned1-hbox")));
1595 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox1")));
1596 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hbox10")));
1599 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_button_control_box")));
1601 gtk_window_set_resizable(GTK_WINDOW(pl3_win
), TRUE
);
1602 if (pl3_wsize
.width
> 0 && pl3_wsize
.height
> 0 && pl3_old_zoom
== PLAYLIST_MINI
)
1604 g_log(LOG_DOMAIN
, G_LOG_LEVEL_DEBUG
, "restore size %i %i\n", pl3_wsize
.width
, pl3_wsize
.height
);
1605 gtk_window_resize(GTK_WINDOW(pl3_win
), pl3_wsize
.width
, pl3_wsize
.height
);
1607 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "sidebar")));
1609 if (cfg_get_single_value_as_int_with_default(config
, "playlist", "cover-image-enable", FALSE
))
1611 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art
), TRUE
);
1612 gtk_widget_show(metaimage_artist_art
);
1614 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_go")),TRUE
);
1615 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")),TRUE
);
1618 g_object_get(G_OBJECT(sidebar_text
), "show_text", &st_shown
, NULL
);
1621 /* restore pane position */
1622 g_object_set(sidebar_text
, "show_text", TRUE
, NULL
);
1623 gtk_widget_set_size_request(GTK_WIDGET(gtk_builder_get_object(pl3_xml
,"sidebar")),
1625 gmpc_sidebar_plugins_update_state(GMPC_PLUGIN_SIDEBAR_STATE_FULL
);
1628 /* Now start hiding */
1631 case PLAYLIST_NO_ZOOM
:
1634 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "hpaned1-hbox")));
1635 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_option")),FALSE
);
1636 gtk_action_set_visible(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_go")),FALSE
);
1637 if (pl3_win
->window
)
1639 if (gdk_window_get_state(pl3_win
->window
) & GDK_WINDOW_STATE_MAXIMIZED
)
1641 gtk_window_unmaximize(GTK_WINDOW(pl3_win
));
1644 if (gdk_window_get_state(pl3_win
->window
) & GDK_WINDOW_STATE_FULLSCREEN
)
1646 gtk_window_unfullscreen(GTK_WINDOW(pl3_win
));
1649 gtk_window_set_resizable(GTK_WINDOW(pl3_win
), FALSE
);
1651 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "sidebar")));
1653 case PLAYLIST_SMALL
:
1654 gmpc_metaimage_set_is_visible(GMPC_METAIMAGE(metaimage_artist_art
), FALSE
);
1656 g_object_set(sidebar_text
, "show_text", FALSE
, NULL
);
1657 gtk_widget_set_size_request(GTK_WIDGET(gtk_builder_get_object(pl3_xml
,"sidebar")),
1660 gtk_widget_queue_draw(GTK_WIDGET(gtk_builder_get_object(pl3_xml
,"sidebar")));
1661 gmpc_sidebar_plugins_update_state(GMPC_PLUGIN_SIDEBAR_STATE_COLLAPSED
);
1663 gtk_widget_grab_focus(pl3_win
);
1669 cfg_set_single_value_as_int(config
, "playlist", "zoomlevel", pl3_zoom
);
1674 * Update the window to status changes in mpd
1676 static void playlist_status_changed(MpdObj
* mi
, ChangedStatusType what
, void *userdata
)
1679 GtkWidget
*pl3_win
= playlist3_get_window();
1681 * if the window isn't there yet, return
1685 control_window_status_update(mi
, what
, control_window
);
1687 * Player state changed
1689 if (what
& MPD_CST_STATE
)
1691 mpd_Song
*song
= mpd_playlist_get_current_song(connection
);
1692 int state
= mpd_player_get_state(mi
);
1695 case MPD_PLAYER_PLAY
:
1697 gchar
*markup
= cfg_get_single_value_as_string_with_default(config
,
1698 "playlist", /* Category */
1699 "window-markup",/* Key */
1701 "[%title% - &[%artist%]]|%name%|%shortfile%"
1704 * Update the image in the menu
1706 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPlayPause")), "gtk-media-pause");
1707 gtk_image_set_from_stock(GTK_IMAGE
1708 (gtk_builder_get_object
1709 (pl3_xml
, "play_button_image")), "gtk-media-pause",
1710 GTK_ICON_SIZE_MENU
);
1713 * Update window title
1715 mpd_song_markup(buffer
, 1024, markup
, mpd_playlist_get_current_song(connection
));
1717 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
1719 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
1722 gchar
*string
= g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles
,
1724 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
1729 gtk_window_set_title(GTK_WINDOW(pl3_win
), buffer
);
1734 case MPD_PLAYER_PAUSE
:
1736 gchar
*markup
= cfg_get_single_value_as_string_with_default(config
,
1737 "playlist", /* Category */
1738 "window-markup",/* Key */
1740 "[%title% - &[%artist%]]|%name%|%shortfile%"
1742 /** Update menu and button images */
1744 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPlayPause")), "gtk-media-play");
1745 gtk_image_set_from_stock(GTK_IMAGE
1746 (gtk_builder_get_object
1747 (pl3_xml
, "play_button_image")), "gtk-media-play",
1748 GTK_ICON_SIZE_MENU
);
1750 * Set paused in Window string
1752 mpd_song_markup(buffer
, 1024 - strlen(_("paused") - 4),
1753 markup
, mpd_playlist_get_current_song(connection
));
1754 /* Append translated paused */
1755 strcat(buffer
, " (");
1756 strcat(buffer
, _("paused"));
1757 strcat(buffer
, ")");
1759 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
1761 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
1764 gchar
*string
= g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles
,
1766 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
1771 gtk_window_set_title(GTK_WINDOW(pl3_win
), buffer
);
1776 gtk_action_set_stock_id(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPlayPause")), "gtk-media-play");
1777 /* Make sure it's reset correctly */
1778 gmpc_progress_set_time(GMPC_PROGRESS(new_pb
), 0, 0);
1780 gtk_image_set_from_stock(GTK_IMAGE
1781 (gtk_builder_get_object
1782 (pl3_xml
, "play_button_image")), "gtk-media-play",
1783 GTK_ICON_SIZE_MENU
);
1784 if (gmpc_profiles_get_number_of_profiles(gmpc_profiles
) > 1)
1786 gchar
*id
= gmpc_profiles_get_current(gmpc_profiles
);
1789 gchar
*string
= g_strdup_printf("[%s] %s", gmpc_profiles_get_name(gmpc_profiles
,
1791 gtk_window_set_title(GTK_WINDOW(pl3_win
), string
);
1796 gtk_window_set_title(GTK_WINDOW(pl3_win
), _("GMPC"));
1798 playlist3_update_header();
1800 if(favorites_button
!= NULL
)
1802 if (state
== MPD_PLAYER_PLAY
|| state
== MPD_PLAYER_PAUSE
)
1804 gmpc_favorites_button_set_song(favorites_button
, song
);
1807 gmpc_favorites_button_set_song(favorites_button
, NULL
);
1812 * Handle song change or Playlist change
1813 * Anything that can change metadta
1815 if (what
& MPD_CST_SONGID
|| what
& MPD_CST_SONGPOS
|| what
& MPD_CST_PLAYLIST
)
1817 playlist3_update_header();
1818 /* make is update markups and stuff */
1819 playlist_status_changed(mi
, MPD_CST_STATE
, NULL
);
1822 * set repeat buttons in menu correct
1824 if (what
& MPD_CST_REPEAT
)
1826 if (mpd_check_connected(connection
))
1828 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "MPDRepeat")),
1829 mpd_player_get_repeat(connection
));
1833 if (what
& MPD_CST_RANDOM
)
1835 if (mpd_check_connected(connection
))
1837 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "MPDRandom")),
1838 mpd_player_get_random(connection
));
1841 if (what
& (MPD_CST_RANDOM
| MPD_CST_REPEAT
| MPD_CST_SINGLE_MODE
| MPD_CST_CONSUME_MODE
))
1843 main_window_update_status_icons();
1845 if (what
& MPD_CST_SINGLE_MODE
)
1847 if (mpd_check_connected(connection
))
1849 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "MPDSingleMode")),
1850 mpd_player_get_single(connection
));
1854 if (what
& MPD_CST_CONSUME_MODE
)
1856 if (mpd_check_connected(connection
))
1858 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "MPDConsumeMode")),
1859 mpd_player_get_consume(connection
));
1862 if (what
& MPD_CST_ELAPSED_TIME
)
1864 if (mpd_check_connected(connection
))
1866 int totalTime
= mpd_status_get_total_song_time(connection
);
1867 int elapsedTime
= mpd_status_get_elapsed_song_time(connection
);
1868 gmpc_progress_set_time(GMPC_PROGRESS(new_pb
), totalTime
, elapsedTime
);
1872 gmpc_progress_set_time(GMPC_PROGRESS(new_pb
), 0, 0);
1875 if (what
& MPD_CST_PERMISSION
)
1877 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDSingleMode")),
1879 mpd_check_connected(connection
) &&
1880 mpd_server_check_command_allowed(connection
, "single") == MPD_SERVER_COMMAND_ALLOWED
1883 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDConsumeMode")),
1885 mpd_check_connected(connection
) &&
1886 mpd_server_check_command_allowed(connection
, "consume") == MPD_SERVER_COMMAND_ALLOWED
1889 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPlayPause")),
1891 mpd_check_connected(connection
) &&
1892 mpd_server_check_command_allowed(connection
, "play") == MPD_SERVER_COMMAND_ALLOWED
1895 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDNext")),
1897 mpd_check_connected(connection
) &&
1898 mpd_server_check_command_allowed(connection
, "next") == MPD_SERVER_COMMAND_ALLOWED
1901 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDPrevious")),
1903 mpd_check_connected(connection
) &&
1904 mpd_server_check_command_allowed(connection
, "previous") == MPD_SERVER_COMMAND_ALLOWED
1907 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDStop")),
1909 mpd_check_connected(connection
) &&
1910 mpd_server_check_command_allowed(connection
, "stop") == MPD_SERVER_COMMAND_ALLOWED
1913 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDRepeat")),
1915 mpd_check_connected(connection
) &&
1916 mpd_server_check_command_allowed(connection
, "repeat") == MPD_SERVER_COMMAND_ALLOWED
1919 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDRandom")),
1921 mpd_check_connected(connection
)&&
1922 mpd_server_check_command_allowed(connection
, "random") == MPD_SERVER_COMMAND_ALLOWED
1925 /* Also update volume stuff */
1926 what
= what
|MPD_CST_VOLUME
;
1929 if (what
& MPD_CST_VOLUME
)
1931 GtkWidget
*volume_button
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "volume_button"));
1932 //gtk_scale_button_get_value(GTK_SCALE_BUTTON(volume_button)) * 100;
1933 int volume
= gmpc_widgets_volume_get_volume_level(GMPC_WIDGETS_VOLUME(volume_button
));
1934 int new_volume
= mpd_status_get_volume(connection
);
1935 if (new_volume
>= 0 &&
1936 mpd_server_check_command_allowed(connection
, "setvol") == MPD_SERVER_COMMAND_ALLOWED
1939 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDMuted")),
1942 gtk_widget_set_sensitive(volume_button
, TRUE
);
1943 /* don't do anything if nothing is changed */
1944 if (new_volume
!= volume
)
1946 gmpc_widgets_volume_set_volume_level(GMPC_WIDGETS_VOLUME(volume_button
), new_volume
);
1950 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "MPDMuted")),
1953 gtk_widget_set_sensitive(volume_button
, FALSE
);
1956 if (what
& MPD_CST_SERVER_ERROR
)
1958 gchar
*error
= mpd_status_get_mpd_error(mi
);
1961 gchar
*mes
= g_markup_printf_escaped("%s: '%s'",
1962 _("MPD Reported the following error"),
1964 playlist3_show_error_message(mes
, ERROR_WARNING
);
1969 if (what
& MPD_CST_OUTPUT
)
1971 playlist3_fill_server_menu();
1973 if (what
& MPD_CST_NEXTSONG
)
1976 GtkWidget
*next_button
= GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "next_button"));
1979 int i
= mpd_player_get_next_song_id(mi
);
1982 mpd_Song
*song
= mpd_playlist_get_song(mi
, i
);
1985 mpd_song_markup(buffer
, 1024, "[%title% - &[%artist%]]|%shortfile%", song
);
1986 gtk_widget_set_tooltip_text(next_button
, buffer
);
1989 gtk_widget_set_tooltip_text(next_button
, "");
1991 gtk_widget_set_tooltip_text(next_button
, "");
1996 gboolean
playlist_player_volume_changed(GtkWidget
* vol_but
, int new_vol
)
1998 int volume
= new_vol
; //gtk_scale_button_get_value(GTK_SCALE_BUTTON(vol_but)) * 100;
1999 int new_volume
= mpd_status_get_volume(connection
);
2000 if (new_volume
>= 0 && new_volume
!= volume
)
2002 mpd_status_set_volume(connection
, volume
);
2009 void about_window(void)
2011 gchar
*path
= gmpc_get_full_glade_path("aboutdialog.ui");
2012 GtkBuilder
*xml
= gtk_builder_new();
2013 GtkWidget
*dialog
= NULL
;
2014 gtk_builder_add_from_file(xml
, path
, NULL
);
2015 dialog
= (GtkWidget
*) gtk_builder_get_object(xml
, "aboutdialog");
2017 gtk_window_set_transient_for(GTK_WINDOW(dialog
), GTK_WINDOW(playlist3_get_window()));
2018 gtk_window_set_position(GTK_WINDOW(dialog
), GTK_WIN_POS_CENTER_ON_PARENT
);
2021 if (strlen(revision
))
2023 path
= g_strdup_printf("%s\nRevision: %s", VERSION
, revision
);
2026 path
= g_strdup_printf("%s\n%s\n", VERSION
, GMPC_TAGLINE
);
2028 gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog
), GMPC_COPYRIGHT
);
2029 gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(dialog
), _("Gnome Music Player Client"));
2030 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog
), GMPC_WEBSITE
);
2031 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog
), path
);
2034 gtk_widget_show(dialog
);
2035 gtk_dialog_run(GTK_DIALOG(dialog
));
2036 gtk_widget_destroy(dialog
);
2037 g_object_unref(xml
);
2041 /****************************************************
2044 void pl3_update_go_menu(void)
2048 GtkWidget
*menu
= NULL
;
2049 GtkAccelGroup
*group
= playlist3_get_accel_group();
2050 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
2051 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_go"));
2053 * Remove any old menu
2055 gtk_menu_item_set_submenu(m_item
, NULL
);
2059 menu
= gtk_menu_new();
2060 gtk_menu_set_accel_group(GTK_MENU(menu
), group
);
2061 if (mpd_check_connected(connection
))
2063 for (i
= 0; i
< num_plugins
; i
++)
2065 if (gmpc_plugin_is_browser(plugins
[i
]))
2067 items
+= gmpc_plugin_browser_add_go_menu(plugins
[i
], menu
);
2077 gtk_widget_show_all(menu
);
2078 gtk_menu_item_set_submenu(m_item
, menu
);
2079 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_go")), TRUE
);
2082 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_go")), FALSE
);
2083 g_object_ref_sink(menu
);
2084 g_object_unref(menu
);
2089 static void pl3_profile_selected(GtkRadioMenuItem
* radio
, gpointer data
)
2091 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(radio
)))
2093 gchar
*uid
= g_object_get_data(G_OBJECT(radio
), "uid");
2098 connection_set_current_profile(uid
);
2099 if (mpd_check_connected(connection
))
2101 mpd_disconnect(connection
);
2108 static void pl3_profiles_changed(GmpcProfiles
* prof
, const int changed
, const int col
, const gchar
* id
)
2110 if (!mpd_check_connected(connection
))
2112 playlist_connection_changed(connection
, 0, NULL
);
2117 static void pl3_update_profiles_menu(GmpcProfiles
* prof
, const int changed
, const int col
, const gchar
* id
)
2120 GtkWidget
*menu
= NULL
;
2121 gchar
*current
= gmpc_profiles_get_current(gmpc_profiles
);
2123 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
2124 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_music/menu_profiles"));
2125 /* check if there is anything changed that is important for us. */
2127 if (changed
== PROFILE_COL_CHANGED
&& col
!= PROFILE_COL_NAME
)
2133 * Remove any old menu
2135 gtk_menu_item_set_submenu(m_item
, NULL
);
2139 menu
= gtk_menu_new();
2141 mult
= gmpc_profiles_get_profiles_ids(gmpc_profiles
);
2144 GSList
*group
= NULL
;
2148 /** Get profile name */
2149 const gchar
*value
= gmpc_profiles_get_name(gmpc_profiles
, (char *)iter
->data
);
2150 GtkWidget
*item
= gtk_radio_menu_item_new_with_label(group
, value
);
2152 group
= gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item
));
2153 /* add to the menu */
2154 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
2156 /* check the current profile */
2157 if (!strcmp((char *)(iter
->data
), current
))
2159 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item
), TRUE
);
2163 * Attach click handler
2165 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(pl3_profile_selected
), NULL
);
2167 /** Attach the uid to the handler */
2168 value
= g_strdup((char *)(iter
->data
));
2169 g_object_set_data_full(G_OBJECT(item
), "uid", (gpointer
) value
, g_free
);
2172 } while ((iter
= g_list_next(iter
)));
2173 g_list_foreach(mult
, (GFunc
) g_free
, NULL
);
2183 gtk_widget_show_all(menu
);
2184 gtk_menu_item_set_submenu(m_item
, menu
);
2185 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_profiles")), TRUE
);
2188 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_profiles")), FALSE
);
2189 g_object_ref_sink(menu
);
2190 g_object_unref(menu
);
2196 static void playlist3_server_output_changed(GtkWidget
* item
, gpointer data
)
2198 int id
= GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item
), "id"));
2199 int state
= gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item
));
2200 mpd_server_set_output_device(connection
, id
, state
);
2205 void playlist3_server_update_db(void)
2207 mpd_database_update_dir(connection
, "/");
2211 static GList
*server_menu_items
= NULL
;
2212 static void playlist3_fill_server_menu(void)
2214 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
2215 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_server"));
2216 /** Clear old items */
2217 if(server_menu_items
!= NULL
)
2219 g_list_foreach(server_menu_items
, (GFunc
)gtk_widget_destroy
, NULL
);
2220 g_list_free(server_menu_items
);
2221 server_menu_items
= NULL
;
2224 /* if connected fill with items */
2225 if (mpd_check_connected(connection
))
2227 GtkWidget
*menu
= gtk_menu_item_get_submenu(GTK_MENU_ITEM(m_item
));
2228 GtkWidget
*menu_item
= NULL
;
2230 MpdData
*data
= NULL
;
2232 data
= mpd_server_get_output_devices(connection
);
2235 menu_item
= gtk_separator_menu_item_new();
2236 server_menu_items
= g_list_append(server_menu_items
, menu_item
);
2237 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
2239 for (; data
; data
= mpd_data_get_next(data
))
2241 menu_item
= gtk_check_menu_item_new_with_label(data
->output_dev
->name
);
2242 server_menu_items
= g_list_append(server_menu_items
, menu_item
);
2243 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item
), data
->output_dev
->enabled
? TRUE
: FALSE
);
2244 gtk_widget_add_accelerator(menu_item
, "activate",
2245 gtk_ui_manager_get_accel_group(GTK_UI_MANAGER(ui
)),
2246 GDK_1
+ i
, GDK_CONTROL_MASK
, GTK_ACCEL_VISIBLE
);
2248 g_signal_connect(G_OBJECT(menu_item
), "toggled", G_CALLBACK(playlist3_server_output_changed
), NULL
);
2249 g_object_set_data(G_OBJECT(menu_item
), "id", GINT_TO_POINTER(data
->output_dev
->id
));
2250 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), menu_item
);
2253 gtk_widget_show_all(menu
);
2254 /* Server Menu Item */
2255 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_server")), TRUE
);
2258 /* Server Menu Item */
2259 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_server")), FALSE
);
2269 extern GmpcBrowsersMetadata
*browsers_metadata
;
2271 void info2_activate(void)
2273 GtkTreeView
*tree
= (GtkTreeView
*) gtk_builder_get_object(pl3_xml
, "cat_tree");
2274 gmpc_browsers_metadata_select_browser(browsers_metadata
, tree
);
2278 void info2_fill_song_view(mpd_Song
* song
)
2281 gmpc_browsers_metadata_set_song(browsers_metadata
, song
);
2285 void info2_fill_artist_view(const gchar
* artist
)
2288 gmpc_browsers_metadata_set_artist(browsers_metadata
, artist
);
2292 void info2_fill_album_view(const gchar
* artist
, const gchar
* album
)
2295 gmpc_browsers_metadata_set_album(browsers_metadata
, artist
, album
);
2299 void playlist3_insert_browser(GtkTreeIter
* iter
, gint position
)
2301 GtkTreeIter it
, *sib
= NULL
;
2303 GtkTreeModel
*model
= GTK_TREE_MODEL(pl3_tree
);
2304 if (gtk_tree_model_get_iter_first(model
, &it
))
2308 gtk_tree_model_get(model
, &it
, PL3_CAT_ORDER
, &pos
, -1);
2309 if (position
<= pos
)
2311 } while (sib
== NULL
&& gtk_tree_model_iter_next(model
, &it
));
2313 gtk_list_store_insert_before(GTK_LIST_STORE(pl3_tree
), iter
, sib
);
2314 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), iter
, PL3_CAT_ORDER
, position
, PL3_CAT_BOLD
, PANGO_WEIGHT_NORMAL
, -1);
2322 void playlist3_destroy(void)
2324 GtkWidget
*win
= playlist3_get_window();
2325 if(server_menu_items
) g_list_free(server_menu_items
);
2326 gtk_widget_destroy(win
);
2327 g_object_unref(pl3_xml
);
2330 GtkWidget
*playlist3_get_window(void)
2332 return GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_win"));
2339 /* Make glade happy */
2340 void url_visit_website(void);
2341 void url_getting_help(void);
2343 void url_visit_website(void)
2345 open_uri(GMPC_WEBSITE
);
2349 void url_getting_help(void)
2351 open_uri(GMPC_BUGTRACKER
);
2355 gmpcPrefPlugin playlist_gpp
=
2357 .construct
= playlist_pref_construct
,
2358 .destroy
= playlist_pref_destroy
2361 gmpcPlugin playlist_plug
=
2363 .name
= N_("Interface"),
2364 .version
= {1, 1, 1},
2365 .plugin_type
= GMPC_INTERNALL
,
2366 .mpd_status_changed
= &playlist_status_changed
,
2367 .mpd_connection_changed
= &playlist_connection_changed
,
2368 .pref
= &playlist_gpp
,
2376 void pl3_tool_menu_update(void)
2380 GtkWidget
*menu
= NULL
;
2381 GtkAccelGroup
*group
= gtk_accel_group_new();
2382 GtkUIManager
*ui
= GTK_UI_MANAGER(gtk_builder_get_object(pl3_xml
, "uimanager1"));
2383 GtkMenuItem
*m_item
= GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui
, "/menubartest/menu_tool"));
2384 gtk_menu_item_set_submenu(m_item
, NULL
);
2385 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_tool")), FALSE
);
2386 if (!mpd_check_connected(connection
))
2389 menu
= gtk_menu_new();
2390 gtk_menu_set_accel_group(GTK_MENU(menu
), group
);
2391 g_object_unref(group
);
2392 gtk_window_add_accel_group(GTK_WINDOW(playlist3_get_window()), group
);
2393 for (i
= 0; i
< num_plugins
; i
++)
2395 menu_items
+= gmpc_plugin_tool_menu_integration(plugins
[i
], GTK_MENU(menu
));
2399 gtk_widget_show_all(menu
);
2400 gtk_menu_item_set_submenu(m_item
, menu
);
2401 gtk_action_set_sensitive(GTK_ACTION(gtk_builder_get_object(pl3_xml
, "menu_tool")), TRUE
);
2404 g_object_ref_sink(menu
);
2405 g_object_unref(menu
);
2410 void easy_command_help_window(void)
2412 if (gmpc_easy_command
)
2413 gmpc_easy_command_help_window(gmpc_easy_command
, NULL
);
2419 * Extra wrappings for menu
2421 extern gmpcPlugin extraplaylist_plugin
;
2422 void enable_extra_playlist(GtkToggleAction
*action
)
2424 gboolean state
= gtk_toggle_action_get_active(action
);
2425 if(extraplaylist_plugin
.set_enabled
)
2427 if(extraplaylist_plugin
.get_enabled() != state
)
2429 extraplaylist_plugin
.set_enabled(state
);
2432 preferences_window_update();
2436 void init_extra_playlist_state(void)
2438 GtkToggleAction
*action
= GTK_TOGGLE_ACTION(gtk_builder_get_object(pl3_xml
, "ViewExtraPlaylist"));
2439 if(extraplaylist_plugin
.get_enabled
)
2441 gtk_toggle_action_set_active(action
, extraplaylist_plugin
.get_enabled());
2445 GtkAccelGroup
*playlist3_get_accel_group(void)
2447 static GtkAccelGroup
*group
= NULL
;
2449 group
= gtk_accel_group_new();
2450 gtk_window_add_accel_group(GTK_WINDOW(playlist3_get_window()), group
);
2455 void open_local_file(void)
2458 gboolean found
= FALSE
;
2459 if(!mpd_check_connected(connection
))
2462 /* Check if MPD supports 'file://' (so local files). */
2463 handlers
= mpd_server_get_url_handlers(connection
);
2467 for(; !found
&& handlers
!= NULL
&& handlers
[i
] != NULL
; i
++) {
2468 if(g_utf8_collate(handlers
[i
], "file://") == 0) {
2472 g_strfreev(handlers
);
2474 /* error message or file open */
2476 /* Message not found */
2477 GtkWidget
*gmd
= gtk_message_dialog_new(
2478 (GtkWindow
*)playlist3_get_window(),
2483 "To playback local files, you need to be connected "
2484 "using unix socket.\n"
2485 "See the MPD website for more information."
2488 gtk_dialog_run(GTK_DIALOG(gmd
));
2489 gtk_widget_destroy(GTK_WIDGET(gmd
));
2491 GtkWidget
*fmd
= gtk_file_chooser_dialog_new(
2492 "Select a local file",
2493 (GtkWindow
*)playlist3_get_window(),
2494 GTK_FILE_CHOOSER_ACTION_OPEN
,
2500 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(fmd
), TRUE
);
2501 switch(gtk_dialog_run(GTK_DIALOG(fmd
)))
2503 case GTK_RESPONSE_OK
:
2506 GSList
*uris
= gtk_file_chooser_get_uris(GTK_FILE_CHOOSER(fmd
));
2509 iter
= g_slist_next(iter
))
2511 char *uri
= g_uri_unescape_string(iter
->data
,NULL
);
2512 url_start_real(uri
);
2515 g_slist_foreach (uris
, (GFunc
) g_free
, NULL
);
2516 g_slist_free (uris
);
2522 gtk_widget_destroy(GTK_WIDGET(fmd
));
2526 void show_user_manual(void);
2527 void show_user_manual(void)
2529 open_help("ghelp:gmpc");
2532 GmpcPluginSidebarState
playlist3_get_sidebar_state(void)
2535 g_object_get(G_OBJECT(sidebar_text
), "show_text", &st_shown
, NULL
);
2536 return st_shown
? GMPC_PLUGIN_SIDEBAR_STATE_FULL
:GMPC_PLUGIN_SIDEBAR_STATE_COLLAPSED
;
2538 /* vim: set noexpandtab ts=4 sw=4 sts=4 tw=80: */