1 /*
2     Glurp - A GTK+ client for Music Player Daemon
3     Copyright (C) 2004, 2005 Andrej Kacian
4 
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.
9 
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.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19     http://musicpd.org/glurp.shtml
20 
21 */
22 
23 #include <glib.h>
24 #include <gtk/gtk.h>
25 #include <gdk/gdkkeysyms.h>
26 #include <stdlib.h>
27 
28 #include <libmpd/libmpd.h>
29 #include <libmpd/libmpd-playlist.h>
30 #include <libmpd/libmpd-database.h>
31 
32 #include "structs.h"
33 #include "support.h"
34 #include "comm.h"
35 #include "gui.h"
36 #include "player.h"
37 #include "conf.h"
38 
39 extern GtkBuilder *builder;
40 extern GlurpState *glurp;
41 
42 
43 
on_move_tab(GtkWidget * tab)44 void on_move_tab(GtkWidget* tab) {
45   GtkWidget *label;
46   GtkWidget *pane;
47   GtkNotebook *notebook[2] = {
48     GTK_NOTEBOOK(gtk_builder_get_object(builder, "glurp_functional_notebook1")),
49     GTK_NOTEBOOK(gtk_builder_get_object(builder, "glurp_functional_notebook2"))
50   };
51   gpointer tab_indexp;
52   gint page_num,notebook_num,tab_index, target_pos;
53   if ( ( page_num = gtk_notebook_page_num(notebook[0], tab) ) >= 0) {
54     notebook_num = 0;
55   } else {
56     if ( ( page_num = gtk_notebook_page_num(notebook[1], tab) ) >= 0) {
57       notebook_num = 1;
58     } else {
59       return;
60     }
61   }
62   /* get the position of this tab */
63   g_object_get(G_OBJECT(tab), "user_data", &tab_indexp, NULL);
64   tab_index = GPOINTER_TO_INT(tab_indexp);
65 
66   label = gtk_notebook_get_tab_label(notebook[notebook_num], tab);
67   g_object_ref(tab);
68   g_object_ref(label);
69   gtk_notebook_remove_page(notebook[notebook_num], page_num);
70   for (target_pos = gtk_notebook_get_n_pages(notebook[1-notebook_num]) - 1 ; target_pos >= 0; target_pos--) {
71     g_object_get(G_OBJECT(gtk_notebook_get_nth_page(notebook[1-notebook_num], target_pos)), "user_data", &tab_indexp, NULL);
72     if (tab_index > GPOINTER_TO_INT(tab_indexp)) {
73       gtk_notebook_insert_page(notebook[1-notebook_num], tab, label, target_pos+1);
74       break;
75     }
76   }
77   if (target_pos < 0)
78     gtk_notebook_prepend_page(notebook[1-notebook_num], tab, label);
79 
80   if (gtk_notebook_get_n_pages(notebook[notebook_num])==0) {
81     pane = GTK_WIDGET(gtk_builder_get_object(builder, "glurp_functional_area"));
82     gtk_paned_set_position(GTK_PANED(pane), (notebook_num==1)?0:pane->allocation.width);
83   }
84   if ( gtk_notebook_get_n_pages( notebook[1-notebook_num] ) == 1) {
85     pane = GTK_WIDGET(gtk_builder_get_object(builder, "glurp_functional_area"));
86     gtk_paned_set_position(GTK_PANED(pane), pane->allocation.width/2);
87   }
88   g_object_unref(tab);
89   g_object_unref(label);
90 }
91 
on_move_playlist_tab_clicked(GtkWidget * widget,gpointer user_data)92 void on_move_playlist_tab_clicked(GtkWidget *widget, gpointer user_data) {
93   on_move_tab(GTK_WIDGET(gtk_builder_get_object(builder, "playlist_page")));
94 }
on_move_database_tab_clicked(GtkWidget * widget,gpointer user_data)95 void on_move_database_tab_clicked(GtkWidget *widget, gpointer user_data) {
96   on_move_tab(GTK_WIDGET(gtk_builder_get_object(builder, "database_page")));
97 }
on_move_streams_tab_clicked(GtkWidget * widget,gpointer user_data)98 void on_move_streams_tab_clicked(GtkWidget *widget, gpointer user_data) {
99   on_move_tab(GTK_WIDGET(gtk_builder_get_object(builder, "streams_page")));
100 }
on_move_playlists_tab_clicked(GtkWidget * widget,gpointer user_data)101 void on_move_playlists_tab_clicked(GtkWidget *widget, gpointer user_data) {
102   on_move_tab(GTK_WIDGET(gtk_builder_get_object(builder, "playlists_page")));
103 }
on_move_config_tab_clicked(GtkWidget * widget,gpointer user_data)104 void on_move_config_tab_clicked(GtkWidget *widget, gpointer user_data) {
105   on_move_tab(GTK_WIDGET(gtk_builder_get_object(builder, "config_page")));
106 }
107 
108 
on_ui_quit(GtkWidget * widget,gpointer user_data)109 void on_ui_quit(GtkWidget *widget, gpointer user_data) {
110 
111   debug("Quitting Glurp...");
112 
113   if (glurp->mpd) {
114     if( mpd_check_connected(glurp->mpd) ) glurp_disconnect();
115 
116     mpd_free(glurp->mpd);
117   }
118   config_save();
119 
120   gtk_main_quit();
121 }
122 
on_window_moved(GtkWidget * widget,GdkEventConfigure * event,gpointer data)123 gboolean on_window_moved(GtkWidget *widget, GdkEventConfigure *event, gpointer data) {
124   debug("Storing window position and size (%dx%d+%d+%d)", event->width, event->height, event->x, event->y);
125 
126   glurp->config->pos_x = event->x;
127   glurp->config->pos_y = event->y;
128 
129   glurp->config->width = event->width;
130   glurp->config->height = event->height;
131 
132   return FALSE;
133 }
134 
set_condensed_modifier_style(GtkWidget * widget,gboolean condensed)135 static void set_condensed_modifier_style(GtkWidget* widget, gboolean condensed) {
136   GtkRcStyle* style;
137   if (condensed) {
138     style = gtk_widget_get_modifier_style(widget);
139     style->xthickness = 0;
140     style->ythickness = 0;
141     gtk_widget_modify_style(widget, style);
142   } else
143     gtk_widget_modify_style(widget, gtk_rc_style_new());
144 }
145 
on_condense_clicked(GtkWidget * widget,gpointer user_data)146 gboolean on_condense_clicked(GtkWidget *widget, gpointer user_data) {
147   GtkWidget *wi, *wi2;
148   guint size;
149   gint x;
150   gint y;
151 
152   wi = GTK_WIDGET(gtk_builder_get_object(builder, "glurp_window_main"));
153   gtk_window_get_position(GTK_WINDOW(wi), &x, &y);
154   gtk_widget_hide(wi);
155 
156   gboolean condensed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
157   size = condensed?gtk_icon_size_from_name ("glurp_condensed"):GTK_ICON_SIZE_BUTTON;
158   if (condensed) {
159     debug("switching to condensed style");
160     gtk_widget_hide_all(GTK_WIDGET(gtk_builder_get_object(builder, "frame_bitrate")));
161     gtk_widget_hide_all(GTK_WIDGET(gtk_builder_get_object(builder, "frame_mode")));
162     gtk_widget_hide_all(GTK_WIDGET(gtk_builder_get_object(builder, "volumebar")));
163     gtk_widget_hide_all(GTK_WIDGET(gtk_builder_get_object(builder, "statusbar_main")));
164     gtk_widget_hide_all(GTK_WIDGET(gtk_builder_get_object(builder, "progressbar")));
165     gtk_widget_hide_all(GTK_WIDGET(gtk_builder_get_object(builder, "togglebutton_outputs")));
166     if( mpd_check_connected(glurp->mpd) )
167     	gtk_widget_hide_all(GTK_WIDGET(gtk_builder_get_object(builder, "button_server_connect")));
168 		else
169 	    gtk_widget_hide_all(GTK_WIDGET(gtk_builder_get_object(builder, "button_server_disconnect")));
170 
171     /* remove decoration, but add a border */
172     wi = GTK_WIDGET(gtk_builder_get_object(builder, "glurp_window_main"));
173     gtk_window_set_decorated(GTK_WINDOW(wi), FALSE);
174     wi2 = gtk_bin_get_child(GTK_BIN(wi));
175     g_object_ref(G_OBJECT(wi2));
176     gtk_container_remove(GTK_CONTAINER(wi), wi2);
177     gtk_container_add(GTK_CONTAINER(wi), gtk_frame_new(NULL));
178     wi = gtk_bin_get_child(GTK_BIN(wi));
179     gtk_frame_set_shadow_type(GTK_FRAME(wi), GTK_SHADOW_ETCHED_OUT);
180     gtk_widget_show(wi);
181     gtk_container_add(GTK_CONTAINER(wi), wi2);
182     g_object_unref(wi2);
183     gtk_container_set_border_width(GTK_CONTAINER(wi2), 3);
184     /* remove frames */
185     glurp->frame_time  = GTK_WIDGET(gtk_builder_get_object(builder, "frame_time"));
186     wi = GTK_WIDGET(gtk_builder_get_object(builder, "hbox_player_info"));
187     wi2 = gtk_bin_get_child(GTK_BIN(glurp->frame_time));
188     g_object_ref(G_OBJECT(glurp->frame_time));
189     g_object_ref(G_OBJECT(wi2));
190     gtk_container_remove(GTK_CONTAINER(wi), glurp->frame_time);
191     gtk_container_remove(GTK_CONTAINER(glurp->frame_time), wi2);
192     gtk_box_pack_start(GTK_BOX(wi), wi2, FALSE, FALSE, 0);
193     g_object_unref(G_OBJECT(wi2));
194 
195     glurp->frame_trackname  = GTK_WIDGET(gtk_builder_get_object(builder, "frame_trackname"));
196     wi2 = gtk_bin_get_child(GTK_BIN(glurp->frame_trackname));
197     g_object_ref(G_OBJECT(glurp->frame_trackname));
198     g_object_ref(G_OBJECT(wi2));
199     gtk_container_remove(GTK_CONTAINER(wi), glurp->frame_trackname);
200     gtk_container_remove(GTK_CONTAINER(glurp->frame_trackname), wi2);
201     gtk_box_pack_start(GTK_BOX(wi), wi2, TRUE, TRUE, 0);
202     g_object_unref(G_OBJECT(wi2));
203   } else {
204     gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "frame_bitrate")));
205     gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "frame_mode")));
206     gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "volumebar")));
207     gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "statusbar_main")));
208     gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "progressbar")));
209     gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "togglebutton_outputs")));
210     if( mpd_check_connected(glurp->mpd) )
211     	gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "button_server_connect")));
212 		else
213     	gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "button_server_disconnect")));
214     /* replace decoration and remove the border */
215     wi = GTK_WIDGET(gtk_builder_get_object(builder, "glurp_window_main"));
216     gtk_window_set_decorated(GTK_WINDOW(wi), TRUE);
217     wi = gtk_bin_get_child(GTK_BIN(wi));
218     wi2 = gtk_bin_get_child(GTK_BIN(wi));
219     g_object_ref(G_OBJECT(wi2));
220     gtk_container_remove(GTK_CONTAINER(wi), wi2);
221     gtk_widget_destroy(wi);
222     wi = GTK_WIDGET(gtk_builder_get_object(builder, "glurp_window_main"));
223     gtk_container_add(GTK_CONTAINER(wi), wi2);
224     g_object_unref(wi2);
225     gtk_container_set_border_width(GTK_CONTAINER(wi2), 0);
226     /* replace frames */
227     wi = GTK_WIDGET(gtk_builder_get_object(builder, "hbox_player_info"));
228 //    wi2 = GTK_WIDGET(gtk_builder_get_object(builder, "button_time"));
229     wi2 = GTK_WIDGET(gtk_builder_get_object(builder, "label_time"));
230     g_object_ref(G_OBJECT(wi2));
231     gtk_container_remove(GTK_CONTAINER(wi), wi2);
232     gtk_box_pack_start(GTK_BOX(wi), glurp->frame_time, FALSE, FALSE, 5);
233     gtk_container_add(GTK_CONTAINER(glurp->frame_time), wi2);
234     g_object_unref(G_OBJECT(glurp->frame_time));
235     g_object_unref(G_OBJECT(wi2));
236 
237     wi2 = GTK_WIDGET(gtk_builder_get_object(builder, "entry_trackname"));
238     g_object_ref(G_OBJECT(wi2));
239     gtk_container_remove(GTK_CONTAINER(wi), wi2);
240     gtk_box_pack_start(GTK_BOX(wi), glurp->frame_trackname, TRUE, TRUE, 5);
241     gtk_container_add(GTK_CONTAINER(glurp->frame_trackname), wi2);
242     g_object_unref(G_OBJECT(glurp->frame_trackname));
243     g_object_unref(G_OBJECT(wi2));
244   }
245   wi = GTK_WIDGET(gtk_builder_get_object(builder, "button_prev"));
246   set_condensed_modifier_style(wi, condensed);
247   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
248   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-prev", size));
249   gtk_widget_show_all(wi);
250   /* prev */
251   wi = GTK_WIDGET(gtk_builder_get_object(builder, "button_prev"));
252   set_condensed_modifier_style(wi, condensed);
253   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
254   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-prev", size) );
255   gtk_widget_show_all(wi);
256   /* play */
257   wi = GTK_WIDGET(gtk_builder_get_object(builder, "button_play"));
258   set_condensed_modifier_style(wi, condensed);
259   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
260   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-play", size) );
261   gtk_widget_show_all(wi);
262   /* pause */
263   wi = GTK_WIDGET(gtk_builder_get_object(builder, "button_pause"));
264   set_condensed_modifier_style(wi, condensed);
265   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
266   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-pause", size) );
267   gtk_widget_show_all(wi);
268   /* stop */
269   wi = GTK_WIDGET(gtk_builder_get_object(builder, "button_stop"));
270   set_condensed_modifier_style(wi, condensed);
271   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
272   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-stop", size) );
273   gtk_widget_show_all(wi);
274   /* next */
275   wi = GTK_WIDGET(gtk_builder_get_object(builder, "button_next"));
276   set_condensed_modifier_style(wi, condensed);
277   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
278   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-next", size) );
279   gtk_widget_show_all(wi);
280 
281   /* playlist show/hide */
282   wi = GTK_WIDGET(gtk_builder_get_object(builder, "togglebutton_playlist"));
283   set_condensed_modifier_style(wi, condensed);
284   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
285   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-playlist", size) );
286   gtk_widget_show_all(wi);
287 
288   /* repeat */
289   wi = GTK_WIDGET(gtk_builder_get_object(builder, "togglebutton_repeat"));
290   set_condensed_modifier_style(wi, condensed);
291   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
292   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-repeat", size) );
293   gtk_widget_show_all(wi);
294 
295   /* random */
296   wi = GTK_WIDGET(gtk_builder_get_object(builder, "togglebutton_random"));
297   set_condensed_modifier_style(wi, condensed);
298   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
299   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-random", size) );
300   gtk_widget_show_all(wi);
301 
302   /* condense */
303   wi = GTK_WIDGET(gtk_builder_get_object(builder, "togglebutton_condense"));
304   set_condensed_modifier_style(wi, condensed);
305   gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(wi)));
306   gtk_container_add(GTK_CONTAINER(wi), gtk_image_new_from_stock("glurp-condense", size) );
307   gtk_widget_show_all(wi);
308 
309   if (condensed)
310     gtk_window_resize(GTK_WINDOW(gtk_builder_get_object(builder, "glurp_window_main")), 1,1);
311 
312   wi = GTK_WIDGET(gtk_builder_get_object(builder, "glurp_window_main"));
313   gtk_window_move(GTK_WINDOW(wi), x, y);
314   gtk_widget_show(wi);
315   return FALSE;
316 };
317 
on_entry_trackname_size_allocate(GtkWidget * widget,GtkAllocation * allocation,gpointer user_data)318 void on_entry_trackname_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) {
319   glurp->trackname_width = allocation->width;
320   gui_check_scroll();
321 }
322 
on_button_config_revert_clicked(GtkWidget * widget,gpointer user_data)323 gboolean on_button_config_revert_clicked(GtkWidget *widget, gpointer user_data) {
324 
325   debug("Revert, refilling config window...");
326   populate_config();
327 
328   return FALSE;
329 }
330 
on_config_destroy(GtkWidget * widget,gpointer user_data)331 gboolean on_config_destroy(GtkWidget *widget, gpointer user_data) {
332   return FALSE;
333 }
334 
on_button_config_apply_clicked(GtkWidget * widget,gpointer user_data)335 gboolean on_button_config_apply_clicked(GtkWidget *widget, gpointer user_data) {
336 
337   debug("Apply pressed, hiding config window...");
338 
339   debug("Storing variables into GlurpConfig");
340   store_config();
341 
342   config_save();
343 
344   statusbar_print("Config saved...");
345 
346   return FALSE;
347 }
348 
on_ui_press_connect(GtkWidget * widget,gpointer user_data)349 gboolean on_ui_press_connect(GtkWidget *widget, gpointer user_data) {
350   glurp_connect();
351   return FALSE;
352 }
353 
on_ui_press_disconnect(GtkWidget * widget,gpointer user_data)354 gboolean on_ui_press_disconnect(GtkWidget *widget, gpointer user_data) {
355   glurp_disconnect();
356   return FALSE;
357 }
358 
on_ui_volume_changed(GtkWidget * widget,gpointer user_data)359 gboolean on_ui_volume_changed(GtkWidget *widget, gpointer user_data) {
360   gdouble i = gtk_scale_button_get_value(GTK_SCALE_BUTTON(widget));
361 
362   if( mpd_check_connected(glurp->mpd) ) {
363     mpd_status_set_volume(glurp->mpd, (int)(i*100));
364 
365     statusbar_print("Volume: %d%%", (int)(i*100));
366   }
367 
368   return FALSE;
369 }
370 
on_ui_progress_change(GtkWidget * widget,gpointer user_data)371 gboolean on_ui_progress_change(GtkWidget *widget, gpointer user_data) {
372   double pos, tt;
373 
374   if(!glurp->progress_dragging) return FALSE;
375 
376   tt = mpd_status_get_total_song_time(glurp->mpd);
377 
378   pos = gtk_range_get_value(GTK_RANGE(widget));
379 
380   debug("Seeking to %d seconds", (gint)pos);
381   statusbar_print("Seek to %02d:%02d/%02d:%02d", (gint)pos/60, (gint)pos%60, (gint)tt/60, (gint)tt%60);
382   mpd_player_seek(glurp->mpd, pos);
383   debug("setting FALSE");
384   glurp->progress_dragging = FALSE;
385 
386   return FALSE;
387 }
388 
on_ui_progress_change_start_kb(GtkWidget * widget,GdkEventKey * event,gpointer user_data)389 gboolean on_ui_progress_change_start_kb(GtkWidget *widget, GdkEventKey *event,
390                 gpointer user_data) {
391   guint k = event->keyval;
392 
393   if( !glurp->progress_dragging &&
394       !(event->state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD1_MASK)) &&
395       ((k == GDK_KP_Left) ||
396        (k == GDK_KP_Right) ||
397        (k == GDK_Left) ||
398        (k == GDK_Right) ||
399        (k == GDK_Page_Up) ||
400        (k == GDK_Page_Down) )) {
401     debug("setting TRUE");
402     glurp->progress_dragging = TRUE;
403   } else if( glurp->progress_dragging )
404     return FALSE;
405   return TRUE;
406 }
407 
on_ui_progress_change_start(GtkWidget * widget,gpointer user_data)408 gboolean on_ui_progress_change_start(GtkWidget *widget, gpointer user_data) {
409   if( !glurp->progress_dragging ) {
410     debug("setting TRUE");
411     glurp->progress_dragging = TRUE;
412   }
413   return FALSE;
414 }
415 
on_ui_playlist_clicked(GtkWidget * widget,gpointer user_data)416 gboolean on_ui_playlist_clicked(GtkWidget *widget, gpointer user_data) {
417   if( !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) )
418     hide_gui_playlist();
419   else
420     show_gui_playlist();
421 
422   return FALSE;
423 }
424 
on_ui_player_play(GtkWidget * widget,gpointer user_data)425 gboolean on_ui_player_play(GtkWidget *widget, gpointer user_data) {
426   GtkTreeView *tv;
427   GtkTreeModel *tm;
428   GtkTreeSelection *sel;
429   GtkTreePath *path;
430   GtkTreeIter iter;
431   gint id, pos, num;
432   GList *selected_rows;
433 
434   tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_playlist"));
435   tm = gtk_tree_view_get_model(tv);
436 
437   if(!gtk_tree_model_iter_n_children(tm, NULL)) {
438     debug("Nothing loaded in playlist, cannot play");
439     statusbar_print("Playlist empty");
440     return FALSE;
441   }
442 
443   if( PAUSED )
444     /* prone to race condition... should be made better. */
445     player_pause();
446   else {
447 
448     sel = gtk_tree_view_get_selection(tv);
449 
450     if( !(num = gtk_tree_selection_count_selected_rows(sel)) ) {
451       debug("No song selected, letting MPD decide which song to play");
452       if( !STOPPED ) player_stop();
453       player_play_song(-1);
454       return FALSE;
455     }
456 
457     if( !(selected_rows = gtk_tree_selection_get_selected_rows(sel, &tm)) ) {
458       debug("Couldn't get selected rows");
459       return FALSE;
460     }
461 
462     path = (GtkTreePath *)g_list_nth_data(selected_rows, 0);
463 
464     if ( !gtk_tree_model_get_iter(tm, &iter, path) ) {
465       debug("Couldn't get GtkTreeIter, what now?");
466       return FALSE;
467     }
468 
469     debug("Getting trackno. of selected song");
470     gtk_tree_model_get(tm, &iter, PL_ID, &id, PL_POS, &pos, -1);
471     debug("Song number is %d, id %d", pos, id);
472 
473     if( num > 1 ) gui_playlist_set_cursor(pos - 1);
474 
475     if( !STOPPED ) player_stop();
476     player_play_song(id);
477   }
478 
479   return FALSE;
480 }
481 
on_ui_player_pause(GtkWidget * widget,gpointer user_data)482 gboolean on_ui_player_pause(GtkWidget *widget, gpointer user_data) {
483   player_pause();
484 
485   return FALSE;
486 }
487 
on_ui_player_stop(GtkWidget * widget,gpointer user_data)488 gboolean on_ui_player_stop(GtkWidget *widget, gpointer user_data) {
489   player_stop();
490 
491   return FALSE;
492 }
493 
on_ui_player_prev(GtkWidget * widget,gpointer user_data)494 gboolean on_ui_player_prev(GtkWidget *widget, gpointer user_data) {
495   player_prev();
496 
497   return FALSE;
498 }
499 
on_ui_player_next(GtkWidget * widget,gpointer user_data)500 gboolean on_ui_player_next(GtkWidget *widget, gpointer user_data) {
501   player_next();
502 
503   return FALSE;
504 }
505 #if 0
506 gboolean on_ui_time_clicked(GtkWidget *widget, gpointer user_data) {
507   if(glurp->config->time_display_left) glurp->config->time_display_left = FALSE;
508   else glurp->config->time_display_left = TRUE;
509 
510   gtk_widget_grab_focus(GTK_WIDGET(gtk_builder_get_object(builder, "glurp_functional_notebook1")));
511 
512   return FALSE;
513 }
514 #endif
on_ui_playlist_row_activated(GtkTreeView * treeview,GtkTreePath * tp,GtkTreeViewColumn * col,gpointer user_data)515 gboolean on_ui_playlist_row_activated(GtkTreeView *treeview, GtkTreePath *tp, GtkTreeViewColumn *col, gpointer user_data) {
516   GtkTreeIter act;
517   GtkTreeModel *model;
518   gint id;
519 
520   debug("Playlist item activated.");
521 
522   if(!mpd_check_connected(glurp->mpd)) {
523     debug("We're not connected, cannot start playing anything.");
524     return FALSE;
525   }
526 
527   model = gtk_tree_view_get_model(treeview);
528   gtk_tree_model_get_iter(model, &act, tp);
529   gtk_tree_model_get(model, &act, PL_ID, &id, -1);
530 
531   player_stop();
532   player_play_song(id);
533 
534   return FALSE;
535 }
536 
on_ui_playlist_list_row_activated(GtkTreeView * treeview,GtkTreePath * tp,GtkTreeViewColumn * col,gpointer user_data)537 gboolean on_ui_playlist_list_row_activated(GtkTreeView *treeview, GtkTreePath *tp, GtkTreeViewColumn *col, gpointer user_data) {
538   GtkTreeIter act;
539   GtkTreeModel *model;
540   gchar *name;
541 
542   debug("playlist activated");
543 
544   if( !mpd_check_connected(glurp->mpd) )  {
545     debug("we're not connected, how can this be?");
546     return FALSE;
547   }
548 
549   model = gtk_tree_view_get_model(treeview);
550   gtk_tree_model_get_iter(model, &act, tp);
551   gtk_tree_model_get(model, &act, 0, &name, -1);
552 
553   load_playlist(name);
554   g_free(name);
555 
556   return FALSE;
557 }
558 
on_ui_playlist_load(GtkWidget * widget,gpointer user_data)559 gboolean on_ui_playlist_load(GtkWidget *widget, gpointer user_data) {
560   GtkTreeView *tv;
561 
562   GtkTreeModel *tm;
563   GtkTreeSelection *sel;
564   GtkTreeIter iter;
565   gchar *name;
566 
567   if( !mpd_check_connected(glurp->mpd) ) {
568     debug("We're not connected, how can this be?");
569     return FALSE;
570   }
571 
572   tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_playlist_list"));
573   tm = gtk_tree_view_get_model(tv);
574 
575   sel = gtk_tree_view_get_selection(tv);
576   if( !gtk_tree_selection_get_selected(sel, &tm, &iter)) {
577     debug("No playlist selected");
578     return FALSE;
579   }
580 
581   debug("getting name of selected playlist");
582   gtk_tree_model_get(tm, &iter, 0, &name, -1);
583 
584   load_playlist(name);
585   g_free(name);
586 
587   return FALSE;
588 }
589 
on_ui_playlist_delete(GtkWidget * widget,gpointer user_data)590 gboolean on_ui_playlist_delete(GtkWidget *widget, gpointer user_data) {
591   GtkTreeView *tv;
592 
593   GtkTreeModel *tm;
594   GtkTreeSelection *sel;
595   GtkTreeIter iter;
596   gchar *name;
597 
598   if( !mpd_check_connected(glurp->mpd) ) {
599     debug("We're not connected, how can this be?");
600     return FALSE;
601   }
602 
603   tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_playlist_list"));
604   tm = gtk_tree_view_get_model(tv);
605 
606   sel = gtk_tree_view_get_selection(tv);
607   if( !gtk_tree_selection_get_selected(sel, &tm, &iter)) {
608     debug("No playlist selected");
609     return FALSE;
610   }
611 
612   gtk_tree_model_get(tm, &iter, 0, &name, -1);
613 
614   mpd_database_delete_playlist(glurp->mpd, name);
615 
616   debug("Playlist '%s' deleted", name);
617   g_free(name);
618   get_playlist_list();
619   populate_gui_playlist_list();
620 
621   return FALSE;
622 }
623 
on_ui_playlist_save(GtkWidget * widget,gpointer user_data)624 gboolean on_ui_playlist_save(GtkWidget *widget, gpointer user_data) {
625   GtkEntry *entry = GTK_ENTRY(gtk_builder_get_object(builder, "entry_playlist_name"));
626   gchar *name = (gchar *)gtk_entry_get_text(entry);
627   GlurpPl *pl;
628 
629   if( !mpd_check_connected(glurp->mpd) ) {
630     debug("We're not connected, how can this be? Ignoring");
631     return FALSE;
632   }
633 
634   if( !name || !g_utf8_strlen(name, -1) ) {
635     debug("Empty playlist name, ignoring");
636     return FALSE;
637   }
638 
639   for( pl = glurp->playlists; pl; pl = pl->next ) {
640     if( !g_ascii_strcasecmp(pl->name, name) ) {
641       debug("Not overwriting existing playlist");
642       return FALSE;
643     }
644   }
645 
646   mpd_database_save_playlist(glurp->mpd, name);
647 
648   debug("Playlist '%s' saved", name);
649   get_playlist_list();
650   populate_gui_playlist_list();
651 
652   return FALSE;
653 }
654 
on_ui_progress_drag(GtkWidget * widget,gpointer user_data)655 gboolean on_ui_progress_drag(GtkWidget *widget, gpointer user_data) {
656   double pos = gtk_range_get_value(GTK_RANGE(widget));
657   double sec, tt;
658   gint t_min, t_sec, s_min, s_sec;
659 
660   //if( !glurp->conn || !glurp->current_song ) return FALSE;
661 
662   if( !glurp->progress_dragging ) return FALSE;
663 
664   tt = glurp->current_song->time;
665 
666   t_min = (int)tt/60;
667   t_sec = (int)tt%60;
668 
669   sec = pos;
670   s_min = (int)sec/60;
671   s_sec = (int)sec%60;
672 
673   statusbar_print("Seek to %02d:%02d/%02d:%02d", s_min, s_sec, t_min, t_sec);
674 
675   return FALSE;
676 }
677 
on_ui_playlist_list_cursor_changed(GtkWidget * widget,gpointer user_data)678 gboolean on_ui_playlist_list_cursor_changed(GtkWidget *widget, gpointer user_data) {
679   GtkTreeView *tv;
680   GtkTreeModel *tm;
681   GtkTreeSelection *sel;
682   GtkTreeIter iter;
683   gchar *name;
684 
685   if( !mpd_check_connected(glurp->mpd) ) {
686     debug("We're not connected, how can this be?");
687     return FALSE;
688   }
689 
690   tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_playlist_list"));
691   tm = gtk_tree_view_get_model(tv);
692 
693   sel = gtk_tree_view_get_selection(tv);
694   if( !gtk_tree_selection_get_selected(sel, &tm, &iter)) {
695     debug("No playlist selected");
696     return FALSE;
697   }
698 
699   gtk_tree_model_get(tm, &iter, 0, &name, -1);
700 
701   gtk_entry_set_text(GTK_ENTRY(gtk_builder_get_object(builder, "entry_playlist_name")), name);
702   g_free(name);
703 
704   return FALSE;
705 }
706 
on_ui_qsearch_activate(GtkWidget * widget,gpointer user_data)707 gboolean on_ui_qsearch_activate(GtkWidget *widget, gpointer user_data)
708 {
709   gchar *srch = (gchar *)gtk_entry_get_text(GTK_ENTRY(widget));
710   gchar *sample = NULL;
711   gint type = gtk_combo_box_get_active(GTK_COMBO_BOX(gtk_builder_get_object(builder, "combobox_qsearch_type")));
712   GtkTreePath *path;
713   GtkTreeIter iter;
714   GtkTreeView *view = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_playlist"));
715   gint cpos, spos;
716   gboolean found = FALSE;
717 
718   if( !srch || !g_utf8_strlen(srch, -1) )
719     return FALSE;
720 
721   debug("QSearch string: '%s'", srch);
722 
723   gtk_tree_view_get_cursor(view, &path, NULL);
724   if( path ) {
725     /* Remember starting position */
726     spos = cpos = atoi(gtk_tree_path_to_string(path));
727     gtk_tree_path_free(path);
728   } else {
729     spos = cpos = 0;
730   }
731 
732   debug("Cursor position: %d", cpos + 1);
733 
734   cpos++;
735 
736   while( !found && cpos != spos ) {
737     if( !gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(glurp->gui_playlist), &iter, NULL, cpos) ) {
738       cpos = 0;
739       continue;
740     }
741 
742     switch(type) {
743       case GLURP_QSEARCH_TITLE:
744         gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_playlist), &iter, PL_TITLE, &sample, -1);
745         if( sample && srch && g_strrstr(g_ascii_strdown(sample, -1), g_ascii_strdown(srch, -1)) ) {
746           debug("Found suitable haystack: '%s'", sample);
747           gui_playlist_scroll(cpos);
748           found = TRUE;
749         }
750 
751         break;
752 
753       case GLURP_QSEARCH_ARTIST:
754         gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_playlist), &iter, PL_TITLE, &sample, -1);
755         if( sample && srch && g_strrstr(g_ascii_strdown(sample, -1), g_ascii_strdown(srch, -1)) ) {
756           debug("Found suitable haystack: '%s'", sample);
757           gui_playlist_scroll(cpos);
758           found = TRUE;
759         }
760 
761         break;
762 
763       case GLURP_QSEARCH_ALBUM:
764         gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_playlist), &iter, PL_TITLE, &sample, -1);
765         if( sample && srch && g_strrstr(g_ascii_strdown(sample, -1), g_ascii_strdown(srch, -1)) ) {
766           debug("Found suitable haystack: '%s'", sample);
767           gui_playlist_scroll(cpos);
768           found = TRUE;
769         }
770 
771         break;
772 
773       case GLURP_QSEARCH_FILENAME:
774         gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_playlist), &iter, PL_TITLE, &sample, -1);
775         if( sample && srch && g_strrstr(g_ascii_strdown(sample, -1), g_ascii_strdown(srch, -1)) ) {
776           debug("Found suitable haystack: '%s'", sample);
777           gui_playlist_scroll(cpos);
778           found = TRUE;
779         }
780 
781         break;
782 
783       case GLURP_QSEARCH_ALL:
784         gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_playlist), &iter, PL_TITLE, &sample, -1);
785         if( sample && srch && g_strrstr(g_ascii_strdown(sample, -1), g_ascii_strdown(srch, -1)) ) {
786           debug("Found suitable haystack: '%s'", sample);
787           gui_playlist_scroll(cpos);
788           found = TRUE;
789           break;
790         }
791 
792         gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_playlist), &iter, PL_TITLE, &sample, -1);
793         if( sample && srch && g_strrstr(g_ascii_strdown(sample, -1), g_ascii_strdown(srch, -1)) ) {
794           debug("Found suitable haystack: '%s'", sample);
795           gui_playlist_scroll(cpos);
796           found = TRUE;
797           break;
798         }
799 
800         gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_playlist), &iter, PL_TITLE, &sample, -1);
801         if( sample && srch && g_strrstr(g_ascii_strdown(sample, -1), g_ascii_strdown(srch, -1)) ) {
802           debug("Found suitable haystack: '%s'", sample);
803           gui_playlist_scroll(cpos);
804           found = TRUE;
805           break;
806         }
807 
808         gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_playlist), &iter, PL_TITLE, &sample, -1);
809         if( sample && srch && g_strrstr(g_ascii_strdown(sample, -1), g_ascii_strdown(srch, -1)) ) {
810           debug("Found suitable haystack: '%s'", sample);
811           gui_playlist_scroll(cpos);
812           found = TRUE;
813           break;
814         }
815 
816         break;
817 
818     }
819 
820     cpos++;
821 
822   }
823 
824   if( !found ) debug("Nothing found...");
825 
826   return FALSE;
827 }
828 
on_menu_add_activate(GtkWidget * widget,gpointer data)829 gboolean on_menu_add_activate(GtkWidget *widget, gpointer data) {
830   return FALSE;
831 }
832 
on_menu_pl_remove_all_activate(GtkWidget * widget,gpointer data)833 gboolean on_menu_pl_remove_all_activate(GtkWidget *widget, gpointer data) {
834   if(!mpd_check_connected(glurp->mpd)) return FALSE;
835 
836   mpd_playlist_clear(glurp->mpd);
837   return FALSE;
838 }
839 
on_menu_pl_remove_selected_activate(GtkWidget * widget,gpointer data)840 gboolean on_menu_pl_remove_selected_activate(GtkWidget *widget, gpointer data) {
841   GtkWidget *tv;
842   GtkTreeModel *tm;
843   GtkTreeSelection *ts;
844   gint num_sel, i, id;
845   GtkTreeIter iter;
846   GList *selected_rows;
847 
848   if(!mpd_check_connected(glurp->mpd)) return FALSE;
849 
850   tv = GTK_WIDGET(gtk_builder_get_object(builder, "treeview_playlist"));
851   tm = gtk_tree_view_get_model(GTK_TREE_VIEW(tv));
852   ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv));
853 
854   num_sel = gtk_tree_selection_count_selected_rows(ts);
855   selected_rows = gtk_tree_selection_get_selected_rows(ts, NULL);
856 
857   debug("Selected %d rows", num_sel);
858 
859   if( num_sel ) {
860     for( i=0; i<num_sel; i++ ) {
861       gtk_tree_model_get_iter(tm, &iter, (GtkTreePath *)g_list_nth_data(selected_rows, i));
862       gtk_tree_model_get(tm, &iter, PL_ID, &id, -1);
863       mpd_playlist_queue_delete_id(glurp->mpd, id);
864     }
865     mpd_playlist_queue_commit(glurp->mpd);
866   }
867   return FALSE;
868 }
869 
on_menu_pl_remove_crop_activate(GtkWidget * widget,gpointer data)870 gboolean on_menu_pl_remove_crop_activate(GtkWidget *widget, gpointer data) {
871   GtkWidget *tv;
872   GtkTreeModel *tm;
873   GtkTreeSelection *ts;
874   GtkTreeIter iter;
875   gint i = 0, id;
876 
877   if(!mpd_check_connected(glurp->mpd)) return FALSE;
878 
879   tv = GTK_WIDGET(gtk_builder_get_object(builder, "treeview_playlist"));
880   tm = gtk_tree_view_get_model(GTK_TREE_VIEW(tv));
881   ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv));
882 
883   if( !gtk_tree_model_get_iter_first(tm, &iter) ) {
884     debug("Couldn't get first iter, playlist empty?");
885     return FALSE;
886   }
887 
888   do {
889     if( !gtk_tree_selection_iter_is_selected(ts, &iter) ) {
890       gtk_tree_model_get(tm, &iter, PL_ID, &id, -1);
891       mpd_playlist_queue_delete_id( glurp->mpd, id);
892     }
893     else i++;
894   } while( gtk_tree_model_iter_next(tm, &iter) );
895 
896   mpd_playlist_queue_commit(glurp->mpd);
897 
898   return FALSE;
899 }
900 
901 
on_ui_add_update_clicked(GtkWidget * widget,gpointer data)902 gboolean on_ui_add_update_clicked(GtkWidget *widget, gpointer data) {
903 
904   gtk_tree_store_clear(glurp->gui_addtree);
905 
906   debug("Removing 'Add' treeview model");
907 //gtk_tree_view_set_model(GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_add")), NULL);
908 
909   gui_updating_disable_add_controls();
910   glurp->updating_db = TRUE;
911   statusbar_print("Updating MPD database, please wait...");
912   debug("Starting to update MPD db...");
913 
914 
915   mpd_database_update_dir(glurp->mpd, "/");
916   mpd_check_error(glurp->mpd);
917 
918   return FALSE;
919 }
920 
on_ui_add_add_clicked(GtkWidget * widget,gpointer data)921 gboolean on_ui_add_add_clicked(GtkWidget *widget, gpointer data) {
922   GtkTreeView *tv;
923   GtkTreeModel *tm;
924   GtkTreeSelection *ts;
925 
926   if(!mpd_check_connected(glurp->mpd)) return FALSE;
927 
928   tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_add"));
929   tm = gtk_tree_view_get_model(tv);
930   if( !(ts = gtk_tree_view_get_selection(tv)) ) {
931     debug("No selection, ignoring");
932     return FALSE;
933   }
934 
935   debug("Starting to add songs...");
936 
937   gui_load_selected();
938 
939   debug("Finished adding songs");
940 
941   return FALSE;
942 }
943 
on_ui_repeat_clicked(GtkWidget * widget,gpointer user_data)944 gboolean on_ui_repeat_clicked(GtkWidget *widget, gpointer user_data) {
945   if( !mpd_check_connected(glurp->mpd) ) {
946     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), FALSE);
947     return FALSE;
948   }
949 
950   if( !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) {
951     statusbar_print("Repeat Off");
952     debug("Repeat Off");
953     mpd_player_set_repeat(glurp->mpd, FALSE);
954 
955   } else {
956     statusbar_print("Repeat On");
957     debug("Repeat On");
958     mpd_player_set_repeat(glurp->mpd, TRUE);
959   }
960   return FALSE;
961 }
962 
on_ui_random_clicked(GtkWidget * widget,gpointer user_data)963 gboolean on_ui_random_clicked(GtkWidget *widget, gpointer user_data) {
964   if( !mpd_check_connected(glurp->mpd) ) {
965     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), FALSE);
966     return FALSE;
967   }
968 
969   if( !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) {
970     statusbar_print("Random Off");
971     debug("Random Off");
972     mpd_player_set_random(glurp->mpd, FALSE);
973   } else {
974     statusbar_print("Random On");
975     debug("Random On");
976     mpd_player_set_random(glurp->mpd, TRUE);
977   }
978   return FALSE;
979 }
980 
981 
on_ui_add_row_expanded(GtkTreeView * tv,GtkTreeIter * iter,GtkTreePath * path,gpointer user_data)982 gboolean on_ui_add_row_expanded(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) {
983   gchar *the_path;
984   gtk_tree_model_get(GTK_TREE_MODEL(glurp->gui_addtree), iter, ADD_NAME, &the_path,-1);
985   debug("expanded path: %s", the_path);
986   gui_add_fill_dir(iter, FALSE);
987 
988   return FALSE;
989 }
990 
on_ui_add_row_activated(GtkTreeView * tv,GtkTreePath * path,GtkTreeViewColumn * col,gpointer user_data)991 void on_ui_add_row_activated(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer user_data) {
992   GtkTreeModel *tm = gtk_tree_view_get_model( tv );
993   GtkTreeIter iter;
994 
995   if (!tm) {
996     debug("Couldn't get the tree model for add tree");
997     return;
998   }
999 
1000   if (!gtk_tree_model_get_iter(tm, &iter, path)) {
1001     debug("couldn't get a valid iter for the activated row (!)");
1002     return;
1003   }
1004 
1005   if( gtk_tree_model_iter_n_children(tm, &iter) > 0 ) {
1006     /* this is a directory, so we expand it. */
1007     debug("A directory is activated in the add window");
1008     if ( gtk_tree_view_row_expanded(tv, path) ) {
1009       gtk_tree_view_collapse_row(tv, path);
1010     } else {
1011       gtk_tree_view_expand_row(tv, path, FALSE);
1012     }
1013   } else {
1014     /* this is a song, add it to the playlist
1015      * fixme: should we add the activated song, or all selected songs? */
1016     debug("A song is activated in the add window");
1017     gui_load_song(tm, iter);
1018   }
1019 }
1020 
1021 
on_ui_add_find_clicked(GtkWidget * widget,gpointer data)1022 gboolean on_ui_add_find_clicked( GtkWidget *widget, gpointer data) {
1023 
1024   if( !mpd_check_connected(glurp->mpd)) {
1025     debug("Not connected, ignoring.");
1026     statusbar_print("Not connected, cannot add");
1027     return FALSE;
1028   }
1029   debug("Search started");
1030 
1031   populate_gui_add_search_tree();
1032   gtk_widget_grab_focus(GTK_WIDGET(gtk_builder_get_object(builder, "treeview_add")));
1033   return TRUE;
1034 
1035 }
1036 
on_entry_add_find_what_activate(GtkWidget * widget,gpointer data)1037 void on_entry_add_find_what_activate( GtkWidget *widget, gpointer data) {
1038   debug("relaying activation of the entry to the find button");
1039   g_signal_emit_by_name( (gpointer) gtk_builder_get_object(builder, "button_add_find"), "clicked");
1040 }
1041 
on_ui_stream_add_clicked(GtkWidget * widget,gpointer user_data)1042 gboolean on_ui_stream_add_clicked(GtkWidget *widget, gpointer user_data) {
1043   gchar *url = get_selected_stream();
1044 
1045   if( !url || !g_utf8_strlen(url, -1) ) {
1046     debug("No stream URL to add, ignoring");
1047 
1048     statusbar_print("No URL to add");
1049 
1050     return FALSE;
1051   }
1052 
1053   debug("Adding URL: '%s'", url);
1054   mpd_playlist_add(glurp->mpd, url);
1055   statusbar_print("URL '%s' added", url);
1056   push_stream(url);
1057   populate_stream_liststore();
1058 
1059   return FALSE;
1060 }
1061 
on_ui_playlist_drag_begin(GtkWidget * widget,GdkDragContext * cont,gpointer user_data)1062 gboolean on_ui_playlist_drag_begin(GtkWidget *widget, GdkDragContext *cont, gpointer user_data) {
1063   debug("DRAG BEGIN");
1064   return FALSE;
1065 }
1066 
on_ui_playlist_drag_drop(GtkTreeView * tree,GdkDragContext * con,gint x,gint y,guint time,gpointer data)1067 gboolean on_ui_playlist_drag_drop(GtkTreeView *tree, GdkDragContext *con, gint x, gint y, guint time, gpointer data) {
1068   GtkTreePath *path = NULL;
1069   GtkTreeViewDropPosition pos;
1070   GtkTreeModel *tm = GTK_TREE_MODEL(glurp->gui_playlist);
1071   GtkTreeIter iter;
1072   gint did, dpos, spos;
1073   gint num_selected;
1074   gint* path_indices;
1075   GtkTreeSelection *sel;
1076   GList *selected_rows, *sel_rows_iterator;
1077 
1078   debug("DRAG DROP");
1079 
1080   if( !gtk_tree_view_get_dest_row_at_pos(tree, x, y, &path, &pos) ) {
1081     debug("Can't determine destination");
1082     return TRUE;
1083   }
1084 
1085   if( !gtk_tree_model_get_iter(tm, &iter, path) ) {
1086     debug("Can't get iter");
1087     return TRUE;
1088   }
1089 
1090   gtk_tree_model_get(tm, &iter, PL_ID, &did, -1);
1091   path_indices = gtk_tree_path_get_indices(path);
1092   dpos = path_indices[gtk_tree_path_get_depth(path) - 1];
1093 
1094   if( pos == GTK_TREE_VIEW_DROP_AFTER ) debug("AFTER id:%d", did);
1095   if( pos == GTK_TREE_VIEW_DROP_BEFORE ) debug("BEFORE id:%d", did);
1096   if( pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE ) debug("INTO OR BEFORE id:%d", did);
1097   if( pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER ) debug("INTO OR AFTER id:%d", did);
1098 
1099   if( pos == GTK_TREE_VIEW_DROP_AFTER ) debug("AFTER pos:%d", dpos);
1100   if( pos == GTK_TREE_VIEW_DROP_BEFORE ) debug("BEFORE pos:%d", dpos);
1101   if( pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE ) debug("INTO OR BEFORE pos:%d", dpos);
1102   if( pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER ) debug("INTO OR AFTER pos:%d", dpos);
1103   if( ( pos == GTK_TREE_VIEW_DROP_BEFORE ) || ( pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE ) ) dpos -= 1;
1104 //  if (dpos < 0) dpos = 0;
1105 
1106   sel = gtk_tree_view_get_selection(tree);
1107   sel_rows_iterator = selected_rows = gtk_tree_selection_get_selected_rows(sel, &tm);
1108   num_selected = gtk_tree_selection_count_selected_rows(sel);
1109   do {
1110     path = (GtkTreePath*)sel_rows_iterator->data;
1111     path_indices = gtk_tree_path_get_indices(path);
1112     spos = path_indices[gtk_tree_path_get_depth(path) - 1];
1113     if( spos >= dpos ) {
1114       dpos++;
1115       debug("dropping backwards");
1116     }
1117     debug("movig from pos %d to pos %d", spos, dpos);
1118     mpd_playlist_move_pos(glurp->mpd, spos, dpos);
1119   } while ( ( sel_rows_iterator = g_list_next(sel_rows_iterator) ) );
1120 
1121   g_list_foreach( selected_rows, (GFunc)gtk_tree_path_free, NULL);
1122   g_list_free( selected_rows );
1123 
1124   gtk_tree_selection_unselect_all(sel);
1125 
1126   return FALSE;
1127 }
1128 
on_ui_playlist_button_press(GtkWidget * widget,GdkEventButton * event,gpointer data)1129 gboolean on_ui_playlist_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data) {
1130   GtkTreePath *path = NULL;
1131   GtkTreeSelection *sel = NULL;
1132   GtkTreeView *tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_playlist"));
1133 
1134   if( event->button != 3 ) return FALSE;
1135 
1136   if( gtk_tree_view_get_path_at_pos(tv, (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL) ) {
1137     debug("[%d,%d]", (gint)event->x, (gint)event->y);
1138     sel = gtk_tree_view_get_selection(tv);
1139     if( !gtk_tree_selection_path_is_selected(sel, path) ) {
1140       debug("User clicked on unselected row, selecting ");
1141       gtk_tree_selection_unselect_all(sel);
1142       gtk_tree_selection_select_path(sel, path);
1143     }
1144   }
1145 
1146   debug("Displaying playlist popup menu");
1147   gtk_menu_popup(GTK_MENU(gtk_builder_get_object(builder, "glurp_menu_playlist")), NULL, NULL, NULL, NULL, event->button, event->time);
1148 
1149   return TRUE;
1150 }
1151 
on_pmenu_playlist_play(GtkWidget * widget,gpointer data)1152 gboolean on_pmenu_playlist_play(GtkWidget *widget, gpointer data) {
1153   debug("POPUP: Playlist -> Play");
1154   on_ui_player_play(GTK_WIDGET(gtk_builder_get_object(builder, "button_play")), NULL);
1155   return FALSE;
1156 }
1157 
on_pmenu_playlist_remove_selected(GtkWidget * widget,gpointer data)1158 gboolean on_pmenu_playlist_remove_selected(GtkWidget *widget, gpointer data) {
1159   debug("POPUP: Playlist -> Remove selected");
1160   on_menu_pl_remove_selected_activate(GTK_WIDGET(gtk_builder_get_object(builder, "button_play")), NULL);
1161   return FALSE;
1162 }
1163 
on_pmenu_playlist_remove_crop(GtkWidget * widget,gpointer data)1164 gboolean on_pmenu_playlist_remove_crop(GtkWidget *widget, gpointer data) {
1165   debug("POPUP: Playlist -> Remove crop");
1166   on_menu_pl_remove_crop_activate(GTK_WIDGET(gtk_builder_get_object(builder, "button_play")), NULL);
1167   return FALSE;
1168 }
1169 
on_pmenu_playlist_remove_all(GtkWidget * widget,gpointer data)1170 gboolean on_pmenu_playlist_remove_all(GtkWidget *widget, gpointer data) {
1171   debug("POPUP: Playlist -> Remove all");
1172   on_menu_pl_remove_all_activate(GTK_WIDGET(gtk_builder_get_object(builder, "button_play")), NULL);
1173   return FALSE;
1174 }
1175 
on_ui_add_button_press(GtkWidget * widget,GdkEventButton * event,gpointer data)1176 gboolean on_ui_add_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data) {
1177   GtkTreePath *path = NULL;
1178   GtkTreeSelection *sel = NULL;
1179   GtkTreeView *tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_add"));
1180 
1181   if( event->button != 3 ) return FALSE;
1182 
1183   if( gtk_tree_view_get_path_at_pos(tv, (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL) ) {
1184     debug("[%d,%d]", (gint)event->x, (gint)event->y);
1185     sel = gtk_tree_view_get_selection(tv);
1186     if( !gtk_tree_selection_path_is_selected(sel, path) ) {
1187       debug("User clicked on unselected row, selecting ");
1188       gtk_tree_selection_unselect_all(sel);
1189       gtk_tree_selection_select_path(sel, path);
1190     }
1191   }
1192 
1193   debug("Displaying add popup menu");
1194   gtk_menu_popup(GTK_MENU(gtk_builder_get_object(builder, "glurp_menu_db")), NULL, NULL, NULL, NULL, event->button, event->time);
1195   return TRUE;
1196 }
1197 
on_pmenu_db_update_selected(GtkWidget * widget,gpointer data)1198 gboolean on_pmenu_db_update_selected(GtkWidget *widget, gpointer data) {
1199   GtkTreeView *tv;
1200   GtkTreeModel *tm;
1201   GtkTreeSelection *ts;
1202   GList *selected_rows;
1203   GtkTreeIter iter;
1204   gint i, num = 0;
1205   gchar *path = NULL;
1206 
1207   debug("POPUP: DB -> Update selected");
1208 
1209   if(!mpd_check_connected(glurp->mpd)) return FALSE;
1210   tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview_add"));
1211   tm = gtk_tree_view_get_model(tv);
1212   if( !((ts = gtk_tree_view_get_selection(tv)) && (num = gtk_tree_selection_count_selected_rows(ts))) ) {
1213     debug("No selection, ignoring");
1214     return FALSE;
1215   }
1216 
1217   selected_rows = gtk_tree_selection_get_selected_rows(ts, NULL);
1218 
1219   debug("Removing 'Add' treeview model");
1220   gtk_tree_view_set_model(tv, NULL);
1221 
1222   gui_updating_disable_add_controls();
1223   glurp->updating_db = TRUE;
1224 
1225   for( i = 0; i < num; i++ ) {
1226     gtk_tree_model_get_iter(tm, &iter, (GtkTreePath *)g_list_nth_data(selected_rows, i));
1227     gtk_tree_model_get(tm, &iter, 1, &path, -1);
1228     mpd_database_update_dir(glurp->mpd, path);
1229     debug("**** Updating '%s'", path);
1230     g_free(path);
1231     if (mpd_check_error(glurp->mpd)) break;
1232   }
1233 
1234   return FALSE;
1235 }
1236 
on_pmenu_db_add_selected(GtkWidget * widget,gpointer data)1237 gboolean on_pmenu_db_add_selected(GtkWidget *widget, gpointer data) {
1238   debug("POPUP: DB -> Add selected");
1239   on_ui_add_add_clicked(GTK_WIDGET(gtk_builder_get_object(builder, "button_add_add")), NULL);
1240   return FALSE;
1241 }
1242 
on_pmenu_db_info(GtkWidget * widget,gpointer data)1243 gboolean on_pmenu_db_info(GtkWidget *widget, gpointer data) {
1244   debug("POPUP: DB -> Database information (STUB)");
1245   return FALSE;
1246 }
1247 
on_pmenu_playlist_shuffle_activate(GtkWidget * widget,gpointer data)1248 gboolean on_pmenu_playlist_shuffle_activate(GtkWidget *widget, gpointer data) {
1249   if( !mpd_check_connected(glurp->mpd) ) {
1250     debug("Not connected");
1251     return FALSE;
1252   }
1253 
1254   mpd_playlist_shuffle(glurp->mpd);
1255 
1256   statusbar_print("Playlist shuffled.");
1257 
1258   return FALSE;
1259 }
1260 
on_togglebutton_pl_remove_toggled(GtkWidget * widget,gpointer data)1261 gboolean on_togglebutton_pl_remove_toggled(GtkWidget *widget, gpointer data) {
1262   if( !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) return FALSE;
1263 
1264   debug("Remove button clicked");
1265   gtk_menu_popup(GTK_MENU(gtk_builder_get_object(builder, "glurp_menu_pl_remove")), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time());
1266   return FALSE;
1267 }
1268 
on_menu_pl_remove_deactivate(GtkWidget * widget,gpointer data)1269 gboolean on_menu_pl_remove_deactivate(GtkWidget *widget, gpointer data) {
1270   debug("Remove menu hidden, deactivating togglebutton");
1271   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "togglebutton_pl_remove")), FALSE);
1272   return FALSE;
1273 }
1274 
on_outputs_toggled(GtkWidget * widget,gpointer data)1275 gboolean on_outputs_toggled(GtkWidget *widget, gpointer data) {
1276   GtkMenu *menu = populate_outputs_menu();
1277 
1278   if( !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) return FALSE;
1279 
1280   debug("Outputs button clicked");
1281 
1282   if( !menu ) return FALSE;
1283 
1284   gtk_menu_popup(populate_outputs_menu(), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time());
1285   return FALSE;
1286 }
1287 
on_menu_outputs_deactivate(GtkWidget * widget,gpointer data)1288 gboolean on_menu_outputs_deactivate(GtkWidget *widget, gpointer data) {
1289   debug("Outputs menu hidden, deactivating togglebutton");
1290   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "togglebutton_outputs")), FALSE);
1291   return FALSE;
1292 }
1293 
on_menu_output_activate(GtkWidget * widget,gpointer data)1294 gboolean on_menu_output_activate(GtkWidget *widget, gpointer data) {
1295   gboolean enable = FALSE;
1296   gint i, d = (gint)data;
1297 
1298   if( d < 0 ) enable = TRUE;
1299   i = abs(d) - 1;
1300 
1301   debug("%s output %d", (enable ? "Enable" : "Disable"), i);
1302 
1303   statusbar_print("%s output %d", (enable ? "Enabling" : "Disabling"), i);
1304   mpd_server_set_output_device(glurp->mpd, i, enable);
1305 
1306   return FALSE;
1307 }
1308 
on_ui_streams_row_activated(GtkTreeView * treeview,GtkTreePath * tp,GtkTreeViewColumn * col,gpointer user_data)1309 gboolean on_ui_streams_row_activated(GtkTreeView *treeview, GtkTreePath *tp, GtkTreeViewColumn *col, gpointer user_data) {
1310   GtkTreeIter act;
1311   GtkTreeModel *model;
1312   gchar* url;
1313   GtkWidget* entry;
1314 
1315   model = gtk_tree_view_get_model(treeview);
1316   gtk_tree_model_get_iter(model, &act, tp);
1317   gtk_tree_model_get(model, &act, 0, &url, -1);
1318   entry = GTK_WIDGET(gtk_builder_get_object(builder, "streams_entry"));
1319   gtk_entry_set_text(GTK_ENTRY(entry), url);
1320   g_free(url);
1321   return FALSE;
1322 }
1323 
on_ui_streams_button_press(GtkWidget * widget,GdkEventButton * event,gpointer data)1324 gboolean on_ui_streams_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data) {
1325   GtkTreePath *path = NULL;
1326   GtkTreeSelection *sel = NULL;
1327   GtkTreeView *tv = GTK_TREE_VIEW(gtk_builder_get_object(builder, "streams_treeview"));
1328 
1329   if( event->button != 3 ) return FALSE;
1330 
1331   if( gtk_tree_view_get_path_at_pos(tv, (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL) ) {
1332     debug("[%d,%d]", (gint)event->x, (gint)event->y);
1333     sel = gtk_tree_view_get_selection(tv);
1334     if( !gtk_tree_selection_path_is_selected(sel, path) ) {
1335       debug("User clicked on unselected row, selecting ");
1336       gtk_tree_selection_unselect_all(sel);
1337       gtk_tree_selection_select_path(sel, path);
1338     }
1339   }
1340 
1341   debug("Displaying stream popup menu");
1342   gtk_menu_popup(GTK_MENU(gtk_builder_get_object(builder, "glurp_menu_streams")), NULL, NULL, NULL, NULL, event->button, event->time);
1343 
1344   return TRUE;
1345 }
1346 
1347 
on_menu_streams_remove_selected_activate(GtkWidget * widget,gpointer user_data)1348 gboolean on_menu_streams_remove_selected_activate(GtkWidget *widget, gpointer user_data) {
1349   GtkWidget *tv;
1350   GtkTreeModel *tm;
1351   GtkTreeSelection *ts;
1352   gint num_sel, i;
1353   gchar* url;
1354   GtkTreeIter iter;
1355   GList *selected_rows;
1356 
1357   if(!mpd_check_connected(glurp->mpd)) return FALSE;
1358 
1359   tv = GTK_WIDGET(gtk_builder_get_object(builder, "streams_treeview"));
1360   tm = gtk_tree_view_get_model(GTK_TREE_VIEW(tv));
1361   ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv));
1362 
1363   num_sel = gtk_tree_selection_count_selected_rows(ts);
1364   selected_rows = gtk_tree_selection_get_selected_rows(ts, NULL);
1365 
1366   debug("Selected %d rows", num_sel);
1367 
1368   if( num_sel ) {
1369     for( i=0; i<num_sel; i++ ) {
1370       gtk_tree_model_get_iter(tm, &iter, (GtkTreePath *)g_list_nth_data(selected_rows, i));
1371       gtk_tree_model_get(tm, &iter, 0, &url, -1);
1372       pull_stream(url);
1373     }
1374   }
1375   populate_stream_liststore();
1376   return FALSE;
1377 }
1378 
1379 // vim: et sw=2 smarttab
1380