3 #include <gdk/gdkkeysyms.h>
4 #include <glade/glade.h>
5 #include <gmpc/plugin.h>
6 #include <gmpc/gmpc_easy_download.h>
7 #include <gmpc/metadata.h>
8 #include <gmpc/gmpc-mpddata-model.h>
9 #include <gmpc/gmpc-mpddata-treeview.h>
10 #include <gmpc/TreeSearchWidget.h>
12 #include "magnatune.h"
14 extern GladeXML
*pl3_xml
;
18 * Function decleration
20 static void magnatune_selected(GtkWidget
*container
);
21 static void magnatune_unselected(GtkWidget
*container
);
22 static void magnatune_add(GtkWidget
*cat_tree
);
23 static void magnatune_download_xml_callback(int download
, int total
,gpointer data
);
24 static void magnatune_download();
25 static void magnatune_mpd_status_changed(MpdObj
*mi
, ChangedStatusType what
, void *data
);
26 static int magnatune_fetch_cover_priority(void);
27 static int magnatune_fetch_get_image(mpd_Song
*song
,MetaDataType type
, char **path
);
28 static int magnatune_cat_menu_popup(GtkWidget
*menu
, int type
, GtkWidget
*tree
, GdkEventButton
*event
);
30 static int magnatune_button_release_event(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
);
31 static int magnatune_button_handle_release_event_tag(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
);
33 static void magnatune_cat_key_press(GtkWidget
*tree
, GdkEventKey
*event
, int selected_type
);
34 static int magnatune_key_press(GtkWidget
*tree
, GdkEventKey
*event
);
35 static void magnatune_show_album_list(GtkTreeSelection
*selection
, gpointer user_data
);
36 static void magnatune_show_song_list(GtkTreeSelection
*selection
, gpointer user_data
);
37 static int magnatune_button_handle_release_event_tag_add(GtkWidget
*button
, gpointer user_data
);
38 static void magnatune_save_myself(void);
39 static GtkTreeRowReference
*magnatune_ref
= NULL
;
43 static int magnatune_get_enabled()
45 return cfg_get_single_value_as_int_with_default(config
, "magnatune", "enable", TRUE
);
47 static void magnatune_set_enabled(int enabled
)
49 cfg_set_single_value_as_int(config
, "magnatune", "enable", enabled
);
52 if(magnatune_ref
== NULL
)
54 magnatune_add(GTK_WIDGET(playlist3_get_category_tree_view()));
57 else if (magnatune_ref
)
59 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
62 magnatune_save_myself();
63 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter
, path
)){
64 gtk_tree_store_remove(playlist3_get_category_tree_store(), &iter
);
66 gtk_tree_path_free(path
);
67 gtk_tree_row_reference_free(magnatune_ref
);
78 /* Playlist window row reference */
80 GtkWidget
*magnatune_pb
= NULL
;
81 GtkWidget
*magnatune_vbox
= NULL
;
82 GtkTreeModel
*mt_store
= NULL
;
83 TreeSearch
*mt_tree_search
= NULL
;
85 GtkWidget
*treeviews
[3] = {NULL
, NULL
,NULL
};
87 static GtkWidget
*magnatune_logo
=NULL
;
88 extern GladeXML
*pl3_xml
;
90 static void magnatune_buy_album()
92 gchar
*uri
= "http://www.magnatune.com/";
93 gchar
*path
= g_strdup_printf("%s%c%s '%s'",DATA_DIR
,G_DIR_SEPARATOR
,"xdg-open",uri
);
94 g_spawn_command_line_async(path
, NULL
);
98 static void magnatune_logo_add()
100 mpd_Song
*song
= mpd_playlist_get_current_song(connection
);
101 GtkWidget
*logo
, *button
;
104 magnatune_logo
= gtk_hbox_new(FALSE
,6);
106 button
= gtk_button_new_with_label("Buy this album\nfrom magnatune");
107 gtk_button_set_relief(GTK_BUTTON(button
), GTK_RELIEF_NONE
);
109 ali
= gtk_alignment_new(0,0.5,0,1);
110 gtk_container_add(GTK_CONTAINER(ali
), button
);
111 logo
= gtk_image_new_from_icon_name("magnatune", GTK_ICON_SIZE_DND
);
112 gtk_button_set_image(GTK_BUTTON(button
), logo
);
113 gtk_box_pack_start(GTK_BOX(magnatune_logo
), ali
, TRUE
, TRUE
,0);
114 gtk_box_pack_end(GTK_BOX(glade_xml_get_widget(pl3_xml
, "vbox5")), magnatune_logo
, FALSE
,FALSE
,0);
115 g_signal_connect(G_OBJECT(button
), "clicked", G_CALLBACK(magnatune_buy_album
), NULL
);
117 if(strstr(song
->file
,"magnatune.com"))
119 gtk_widget_show_all(magnatune_logo
);
127 static void magnatune_logo_init()
131 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default (),DATA_DIR
);
133 gtk_init_add((GtkFunction
)magnatune_logo_add
, NULL
);
135 * init the magnatune stuff
145 static void magnatune_mpd_status_changed(MpdObj
*mi
, ChangedStatusType what
, void *data
)
149 if(what
&(MPD_CST_SONGID
|MPD_CST_STATE
))
151 mpd_Song
*song
= mpd_playlist_get_current_song(mi
);
153 if(strstr(song
->file
,"magnatune.com"))
155 gtk_widget_show_all(magnatune_logo
);
159 gtk_widget_hide(magnatune_logo
);
163 static void magnatune_get_genre_list()
165 MpdData
*data
= NULL
;
166 data
= magnatune_db_get_genre_list();
167 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]))),data
);
170 static void magnatune_show_album_list(GtkTreeSelection
*selection
, gpointer user_data
)
172 MpdData
*data
= NULL
;
174 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
175 if(gtk_tree_selection_get_selected(selection
, &model
, &piter
))
178 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
179 data
= magnatune_db_get_artist_list(genre
);
183 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]))),data
);
186 static void magnatune_show_song_list(GtkTreeSelection
*selection
, gpointer user_data
)
188 MpdData
*data
= NULL
;
190 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
191 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
192 gchar
*genre
= NULL
, *artist
= NULL
, *album
= NULL
;
193 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
196 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
197 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
199 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
200 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
202 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
203 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]));
204 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]));
205 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
207 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&album
,-1);
211 data
= magnatune_db_get_song_list(genre
, artist
, album
);
212 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(mt_store
), data
);
215 static void magnatune_show_artist_list(GtkTreeSelection
*selection
, gpointer user_data
)
218 MpdData
*data
= NULL
;
219 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
220 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
222 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
224 GList
*iter
,*list
= NULL
;
227 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
228 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
230 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
231 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
233 GList
*iter
,*list
= NULL
;
236 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
237 data
= magnatune_db_get_album_list(genre
,artist
);
238 gmpc_mpddata_model_set_request_artist(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]))),artist
);
243 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]))),data
);
246 static void magnatune_add_album_row_activated(GtkTreeView
*tree
, GtkTreePath
*path
, GtkTreeViewColumn
*col
, gpointer data
)
248 GtkTreeModel
*model
= gtk_tree_view_get_model(tree
);
251 if(gtk_tree_model_get_iter(model
, &iter_r
, path
))
254 gtk_tree_model_get(model
, &iter_r
, MPDDATA_MODEL_COL_PATH
, &path
, -1);
260 static gboolean
magnatune_search_equal_func(GtkTreeModel
*model
, int column
, const gchar
*key
, GtkTreeIter
*iter
, gpointer data
)
262 gchar
*compare
= NULL
;
263 gtk_tree_model_get(model
,iter
, column
, &compare
, -1);
265 gchar
*a
= g_utf8_casefold(key
, -1);
266 gchar
*b
= g_utf8_casefold(compare
, -1);
279 static void magnatune_search_activate(TreeSearch
*ts
)
281 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
282 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(ts
->treeview
));
283 if (gtk_tree_selection_count_selected_rows (selection
) == 1)
285 GList
*list
= gtk_tree_selection_get_selected_rows (selection
, &model
);
286 magnatune_add_album_row_activated(GTK_TREE_VIEW(ts
->treeview
),(GtkTreePath
*)list
->data
, NULL
,NULL
);
288 g_list_foreach (list
, (GFunc
) gtk_tree_path_free
, NULL
);
293 static void magnatune_init()
296 GtkWidget
*tree
= NULL
;
297 GtkWidget
*sw
= NULL
;
298 GtkCellRenderer
*renderer
= NULL
;
299 GtkWidget
*paned
= NULL
;
300 GtkWidget
*hbox
= NULL
;
301 GtkWidget
*vbox
= NULL
;
302 GtkTreeModel
*model
= NULL
;
303 GtkTreeViewColumn
*column
= NULL
;
304 int position
= cfg_get_single_value_as_int_with_default(config
, "magnatune", "pane-pos", 150);
305 magnatune_vbox
= gtk_vpaned_new();
306 gtk_paned_set_position(GTK_PANED(magnatune_vbox
), position
);
309 vbox
= gtk_vbox_new(FALSE
,6);
315 mt_store
= (GtkTreeModel
*)gmpc_mpddata_model_new();
318 paned
= gtk_hbox_new(TRUE
,6);
319 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
321 sw
= gtk_scrolled_window_new(NULL
, NULL
);
322 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
323 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
324 treeviews
[0] = gtk_tree_view_new_with_model(model
);
325 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[0]), MPDDATA_MODEL_COL_SONG_TITLE
);
326 g_signal_connect(G_OBJECT(treeviews
[0]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(0));
328 column
= gtk_tree_view_column_new();
329 gtk_tree_view_column_set_title(column
, "Genre");
332 renderer
= gtk_cell_renderer_pixbuf_new();
333 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
334 gtk_tree_view_column_add_attribute(column
, renderer
, "icon-name", MPDDATA_MODEL_COL_ICON_ID
);
335 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
336 renderer
= gtk_cell_renderer_text_new();
337 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
338 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
339 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[0]),column
, -1);
341 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[0]);
342 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
344 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]))), "changed", G_CALLBACK(magnatune_show_album_list
), NULL
);
347 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
348 sw
= gtk_scrolled_window_new(NULL
, NULL
);
349 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
350 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
351 treeviews
[1] = gtk_tree_view_new_with_model(model
);
353 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[1]), MPDDATA_MODEL_COL_SONG_TITLE
);
354 g_signal_connect(G_OBJECT(treeviews
[1]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(1));
356 column
= gtk_tree_view_column_new();
357 gtk_tree_view_column_set_title(column
, "Artist");
358 size
= cfg_get_single_value_as_int_with_default(config
, "gmpc-mpddata-model", "icon-size", 64);
359 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
360 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews
[1]), TRUE
);
363 renderer
= gtk_cell_renderer_pixbuf_new();
364 gtk_cell_renderer_set_fixed_size(renderer
, size
,size
);
366 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
367 gtk_tree_view_column_add_attribute(column
, renderer
, "pixbuf", MPDDATA_MODEL_META_DATA
);
368 renderer
= gtk_cell_renderer_text_new();
369 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
370 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
371 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[1]),column
, -1);
373 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[1]);
374 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
376 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]))), "changed", G_CALLBACK(magnatune_show_artist_list
), NULL
);
379 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
380 sw
= gtk_scrolled_window_new(NULL
, NULL
);
381 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
382 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
383 treeviews
[2] = gtk_tree_view_new_with_model(model
);
384 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[2]), MPDDATA_MODEL_COL_SONG_TITLE
);
386 g_signal_connect(G_OBJECT(treeviews
[2]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(2));
388 column
= gtk_tree_view_column_new();
389 gtk_tree_view_column_set_title(column
, "Album");
390 size
= cfg_get_single_value_as_int_with_default(config
, "gmpc-mpddata-model", "icon-size", 64);
391 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
392 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews
[2]), TRUE
);
395 renderer
= gtk_cell_renderer_pixbuf_new();
396 gtk_cell_renderer_set_fixed_size(renderer
, size
,size
);
398 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
399 gtk_tree_view_column_add_attribute(column
, renderer
, "pixbuf", MPDDATA_MODEL_META_DATA
);
400 renderer
= gtk_cell_renderer_text_new();
401 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
402 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
403 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[2]),column
, -1);
405 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[2]);
406 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
409 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
410 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
411 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
413 gtk_paned_add1(GTK_PANED(magnatune_vbox
), paned
);
414 gtk_widget_show_all(paned
);
418 sw
= gtk_scrolled_window_new(NULL
, NULL
);
419 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
420 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
423 tree
= (GtkWidget
*)gmpc_mpddata_treeview_new("magnatune",TRUE
,GTK_TREE_MODEL(mt_store
));
424 g_signal_connect(G_OBJECT(tree
), "row-activated", G_CALLBACK(magnatune_add_album_row_activated
), NULL
);
426 g_signal_connect(G_OBJECT(tree
), "button-press-event", G_CALLBACK(magnatune_button_release_event
), tree
);
427 g_signal_connect(G_OBJECT(tree
), "key-press-event", G_CALLBACK(magnatune_key_press
), NULL
);
429 gtk_container_add(GTK_CONTAINER(sw
), tree
);
430 gtk_box_pack_start(GTK_BOX(vbox
),sw
, TRUE
, TRUE
,0);
432 mt_tree_search
= (TreeSearch
*)treesearch_new(GTK_TREE_VIEW(tree
), MPDDATA_MODEL_COL_SONG_TITLE
);
433 gtk_box_pack_end(GTK_BOX(vbox
), GTK_WIDGET(mt_tree_search
), FALSE
, TRUE
, 0);
434 g_signal_connect(G_OBJECT(mt_tree_search
), "result-activate", G_CALLBACK(magnatune_search_activate
),NULL
);
437 gtk_widget_show_all(sw
);
438 gtk_widget_show(vbox
);
440 * Progress Bar for the bottom
442 magnatune_pb
= gtk_progress_bar_new();
443 gtk_box_pack_end(GTK_BOX(vbox
), magnatune_pb
, FALSE
, TRUE
, 0);
444 gtk_paned_add2(GTK_PANED(magnatune_vbox
), vbox
);
447 g_object_ref(magnatune_vbox
);
451 static void magnatune_selected(GtkWidget
*container
)
453 if(magnatune_vbox
== NULL
)
456 gtk_container_add(GTK_CONTAINER(container
), magnatune_vbox
);
457 gtk_widget_show(magnatune_vbox
);
458 if(!magnatune_db_has_data())
460 magnatune_download();
462 magnatune_get_genre_list();
464 gtk_container_add(GTK_CONTAINER(container
), magnatune_vbox
);
465 gtk_widget_show(magnatune_vbox
);
468 static void magnatune_unselected(GtkWidget
*container
)
470 gtk_container_remove(GTK_CONTAINER(container
), magnatune_vbox
);
473 static void magnatune_download_xml_callback(int download
, int total
,gpointer data
)
475 GtkWidget
*pb
= data
;
478 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb
), download
/(float)total
);
480 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pb
));
483 label
= g_strdup_printf("%.2f mb",(download
>>10)/1024.0);
485 else if (download
>>10)
487 label
= g_strdup_printf("%i kb",download
>>10);
491 label
= g_strdup_printf("%i b",download
);
493 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pb
), label
);
495 while(gtk_events_pending())
496 gtk_main_iteration();
499 static void magnatune_download()
501 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml
, "pl3_win"), FALSE
);
502 gtk_widget_show(magnatune_pb
);
503 magnatune_db_download_xml(magnatune_download_xml_callback
, magnatune_pb
);
504 gtk_widget_hide(magnatune_pb
);
505 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml
, "pl3_win"), TRUE
);
508 static void magnatune_add(GtkWidget
*cat_tree
)
510 GtkTreePath
*path
= NULL
;
511 GtkTreeIter iter
,child
;
512 GtkTreeStore
*pl3_tree
= (GtkTreeStore
*)gtk_tree_view_get_model(GTK_TREE_VIEW(cat_tree
));
513 gint pos
= cfg_get_single_value_as_int_with_default(config
, "magnatune","position",20);
515 if(!cfg_get_single_value_as_int_with_default(config
, "magnatune", "enable", TRUE
)) return;
517 debug_printf(DEBUG_INFO
,"Adding at position: %i", pos
);
518 playlist3_insert_browser(&iter
, pos
);
519 /*gtk_tree_store_append(pl3_tree, &iter, NULL);*/
520 gtk_tree_store_set(pl3_tree
, &iter
,
521 PL3_CAT_TYPE
, plugin
.id
,
522 PL3_CAT_TITLE
, "Magnatune Browser",
524 PL3_CAT_ICON_ID
, "magnatune",
526 PL3_CAT_ICON_SIZE
,GTK_ICON_SIZE_DND
,-1);
528 * Clean up old row reference if it exists
532 gtk_tree_row_reference_free(magnatune_ref
);
533 magnatune_ref
= NULL
;
536 * create row reference
538 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter
);
541 magnatune_ref
= gtk_tree_row_reference_new(GTK_TREE_MODEL(playlist3_get_category_tree_store()), path
);
542 gtk_tree_path_free(path
);
546 static char * __magnatune_process_string(char *name
)
553 /* only gonna be smaller */
554 char *result
= g_malloc0((strlen(name
)+1+spaces
*2)*sizeof(char));
555 for(i
=0; i
< strlen(name
);i
++)
557 if(name
[i
] == '(' || name
[i
] == '[') depth
++;
558 else if (name
[i
] == ')' || name
[i
] == ']') depth
--;
565 for(i
=j
-1;i
>0 && result
[i
] == ' ';i
--)
573 static int magnatune_fetch_cover_priority(void){
574 return cfg_get_single_value_as_int_with_default(config
, "magnatune", "priority", 80);
576 static int magnatune_fetch_get_image(mpd_Song
*song
,MetaDataType type
, char **path
)
579 if(magnatune_db_has_data() == FALSE
)
580 return META_DATA_UNAVAILABLE
;
581 if(type
== META_ARTIST_ART
&& song
->artist
)
583 char *artist
= __magnatune_process_string(song
->artist
);
584 char *value
= magnatune_db_get_value(artist
,NULL
,META_ARTIST_ART
);
587 gchar
*filename
= NULL
;
588 gmpc_easy_download_struct dld
= {NULL
, 0, -1, NULL
,NULL
};
589 filename
= g_strdup_printf("%s.jpg", artist
);
590 *path
= gmpc_get_covers_path(filename
);
592 if(gmpc_easy_download(value
, &dld
))
594 g_file_set_contents(*path
, dld
.data
, dld
.size
, NULL
);
595 return META_DATA_AVAILABLE
;
597 gmpc_easy_download_clean(&dld
);
603 else if(type
== META_ALBUM_ART
&& song
->artist
&& song
->album
)
605 char *artist
= __magnatune_process_string(song
->artist
);
606 char *album
= __magnatune_process_string(song
->album
);
607 char *value
= magnatune_db_get_value(artist
,album
,META_ALBUM_ART
);
611 gmpc_easy_download_struct dld
= {NULL
, 0, -1, NULL
,NULL
};
612 filename
= g_strdup_printf("%s-%s.jpg", artist
,album
);
613 *path
= gmpc_get_covers_path(filename
);
615 if(gmpc_easy_download(value
, &dld
))
617 g_file_set_contents(*path
, dld
.data
, dld
.size
, NULL
);
618 return META_DATA_AVAILABLE
;
620 gmpc_easy_download_clean(&dld
);
626 return META_DATA_UNAVAILABLE
;
628 static void magnatune_redownload_reload_db()
631 GtkTreeModel
*model
= gtk_tree_row_reference_get_model(magnatune_ref
);
632 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
633 if(path
&& gtk_tree_model_get_iter(model
, &iter
, path
))
636 while(gtk_tree_model_iter_children(model
, &citer
,&iter
))
638 gtk_tree_store_remove(GTK_TREE_STORE(model
), &citer
);
640 magnatune_download();
641 magnatune_get_genre_list();
644 gtk_tree_path_free(path
);
647 static void magnatune_cat_menu_add()
650 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(playlist3_get_category_tree_view());
651 GtkTreeModel
*model
= (GtkTreeModel
*)playlist3_get_category_tree_store();
654 if(!gtk_tree_selection_get_selected(sel
,&model
,&citer
))
659 * Get the level we are on.
661 tpath
= gtk_tree_model_get_path(model
, &citer
);
662 depth
= gtk_tree_path_get_depth(tpath
);
663 gtk_tree_path_free(tpath
);
669 gtk_tree_model_get(model
, &citer
, PL3_CAT_INT_ID
,&genre
, -1);
672 list
= magnatune_db_get_url_list(genre
, NULL
,NULL
);
673 for(node
= list
; node
; node
= node
->next
)
675 mpd_playlist_queue_add(connection
, node
->data
);
677 mpd_playlist_queue_commit(connection
);
678 g_list_foreach(list
, (GFunc
)g_free
, NULL
);
689 if(gtk_tree_model_iter_parent(model
, &iter
, &citer
))
692 gtk_tree_model_get(model
, &iter
, PL3_CAT_INT_ID
,&genre
, -1);
693 gtk_tree_model_get(model
, &citer
, PL3_CAT_INT_ID
,&artist
, -1);
694 list
= magnatune_db_get_url_list(genre
, artist
,NULL
);
695 for(node
= list
; node
; node
= node
->next
)
697 mpd_playlist_queue_add(connection
, node
->data
);
699 mpd_playlist_queue_commit(connection
);
700 g_list_foreach(list
, (GFunc
)g_free
, NULL
);
712 static void magnatune_cat_menu_replace()
714 mpd_playlist_clear(connection
);
715 magnatune_cat_menu_add();
716 mpd_player_play(connection
);
720 static int magnatune_cat_menu_popup(GtkWidget
*menu
, int type
, GtkWidget
*tree
, GdkEventButton
*event
)
723 if(type
!= plugin
.id
) return 0;
726 /* add the clear widget */
727 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_REFRESH
,NULL
);
728 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
729 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_redownload_reload_db
), NULL
);
735 static void magnatune_add_selected(GtkWidget
*button
, GtkTreeView
*tree
)
737 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
738 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
739 GList
*list
= gtk_tree_selection_get_selected_rows(sel
,&model
);
743 for(node
= list
; node
; node
= g_list_next(node
))
746 if(gtk_tree_model_get_iter(model
, &iter
, node
->data
))
749 gtk_tree_model_get(model
, &iter
, MPDDATA_MODEL_COL_PATH
, &path
, -1);
750 mpd_playlist_queue_add(connection
, path
);
754 mpd_playlist_queue_commit(connection
);
755 g_list_foreach (list
, (GFunc
)gtk_tree_path_free
, NULL
);
759 static void magnatune_replace_selected(GtkWidget
*button
, GtkTreeView
*tree
)
761 mpd_playlist_clear(connection
);
762 magnatune_add_selected(button
, tree
);
763 mpd_player_play(connection
);
767 static void magnatune_list_edit_columns(GtkMenuItem
*item
, GtkWidget
*widget
)
769 gmpc_mpddata_treeview_edit_columns(GMPC_MPDDATA_TREEVIEW(widget
));
771 static int magnatune_button_handle_release_event_tag_add(GtkWidget
*button
, gpointer userdata
)
775 int position
= GPOINTER_TO_INT(userdata
);
776 gchar
*genre
=NULL
, *artist
=NULL
, *album
=NULL
;
777 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
778 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
780 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
782 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
786 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
787 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
788 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
790 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
795 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]));
796 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]));
797 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
799 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&album
,-1);
802 list
= magnatune_db_get_url_list(genre
, artist
, album
);
803 for(;list
; list
= list
->next
)
805 mpd_playlist_queue_add(connection
, list
->data
);
807 mpd_playlist_queue_commit(connection
);
810 g_list_foreach(list
, g_free
, NULL
);
822 static int magnatune_button_handle_release_event_tag_replace(GtkWidget
*button
, gpointer userdata
)
824 mpd_playlist_clear(connection
);
825 magnatune_button_handle_release_event_tag_add(button
,userdata
);
826 mpd_player_play(connection
);
830 static int magnatune_button_handle_release_event_tag(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
)
833 int position
= GPOINTER_TO_INT(data
);
834 if(event
->button
!= 3) return FALSE
;
837 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
838 if(gtk_tree_selection_count_selected_rows(sel
)> 0)
840 GtkWidget
*menu
= gtk_menu_new();
844 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD
,NULL
);
845 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
), item
);
846 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_add
), data
);
848 item
= gtk_image_menu_item_new_with_label("Replace");
849 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
850 gtk_image_new_from_stock(GTK_STOCK_REDO
, GTK_ICON_SIZE_MENU
));
851 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
852 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_replace
), data
);
853 gtk_widget_show_all(menu
);
854 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
,NULL
, NULL
, event
->button
, event
->time
);
860 static int magnatune_button_release_event(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
)
862 if(event
->button
!= 3) return FALSE
;
865 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
867 if(gtk_tree_selection_count_selected_rows(sel
)> 0)
869 GtkWidget
*menu
= gtk_menu_new();
870 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
872 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD
,NULL
);
873 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
), item
);
874 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_add_selected
), tree
);
876 item
= gtk_image_menu_item_new_with_label("Replace");
877 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
878 gtk_image_new_from_stock(GTK_STOCK_REDO
, GTK_ICON_SIZE_MENU
));
879 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
881 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_replace_selected
), tree
);
884 item
= gtk_separator_menu_item_new();
885 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
887 item
= gtk_image_menu_item_new_with_label(("Edit Columns"));
888 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
889 gtk_image_new_from_stock(GTK_STOCK_EDIT
, GTK_ICON_SIZE_MENU
));
890 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
891 g_signal_connect(G_OBJECT(item
), "activate",
892 G_CALLBACK(magnatune_list_edit_columns
), tree
);
894 gtk_widget_show_all(menu
);
896 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
,NULL
, NULL
, event
->button
, event
->time
);
902 static void magnatune_cat_key_press(GtkWidget
*tree
, GdkEventKey
*event
, int selected_type
)
904 if(selected_type
!= plugin
.id
) return;
905 if(event
->state
&GDK_CONTROL_MASK
&& event
->keyval
== GDK_Insert
)
907 magnatune_cat_menu_replace();
909 else if(event
->keyval
== GDK_Insert
)
911 magnatune_cat_menu_add();
916 static int magnatune_key_press(GtkWidget
*tree
, GdkEventKey
*event
)
918 if(event
->state
&GDK_CONTROL_MASK
&& event
->keyval
== GDK_Insert
)
920 magnatune_replace_selected(NULL
, GTK_TREE_VIEW(tree
));
922 else if(event
->keyval
== GDK_Insert
)
924 magnatune_add_selected(NULL
, GTK_TREE_VIEW(tree
));
926 else if (event
->keyval
== GDK_f
&& event
->state
&GDK_CONTROL_MASK
)
928 treesearch_start(mt_tree_search
);
931 else if((event
->state
&(GDK_CONTROL_MASK
|GDK_MOD1_MASK
)) == 0 &&
932 ((event
->keyval
>= GDK_space
&& event
->keyval
<= GDK_z
)))
935 data
[0] = (char)gdk_keyval_to_unicode(event
->keyval
);
937 treesearch_start(TREESEARCH(mt_tree_search
));
938 gtk_entry_set_text(GTK_ENTRY(TREESEARCH(mt_tree_search
)->entry
),data
);
939 gtk_editable_set_position(GTK_EDITABLE(TREESEARCH(mt_tree_search
)->entry
),1);
944 static void magnatune_save_myself(void)
948 int position
= gtk_paned_get_position(GTK_PANED(magnatune_vbox
));
949 cfg_set_single_value_as_int(config
, "magnatune", "pane-pos", position
);
953 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
956 gint
*indices
= gtk_tree_path_get_indices(path
);
957 debug_printf(DEBUG_INFO
,"Saving myself to position: %i\n", indices
[0]);
958 cfg_set_single_value_as_int(config
, "magnatune","position",indices
[0]);
959 gtk_tree_path_free(path
);
964 static void magnatune_destroy(void)
966 magnatune_db_destroy();
968 gtk_widget_destroy(magnatune_vbox
);
971 gmpcMetaDataPlugin magnatune_cover
= {
972 magnatune_fetch_cover_priority
,
973 magnatune_fetch_get_image
977 /* Needed plugin_wp stuff */
978 gmpcPlBrowserPlugin magnatune_gbp
= {
979 .add
= magnatune_add
,
980 .selected
= magnatune_selected
,
981 .unselected
= magnatune_unselected
,
982 .cat_right_mouse_menu
= magnatune_cat_menu_popup
,
983 .cat_key_press
= magnatune_cat_key_press
986 int plugin_api_version
= PLUGIN_API_VERSION
;
988 gmpcPlugin plugin
= {
989 .name
= "Magnatune Stream Browser",
990 .version
= {PLUGIN_MAJOR_VERSION
,PLUGIN_MINOR_VERSION
,PLUGIN_MICRO_VERSION
},
991 .plugin_type
= GMPC_PLUGIN_PL_BROWSER
|GMPC_PLUGIN_META_DATA
,
992 /* Creation and destruction */
993 .init
= magnatune_logo_init
,
994 .destroy
= magnatune_destroy
,
995 .save_yourself
= magnatune_save_myself
,
996 .mpd_status_changed
= magnatune_mpd_status_changed
,
998 /* Browser extention */
999 .browser
= &magnatune_gbp
,
1000 .metadata
= &magnatune_cover
,
1002 /* get/set enabled */
1003 .get_enabled
= magnatune_get_enabled
,
1004 .set_enabled
= magnatune_set_enabled