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.
25 #include "playlist3.h"
26 #include "mpdinteraction.h"
27 #include "advanced-search.h"
28 #include "gmpc-extras.h"
30 //G_LOCK_DEFINE (connecting_lock);
32 int current_volume
= 0;
34 static GMutex
*connecting_lock
= NULL
; //g_mutex_new();//G_STATIC_MUTEX_INIT;
36 /* Server Settings plugin */
37 static void server_pref_construct(GtkWidget
*);
38 static void server_pref_destroy(GtkWidget
*);
40 /* Connection settings plugin */
41 static void connection_pref_construct(GtkWidget
* container
);
42 static void connection_pref_destroy(GtkWidget
* container
);
44 void server_pref_replaygain_changed(GtkComboBox
* combo
, gpointer data
);
45 static void ServerStatusChangedCallback(MpdObj
* mi
, ChangedStatusType what
, void *userdata
);
47 static GtkBuilder
*server_pref_xml
= NULL
;
48 static GtkBuilder
*connection_pref_xml
= NULL
;
50 gmpcPrefPlugin server_gpp
= {
51 server_pref_construct
,
55 /* Glade prototypes, would be static without glade */
56 void xfade_enable_toggled(GtkToggleButton
* but
);
57 void xfade_time_changed(GtkSpinButton
* but
);
58 void entry_auth_changed(GtkEntry
* entry
);
60 void select_directory_dialog(GtkWidget
*button
);
61 void auth_enable_toggled(GtkToggleButton
* but
);
63 void preferences_window_autoconnect(GtkToggleButton
* tog
);
64 void preferences_window_connect(GtkWidget
* but
);
65 void preferences_window_disconnect(GtkWidget
* but
);
66 void update_preferences_name(GtkWidget
* entry
);
67 void update_preferences_hostname(GtkWidget
* entry
);
68 void update_preferences_portnumber(GtkWidget
* wid
);
69 void update_preferences_information(GtkWidget
* wid
);
70 void connection_profiles_changed(GtkComboBox
* combo
, gpointer data
);
71 void connection_add_profile(GtkWidget
* but
);
72 void connection_remove_profile(GtkWidget
* but
);
73 void submenu_artist_clicked(GtkWidget
* item
);
74 void submenu_album_clicked(GtkWidget
* item
);
75 void submenu_genre_clicked(GtkWidget
* item
);
76 void submenu_dir_clicked(GtkWidget
* item
);
78 static void mpd_interaction_init(void)
82 gmpcPlugin server_plug
= {
83 .name
= N_("Server Settings"), /** name */
84 .version
= {1, 1, 1}, /** Version */
85 .plugin_type
= GMPC_INTERNALL
, /** Plugin Type */
86 .init
= mpd_interaction_init
,/** init */
87 .mpd_status_changed
= ServerStatusChangedCallback
, /** status changed */
88 .pref
= &server_gpp
/** preferences */
99 gmpcPrefPlugin connection_gpp
= {
100 connection_pref_construct
,
101 connection_pref_destroy
104 gmpcPlugin connection_plug
= {
105 .name
= N_("Connection"), /* name */
106 .version
= {1, 1, 1}, /* version */
107 .plugin_type
= GMPC_INTERNALL
, /* type */
108 .pref
= &connection_gpp
/* preferences */
111 guint connecting_pulse
= 0;
112 gboolean
connecting_pulse_callback(void);
113 gboolean
connecting_pulse_callback(void)
117 GtkProgressBar
*pb
= GTK_PROGRESS_BAR(gtk_builder_get_object(pl3_xml
, "pl3_progressbar"));
118 gtk_progress_bar_pulse(pb
);
123 /* this function doesnt use the start/stop_mpd_action because it the user doesnt want to see that */
125 int update_mpd_status(void)
127 if (!mpd_check_connected(connection
))
129 mpd_status_update(connection
);
134 static int connected_to_mpd(mpd_Connection
* mpd_conn
)
136 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_progressbar")));
137 g_source_remove(connecting_pulse
);
138 connecting_pulse
= 0;
139 g_mutex_unlock(connecting_lock
);
142 mpd_connect_real(connection
, mpd_conn
);
148 static void connection_thread(void)
150 gchar
* hostname
= connection_get_hostname();
151 mpd_Connection
*conn
= mpd_newConnection(hostname
, connection_get_port(), cfg_get_single_value_as_float_with_default(config
, "connection", "timeout", DEFAULT_TIMEOUT
));
154 g_idle_add((GSourceFunc
) connected_to_mpd
, conn
);
158 /* the functiont that connects to mpd */
159 int connect_to_mpd(void)
162 if (connecting_lock
== NULL
)
164 connecting_lock
= g_mutex_new();
166 if (! /*G_TRYLOCK */ g_mutex_trylock(connecting_lock
))
173 string
= connection_get_hostname();
174 mpd_set_hostname(connection
, string
);
179 mpd_set_port(connection
, connection_get_port());
183 mpd_set_connection_timeout(connection
,
184 cfg_get_single_value_as_float_with_default(config
, "connection", "timeout",
187 if (connection_use_auth())
189 string
= connection_get_password();
190 mpd_set_password(connection
, string
);
194 mpd_set_password(connection
, "");
196 g_thread_create((GThreadFunc
) connection_thread
, NULL
, FALSE
, NULL
);
197 connecting_pulse
= g_timeout_add(200, (GSourceFunc
) (connecting_pulse_callback
), NULL
);
198 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(gtk_builder_get_object(pl3_xml
, "pl3_progressbar")), _("Connecting"));
199 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(pl3_xml
, "pl3_progressbar")));
203 mpd_stats_update(connection);
205 /* set that user wants to connect */
206 gmpc_connected
= TRUE
;
211 /******************************************************
215 /* the normal play functions, stop, play, next, prev */
216 /* returns FALSE when everything went ok */
219 if (mpd_server_check_command_allowed(connection
, "next") == MPD_SERVER_COMMAND_ALLOWED
)
221 mpd_player_next(connection
);
228 if (mpd_server_check_command_allowed(connection
, "previous") == MPD_SERVER_COMMAND_ALLOWED
)
229 mpd_player_prev(connection
);
235 if (mpd_server_check_command_allowed(connection
, "stop") == MPD_SERVER_COMMAND_ALLOWED
)
236 mpd_player_stop(connection
);
244 mpd_check_connected(connection
) &&
245 mpd_server_check_command_allowed(connection
, "pause") == MPD_SERVER_COMMAND_ALLOWED
)
246 mpd_player_pause(connection
);
250 int real_play_song(void)
252 if (mpd_server_check_command_allowed(connection
, "play") == MPD_SERVER_COMMAND_ALLOWED
)
253 mpd_player_play(connection
);
257 int real_pause_song(void)
259 int state
= mpd_player_get_state(connection
);
260 if (state
== MPD_PLAYER_PLAY
)
262 if (mpd_server_check_command_allowed(connection
, "pause") == MPD_SERVER_COMMAND_ALLOWED
)
263 mpd_player_pause(connection
);
269 int state
= mpd_player_get_state(connection
);
270 if (state
== MPD_PLAYER_STOP
)
272 if (mpd_server_check_command_allowed(connection
, "play") == MPD_SERVER_COMMAND_ALLOWED
)
273 mpd_player_play(connection
);
274 } else if (state
== MPD_PLAYER_PAUSE
|| state
== MPD_PLAYER_PLAY
)
276 if (mpd_server_check_command_allowed(connection
, "pause") == MPD_SERVER_COMMAND_ALLOWED
)
277 mpd_player_pause(connection
);
282 void random_pl(GtkToggleButton
* tb
)
284 if (gtk_toggle_button_get_active(tb
) != mpd_player_get_random(connection
))
285 mpd_player_set_random(connection
, !mpd_player_get_random(connection
));
288 void repeat_pl(GtkToggleButton
* tb
)
290 if (gtk_toggle_button_get_active(tb
) != mpd_player_get_repeat(connection
))
291 mpd_player_set_repeat(connection
, !mpd_player_get_repeat(connection
));
296 if (mpd_server_check_command_allowed(connection
, "seek") == MPD_SERVER_COMMAND_ALLOWED
)
297 mpd_player_seek(connection
, mpd_status_get_elapsed_song_time(connection
) + n
);
306 void song_fastforward(void)
311 void song_fastbackward(void)
316 void repeat_toggle(void)
318 mpd_player_set_repeat(connection
, !mpd_player_get_repeat(connection
));
321 void repeat_single_toggle(void)
323 mpd_player_set_single(connection
, !mpd_player_get_single(connection
));
326 void consume_toggle(void)
328 mpd_player_set_consume(connection
, !mpd_player_get_consume(connection
));
331 void random_toggle(void)
333 mpd_player_set_random(connection
, !mpd_player_get_random(connection
));
338 mpd_status_set_volume(connection
, mpd_status_get_volume(connection
) + 5);
341 void volume_down(void)
343 mpd_status_set_volume(connection
, mpd_status_get_volume(connection
) - 5);
346 void volume_mute(void)
348 mpd_status_set_volume(connection
, 0);
351 void volume_unmute(void)
353 if (mpd_status_get_volume(connection
) == 0)
354 mpd_status_set_volume(connection
, current_volume
);
357 void volume_toggle_mute(void)
359 if (current_volume
> 0 && mpd_status_get_volume(connection
) == 0)
361 mpd_status_set_volume(connection
, current_volume
);
364 mpd_status_set_volume(connection
, 0);
368 /*****************************************************************
371 static void outputs_toggled(GtkCellRendererToggle
* cell
, gchar
* path_str
, GtkTreeView
* view
)
376 GtkTreeModel
*model
= gtk_tree_view_get_model(view
);
377 GtkTreePath
*path
= gtk_tree_path_new_from_string(path_str
);
379 if (gtk_tree_model_get_iter(model
, &iter
, path
))
381 gtk_tree_model_get(model
, &iter
, ENABLED_COL
, &state
, ID_COL
, &id
, -1);
383 mpd_server_set_output_device(connection
, id
, state
);
385 gtk_list_store_set(GTK_LIST_STORE(model
), &iter
, ENABLED_COL
, state
, -1);
387 gtk_tree_path_free(path
);
390 static void create_outputs_tree(void)
393 GtkCellRenderer
*cell
;
394 GtkTreeViewColumn
*col
;
397 tree
= GTK_TREE_VIEW(gtk_builder_get_object(server_pref_xml
, "tv_outputs"));
398 model
= gtk_list_store_new(3, G_TYPE_BOOLEAN
, G_TYPE_STRING
, G_TYPE_INT
);
399 gtk_tree_view_set_model(tree
, GTK_TREE_MODEL(model
));
400 g_object_unref(G_OBJECT(model
));
402 cell
= gtk_cell_renderer_toggle_new();
403 col
= gtk_tree_view_column_new();
404 gtk_tree_view_column_pack_start(col
, cell
, TRUE
);
405 gtk_tree_view_column_add_attribute(col
, cell
, "active", 0);
406 gtk_tree_view_column_set_title(col
, "Enabled");
407 gtk_tree_view_append_column(tree
, col
);
408 g_signal_connect(G_OBJECT(cell
), "toggled", G_CALLBACK(outputs_toggled
), tree
);
410 cell
= gtk_cell_renderer_text_new();
411 col
= gtk_tree_view_column_new();
412 gtk_tree_view_column_pack_start(col
, cell
, TRUE
);
413 gtk_tree_view_column_add_attribute(col
, cell
, "text", 1);
414 gtk_tree_view_column_set_title(col
, "Name");
415 gtk_tree_view_append_column(tree
, col
);
417 col
= gtk_tree_view_column_new();
418 gtk_tree_view_column_set_visible(col
, FALSE
);
419 gtk_tree_view_append_column(tree
, col
);
422 static void update_outputs_settings(void)
428 frame
= GTK_FRAME(gtk_builder_get_object(server_pref_xml
, "frm_outputs"));
430 GTK_LIST_STORE(gtk_tree_view_get_model
431 (GTK_TREE_VIEW(gtk_builder_get_object(server_pref_xml
, "tv_outputs"))));
432 gtk_list_store_clear(store
);
433 if (mpd_check_connected(connection
) && mpd_server_check_version(connection
, 0, 12, 0))
435 MpdData
*data
= mpd_server_get_output_devices(connection
);
436 while (data
!= NULL
&& data
->output_dev
->id
!= -10)
438 gtk_list_store_append(store
, &iter
);
439 gtk_list_store_set(store
, &iter
,
440 0, data
->output_dev
->enabled
? TRUE
: FALSE
,
441 1, data
->output_dev
->name
, 2, data
->output_dev
->id
, -1);
442 data
= mpd_data_get_next(data
);
444 gtk_widget_set_sensitive(GTK_WIDGET(frame
), TRUE
);
445 gtk_widget_show_all(GTK_WIDGET(frame
));
448 gtk_widget_set_sensitive(GTK_WIDGET(frame
), FALSE
);
452 void xfade_enable_toggled(GtkToggleButton
* but
)
455 int bool1
= gtk_toggle_button_get_active(but
);
456 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "sb_fade_time")), bool1
);
460 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
461 (gtk_builder_get_object(server_pref_xml
, "sb_fade_time")));
462 mpd_status_set_crossfade(connection
, fade_time
);
465 mpd_status_set_crossfade(connection
, 0);
469 void xfade_time_changed(GtkSpinButton
* but
)
472 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
473 (gtk_builder_get_object(server_pref_xml
, "sb_fade_time")));
474 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(server_pref_xml
, "cb_fading"))))
478 mpd_status_set_crossfade(connection
, fade_time
);
481 static void xfade_update(void)
483 if (mpd_status_get_crossfade(connection
) > 0)
485 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(server_pref_xml
, "sb_fade_time")),
486 mpd_status_get_crossfade(connection
));
488 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(server_pref_xml
, "cb_fading")),
489 mpd_status_get_crossfade(connection
) ? TRUE
: FALSE
);
491 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "sb_fade_time")),
492 (mpd_status_get_crossfade(connection
)) ? TRUE
: FALSE
);
499 void play_path(const gchar
* path
)
503 if (mpd_server_check_command_allowed(connection
, "playlistfind") == MPD_SERVER_COMMAND_ALLOWED
)
505 MpdData
*data
= NULL
;
506 mpd_playlist_search_start(connection
, TRUE
);
507 mpd_playlist_search_add_constraint(connection
, MPD_TAG_ITEM_FILENAME
, path
);
508 data
= mpd_playlist_search_commit(connection
);
511 mpd_player_play_id(connection
, data
->song
->id
);
516 if (mpd_server_check_command_allowed(connection
, "addid") == MPD_SERVER_COMMAND_ALLOWED
)
518 int songid
= mpd_playlist_add_get_id(connection
, (gchar
*) path
);
521 mpd_player_play_id(connection
, songid
);
527 void add_artist(const gchar
* artist
)
529 MpdData
*data
= NULL
;
531 g_return_if_fail(artist
!= NULL
);
533 mpd_database_search_start(connection
, TRUE
);
534 mpd_database_search_add_constraint(connection
, MPD_TAG_ITEM_ARTIST
, artist
);
535 data
= mpd_database_search_commit(connection
);
538 data
= misc_sort_mpddata_by_album_disc_track(data
);
539 for (; data
; data
= mpd_data_get_next(data
))
541 mpd_playlist_queue_add(connection
, data
->song
->file
);
543 mpd_playlist_queue_commit(connection
);
547 void add_album(const gchar
* artist
, const gchar
* album
)
549 MpdData
*data
= NULL
;
551 g_return_if_fail(artist
!= NULL
);
552 g_return_if_fail(album
!= NULL
);
554 mpd_database_search_start(connection
, TRUE
);
555 mpd_database_search_add_constraint(connection
, MPD_TAG_ITEM_ARTIST
, artist
);
556 mpd_database_search_add_constraint(connection
, MPD_TAG_ITEM_ALBUM
, album
);
557 data
= mpd_database_search_commit(connection
);
560 data
= misc_sort_mpddata_by_album_disc_track(data
);
561 for (; data
; data
= mpd_data_get_next(data
))
563 mpd_playlist_queue_add(connection
, data
->song
->file
);
565 mpd_playlist_queue_commit(connection
);
569 void add_genre(const gchar
* genre
)
571 MpdData
*data
= NULL
;
573 g_return_if_fail(genre
!= NULL
);
575 mpd_database_search_start(connection
, TRUE
);
576 mpd_database_search_add_constraint(connection
, MPD_TAG_ITEM_GENRE
, genre
);
577 data
= mpd_database_search_commit(connection
);
580 data
= misc_sort_mpddata_by_album_disc_track(data
);
581 for (; data
; data
= mpd_data_get_next(data
))
583 mpd_playlist_queue_add(connection
, data
->song
->file
);
585 mpd_playlist_queue_commit(connection
);
589 void add_directory(const gchar
* path
)
591 gchar
*dirpath
= g_path_get_dirname(path
);
592 MpdData
*data
= mpd_database_get_directory(connection
, dirpath
);
595 data
= misc_sort_mpddata_by_album_disc_track(data
);
596 for (; data
; data
= mpd_data_get_next(data
))
598 if (data
->type
== MPD_DATA_TYPE_SONG
)
600 mpd_playlist_queue_add(connection
, data
->song
->file
);
603 mpd_playlist_queue_commit(connection
);
608 void ServerStatusChangedCallback(MpdObj
* mi
, ChangedStatusType what
, void *userdata
)
610 if (what
& MPD_CST_VOLUME
)
612 int volume
= mpd_status_get_volume(connection
);
614 current_volume
= volume
;
617 if (!server_pref_xml
)
619 if (what
& MPD_CST_CROSSFADE
)
623 if (what
& MPD_CST_OUTPUT
)
625 update_outputs_settings();
627 if (what
& MPD_CST_REPLAYGAIN
)
631 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(server_pref_xml
, "replay_gain_combo")),
632 mpd_server_get_replaygain_mode(connection
));
637 static void server_pref_destroy(GtkWidget
* container
)
641 GtkWidget
*vbox
= GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "server-vbox"));
642 gtk_container_remove(GTK_CONTAINER(container
), vbox
);
643 g_object_unref(server_pref_xml
);
644 server_pref_xml
= NULL
;
648 void server_pref_replaygain_changed(GtkComboBox
* combo
, gpointer data
)
650 unsigned int cur
= gtk_combo_box_get_active(combo
);
651 if (cur
!= mpd_server_get_replaygain_mode(connection
))
653 if (mpd_server_check_command_allowed(connection
, "replay_gain_mode") == MPD_SERVER_COMMAND_ALLOWED
)
655 mpd_server_set_replaygain_mode(connection
, cur
);
661 static void server_pref_construct(GtkWidget
* container
)
663 gchar
*path
= gmpc_get_full_glade_path("preferences-server.ui");
664 server_pref_xml
= gtk_builder_new();
665 gtk_builder_add_from_file(server_pref_xml
, path
, NULL
);
670 GtkWidget
*vbox
= GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "server-vbox"));
671 GtkWidget
*frame
= GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "replay_gain_frame"));
672 create_outputs_tree();
673 update_outputs_settings();
674 if (!mpd_check_connected(connection
))
676 gtk_widget_set_sensitive(vbox
, FALSE
);
677 gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "hb_warning_mesg")));
680 gtk_widget_set_sensitive(vbox
, TRUE
);
681 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "hb_warning_mesg")));
683 switch (mpd_server_check_command_allowed(connection
, "replay_gain_status"))
685 case MPD_SERVER_COMMAND_ALLOWED
:
687 gtk_combo_box_set_active(GTK_COMBO_BOX(gtk_builder_get_object(server_pref_xml
, "replay_gain_combo")),
688 mpd_server_get_replaygain_mode(connection
));
689 switch (mpd_server_check_command_allowed(connection
, "replay_gain_mode"))
691 case MPD_SERVER_COMMAND_ALLOWED
:
694 gtk_widget_set_sensitive(frame
, FALSE
);
699 case MPD_SERVER_COMMAND_NOT_ALLOWED
:
700 gtk_widget_set_sensitive(frame
, FALSE
);
702 case MPD_SERVER_COMMAND_NOT_SUPPORTED
:
704 gtk_widget_hide(frame
);
707 if (mpd_status_get_crossfade(connection
) == 0)
709 gtk_toggle_button_set_active(
710 GTK_TOGGLE_BUTTON(gtk_builder_get_object(server_pref_xml
, "cb_fading")), FALSE
);
711 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "sb_fade_time")), FALSE
);
714 gtk_toggle_button_set_active(
715 GTK_TOGGLE_BUTTON(gtk_builder_get_object(server_pref_xml
, "cb_fading")), TRUE
);
716 gtk_spin_button_set_value(GTK_SPIN_BUTTON(gtk_builder_get_object(server_pref_xml
, "sb_fade_time")),
717 mpd_status_get_crossfade(connection
));
718 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(server_pref_xml
, "sb_fade_time")), TRUE
);
721 gtk_container_add(GTK_CONTAINER(container
), vbox
);
722 // glade_xml_signal_autoconnect(server_pref_xml);
723 gtk_builder_connect_signals(server_pref_xml
, NULL
);
727 /**************************************************
728 * Connection Preferences *
730 static void gmpc_profiles_changed_pref_win(GmpcProfiles
* prof
, GmpcProfilesAction changed
, GmpcProfilesColumn col
, const char *id
,
735 case GMPC_PROFILES_ACTION_ADDED
:
737 GtkComboBox
*combo
= GTK_COMBO_BOX(gtk_builder_get_object(xml
, "cb_profiles"));
739 const char *name
= gmpc_profiles_get_name(prof
, id
);
740 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
741 gtk_list_store_append(GTK_LIST_STORE(store
), &iter
);
742 gtk_list_store_set(GTK_LIST_STORE(store
), &iter
, 0, id
, 1, name
, -1);
745 case GMPC_PROFILES_ACTION_REMOVED
:
748 case GMPC_PROFILES_ACTION_COL_CHANGED
:
751 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(xml
, "cb_profiles");
752 GtkListStore
*store
= (GtkListStore
*) gtk_combo_box_get_model(combo
);
753 /* tell it to update all the information in the view.
754 * might be to much work, so check id*/
756 if (gtk_combo_box_get_active_iter(combo
, &iter
) && id
)
759 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, -1);
760 if (strcmp(uid
, id
) == 0)
762 connection_profiles_changed(combo
, NULL
);
773 static void gmpc_connection_changed_pref_win(GmpcConnection
* object
, MpdObj
* mi
, int connected
, GtkBuilder
* xml
)
775 if (connected
!= mpd_check_connected(mi
))
779 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(xml
, "bt_con"), TRUE
);
780 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(xml
, "bt_dis"), FALSE
);
783 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(xml
, "bt_con"), FALSE
);
784 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(xml
, "bt_dis"), TRUE
);
788 void entry_auth_changed(GtkEntry
* entry
)
790 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "connection-vbox");
791 gulong
*a
= g_object_get_data(G_OBJECT(vbox
), "profile-signal-handler");
792 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles");
794 GtkListStore
*store
= (GtkListStore
*) gtk_combo_box_get_model(combo
);
795 if (gtk_combo_box_get_active_iter(combo
, &iter
))
797 gchar
*value
= NULL
, *uid
= NULL
;
798 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, 1, &value
, -1);
799 g_signal_handler_block(G_OBJECT(gmpc_profiles
), *a
);
800 gmpc_profiles_set_password(gmpc_profiles
, uid
,
802 gtk_entry_get_text(GTK_ENTRY
804 gtk_builder_get_object(connection_pref_xml
, "entry_auth"))));
805 g_signal_handler_unblock(G_OBJECT(gmpc_profiles
), *a
);
811 void auth_enable_toggled(GtkToggleButton
* but
)
813 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "connection-vbox");
814 gulong
*a
= g_object_get_data(G_OBJECT(vbox
), "profile-signal-handler");
815 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles");
817 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
818 if (gtk_combo_box_get_active_iter(combo
, &iter
))
820 char *value
= NULL
, *uid
= NULL
;
821 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, 1, &value
, -1);
822 g_signal_handler_block(G_OBJECT(gmpc_profiles
), *a
);
824 gmpc_profiles_set_do_auth(gmpc_profiles
, uid
, gtk_toggle_button_get_active(but
));
825 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "entry_auth"),
826 gmpc_profiles_get_do_auth(gmpc_profiles
, uid
));
828 g_signal_handler_unblock(G_OBJECT(gmpc_profiles
), *a
);
834 void update_preferences_name(GtkWidget
* entry
)
836 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "connection-vbox");
837 gulong
*a
= g_object_get_data(G_OBJECT(vbox
), "profile-signal-handler");
838 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles");
840 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
841 if (gtk_combo_box_get_active_iter(combo
, &iter
))
843 char *value
= NULL
, *uid
= NULL
;
844 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, 1, &value
, -1);
845 g_signal_handler_block(G_OBJECT(gmpc_profiles
), *a
);
847 gmpc_profiles_set_name(gmpc_profiles
, uid
,
849 gtk_entry_get_text(GTK_ENTRY
851 gtk_builder_get_object(connection_pref_xml
, "name_entry"))));
852 g_signal_handler_unblock(G_OBJECT(gmpc_profiles
), *a
);
858 gtk_entry_get_text(GTK_ENTRY((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "name_entry")));
859 gtk_list_store_set(GTK_LIST_STORE(store
), &iter
, 1, value
, -1);
863 G_MODULE_EXPORT
void select_directory_dialog(GtkWidget
*button
)
866 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles");
868 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
870 if (gtk_combo_box_get_active_iter(combo
, &iter
))
872 GtkWidget
*d
= gtk_file_chooser_dialog_new(_("Select the music directory"),
873 GTK_WINDOW(gtk_widget_get_toplevel(button
)),
874 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
,
880 GTK_RESPONSE_OK
,NULL
);
881 const char *value
= NULL
; char *uid
= NULL
;
882 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, -1);
883 value
= gmpc_profiles_get_music_directory(gmpc_profiles
, uid
);
884 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(d
), value
);
885 switch(gtk_dialog_run(GTK_DIALOG(d
)))
887 case GTK_RESPONSE_REJECT
:
888 gmpc_profiles_set_music_directory(gmpc_profiles
, uid
,(char *)"");
890 case GTK_RESPONSE_OK
:
891 gmpc_profiles_set_music_directory(gmpc_profiles
, uid
,
892 gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d
)));
897 gtk_widget_destroy(d
);
902 void update_preferences_hostname(GtkWidget
* entry
)
904 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles");
905 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "connection-vbox");
906 gulong
*a
= g_object_get_data(G_OBJECT(vbox
), "profile-signal-handler");
908 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
910 if (gtk_combo_box_get_active_iter(combo
, &iter
))
912 char *value
= NULL
, *uid
= NULL
;
913 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, 1, &value
, -1);
914 g_signal_handler_block(G_OBJECT(gmpc_profiles
), *a
);
916 gmpc_profiles_set_hostname(gmpc_profiles
, uid
,
918 gtk_entry_get_text(GTK_ENTRY
920 gtk_builder_get_object(connection_pref_xml
, "hostname_entry"))));
921 g_signal_handler_unblock(G_OBJECT(gmpc_profiles
), *a
);
928 void update_preferences_portnumber(GtkWidget
* wid
)
930 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "connection-vbox");
931 gulong
*a
= g_object_get_data(G_OBJECT(vbox
), "profile-signal-handler");
932 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles");
934 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
935 if (gtk_combo_box_get_active_iter(combo
, &iter
))
937 char *value
= NULL
, *uid
= NULL
;
938 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, 1, &value
, -1);
939 g_signal_handler_block(G_OBJECT(gmpc_profiles
), *a
);
940 gmpc_profiles_set_port(gmpc_profiles
, uid
,
941 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
943 gtk_builder_get_object(connection_pref_xml
,
945 g_signal_handler_unblock(G_OBJECT(gmpc_profiles
), *a
);
951 void update_preferences_information(GtkWidget
* wid
)
953 cfg_set_single_value_as_float(config
, "connection", "timeout",
955 gtk_spin_button_get_value(GTK_SPIN_BUTTON
957 gtk_builder_get_object(connection_pref_xml
,
960 /* update timeout live */
961 if (mpd_check_connected(connection
))
963 mpd_set_connection_timeout(connection
,
965 gtk_spin_button_get_value(GTK_SPIN_BUTTON
967 gtk_builder_get_object(connection_pref_xml
,
972 void preferences_window_autoconnect(GtkToggleButton
* tog
)
974 cfg_set_single_value_as_int(config
, "connection", "autoconnect", gtk_toggle_button_get_active(tog
));
977 void preferences_window_connect(GtkWidget
* but
)
979 if (connection_pref_xml
)
981 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles");
983 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
984 if (gtk_combo_box_get_active_iter(combo
, &iter
))
987 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, -1);
990 connection_set_current_profile(uid
);
991 if (!mpd_check_connected(connection
))
1000 if (!mpd_check_connected(connection
))
1006 void disconnect_from_mpd(void)
1008 /* set that user doesn't want to connect */
1009 gmpc_connected
= FALSE
;
1010 mpd_disconnect(connection
);
1012 void preferences_window_disconnect(GtkWidget
* but
)
1014 disconnect_from_mpd();
1017 static void connection_pref_destroy(GtkWidget
* container
)
1019 GtkWidget
*widget
= gtk_bin_get_child(GTK_BIN(container
));
1022 if (connection_pref_xml
)
1024 gtk_container_remove(GTK_CONTAINER(container
), widget
);
1025 g_object_unref(connection_pref_xml
);
1026 connection_pref_xml
= NULL
;
1031 void connection_profiles_changed(GtkComboBox
* combo
, gpointer data
)
1033 GtkBuilder
*xml
= connection_pref_xml
;
1035 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
1036 if (gtk_combo_box_get_active_iter(combo
, &iter
))
1038 char *value
= NULL
, *uid
= NULL
, *string
;
1040 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, 1, &value
, -1);
1045 gtk_entry_set_text(GTK_ENTRY((GtkWidget
*) gtk_builder_get_object(xml
, "name_entry")), value
);
1049 string
= g_strdup(gmpc_profiles_get_hostname(gmpc_profiles
, uid
));
1050 gtk_entry_set_text(GTK_ENTRY((GtkWidget
*) gtk_builder_get_object(xml
, "hostname_entry")), string
);
1055 gtk_spin_button_set_value(GTK_SPIN_BUTTON((GtkWidget
*) gtk_builder_get_object(xml
, "port_spin")),
1056 gmpc_profiles_get_port(gmpc_profiles
, uid
));
1059 * Set password check, and entry
1061 string
= gmpc_profiles_get_password(gmpc_profiles
, uid
);
1062 gtk_toggle_button_set_active((GtkToggleButton
*)
1063 gtk_builder_get_object(xml
, "ck_auth"),
1064 gmpc_profiles_get_do_auth(gmpc_profiles
, uid
));
1065 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(xml
, "entry_auth"),
1066 gmpc_profiles_get_do_auth(gmpc_profiles
, uid
));
1068 gtk_entry_set_text(GTK_ENTRY((GtkWidget
*) gtk_builder_get_object(xml
, "entry_auth")),
1073 * Set music directory
1075 md
= gmpc_profiles_get_music_directory(gmpc_profiles
, uid
);
1076 gtk_label_set_text(GTK_LABEL(gtk_builder_get_object(xml
,"music_directory_label")), (md
&& md
[0] != 0)?md
:_("(None)"));
1078 * Only enable the rmeove button when there is more then 1 profile
1080 if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store
), NULL
) > 1)
1082 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(xml
, "remove_butt"), TRUE
);
1085 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(xml
, "remove_butt"), FALSE
);
1093 void connection_add_profile(GtkWidget
* but
)
1095 gchar
*value
= NULL
;
1096 GtkBuilder
*xml
= connection_pref_xml
;
1097 GtkWidget
*vbox
= (GtkWidget
*) gtk_builder_get_object(xml
, "connection-vbox");
1098 gulong
*a
= g_object_get_data(G_OBJECT(vbox
), "profile-signal-handler");
1099 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(xml
, "cb_profiles");
1101 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
1103 g_signal_handler_block(G_OBJECT(gmpc_profiles
), *a
);
1104 value
= gmpc_profiles_create_new_item(gmpc_profiles
, NULL
); /*g_strdup_printf("%u", g_random_int()); */
1105 gtk_list_store_append(GTK_LIST_STORE(store
), &iter
);
1106 gtk_list_store_set(GTK_LIST_STORE(store
), &iter
, 0, value
, 1, "Name", -1);
1107 gtk_combo_box_set_active_iter(GTK_COMBO_BOX((GtkWidget
*) gtk_builder_get_object(xml
, "cb_profiles")), &iter
);
1108 g_signal_handler_unblock(G_OBJECT(gmpc_profiles
), *a
);
1111 void connection_remove_profile(GtkWidget
* but
)
1113 GtkBuilder
*xml
= connection_pref_xml
;
1114 GtkComboBox
*combo
= (GtkComboBox
*) gtk_builder_get_object(xml
, "cb_profiles");
1116 GtkTreeModel
*store
= gtk_combo_box_get_model(combo
);
1117 if (gtk_combo_box_get_active_iter(combo
, &iter
))
1119 char *value
= NULL
, *uid
= NULL
;
1120 gtk_tree_model_get(GTK_TREE_MODEL(store
), &iter
, 0, &uid
, 1, &value
, -1);
1121 gmpc_profiles_remove_item(gmpc_profiles
, uid
);
1122 gtk_list_store_remove(GTK_LIST_STORE(store
), &iter
);
1125 gtk_combo_box_set_active(GTK_COMBO_BOX((GtkWidget
*) gtk_builder_get_object(xml
, "cb_profiles")), 0);
1129 static void destroy_profile_signal_handler(gpointer box
)
1132 g_signal_handler_disconnect(G_OBJECT(gmpc_profiles
), *a
);
1136 static void destroy_connection_signal_handler(gpointer box
)
1139 g_signal_handler_disconnect(G_OBJECT(gmpcconn
), *a
);
1143 static void connection_pref_construct(GtkWidget
* container
)
1146 gchar
*def_profile
= NULL
;
1148 GtkWidget
*vbox
= NULL
;
1149 GtkCellRenderer
*renderer
= NULL
;
1150 GtkListStore
*store
= NULL
;
1151 gchar
*path
= gmpc_get_full_glade_path("preferences-connection.ui");
1152 connection_pref_xml
= gtk_builder_new(); //glade_xml_new(path, "connection-vbox",NULL);
1153 gtk_builder_add_from_file(connection_pref_xml
, path
, NULL
);
1156 vbox
= (GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "connection-vbox");
1161 def_profile
= gmpc_profiles_get_current(gmpc_profiles
);
1162 store
= gtk_list_store_new(2, G_TYPE_STRING
, G_TYPE_STRING
);
1163 gtk_combo_box_set_model(GTK_COMBO_BOX((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles")),
1164 GTK_TREE_MODEL(store
));
1165 renderer
= gtk_cell_renderer_text_new();
1166 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT
1167 ((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles")), renderer
,
1169 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT
1170 ((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles")), renderer
,
1173 mult
= gmpc_profiles_get_profiles_ids(gmpc_profiles
);
1181 const gchar
*value
= gmpc_profiles_get_name(gmpc_profiles
, (char *)iter
->data
);
1182 gtk_list_store_append(store
, &piter
);
1183 gtk_list_store_set(store
, &piter
, 0, iter
->data
, 1, value
, -1);
1184 if (!strcmp((char *)(iter
->data
), def_profile
))
1186 gtk_combo_box_set_active(GTK_COMBO_BOX
1187 ((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles")), i
);
1190 } while ((iter
= g_list_next(iter
)));
1194 /* GtkTreeIter piter;
1195 gchar *value = cfg_get_single_value_as_string_with_default(profiles, "Default", "name", "Default");
1196 gtk_list_store_append(store, &piter);
1197 gtk_list_store_set(store, &piter, 0,"Default", 1,value,-1);
1199 gtk_combo_box_set_active(GTK_COMBO_BOX((GtkWidget *) gtk_builder_get_object(connection_pref_xml, "cb_profiles")),0);
1202 q_free(def_profile
);
1204 connection_profiles_changed(GTK_COMBO_BOX((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "cb_profiles")),
1207 gtk_spin_button_set_value(GTK_SPIN_BUTTON
1208 ((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "timeout_spin")),
1209 (gdouble
) cfg_get_single_value_as_float_with_default(config
, "connection", "timeout",
1211 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
1212 ((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "ck_autocon")),
1213 cfg_get_single_value_as_int_with_default(config
, "connection", "autoconnect", DEFAULT_AUTOCONNECT
));
1215 /* set the right sensitive stuff */
1216 if (!mpd_check_connected(connection
))
1218 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "bt_con"), TRUE
);
1219 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "bt_dis"), FALSE
);
1222 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "bt_con"), FALSE
);
1223 gtk_widget_set_sensitive((GtkWidget
*) gtk_builder_get_object(connection_pref_xml
, "bt_dis"), TRUE
);
1225 gtk_container_add(GTK_CONTAINER(container
), vbox
);
1226 //glade_xml_signal_autoconnect(connection_pref_xml);
1227 gtk_builder_connect_signals(connection_pref_xml
, NULL
);
1229 a
= g_malloc0(sizeof(*a
));
1230 *a
= g_signal_connect(G_OBJECT(gmpc_profiles
), "changed",
1231 G_CALLBACK(gmpc_profiles_changed_pref_win
), connection_pref_xml
);
1232 g_object_set_data_full(G_OBJECT(vbox
), "profile-signal-handler", a
, destroy_profile_signal_handler
);
1234 a
= g_malloc0(sizeof(*a
));
1235 *a
= g_signal_connect(G_OBJECT(gmpcconn
), "connection-changed",
1236 G_CALLBACK(gmpc_connection_changed_pref_win
), connection_pref_xml
);
1237 g_object_set_data_full(G_OBJECT(vbox
), "conn-signal-handler", a
, destroy_connection_signal_handler
);
1241 void connection_set_current_profile(const char *uid
)
1243 gmpc_profiles_set_current(gmpc_profiles
, uid
);
1246 void connection_set_password(char *password
)
1248 gchar
*profile
= gmpc_profiles_get_current(gmpc_profiles
);
1250 * if NULL, or length 0, then disable, else set
1252 if (password
&& password
[0] != '\0')
1254 gmpc_profiles_set_password(gmpc_profiles
, profile
, password
);
1255 gmpc_profiles_set_do_auth(gmpc_profiles
, profile
, TRUE
);
1259 gmpc_profiles_set_password(gmpc_profiles
, profile
, NULL
);
1260 gmpc_profiles_set_do_auth(gmpc_profiles
, profile
, FALSE
);
1265 int connection_use_auth(void)
1268 gchar
*profile
= gmpc_profiles_get_current(gmpc_profiles
);
1269 retv
= gmpc_profiles_get_do_auth(gmpc_profiles
, profile
);
1274 char *connection_get_hostname(void)
1276 gchar
*profile
= gmpc_profiles_get_current(gmpc_profiles
);
1277 gchar
*retv
= gmpc_profiles_get_hostname(gmpc_profiles
, profile
);
1283 int connection_get_port(void)
1286 gchar
*profile
= gmpc_profiles_get_current(gmpc_profiles
);
1287 retv
= gmpc_profiles_get_port(gmpc_profiles
, profile
);
1292 char *connection_get_password(void)
1294 gchar
*profile
= gmpc_profiles_get_current(gmpc_profiles
);
1295 gchar
*retv
= gmpc_profiles_get_password(gmpc_profiles
, profile
);
1300 const char *connection_get_music_directory(void)
1302 gchar
*profile
= gmpc_profiles_get_current(gmpc_profiles
);
1303 const gchar
*retv
= gmpc_profiles_get_music_directory(gmpc_profiles
, profile
);
1309 * Helper menu functions *
1311 void submenu_artist_clicked(GtkWidget
* item
)
1313 gchar
*artist
= g_object_get_data(G_OBJECT(item
), "artist");
1317 void submenu_album_clicked(GtkWidget
* item
)
1319 gchar
*artist
= g_object_get_data(G_OBJECT(item
), "artist");
1320 gchar
*album
= g_object_get_data(G_OBJECT(item
), "album");
1321 add_album(artist
, album
);
1324 void submenu_genre_clicked(GtkWidget
* item
)
1326 gchar
*genre
= g_object_get_data(G_OBJECT(item
), "genre");
1330 void submenu_dir_clicked(GtkWidget
* item
)
1332 gchar
*dir
= g_object_get_data(G_OBJECT(item
), "path");
1336 void submenu_for_song(GtkWidget
* menu
, mpd_Song
* song
)
1341 smenu
= gtk_menu_new();
1344 gchar
*schema
= g_uri_parse_scheme(song
->file
);
1345 /* If it has a schame, it isn't an mpd url */
1348 g_object_ref_sink(smenu
);
1349 g_object_unref(smenu
);
1354 if (song
->artist
&& song
->album
)
1356 /* Add all from album */
1357 sitem
= gtk_image_menu_item_new_with_label(_("All from album"));
1358 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(sitem
),
1359 gtk_image_new_from_icon_name("media-album", GTK_ICON_SIZE_MENU
));
1360 g_object_set_data_full(G_OBJECT(sitem
), "artist", g_strdup(song
->artist
), g_free
);
1361 g_object_set_data_full(G_OBJECT(sitem
), "album", g_strdup(song
->album
), g_free
);
1362 g_signal_connect(G_OBJECT(sitem
), "activate", G_CALLBACK(submenu_album_clicked
), NULL
);
1363 gtk_menu_shell_append(GTK_MENU_SHELL(smenu
), sitem
);
1364 gtk_widget_show(sitem
);
1369 /* Add all from artist */
1370 sitem
= gtk_image_menu_item_new_with_label(_("All from artist"));
1371 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(sitem
),
1372 gtk_image_new_from_icon_name("media-artist", GTK_ICON_SIZE_MENU
));
1373 g_object_set_data_full(G_OBJECT(sitem
), "artist", g_strdup(song
->artist
), g_free
);
1374 g_signal_connect(G_OBJECT(sitem
), "activate", G_CALLBACK(submenu_artist_clicked
), NULL
);
1375 gtk_menu_shell_append(GTK_MENU_SHELL(smenu
), sitem
);
1376 gtk_widget_show(sitem
);
1380 /* Add all from genre */
1381 sitem
= gtk_menu_item_new_with_label(_("All from genre"));
1382 g_object_set_data_full(G_OBJECT(sitem
), "genre", g_strdup(song
->genre
), g_free
);
1383 g_signal_connect(G_OBJECT(sitem
), "activate", G_CALLBACK(submenu_genre_clicked
), NULL
);
1384 gtk_menu_shell_append(GTK_MENU_SHELL(smenu
), sitem
);
1385 gtk_widget_show(sitem
);
1388 /* Add all from file */
1389 sitem
= gtk_image_menu_item_new_with_label(_("All from same directory"));
1390 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(sitem
),
1391 gtk_image_new_from_icon_name("gtk-directory", GTK_ICON_SIZE_MENU
));
1392 g_object_set_data_full(G_OBJECT(sitem
), "path", g_strdup(song
->file
), g_free
);
1393 g_signal_connect(G_OBJECT(sitem
), "activate", G_CALLBACK(submenu_dir_clicked
), NULL
);
1394 gtk_menu_shell_append(GTK_MENU_SHELL(smenu
), sitem
);
1395 gtk_widget_show(sitem
);
1396 /* Create sub menu */
1398 item
= gtk_menu_item_new_with_label(_("Add more"));
1399 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item
), smenu
);
1400 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
1401 gtk_widget_show(item
);
1403 gtk_widget_show(smenu
);
1407 /* vim: set noexpandtab ts=4 sw=4 sts=4 tw=120: */