/* Glurp - A GTK+ client for Music Player Daemon Copyright (C) 2004, 2005 Andrej Kacian This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA http://musicpd.org/glurp.shtml */ #include #include #include #include #include "structs.h" #include "support.h" #include "comm.h" #include "conf.h" #include "player.h" #include "gui.h" extern GladeXML *guixml, *configxml, *plxml, *addxml, *streamxml; extern GlurpState *glurp; /* this should only be called at startup */ gboolean glurp_init_gui() { GtkWidget *window_main = NULL; /* PangoFontDescription *time_font; time_font = pango_font_description_from_string("Sans 14");*/ glurp->progress_dragging = FALSE; glurp->gui_playlist = NULL; debug("Trying to load glurp.glade from installed directory first"); if( !(guixml = glade_xml_new( glade_path(), NULL, NULL )) ) { debug("Could not load glade file, giving up. Goodnight."); } glade_xml_signal_autoconnect( guixml ); create_playlist_liststore(); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(glade_xml_get_widget(guixml, "treeview_playlist")), TRUE); gtk_combo_box_set_active(GTK_COMBO_BOX(glade_xml_get_widget(guixml, "combobox_qsearch_type")), GLURP_QSEARCH_ALL); /* gtk_widget_modify_font(glade_xml_get_widget(guixml, "button_time"), time_font); */ /* put correct icons to player control buttons */ /* prev */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_prev")), gtk_image_new_from_file(DATADIR "pixmaps/player-prev.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_prev")); /* play */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_play")), gtk_image_new_from_file(DATADIR "pixmaps/player-play.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_play")); /* pause */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_pause")), gtk_image_new_from_file(DATADIR "pixmaps/player-pause.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_pause")); /* stop */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_stop")), gtk_image_new_from_file(DATADIR "pixmaps/player-stop.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_stop")); /* next */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_next")), gtk_image_new_from_file(DATADIR "pixmaps/player-next.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_next")); /* connect/disconnect */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_server_disconnect")), gtk_image_new_from_file(DATADIR "pixmaps/offline.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_server_disconnect")); gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_server_connect")), gtk_image_new_from_file(DATADIR "pixmaps/online.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_server_connect")); /* config */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_config")), gtk_image_new_from_file(DATADIR "pixmaps/config.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_config")); /* playlist show/hide */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "togglebutton_playlist")), gtk_image_new_from_file(DATADIR "pixmaps/playlist.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "togglebutton_playlist")); /* repeat */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "togglebutton_repeat")), gtk_image_new_from_file(DATADIR "pixmaps/player-repeat.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "togglebutton_repeat")); /* random */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "togglebutton_random")), gtk_image_new_from_file(DATADIR "pixmaps/player-random.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "togglebutton_random")); /* add */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "togglebutton_pl_add")), gtk_image_new_from_file(DATADIR "pixmaps/add.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "togglebutton_pl_add")); /* remove */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "togglebutton_pl_remove")), gtk_image_new_from_file(DATADIR "pixmaps/remove.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "togglebutton_pl_remove")); /* playlists */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "button_playlists")), gtk_image_new_from_file(DATADIR "pixmaps/playlists.png")); gtk_widget_show_all(glade_xml_get_widget(guixml, "button_playlists")); /* outputs */ gtk_container_add(GTK_CONTAINER(glade_xml_get_widget(guixml, "togglebutton_outputs")), gtk_image_new_from_file(DATADIR "pixmaps/outputs.png")); /* optionally show playlist */ show_gui_playlist(); if(glurp->config->playlist_vis_on_start) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_playlist")), TRUE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_playlist")), FALSE); hide_gui_playlist(); } gui_set_disconnected(); window_main = glade_xml_get_widget( guixml, "glurp_window_main" ); title_print(window_main, NULL); gui_refresh_playlist_columns(); /* a futile attempt to restore saved position if( glurp->config->pos_x != -11000 && glurp->config->pos_y != -11000 ) gtk_window_move(GTK_WINDOW(window_main), glurp->config->pos_x, glurp->config->pos_y); */ /* restore window size if requested */ if( glurp->config->width >= 0 && glurp->config->height >= 0 && glurp->config->save_size ) gtk_window_resize(GTK_WINDOW(window_main), glurp->config->width, glurp->config->height); gtk_window_set_icon(GTK_WINDOW(window_main), gdk_pixbuf_new_from_file(DATADIR "pixmaps/media-audiofile.png", NULL)); debug("Showing main window..."); gtk_widget_show(window_main); return TRUE; } void populate_config() { GtkWidget *w; w = glade_xml_get_widget(configxml, "entry_hostname"); if(glurp->config->server_host) gtk_entry_set_text(GTK_ENTRY(w), glurp->config->server_host); w = glade_xml_get_widget(configxml, "entry_port"); if(glurp->config->server_port) gtk_entry_set_text(GTK_ENTRY(w), g_strdup_printf("%d", glurp->config->server_port)); w = glade_xml_get_widget(configxml, "entry_password"); if(glurp->config->server_pass) gtk_entry_set_text(GTK_ENTRY(w), glurp->config->server_pass); w = glade_xml_get_widget(configxml, "checkbutton_autoconnect"); if(glurp->config->autoconnect) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "checkbutton_save_size"); if(glurp->config->autoconnect) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "checkbutton_playlist_vis"); if(glurp->config->playlist_vis_on_start) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "spinbutton_refresh_rate"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), glurp->config->refresh_rate); w = glade_xml_get_widget(configxml, "checkbutton_col_filename"); if(glurp->config->playlist_columns[PL_FILENAME]) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "checkbutton_col_artist"); if(glurp->config->playlist_columns[PL_ARTIST]) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "checkbutton_col_title"); if(glurp->config->playlist_columns[PL_TITLE]) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "checkbutton_col_album"); if(glurp->config->playlist_columns[PL_ALBUM]) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "checkbutton_col_name"); if(glurp->config->playlist_columns[PL_NAME]) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "checkbutton_col_pos"); if(glurp->config->playlist_columns[PL_POS]) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); w = glade_xml_get_widget(configxml, "checkbutton_col_id"); if(glurp->config->playlist_columns[PL_ID]) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0); } void store_config() { GtkWidget *w; long nr; g_free(glurp->config->server_host); w = glade_xml_get_widget(configxml, "entry_hostname"); glurp->config->server_host = g_strdup(gtk_entry_get_text(GTK_ENTRY(w))); w = glade_xml_get_widget(configxml, "entry_port"); glurp->config->server_port = atoi(gtk_entry_get_text(GTK_ENTRY(w))); g_free(glurp->config->server_pass); w = glade_xml_get_widget(configxml, "entry_password"); glurp->config->server_pass = g_strdup(gtk_entry_get_text(GTK_ENTRY(w))); w = glade_xml_get_widget(configxml, "checkbutton_autoconnect"); glurp->config->autoconnect = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "checkbutton_playlist_vis"); glurp->config->playlist_vis_on_start = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "spinbutton_refresh_rate"); nr = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); if( nr != glurp->config->refresh_rate ) { debug("Refresh rate changed, setting timeout to %dms", nr); glurp->refresh_rate_status++; /* a safety check to keep the counter in loop */ if( glurp->refresh_rate_status > 30000 ) glurp->refresh_rate_status = 0; g_timeout_add(nr, gui_update_cb, GINT_TO_POINTER(glurp->refresh_rate_status)); glurp->config->refresh_rate = nr; } w = glade_xml_get_widget(configxml, "checkbutton_save_size"); glurp->config->save_size = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "checkbutton_col_filename"); glurp->config->playlist_columns[PL_FILENAME] = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "checkbutton_col_artist"); glurp->config->playlist_columns[PL_ARTIST] = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "checkbutton_col_title"); glurp->config->playlist_columns[PL_TITLE] = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "checkbutton_col_album"); glurp->config->playlist_columns[PL_ALBUM] = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "checkbutton_col_name"); glurp->config->playlist_columns[PL_NAME] = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "checkbutton_col_pos"); glurp->config->playlist_columns[PL_POS] = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); w = glade_xml_get_widget(configxml, "checkbutton_col_id"); glurp->config->playlist_columns[PL_ID] = yesno(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); } void create_playlist_liststore() { GtkListStore *liststore; GtkTreeViewColumn *column; GtkCellRenderer *rend; GtkWidget *tv; if(glurp->gui_playlist) return; liststore = gtk_list_store_new( NUM_PL, G_TYPE_STRING, /* filename */ G_TYPE_STRING, /* artist */ G_TYPE_STRING, /* title */ G_TYPE_STRING, /* album */ G_TYPE_STRING, /* track */ G_TYPE_STRING, /* name */ G_TYPE_INT, /* pos */ G_TYPE_INT, /* id */ G_TYPE_INT, /* bold */ G_TYPE_BOOLEAN /* bold-set */ ); debug("playlist liststore created"); tv = glade_xml_get_widget(guixml, "treeview_playlist"); gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(liststore)); gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)), GTK_SELECTION_MULTIPLE); rend = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Filename", rend, "text", PL_FILENAME, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(column, TRUE); column = gtk_tree_view_column_new_with_attributes("Artist", rend, "text", PL_ARTIST, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(column, TRUE); column = gtk_tree_view_column_new_with_attributes("Title", rend, "text", PL_TITLE, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(column, TRUE); column = gtk_tree_view_column_new_with_attributes("Album", rend, "text", PL_ALBUM, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(column, TRUE); column = gtk_tree_view_column_new_with_attributes("Track", rend, "text", PL_TRACK, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(column, FALSE); column = gtk_tree_view_column_new_with_attributes("#", rend, "text", PL_POS, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(column, TRUE); column = gtk_tree_view_column_new_with_attributes("Id", rend, "text", PL_ID, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_widget_show(tv); glurp->gui_playlist = liststore; } void add_song_to_gui_playlist(GlurpSong *song, gint pos) { GtkTreeIter iter; if( !glurp->gui_playlist ) { debug("No playlist liststore!"); return; } if( !song ) { debug("song == NULL, ignoring"); return; } gtk_list_store_append(glurp->gui_playlist, &iter); gtk_list_store_set(glurp->gui_playlist, &iter, PL_POS, pos, -1); if(song->file && g_utf8_validate(song->file, -1, NULL)) gtk_list_store_set(glurp->gui_playlist, &iter, PL_FILENAME, song->file, -1); if(song->artist && g_utf8_validate(song->artist, -1, NULL)) gtk_list_store_set(glurp->gui_playlist, &iter, PL_ARTIST, song->artist, -1); if(song->title && g_utf8_validate(song->title, -1, NULL)) gtk_list_store_set(glurp->gui_playlist, &iter, PL_TITLE, song->title, -1); if(song->album && g_utf8_validate(song->album, -1, NULL)) gtk_list_store_set(glurp->gui_playlist, &iter, PL_ALBUM, song->album, -1); if(song->track && g_utf8_validate(song->track, -1, NULL)) gtk_list_store_set(glurp->gui_playlist, &iter, PL_TRACK, song->track, -1); if(song->name && g_utf8_validate(song->name, -1, NULL)) gtk_list_store_set(glurp->gui_playlist, &iter, PL_NAME, song->name, -1); if( song->pos ) gtk_list_store_set(glurp->gui_playlist, &iter, PL_POS, song->pos + 1, -1); if( song->id ) gtk_list_store_set(glurp->gui_playlist, &iter, PL_ID, song->id, -1); } void populate_gui_playlist() { GlurpSong *s = NULL; gint i = 1; gtk_list_store_clear(glurp->gui_playlist); for( s = glurp->playlist; s; s = s->next ) { add_song_to_gui_playlist(s, i); i++; } statusbar_print("Playlist updated from server"); } void hide_gui_playlist() { gint width, height; gtk_widget_hide(glade_xml_get_widget(guixml, "vbox_playlist")); gtk_window_get_size(GTK_WINDOW(glade_xml_get_widget(guixml, "glurp_window_main")), &width, &height); gtk_window_resize(GTK_WINDOW(glade_xml_get_widget(guixml, "glurp_window_main")), width, 1); } void show_gui_playlist() { gtk_widget_show(glade_xml_get_widget(guixml, "vbox_playlist")); } void create_playlist_list_liststore() { GtkListStore *ls; GtkTreeViewColumn *col; GtkCellRenderer *rend; GtkWidget *tv; if(glurp->gui_playlist_list) return; debug("Creating playlist list liststore..."); ls = gtk_list_store_new(1, G_TYPE_STRING); tv = glade_xml_get_widget(plxml, "treeview_playlist_list"); gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(ls)); rend = gtk_cell_renderer_text_new(); col = gtk_tree_view_column_new_with_attributes("Filename", rend, "text", 0, NULL); gtk_tree_view_column_set_resizable(col, FALSE); gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col); gtk_widget_show(tv); glurp->gui_playlist_list = ls; debug("Playlist list liststore created"); } void gui_set_connecting() { gtk_widget_hide(glade_xml_get_widget(guixml, "button_server_disconnect")); gtk_widget_show(glade_xml_get_widget(guixml, "button_server_connect")); } void gui_set_connected() { mpd_Status *status = NULL; if( !(status = get_status(TRUE)) ) { debug("Couldn't get mpd state, disconnecting"); glurp_disconnect(); return; } if( status->repeat ) { debug("MPD repeat is ON"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_repeat")), TRUE); } else { debug("MPD repeat is OFF"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_repeat")), FALSE); } if( status->random ) { debug("MPD random is ON"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_random")), TRUE); } else { debug("MPD random is OFF"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_random")), FALSE); } gtk_widget_set_sensitive(glade_xml_get_widget(guixml, "volumebar"), TRUE); if( OUTPUTS_CAPABLE_MPD ) gtk_widget_show_all(glade_xml_get_widget(guixml, "togglebutton_outputs")); } void gui_set_disconnected() { gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(guixml, "entry_trackname")), "Not connected..."); gtk_widget_set_sensitive(glade_xml_get_widget(guixml, "progressbar"), FALSE); gtk_widget_set_sensitive(glade_xml_get_widget(guixml, "volumebar"), FALSE); gtk_range_set_value(GTK_RANGE(glade_xml_get_widget(guixml, "progressbar")), 0); gtk_range_set_value(GTK_RANGE(glade_xml_get_widget(guixml, "volumebar")), 0); gtk_button_set_label(GTK_BUTTON(glade_xml_get_widget(guixml, "button_time")), "--:--"); gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(guixml, "label_bitrate")), "---"); gtk_widget_hide(glade_xml_get_widget(guixml, "button_server_connect")); gtk_widget_show(glade_xml_get_widget(guixml, "button_server_disconnect")); gtk_widget_hide(glade_xml_get_widget(guixml, "button_pause")); gtk_widget_show(glade_xml_get_widget(guixml, "button_play")); gtk_widget_hide(glade_xml_get_widget(guixml, "togglebutton_outputs")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_repeat")), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_random")), FALSE); clear_playlist(); gtk_list_store_clear(glurp->gui_playlist); glurp->playlist_version = -1; glurp->scroll = 0; statusbar_print("Disconnected"); } gboolean gui_update_cb(gpointer val) { return gui_update(GPOINTER_TO_INT(val)); } gboolean gui_update(gint refresh_rate_status) { gdouble pos = 0; GlurpSong *s = NULL; mpd_Status *status = NULL; gint tel, e_min, e_sec; gchar *title; gboolean changed = FALSE, firstrun = FALSE; if( DISCONNECTED || DISCONNECTING ) { debug("Resetting GUI to disconnected state."); glurp_disconnect(); return FALSE; } /* detect first run */ if( !glurp->playlist_version ) firstrun = TRUE; if( refresh_rate_status != glurp->refresh_rate_status ) { return FALSE; } mpd_sendCommandListOkBegin(glurp->conn); mpd_sendStatusCommand(glurp->conn); mpd_sendPlChangesCommand(glurp->conn, glurp->playlist_version); mpd_sendCommandListEnd(glurp->conn); if( (status = get_status(FALSE)) ) { mpd_nextListOkCommand(glurp->conn); changed = glurp_process_plchanges(status); mpd_finishCommand(glurp->conn); } else { glurp_disconnect(); return FALSE; } glurp->play_state = status->state; /* PERIODIC: unhilight song */ if( !PLAYING && !PAUSED && glurp->prev_song_num != -1 ) { gui_playlist_hilight(-1); glurp->scroll = 0; } /* PERIODIC: update volumebar */ gtk_range_set_value(GTK_RANGE(glade_xml_get_widget(guixml, "volumebar")), status->volume); /* PERIODIC: save number of current song */ glurp->current_song = glurp_get_nth_song(status->song); /* PERIODIC: check to see if we need to update the playlist from MPD */ if( glurp->playlist_version != status->playlist ) { debug("Playlist version has changed, reloading from server..."); update_playlist(); populate_gui_playlist(); glurp->playlist_version = status->playlist; } /* PERIODIC: update progressbar if a song is playing or paused */ if(!glurp->progress_dragging) { if( PLAYING || PAUSED ) { gtk_widget_set_sensitive(glade_xml_get_widget(guixml, "progressbar"), TRUE); pos = ((double)status->elapsedTime/(double)status->totalTime)*100; gtk_range_set_value(GTK_RANGE(glade_xml_get_widget(guixml, "progressbar")), pos); } else { gtk_widget_set_sensitive(glade_xml_get_widget(guixml, "progressbar"), FALSE); gtk_range_set_value(GTK_RANGE(glade_xml_get_widget(guixml, "progressbar")), 0); } } /* PERIODIC: update song name */ if( PLAYING || PAUSED ) { if( !(s = get_nth_song_from_playlist(status->song)) ) { debug("Could not get song #%d info from playlist", status->song + 1); statusbar_print("Could not get current song information from server, disconnecting..."); glurp_disconnect(); return FALSE; } if( s->artist || s->title ) title = g_strdup_printf("%d. %s - %s", status->song + 1, (s->artist ? s->artist : ""), (s->title ? s->title : "")); else title = g_strdup_printf("%d. %s", status->song + 1, strip_dirs(s->file)); gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(guixml, "entry_trackname")), title); g_free(title); } else { gtk_entry_set_text(GTK_ENTRY(glade_xml_get_widget(guixml, "entry_trackname")), "Stopped..."); } /* PERIODIC: update time display */ if(glurp->config->time_display_left) tel = status->totalTime - status->elapsedTime; else tel = status->elapsedTime; e_min = tel/60; e_sec = tel%60; gtk_button_set_label(GTK_BUTTON(glade_xml_get_widget(guixml, "button_time")), (const gchar *)g_strdup_printf("%s%02d:%02d", (glurp->config->time_display_left ? "-" : ""), e_min, e_sec)); /* PERIODIC: update bitrate and mode labels */ if( PLAYING || PAUSED ) { gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(guixml, "label_bitrate")), g_strdup_printf("%dkbps", status->bitRate)); gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(guixml, "label_mode")), g_strdup_printf("%s", (status->channels > 2 ? "More" : (status->channels == 2 ? "Stereo" : "Mono" )))); } else { gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(guixml, "label_bitrate")), g_strdup("---kbps")); gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(guixml, "label_mode")), g_strdup("---")); } /* PERIODIC: make display correct button from PLAY and PAUSE duo */ if( PLAYING ) { gtk_widget_hide(glade_xml_get_widget(guixml, "button_play")); gtk_widget_show(glade_xml_get_widget(guixml, "button_pause")); } else { gtk_widget_hide(glade_xml_get_widget(guixml, "button_pause")); gtk_widget_show(glade_xml_get_widget(guixml, "button_play")); } /* PERIODIC: update repeat button */ if( status->repeat ) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_repeat")), TRUE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_repeat")), FALSE); } /* PERIODIC: update random button */ if( status->random ) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_random")), TRUE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glade_xml_get_widget(guixml, "togglebutton_random")), FALSE); } if( changed && CONNECTED && (PLAYING || PAUSED) ) { debug("Moving playlist focus to #%d", status->song); g_idle_add_full(G_PRIORITY_LOW, (GSourceFunc)gui_playlist_scroll_cb, GINT_TO_POINTER(status->song), NULL); g_idle_add_full(G_PRIORITY_LOW, (GSourceFunc)gui_playlist_hilight_cb, GINT_TO_POINTER(status->song), NULL); } /* PERIODIC: update bold row when song changes */ if( PLAYING || PAUSED ) { if( status->song != glurp->prev_song_num ) { g_idle_add_full(G_PRIORITY_LOW, (GSourceFunc)gui_playlist_hilight, GINT_TO_POINTER(status->song), NULL); } } /* reset scrolling if song is changed */ if( changed ) { debug("Song changed, stopping titlebar scrolling"); glurp->scroll = 0; } /* PERIODIC: if appropriate, check that trackname is being scrolled */ if( (PLAYING || PAUSED) && !glurp->scroll && \ g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(guixml, "entry_trackname"))), -1) > TRACKNAME_SCROLL_START ) { debug("Starting song scroll"); g_timeout_add(200, gui_trackname_scroll, NULL); glurp->scroll++; } /* PERIODIC: reenable Add window controls if we just finished updating db (>=0.11.0) */ if( NONBLOCKING_UPDATE_CAPABLE_MPD && !status->updatingDb && glurp->updating_db ) { statusbar_print("Database updated"); if( addxml ) { gui_updating_enable_add_controls(); populate_gui_add_tree(); } glurp->updating_db = FALSE; } if( changed ) { if( CONNECTED && (PLAYING || PAUSED) ) { if( firstrun ) { debug("Moving playlist focus"); // g_idle_add_full(G_PRIORITY_LOW, (GSourceFunc)gui_playlist_scroll_cb, GINT_TO_POINTER(status->song), NULL); } g_idle_add_full(G_PRIORITY_LOW, (GSourceFunc)gui_playlist_hilight_cb, GINT_TO_POINTER(status->song), NULL); } } mpd_freeStatus(status); return TRUE; } void add_playlist_to_gui_list(GlurpPl *pl) { GtkTreeIter iter; if( !glurp->gui_playlist_list ) { debug("No playlist list liststore!"); return; } if( !pl ) { debug("pl == NULL, ignoring"); return; } gtk_list_store_append(glurp->gui_playlist_list, &iter); gtk_list_store_set(glurp->gui_playlist_list, &iter, 0, pl->name, -1); } void populate_gui_playlist_list() { GlurpPl *pl; GtkTreeView *tv; GtkTreeModel *tm; GtkTreePath *path; GtkTreeIter iter; gtk_list_store_clear(glurp->gui_playlist_list); if( !glurp->playlists ) return; for( pl = glurp->playlists; pl; pl = pl->next ) { debug("Adding '%s' to gui list", pl->name); add_playlist_to_gui_list(pl); } tv = GTK_TREE_VIEW(glade_xml_get_widget(plxml, "treeview_playlist_list")); tm = gtk_tree_view_get_model(tv); gtk_tree_model_get_iter_first(tm, &iter); path = gtk_tree_model_get_path(tm, &iter); gtk_tree_view_set_cursor(tv, path, gtk_tree_view_get_column(tv, 0), FALSE); gtk_tree_view_columns_autosize(tv); } void playlists_window_destroyed() { if(!plxml && !glurp->gui_playlist_list) return; debug("playlists window destroyed, cleaning up"); plxml = NULL; if( G_IS_OBJECT(glurp->gui_playlist_list) ) g_object_unref(G_OBJECT(glurp->gui_playlist_list)); glurp->gui_playlist_list = NULL; } void gui_playlist_set_cursor(gint pos) { GtkTreeView *tv; GtkTreeModel *tm; GtkTreePath *path; GtkTreeIter iter; debug("Scrolling to row #%d", pos + 1); tv = GTK_TREE_VIEW(glade_xml_get_widget(guixml, "treeview_playlist")); tm = gtk_tree_view_get_model(tv); gtk_tree_model_iter_nth_child(tm, &iter, NULL, pos); path = gtk_tree_model_get_path(tm, &iter); gtk_tree_view_set_cursor(tv, path, gtk_tree_view_get_column(tv, PL_TRACK), FALSE); gtk_tree_path_free(path); } gboolean gui_playlist_scroll_cb(gpointer val) { return gui_playlist_scroll(GPOINTER_TO_INT(val)); } gboolean gui_playlist_scroll(gint pos) { GtkTreeView *tv; GtkTreeModel *tm; GtkTreePath *path; GtkTreeIter iter; debug("Scrolling to row #%d", pos + 1); tv = GTK_TREE_VIEW(glade_xml_get_widget(guixml, "treeview_playlist")); tm = gtk_tree_view_get_model(tv); gtk_tree_model_iter_nth_child(tm, &iter, NULL, pos); path = gtk_tree_model_get_path(tm, &iter); gtk_tree_view_scroll_to_cell(tv, path, NULL, TRUE, 0.5, 0); gtk_tree_view_set_cursor(tv, path, gtk_tree_view_get_column(tv, PL_TRACK), FALSE); gtk_tree_path_free(path); return FALSE; } gboolean gui_playlist_hilight_cb(gpointer val) { return gui_playlist_hilight(GPOINTER_TO_INT(val)); } gboolean gui_playlist_hilight(gint pos) { GtkTreeView *tv; GtkTreeModel *tm; GtkTreeIter iter; if( pos < -1 ) return FALSE; tv = GTK_TREE_VIEW(glade_xml_get_widget(guixml, "treeview_playlist")); tm = gtk_tree_view_get_model(tv); if(glurp->prev_song_num != -1) { gtk_tree_model_iter_nth_child(tm, &iter, NULL, glurp->prev_song_num); gtk_list_store_set(GTK_LIST_STORE(tm), &iter, PL_BOLD, PANGO_WEIGHT_NORMAL, PL_BOLD_SET, TRUE, -1); } glurp->prev_song_num = pos; if( pos >= 0 ) { gtk_tree_model_iter_nth_child(tm, &iter, NULL, pos); gtk_list_store_set(GTK_LIST_STORE(tm), &iter, PL_BOLD, PANGO_WEIGHT_ULTRABOLD, PL_BOLD_SET, TRUE, -1); } return FALSE; } gboolean gui_trackname_scroll() { GtkEntry *entry = GTK_ENTRY(glade_xml_get_widget(guixml, "entry_trackname")); gint length = g_utf8_strlen(gtk_entry_get_text(entry), -1); if( !CONNECTED || !(PLAYING || PAUSED) || length < TRACKNAME_SCROLL_START ) { debug("Scrolling not started"); return FALSE; } if( glurp->scroll == 1 ) { debug("Scrolling started, glurp->scroll = %d", glurp->scroll); glurp->scroll = TRACKNAME_SCROLL_START; } if( glurp->scroll > 0 ) { if( glurp->scroll <= length ) glurp->scroll++; else glurp->scroll = - TRACKNAME_SCROLL_START; } else { if( -(glurp->scroll) < length ) glurp->scroll--; else glurp->scroll = TRACKNAME_SCROLL_START; } if( glurp->scroll > 0 ) gtk_editable_set_position(GTK_EDITABLE(entry), glurp->scroll); else gtk_editable_set_position(GTK_EDITABLE(entry), length + glurp->scroll); if( gtk_widget_is_focus(GTK_WIDGET(entry)) ) gtk_widget_grab_focus(glade_xml_get_widget(guixml, "treeview_playlist")); return TRUE; } void add_window_destroyed() { if( !addxml ) return; debug("'add' window destroyed, cleaning up"); addxml = NULL; } void create_gui_add_tree() { GtkWidget *tv; GtkTreeViewColumn *column; GtkCellRenderer *rend, *prend; debug("Creating 'add' treeview..."); if( !glurp->gui_addtree ) { glurp->gui_addtree = gtk_tree_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, GDK_TYPE_PIXBUF ); debug("'add' treestore created"); } tv = glade_xml_get_widget(addxml, "treeview_add"); rend = gtk_cell_renderer_text_new(); prend = gtk_cell_renderer_pixbuf_new(); column = gtk_tree_view_column_new(); gtk_tree_view_column_pack_end(column, rend, TRUE); gtk_tree_view_column_set_attributes(column, rend, "text", ADD_NAME, NULL); gtk_tree_view_column_pack_start(column, prend, FALSE); gtk_tree_view_column_set_title(column, "Database"); gtk_tree_view_column_add_attribute(column, prend, "pixbuf", ADD_ICON); gtk_tree_view_column_set_resizable(column, FALSE); gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column); column = gtk_tree_view_column_new_with_attributes("", rend, NULL); gtk_tree_view_column_set_resizable(column, FALSE); gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column); gtk_tree_view_column_set_visible(column, FALSE); column = gtk_tree_view_column_new_with_attributes("", rend, NULL); gtk_tree_view_column_set_resizable(column, FALSE); gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column); gtk_tree_view_column_set_visible(column, FALSE); gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)), GTK_SELECTION_MULTIPLE); gtk_widget_show(tv); debug("'add' treeview created"); } void populate_gui_add_tree() { if( !glurp->gui_addtree ) return; gtk_tree_store_clear(GTK_TREE_STORE(glurp->gui_addtree)); glurp->num_add_dirs = 0; glurp_add_add_dir("", NULL); if( !glurp->updating_db ) { debug("Setting 'Add' treeview model"); gtk_tree_view_set_model(GTK_TREE_VIEW(glade_xml_get_widget(addxml, "treeview_add")), GTK_TREE_MODEL(glurp->gui_addtree)); } } void populate_gui_add_search_tree() { GtkComboBox* combo_type; GtkEntry* find_entry; GtkTreeIter iter; GtkTreePath *path; gint n, nd; const gchar *what; if (!glurp->gui_addtree) return; /* remove last toplevel item if it's search results */ n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(glurp->gui_addtree), NULL); gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(glurp->gui_addtree), &iter, NULL, n - 1); gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_addtree), &iter, ADD_NUM_DIRS, &nd, -1); if( nd == -2 ) { /* last item is search results, let's ixnay it */ debug("Removing previous search results treeview item"); gtk_tree_store_remove(glurp->gui_addtree, &iter); } combo_type = GTK_COMBO_BOX(glade_xml_get_widget(addxml, "combo_add_find_type")); debug("Adding a folder for find results"); find_entry = GTK_ENTRY(glade_xml_get_widget(addxml, "entry_add_find_what")); what = gtk_entry_get_text(find_entry); if( what && g_utf8_strlen(what, -1) ) { gtk_tree_store_append(glurp->gui_addtree, &iter, NULL); gtk_tree_store_set(glurp->gui_addtree, &iter, ADD_ICON, gtk_widget_render_icon(glade_xml_get_widget(addxml, "glurp_window_add"), GTK_STOCK_FIND, GTK_ICON_SIZE_SMALL_TOOLBAR, "icon"), ADD_NAME, "Search results", ADD_NUM_DIRS, -2, -1); path = gtk_tree_model_get_path(GTK_TREE_MODEL(glurp->gui_addtree), &iter); glurp_add_search_result_dir( gtk_entry_get_text(find_entry), gtk_combo_box_get_active(combo_type), path); } if( !glurp->updating_db ) { debug("Setting 'Add' treeview model"); gtk_tree_view_set_model(GTK_TREE_VIEW(glade_xml_get_widget(addxml, "treeview_add")), GTK_TREE_MODEL(glurp->gui_addtree)); } gtk_editable_select_region(GTK_EDITABLE(find_entry), 0, -1); } void gui_load_selected() { GtkTreeIter iter; GtkTreeView *tv = GTK_TREE_VIEW(glade_xml_get_widget(addxml, "treeview_add")); GtkTreeModel *tm; GtkTreeSelection *ts; GList *selected_rows; gint i, num; tm = gtk_tree_view_get_model(tv); if( !(ts = gtk_tree_view_get_selection(tv)) || !(num = gtk_tree_selection_count_selected_rows(ts)) ) { debug("No selection, ignoring"); return; } selected_rows = gtk_tree_selection_get_selected_rows(ts, NULL); for( i = 0; i < num; i++ ) { gtk_tree_model_get_iter(tm, &iter, (GtkTreePath *)g_list_nth_data(selected_rows, i)); gui_load_song(tm, iter); } return; } void gui_load_song(GtkTreeModel *tm, GtkTreeIter iter) { gchar *fname = NULL; GtkTreeIter child; gint i; gui_add_fill_dir(&iter, TRUE); if( gtk_tree_model_iter_has_child(tm, &iter) ) { for( i = 0; i < gtk_tree_model_iter_n_children(tm, &iter); i++ ) { gtk_tree_model_iter_nth_child(tm, &child, &iter, i); gui_load_song(tm, child); } return; } gtk_tree_model_get(tm, &iter, 1, &fname, -1); if( fname && g_utf8_strlen(fname, -1) ) { debug("Adding song '%s'", fname); mpd_sendAddCommand(glurp->conn, fname); mpd_finishCommand(glurp->conn); g_free(fname); if( check_mpd_error() ) { glurp_disconnect(); return; } } else debug("Invalid song filename"); return; } void gui_updating_disable_add_controls() { debug("Disabling 'add' controls"); gtk_widget_set_sensitive(glade_xml_get_widget(addxml, "scrolledwindow_add"), FALSE); gtk_widget_set_sensitive(glade_xml_get_widget(addxml, "button_add_update"), FALSE); gtk_widget_set_sensitive(glade_xml_get_widget(addxml, "button_add_add"), FALSE); debug("Removing 'Add' treeview model"); gtk_tree_view_set_model(GTK_TREE_VIEW(glade_xml_get_widget(addxml, "treeview_add")), NULL); } void gui_updating_enable_add_controls() { debug("Enabling 'add' controls"); gtk_widget_set_sensitive(glade_xml_get_widget(addxml, "scrolledwindow_add"), TRUE); gtk_widget_set_sensitive(glade_xml_get_widget(addxml, "button_add_update"), TRUE); gtk_widget_set_sensitive(glade_xml_get_widget(addxml, "button_add_add"), TRUE); debug("Setting 'Add' treeview model"); gtk_tree_view_set_model(GTK_TREE_VIEW(glade_xml_get_widget(addxml, "treeview_add")), GTK_TREE_MODEL(glurp->gui_addtree)); } void gui_add_fill_dir(GtkTreeIter *iter, gboolean silent) { GtkTreeView *tv = GTK_TREE_VIEW(glade_xml_get_widget(addxml, "treeview_add")); GtkTreeModel *tm = gtk_tree_view_get_model(tv); GtkTreeIter child; gint nd; gchar *filepath; gtk_tree_model_get(tm, iter, ADD_NUM_DIRS, &nd, ADD_FILENAME, &filepath, -1); if( gtk_tree_model_iter_n_children(tm, iter) == 1 && nd == -1 ) { if( !gtk_tree_model_iter_children(tm, &child, iter) ) { debug("Couldn't get stub child"); return; } debug("Filling dir '%s'", filepath); gtk_tree_store_set(GTK_TREE_STORE(tm), iter, ADD_NUM_DIRS, 0, -1); glurp_add_add_dir(filepath, gtk_tree_model_get_path(tm, iter)); gtk_tree_store_remove(GTK_TREE_STORE(tm), &child); if( silent ) gtk_tree_view_collapse_row(tv, gtk_tree_model_get_path(tm, iter)); debug("Filling complete"); } } gboolean gui_get_iter_by_id(GtkTreeIter *iter, gint id) { GtkTreeModel *tm = GTK_TREE_MODEL(glurp->gui_playlist); gint cid; if( !gtk_tree_model_get_iter_first(tm, iter) ) { debug("Couldn't get first iter"); return FALSE; } do { gtk_tree_model_get(tm, iter, PL_ID, &cid, -1); if( cid == id ) return TRUE; } while( gtk_tree_model_iter_next(tm, iter) ); return FALSE; } gboolean gui_get_iter_by_pos(GtkTreeIter *iter, gint pos) { GtkTreeModel *tm = GTK_TREE_MODEL(glurp->gui_playlist); gint cpos = 0; if( !gtk_tree_model_get_iter_first(tm, iter) ) { debug("Couldn't get first iter"); return FALSE; } while( cpos < pos ) { if( !gtk_tree_model_iter_next(tm, iter) ) return FALSE;; cpos++; } return TRUE; } void gui_update_song(gint id) { GlurpSong *s = NULL; GtkListStore *ls = glurp->gui_playlist; GtkTreeModel *tm = GTK_TREE_MODEL(ls); GtkTreeIter iter; gint spos, i; /* get GlurpSong */ if( !(s = get_song_by_id(id)) ) { debug("Couldn't get song"); return; } /* get song position in internal playlist */ spos = get_song_pos(s); if( !gui_get_iter_by_pos(&iter, spos) ) { debug("Couldn't get requested iter, adding song"); add_song_to_gui_playlist(s, spos + 1); return; } /* get GtkTreeIter */ for(i = 0, gtk_tree_model_get_iter_first(tm, &iter); i < spos; i++, gtk_tree_model_iter_next(tm, &iter) ) {} debug("Modifying playlist row..."); gtk_list_store_set(ls, &iter, PL_FILENAME, s->file, PL_ARTIST, s->artist, PL_TITLE, s->title, PL_ALBUM, s->album, PL_TRACK, s->track, PL_NAME, s->name, PL_POS, s->pos + 1, PL_ID, s->id, -1); } void gui_trim_playlist_end(gint last) { GtkTreeModel *tm = GTK_TREE_MODEL(glurp->gui_playlist); GtkTreeIter iter, riter; GtkTreePath *lpath; gint i; if( last == -1 ) { debug("Clearing GUI playlist"); gtk_list_store_clear(glurp->gui_playlist); return; } /* get the path to last row we want to keep */ for(i = 0, gtk_tree_model_get_iter_first(tm, &iter); i <= last - 1 && &iter; i++, gtk_tree_model_iter_next(tm, &iter) ) {} lpath = gtk_tree_model_get_path(tm, &iter); while( gtk_tree_model_get_iter(tm, &riter, lpath) && gtk_tree_model_iter_next(tm, &riter) ) gtk_list_store_remove(glurp->gui_playlist, &riter); } void create_stream_liststore() { GtkListStore *ls; GtkWidget *tv; if(glurp->gui_stream_list) { debug("Stream liststore exists, returning"); return; } debug("Creating stream liststore..."); ls = gtk_list_store_new(1, G_TYPE_STRING); tv = glade_xml_get_widget(streamxml, "comboboxentry_stream_url"); gtk_entry_set_activates_default(GTK_ENTRY(GTK_BIN(glade_xml_get_widget(streamxml, "comboboxentry_stream_url"))->child), TRUE); gtk_widget_grab_focus(GTK_WIDGET(GTK_BIN(glade_xml_get_widget(streamxml, "comboboxentry_stream_url"))->child)); gtk_combo_box_set_model(GTK_COMBO_BOX(tv), GTK_TREE_MODEL(ls)); gtk_combo_box_entry_set_text_column(GTK_COMBO_BOX_ENTRY(tv), 0); glurp->gui_stream_list = ls; debug("Stream combobox model created"); } void populate_stream_liststore() { GlurpStream *s = NULL; GtkTreeIter iter; gtk_list_store_clear(glurp->gui_stream_list); for( s = glurp->stream_history; s; s = s->next ) { debug("Adding row '%s'", s->url); gtk_list_store_append(glurp->gui_stream_list, &iter); gtk_list_store_set(glurp->gui_stream_list, &iter, 0, g_strdup(s->url), -1); } statusbar_print("Stream combobox model populated"); } void stream_window_destroyed() { if(!streamxml && !glurp->gui_stream_list) return; debug("playlists window destroyed, cleaning up"); streamxml = NULL; if( G_IS_OBJECT(glurp->gui_stream_list) ) g_object_unref(G_OBJECT(glurp->gui_stream_list)); glurp->gui_stream_list = NULL; } gchar *get_selected_stream() { gchar *text = NULL; GtkWidget *cb = NULL; if( !streamxml || !glurp->gui_stream_list ) { debug("No combobox"); return NULL; } cb = glade_xml_get_widget(streamxml, "comboboxentry_stream_url"); text = (gchar *)gtk_entry_get_text(GTK_ENTRY(GTK_BIN(cb)->child)); return text; } void gui_refresh_playlist_columns() { GtkTreeViewColumn *col = NULL; GtkCellRenderer *rend; GtkTreeView *tv = GTK_TREE_VIEW(glade_xml_get_widget(guixml, "treeview_playlist")); debug("Starting to update playlist columns"); while( (col = gtk_tree_view_get_column(GTK_TREE_VIEW(tv), 0)) ) { gtk_tree_view_remove_column(tv, col); } rend = gtk_cell_renderer_text_new(); if( glurp->config->playlist_columns[PL_POS] ) { col = gtk_tree_view_column_new_with_attributes("#", rend, "text", PL_POS, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(col, TRUE); gtk_tree_view_append_column(tv, col); } if( glurp->config->playlist_columns[PL_ID] ) { col = gtk_tree_view_column_new_with_attributes("Id", rend, "text", PL_ID, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(col, TRUE); gtk_tree_view_append_column(tv, col); } if( glurp->config->playlist_columns[PL_TITLE] ) { col = gtk_tree_view_column_new_with_attributes("Title", rend, "text", PL_TITLE, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(col, TRUE); gtk_tree_view_append_column(tv, col); } if( glurp->config->playlist_columns[PL_NAME] ) { col = gtk_tree_view_column_new_with_attributes("Name", rend, "text", PL_TITLE, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(col, TRUE); gtk_tree_view_append_column(tv, col); } if( glurp->config->playlist_columns[PL_ARTIST] ) { col = gtk_tree_view_column_new_with_attributes("Artist", rend, "text", PL_ARTIST, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(col, TRUE); gtk_tree_view_append_column(tv, col); } if( glurp->config->playlist_columns[PL_ALBUM] ) { col = gtk_tree_view_column_new_with_attributes("Album", rend, "text", PL_ALBUM, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(col, TRUE); gtk_tree_view_append_column(tv, col); } if( glurp->config->playlist_columns[PL_FILENAME] ) { col = gtk_tree_view_column_new_with_attributes("Filename", rend, "text", PL_FILENAME, "weight", PL_BOLD, "weight-set", PL_BOLD_SET, NULL); gtk_tree_view_column_set_resizable(col, TRUE); gtk_tree_view_append_column(tv, col); } debug("Playlist columns updated"); } GtkMenu *populate_outputs_menu() { GtkWidget *menu = gtk_menu_new(); GtkWidget *hbox, *label, *icon; GtkMenuItem *item = NULL; mpd_OutputEntity *output; gint i; mpd_sendOutputsCommand(glurp->conn); while( (output = mpd_getNextOutput(glurp->conn)) ) { debug("%d: %s", output->id, output->name); hbox = GTK_WIDGET(gtk_hbox_new(FALSE, 0)); gtk_widget_show(hbox); /* "enabled" icon */ if( output->enabled ) { icon = gtk_image_new_from_stock(GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU); i = output->id + 1; } else { icon = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); i = -(output->id + 1); } gtk_widget_show(icon); gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0); /* label */ label = GTK_WIDGET(gtk_label_new(g_strdup_printf("%d: %s", output->id, output->name))); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); item = GTK_MENU_ITEM(gtk_menu_item_new()); gtk_container_add(GTK_CONTAINER(item), hbox); gtk_menu_shell_append(GTK_MENU_SHELL(menu), GTK_WIDGET(item)); gtk_widget_show(GTK_WIDGET(item)); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(on_menu_output_activate), (gpointer)i); g_free(output); } mpd_finishCommand(glurp->conn); if( check_mpd_error() ) { glurp_disconnect(); return NULL; } g_signal_connect(G_OBJECT(menu), "deactivate", G_CALLBACK(on_menu_outputs_deactivate), NULL); return GTK_MENU(menu); } void gui_add_append(gchar *path, GtkTreePath *gpath, gboolean song) { GtkTreeModel *tm = GTK_TREE_MODEL(glurp->gui_addtree); GtkTreeIter iparent, iter, newchild; gint nd; debug("Adding '%s'", path); /* get stored number of dirs in parent dir */ if( gpath ) { gtk_tree_model_get_iter(tm, &iparent, gpath); gtk_tree_model_get(tm, &iparent, ADD_NUM_DIRS, &nd, -1); } if( song ) { gtk_tree_store_append(glurp->gui_addtree, &iter, (gpath ? &iparent : NULL)); gtk_tree_store_set(glurp->gui_addtree, &iter, 3, gdk_pixbuf_new_from_file(DATADIR "pixmaps/media-audiofile.png", NULL), -1); } else { gtk_tree_store_insert(glurp->gui_addtree, &iter, (gpath ? &iparent : NULL), (gpath ? nd : glurp->num_add_dirs)); if( gpath ) gtk_tree_store_set(glurp->gui_addtree, &iparent, 2, nd+1, -1); else glurp->num_add_dirs++; gtk_tree_store_set(glurp->gui_addtree, &iter, 3, gtk_widget_render_icon(glade_xml_get_widget(guixml, "glurp_window_main"), GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, "icon"), -1); gtk_tree_store_set(glurp->gui_addtree, &iter, ADD_NUM_DIRS, -1, -1); gtk_tree_store_insert(glurp->gui_addtree, &newchild, &iter, (gpath ? nd : glurp->num_add_dirs)); } gtk_tree_store_set(glurp->gui_addtree, &iter, ADD_NAME, glurp_filename(path), ADD_FILENAME, path, -1); if( gpath ) gtk_tree_view_expand_row(GTK_TREE_VIEW(glade_xml_get_widget(addxml, "treeview_add")), gpath, FALSE); }