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
;
42 static int downloading
= FALSE
;
46 static int magnatune_get_enabled()
48 return cfg_get_single_value_as_int_with_default(config
, "magnatune", "enable", TRUE
);
50 static void magnatune_set_enabled(int enabled
)
52 cfg_set_single_value_as_int(config
, "magnatune", "enable", enabled
);
55 if(magnatune_ref
== NULL
)
57 magnatune_add(GTK_WIDGET(playlist3_get_category_tree_view()));
60 else if (magnatune_ref
)
62 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
65 magnatune_save_myself();
66 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter
, path
)){
67 gtk_list_store_remove(playlist3_get_category_tree_store(), &iter
);
69 gtk_tree_path_free(path
);
70 gtk_tree_row_reference_free(magnatune_ref
);
81 /* Playlist window row reference */
83 GtkWidget
*magnatune_pb
= NULL
;
84 GtkWidget
*magnatune_vbox
= NULL
;
85 GtkTreeModel
*mt_store
= NULL
;
86 TreeSearch
*mt_tree_search
= NULL
;
88 GtkWidget
*treeviews
[3] = {NULL
, NULL
,NULL
};
90 static GtkWidget
*magnatune_logo
=NULL
;
91 extern GladeXML
*pl3_xml
;
93 static void magnatune_buy_album()
95 gchar
*uri
= "http://www.magnatune.com/";
96 gchar
*path
= g_strdup_printf("%s%c%s '%s'",DATA_DIR
,G_DIR_SEPARATOR
,"xdg-open",uri
);
97 g_spawn_command_line_async(path
, NULL
);
101 static void magnatune_logo_add()
103 mpd_Song
*song
= mpd_playlist_get_current_song(connection
);
104 GtkWidget
*logo
, *button
;
107 magnatune_logo
= gtk_hbox_new(FALSE
,6);
109 button
= gtk_button_new_with_label("Buy this album\nfrom magnatune");
110 gtk_button_set_relief(GTK_BUTTON(button
), GTK_RELIEF_NONE
);
112 ali
= gtk_alignment_new(0,0.5,0,1);
113 gtk_container_add(GTK_CONTAINER(ali
), button
);
114 logo
= gtk_image_new_from_icon_name("magnatune", GTK_ICON_SIZE_DND
);
115 gtk_button_set_image(GTK_BUTTON(button
), logo
);
116 gtk_box_pack_start(GTK_BOX(magnatune_logo
), ali
, TRUE
, TRUE
,0);
117 gtk_box_pack_end(GTK_BOX(glade_xml_get_widget(pl3_xml
, "vbox5")), magnatune_logo
, FALSE
,FALSE
,0);
118 g_signal_connect(G_OBJECT(button
), "clicked", G_CALLBACK(magnatune_buy_album
), NULL
);
120 if(strstr(song
->file
,"magnatune.com"))
122 gtk_widget_show_all(magnatune_logo
);
130 static void magnatune_logo_init()
134 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default (),DATA_DIR
);
136 gtk_init_add((GtkFunction
)magnatune_logo_add
, NULL
);
138 * init the magnatune stuff
148 static void magnatune_mpd_status_changed(MpdObj
*mi
, ChangedStatusType what
, void *data
)
152 if(what
&(MPD_CST_SONGID
|MPD_CST_STATE
))
154 mpd_Song
*song
= mpd_playlist_get_current_song(mi
);
156 if(strstr(song
->file
,"magnatune.com"))
158 gtk_widget_show_all(magnatune_logo
);
162 gtk_widget_hide(magnatune_logo
);
166 void magnatune_get_genre_list()
168 MpdData
*data
= NULL
;
169 data
= magnatune_db_get_genre_list();
170 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]))),data
);
173 static void magnatune_show_album_list(GtkTreeSelection
*selection
, gpointer user_data
)
175 MpdData
*data
= NULL
;
177 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
178 if(gtk_tree_selection_get_selected(selection
, &model
, &piter
))
181 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
182 data
= magnatune_db_get_artist_list(genre
);
186 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]))),data
);
189 static void magnatune_show_song_list(GtkTreeSelection
*selection
, gpointer user_data
)
191 MpdData
*data
= NULL
;
193 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
194 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
195 gchar
*genre
= NULL
, *artist
= NULL
, *album
= NULL
;
196 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
199 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
200 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
202 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
203 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
205 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
206 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]));
207 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]));
208 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
210 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&album
,-1);
214 data
= magnatune_db_get_song_list(genre
, artist
, album
);
215 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(mt_store
), data
);
218 static void magnatune_show_artist_list(GtkTreeSelection
*selection
, gpointer user_data
)
221 MpdData
*data
= NULL
;
222 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
223 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
225 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
227 GList
*iter
,*list
= NULL
;
230 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
231 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
233 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
234 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
236 GList
*iter
,*list
= NULL
;
239 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
240 data
= magnatune_db_get_album_list(genre
,artist
);
241 gmpc_mpddata_model_set_request_artist(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]))),artist
);
246 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]))),data
);
249 static void magnatune_add_album_row_activated(GtkTreeView
*tree
, GtkTreePath
*path
, GtkTreeViewColumn
*col
, gpointer data
)
251 GtkTreeModel
*model
= gtk_tree_view_get_model(tree
);
254 if(gtk_tree_model_get_iter(model
, &iter_r
, path
))
257 gtk_tree_model_get(model
, &iter_r
, MPDDATA_MODEL_COL_PATH
, &path
, -1);
263 static gboolean
magnatune_search_equal_func(GtkTreeModel
*model
, int column
, const gchar
*key
, GtkTreeIter
*iter
, gpointer data
)
265 gchar
*compare
= NULL
;
266 gtk_tree_model_get(model
,iter
, column
, &compare
, -1);
268 gchar
*a
= g_utf8_casefold(key
, -1);
269 gchar
*b
= g_utf8_casefold(compare
, -1);
282 static void magnatune_search_activate(TreeSearch
*ts
)
284 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
285 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(ts
->treeview
));
286 if (gtk_tree_selection_count_selected_rows (selection
) == 1)
288 GList
*list
= gtk_tree_selection_get_selected_rows (selection
, &model
);
289 magnatune_add_album_row_activated(GTK_TREE_VIEW(ts
->treeview
),(GtkTreePath
*)list
->data
, NULL
,NULL
);
291 g_list_foreach (list
, (GFunc
) gtk_tree_path_free
, NULL
);
296 static void magnatune_init()
299 GtkWidget
*tree
= NULL
;
300 GtkWidget
*sw
= NULL
;
301 GtkCellRenderer
*renderer
= NULL
;
302 GtkWidget
*paned
= NULL
;
303 GtkWidget
*hbox
= NULL
;
304 GtkWidget
*vbox
= NULL
;
305 GtkTreeModel
*model
= NULL
;
306 GtkTreeViewColumn
*column
= NULL
;
307 int position
= cfg_get_single_value_as_int_with_default(config
, "magnatune", "pane-pos", 150);
308 magnatune_vbox
= gtk_vpaned_new();
309 gtk_paned_set_position(GTK_PANED(magnatune_vbox
), position
);
312 vbox
= gtk_vbox_new(FALSE
,6);
318 mt_store
= (GtkTreeModel
*)gmpc_mpddata_model_new();
321 paned
= gtk_hbox_new(TRUE
,6);
322 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
324 sw
= gtk_scrolled_window_new(NULL
, NULL
);
325 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
326 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
327 treeviews
[0] = gtk_tree_view_new_with_model(model
);
328 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[0]), MPDDATA_MODEL_COL_SONG_TITLE
);
329 g_signal_connect(G_OBJECT(treeviews
[0]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(0));
331 column
= gtk_tree_view_column_new();
332 gtk_tree_view_column_set_title(column
, "Genre");
335 renderer
= gtk_cell_renderer_pixbuf_new();
336 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
337 gtk_tree_view_column_add_attribute(column
, renderer
, "icon-name", MPDDATA_MODEL_COL_ICON_ID
);
338 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
339 renderer
= gtk_cell_renderer_text_new();
340 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
341 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
342 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[0]),column
, -1);
344 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[0]);
345 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
347 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]))), "changed", G_CALLBACK(magnatune_show_album_list
), NULL
);
350 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
351 sw
= gtk_scrolled_window_new(NULL
, NULL
);
352 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
353 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
354 treeviews
[1] = gtk_tree_view_new_with_model(model
);
356 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[1]), MPDDATA_MODEL_COL_SONG_TITLE
);
357 g_signal_connect(G_OBJECT(treeviews
[1]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(1));
359 column
= gtk_tree_view_column_new();
360 gtk_tree_view_column_set_title(column
, "Artist");
361 size
= cfg_get_single_value_as_int_with_default(config
, "gmpc-mpddata-model", "icon-size", 64);
362 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
363 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews
[1]), TRUE
);
366 renderer
= gtk_cell_renderer_pixbuf_new();
367 gtk_cell_renderer_set_fixed_size(renderer
, size
,size
);
369 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
370 gtk_tree_view_column_add_attribute(column
, renderer
, "pixbuf", MPDDATA_MODEL_META_DATA
);
371 renderer
= gtk_cell_renderer_text_new();
372 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
373 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
374 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[1]),column
, -1);
376 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[1]);
377 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
379 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]))), "changed", G_CALLBACK(magnatune_show_artist_list
), NULL
);
382 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
383 sw
= gtk_scrolled_window_new(NULL
, NULL
);
384 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
385 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
386 treeviews
[2] = gtk_tree_view_new_with_model(model
);
387 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[2]), MPDDATA_MODEL_COL_SONG_TITLE
);
389 g_signal_connect(G_OBJECT(treeviews
[2]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(2));
391 column
= gtk_tree_view_column_new();
392 gtk_tree_view_column_set_title(column
, "Album");
393 size
= cfg_get_single_value_as_int_with_default(config
, "gmpc-mpddata-model", "icon-size", 64);
394 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
395 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews
[2]), TRUE
);
398 renderer
= gtk_cell_renderer_pixbuf_new();
399 gtk_cell_renderer_set_fixed_size(renderer
, size
,size
);
401 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
402 gtk_tree_view_column_add_attribute(column
, renderer
, "pixbuf", MPDDATA_MODEL_META_DATA
);
403 renderer
= gtk_cell_renderer_text_new();
404 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
405 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
406 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[2]),column
, -1);
408 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[2]);
409 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
412 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
413 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
414 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
416 gtk_paned_add1(GTK_PANED(magnatune_vbox
), paned
);
417 gtk_widget_show_all(paned
);
421 sw
= gtk_scrolled_window_new(NULL
, NULL
);
422 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
423 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
426 tree
= (GtkWidget
*)gmpc_mpddata_treeview_new("magnatune",TRUE
,GTK_TREE_MODEL(mt_store
));
427 g_signal_connect(G_OBJECT(tree
), "row-activated", G_CALLBACK(magnatune_add_album_row_activated
), NULL
);
429 g_signal_connect(G_OBJECT(tree
), "button-press-event", G_CALLBACK(magnatune_button_release_event
), tree
);
430 g_signal_connect(G_OBJECT(tree
), "key-press-event", G_CALLBACK(magnatune_key_press
), NULL
);
432 gtk_container_add(GTK_CONTAINER(sw
), tree
);
433 gtk_box_pack_start(GTK_BOX(vbox
),sw
, TRUE
, TRUE
,0);
435 mt_tree_search
= (TreeSearch
*)treesearch_new(GTK_TREE_VIEW(tree
), MPDDATA_MODEL_COL_SONG_TITLE
);
436 gtk_box_pack_end(GTK_BOX(vbox
), GTK_WIDGET(mt_tree_search
), FALSE
, TRUE
, 0);
437 g_signal_connect(G_OBJECT(mt_tree_search
), "result-activate", G_CALLBACK(magnatune_search_activate
),NULL
);
440 gtk_widget_show_all(sw
);
441 gtk_widget_show(vbox
);
443 * Progress Bar for the bottom
445 magnatune_pb
= gtk_progress_bar_new();
446 gtk_box_pack_end(GTK_BOX(vbox
), magnatune_pb
, FALSE
, TRUE
, 0);
447 gtk_paned_add2(GTK_PANED(magnatune_vbox
), vbox
);
450 g_object_ref(magnatune_vbox
);
454 static void magnatune_selected(GtkWidget
*container
)
456 if(magnatune_vbox
== NULL
)
459 gtk_container_add(GTK_CONTAINER(container
), magnatune_vbox
);
460 gtk_widget_show(magnatune_vbox
);
461 if(!magnatune_db_has_data())
463 magnatune_download();
466 magnatune_get_genre_list();
468 gtk_container_add(GTK_CONTAINER(container
), magnatune_vbox
);
469 gtk_widget_show(magnatune_vbox
);
472 static void magnatune_unselected(GtkWidget
*container
)
474 gtk_container_remove(GTK_CONTAINER(container
), magnatune_vbox
);
477 int magnatune_end_download()
481 magnatune_get_genre_list();
482 gtk_widget_hide(magnatune_pb
);
483 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml
, "pl3_win"), TRUE
);
487 typedef struct _Pass
{
493 static int magnatune_download_xml_callback_real(Pass
*p
);
494 /* Move it to main thread, by pushing in idle */
495 static void magnatune_download_xml_callback(int download
, int total
,gpointer data
)
497 Pass
*p
= g_malloc0(sizeof(*p
));
499 p
->download
= download
;
501 g_idle_add(magnatune_download_xml_callback_real
, p
);
504 static int magnatune_download_xml_callback_real(Pass
*p
)
506 GtkWidget
*pb
= p
->pb
;
507 int download
= p
->download
;
508 int total
= p
->total
;
510 // gdk_threads_enter();
512 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb
), download
/(float)total
);
514 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pb
));
517 label
= g_strdup_printf("%.2f mb",(download
>>10)/1024.0);
519 else if (download
>>10)
521 label
= g_strdup_printf("%i kb",download
>>10);
525 label
= g_strdup_printf("%i b",download
);
527 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pb
), label
);
529 // while(gtk_events_pending())
530 // gtk_main_iteration();
531 // gdk_threads_leave();
536 static void magnatune_download()
539 // gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), FALSE);
540 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]))),NULL
);
541 gtk_widget_show(magnatune_pb
);
542 magnatune_db_download_xml(magnatune_download_xml_callback
, magnatune_pb
);
543 // gtk_widget_hide(magnatune_pb);
544 // gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), TRUE);
547 static void magnatune_add(GtkWidget
*cat_tree
)
549 GtkTreePath
*path
= NULL
;
550 GtkTreeIter iter
,child
;
551 GtkTreeStore
*pl3_tree
= (GtkTreeStore
*)gtk_tree_view_get_model(GTK_TREE_VIEW(cat_tree
));
552 gint pos
= cfg_get_single_value_as_int_with_default(config
, "magnatune","position",20);
554 if(!cfg_get_single_value_as_int_with_default(config
, "magnatune", "enable", TRUE
)) return;
556 debug_printf(DEBUG_INFO
,"Adding at position: %i", pos
);
557 playlist3_insert_browser(&iter
, pos
);
558 gtk_list_store_set(pl3_tree
, &iter
,
559 PL3_CAT_TYPE
, plugin
.id
,
560 PL3_CAT_TITLE
, "Magnatune Browser",
562 PL3_CAT_ICON_ID
, "magnatune",
564 PL3_CAT_ICON_SIZE
,GTK_ICON_SIZE_DND
,-1);
566 * Clean up old row reference if it exists
570 gtk_tree_row_reference_free(magnatune_ref
);
571 magnatune_ref
= NULL
;
574 * create row reference
576 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter
);
579 magnatune_ref
= gtk_tree_row_reference_new(GTK_TREE_MODEL(playlist3_get_category_tree_store()), path
);
580 gtk_tree_path_free(path
);
584 static char * __magnatune_process_string(char *name
)
591 /* only gonna be smaller */
592 char *result
= g_malloc0((strlen(name
)+1+spaces
*2)*sizeof(char));
593 for(i
=0; i
< strlen(name
);i
++)
595 if(name
[i
] == '(' || name
[i
] == '[') depth
++;
596 else if (name
[i
] == ')' || name
[i
] == ']') depth
--;
603 for(i
=j
-1;i
>0 && result
[i
] == ' ';i
--)
611 static int magnatune_fetch_cover_priority(void){
612 return cfg_get_single_value_as_int_with_default(config
, "magnatune", "priority", 80);
614 static void magnatune_fetch_cover_priority_set(int priority
){
615 cfg_set_single_value_as_int(config
, "magnatune", "priority", priority
);
617 static int magnatune_fetch_get_image(mpd_Song
*song
,MetaDataType type
, char **path
)
620 if(magnatune_db_has_data() == FALSE
)
621 return META_DATA_UNAVAILABLE
;
622 if(type
== META_ARTIST_ART
&& song
->artist
)
624 char *artist
= __magnatune_process_string(song
->artist
);
625 char *value
= magnatune_db_get_value(artist
,NULL
,META_ARTIST_ART
);
628 gmpc_easy_download_struct dld
= {NULL
, 0, -1, NULL
,NULL
};
629 *path
= gmpc_get_metadata_filename(META_ARTIST_ART
, song
, NULL
);
630 if(gmpc_easy_download(value
, &dld
))
632 g_file_set_contents(*path
, dld
.data
, dld
.size
, NULL
);
633 return META_DATA_AVAILABLE
;
635 gmpc_easy_download_clean(&dld
);
641 else if(type
== META_ALBUM_ART
&& song
->artist
&& song
->album
)
643 char *artist
= __magnatune_process_string(song
->artist
);
644 char *album
= __magnatune_process_string(song
->album
);
645 char *value
= magnatune_db_get_value(artist
,album
,META_ALBUM_ART
);
648 gmpc_easy_download_struct dld
= {NULL
, 0, -1, NULL
,NULL
};
650 *path
= gmpc_get_metadata_filename(META_ALBUM_ART
, song
, NULL
);
651 if(gmpc_easy_download(value
, &dld
))
653 g_file_set_contents(*path
, dld
.data
, dld
.size
, NULL
);
654 return META_DATA_AVAILABLE
;
656 gmpc_easy_download_clean(&dld
);
662 return META_DATA_UNAVAILABLE
;
664 static void magnatune_redownload_reload_db()
667 GtkTreeModel
*model
= gtk_tree_row_reference_get_model(magnatune_ref
);
668 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
669 if(path
&& gtk_tree_model_get_iter(model
, &iter
, path
))
672 while(gtk_tree_model_iter_children(model
, &citer
,&iter
))
674 gtk_list_store_remove(GTK_LIST_STORE(model
), &citer
);
676 magnatune_download();
677 //magnatune_get_genre_list();
680 gtk_tree_path_free(path
);
683 static void magnatune_cat_menu_add()
686 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(playlist3_get_category_tree_view());
687 GtkTreeModel
*model
= (GtkTreeModel
*)playlist3_get_category_tree_store();
690 if(!gtk_tree_selection_get_selected(sel
,&model
,&citer
))
695 * Get the level we are on.
697 tpath
= gtk_tree_model_get_path(model
, &citer
);
698 depth
= gtk_tree_path_get_depth(tpath
);
699 gtk_tree_path_free(tpath
);
705 gtk_tree_model_get(model
, &citer
, PL3_CAT_INT_ID
,&genre
, -1);
708 list
= magnatune_db_get_url_list(genre
, NULL
,NULL
);
709 for(node
= list
; node
; node
= node
->next
)
711 mpd_playlist_queue_add(connection
, node
->data
);
713 mpd_playlist_queue_commit(connection
);
714 g_list_foreach(list
, (GFunc
)g_free
, NULL
);
725 if(gtk_tree_model_iter_parent(model
, &iter
, &citer
))
728 gtk_tree_model_get(model
, &iter
, PL3_CAT_INT_ID
,&genre
, -1);
729 gtk_tree_model_get(model
, &citer
, PL3_CAT_INT_ID
,&artist
, -1);
730 list
= magnatune_db_get_url_list(genre
, artist
,NULL
);
731 for(node
= list
; node
; node
= node
->next
)
733 mpd_playlist_queue_add(connection
, node
->data
);
735 mpd_playlist_queue_commit(connection
);
736 g_list_foreach(list
, (GFunc
)g_free
, NULL
);
748 static void magnatune_cat_menu_replace()
750 mpd_playlist_clear(connection
);
751 magnatune_cat_menu_add();
752 mpd_player_play(connection
);
756 static int magnatune_cat_menu_popup(GtkWidget
*menu
, int type
, GtkWidget
*tree
, GdkEventButton
*event
)
759 if(type
!= plugin
.id
) return 0;
760 else if (!downloading
)
762 /* add the clear widget */
763 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_REFRESH
,NULL
);
764 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
765 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_redownload_reload_db
), NULL
);
771 static void magnatune_add_selected(GtkWidget
*button
, GtkTreeView
*tree
)
773 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
774 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
775 GList
*list
= gtk_tree_selection_get_selected_rows(sel
,&model
);
779 for(node
= list
; node
; node
= g_list_next(node
))
782 if(gtk_tree_model_get_iter(model
, &iter
, node
->data
))
785 gtk_tree_model_get(model
, &iter
, MPDDATA_MODEL_COL_PATH
, &path
, -1);
786 mpd_playlist_queue_add(connection
, path
);
790 mpd_playlist_queue_commit(connection
);
791 g_list_foreach (list
, (GFunc
)gtk_tree_path_free
, NULL
);
795 static void magnatune_replace_selected(GtkWidget
*button
, GtkTreeView
*tree
)
797 mpd_playlist_clear(connection
);
798 magnatune_add_selected(button
, tree
);
799 mpd_player_play(connection
);
803 static void magnatune_list_edit_columns(GtkMenuItem
*item
, GtkWidget
*widget
)
805 gmpc_mpddata_treeview_edit_columns(GMPC_MPDDATA_TREEVIEW(widget
));
807 static int magnatune_button_handle_release_event_tag_add(GtkWidget
*button
, gpointer userdata
)
811 int position
= GPOINTER_TO_INT(userdata
);
812 gchar
*genre
=NULL
, *artist
=NULL
, *album
=NULL
;
813 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
814 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
816 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
818 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
822 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
823 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
824 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
826 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
831 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]));
832 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]));
833 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
835 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&album
,-1);
838 list
= magnatune_db_get_url_list(genre
, artist
, album
);
839 for(;list
; list
= list
->next
)
841 mpd_playlist_queue_add(connection
, list
->data
);
843 mpd_playlist_queue_commit(connection
);
846 g_list_foreach(list
, g_free
, NULL
);
858 static int magnatune_button_handle_release_event_tag_replace(GtkWidget
*button
, gpointer userdata
)
860 mpd_playlist_clear(connection
);
861 magnatune_button_handle_release_event_tag_add(button
,userdata
);
862 mpd_player_play(connection
);
866 static int magnatune_button_handle_release_event_tag(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
)
869 int position
= GPOINTER_TO_INT(data
);
870 if(event
->button
!= 3) return FALSE
;
873 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
874 if(gtk_tree_selection_count_selected_rows(sel
)> 0)
876 GtkWidget
*menu
= gtk_menu_new();
880 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD
,NULL
);
881 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
), item
);
882 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_add
), data
);
884 item
= gtk_image_menu_item_new_with_label("Replace");
885 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
886 gtk_image_new_from_stock(GTK_STOCK_REDO
, GTK_ICON_SIZE_MENU
));
887 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
888 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_replace
), data
);
889 gtk_widget_show_all(menu
);
890 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
,NULL
, NULL
, event
->button
, event
->time
);
896 static int magnatune_button_release_event(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
)
898 if(event
->button
!= 3) return FALSE
;
901 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
903 if(gtk_tree_selection_count_selected_rows(sel
)> 0)
905 GtkWidget
*menu
= gtk_menu_new();
906 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
908 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD
,NULL
);
909 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
), item
);
910 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_add_selected
), tree
);
912 item
= gtk_image_menu_item_new_with_label("Replace");
913 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
914 gtk_image_new_from_stock(GTK_STOCK_REDO
, GTK_ICON_SIZE_MENU
));
915 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
917 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_replace_selected
), tree
);
920 item
= gtk_separator_menu_item_new();
921 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
923 item
= gtk_image_menu_item_new_with_label(("Edit Columns"));
924 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
925 gtk_image_new_from_stock(GTK_STOCK_EDIT
, GTK_ICON_SIZE_MENU
));
926 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
927 g_signal_connect(G_OBJECT(item
), "activate",
928 G_CALLBACK(magnatune_list_edit_columns
), tree
);
930 gtk_widget_show_all(menu
);
932 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
,NULL
, NULL
, event
->button
, event
->time
);
938 static void magnatune_cat_key_press(GtkWidget
*tree
, GdkEventKey
*event
, int selected_type
)
940 if(selected_type
!= plugin
.id
) return;
941 if(event
->state
&GDK_CONTROL_MASK
&& event
->keyval
== GDK_Insert
)
943 magnatune_cat_menu_replace();
945 else if(event
->keyval
== GDK_Insert
)
947 magnatune_cat_menu_add();
952 static int magnatune_key_press(GtkWidget
*tree
, GdkEventKey
*event
)
954 if(event
->state
&GDK_CONTROL_MASK
&& event
->keyval
== GDK_Insert
)
956 magnatune_replace_selected(NULL
, GTK_TREE_VIEW(tree
));
958 else if(event
->keyval
== GDK_Insert
)
960 magnatune_add_selected(NULL
, GTK_TREE_VIEW(tree
));
962 else if (event
->keyval
== GDK_f
&& event
->state
&GDK_CONTROL_MASK
)
964 treesearch_start(mt_tree_search
);
967 else if((event
->state
&(GDK_CONTROL_MASK
|GDK_MOD1_MASK
)) == 0 &&
968 ((event
->keyval
>= GDK_space
&& event
->keyval
<= GDK_z
)))
971 data
[0] = (char)gdk_keyval_to_unicode(event
->keyval
);
973 treesearch_start(TREESEARCH(mt_tree_search
));
974 gtk_entry_set_text(GTK_ENTRY(TREESEARCH(mt_tree_search
)->entry
),data
);
975 gtk_editable_set_position(GTK_EDITABLE(TREESEARCH(mt_tree_search
)->entry
),1);
980 static void magnatune_save_myself(void)
984 int position
= gtk_paned_get_position(GTK_PANED(magnatune_vbox
));
985 cfg_set_single_value_as_int(config
, "magnatune", "pane-pos", position
);
989 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
992 gint
*indices
= gtk_tree_path_get_indices(path
);
993 debug_printf(DEBUG_INFO
,"Saving myself to position: %i\n", indices
[0]);
994 cfg_set_single_value_as_int(config
, "magnatune","position",indices
[0]);
995 gtk_tree_path_free(path
);
1000 static void magnatune_destroy(void)
1002 magnatune_db_destroy();
1004 gtk_widget_destroy(magnatune_vbox
);
1007 gmpcMetaDataPlugin magnatune_cover
= {
1008 .get_priority
= magnatune_fetch_cover_priority
,
1009 .set_priority
= magnatune_fetch_cover_priority_set
,
1010 .get_image
= magnatune_fetch_get_image
1014 /* Needed plugin_wp stuff */
1015 gmpcPlBrowserPlugin magnatune_gbp
= {
1016 .add
= magnatune_add
,
1017 .selected
= magnatune_selected
,
1018 .unselected
= magnatune_unselected
,
1019 .cat_right_mouse_menu
= magnatune_cat_menu_popup
,
1020 .cat_key_press
= magnatune_cat_key_press
1023 int plugin_api_version
= PLUGIN_API_VERSION
;
1025 gmpcPlugin plugin
= {
1026 .name
= "Magnatune Stream Browser",
1027 .version
= {PLUGIN_MAJOR_VERSION
,PLUGIN_MINOR_VERSION
,PLUGIN_MICRO_VERSION
},
1028 .plugin_type
= GMPC_PLUGIN_PL_BROWSER
|GMPC_PLUGIN_META_DATA
,
1029 /* Creation and destruction */
1030 .init
= magnatune_logo_init
,
1031 .destroy
= magnatune_destroy
,
1032 .save_yourself
= magnatune_save_myself
,
1033 .mpd_status_changed
= magnatune_mpd_status_changed
,
1035 /* Browser extention */
1036 .browser
= &magnatune_gbp
,
1037 .metadata
= &magnatune_cover
,
1039 /* get/set enabled */
1040 .get_enabled
= magnatune_get_enabled
,
1041 .set_enabled
= magnatune_set_enabled