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()
132 gchar
*path
= gmpc_plugin_get_data_path(&plugin
);
133 gchar
*url
= g_build_path(G_DIR_SEPARATOR_S
,path
, "magnatune", NULL
);
134 debug_printf(DEBUG_WARNING
,"Found url: %s\n", url
);
135 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default (),url
);
139 gtk_init_add((GtkFunction
)magnatune_logo_add
, NULL
);
141 * init the magnatune stuff
151 static void magnatune_mpd_status_changed(MpdObj
*mi
, ChangedStatusType what
, void *data
)
155 if(what
&(MPD_CST_SONGID
|MPD_CST_STATE
))
157 mpd_Song
*song
= mpd_playlist_get_current_song(mi
);
159 if(strstr(song
->file
,"magnatune.com"))
161 gtk_widget_show_all(magnatune_logo
);
165 gtk_widget_hide(magnatune_logo
);
169 void magnatune_get_genre_list()
171 MpdData
*data
= NULL
;
172 data
= magnatune_db_get_genre_list();
173 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]))),data
);
176 static void magnatune_show_album_list(GtkTreeSelection
*selection
, gpointer user_data
)
178 MpdData
*data
= NULL
;
180 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
181 if(gtk_tree_selection_get_selected(selection
, &model
, &piter
))
184 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
185 data
= magnatune_db_get_artist_list(genre
);
189 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]))),data
);
192 static void magnatune_show_song_list(GtkTreeSelection
*selection
, gpointer user_data
)
194 MpdData
*data
= NULL
;
196 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
197 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
198 gchar
*genre
= NULL
, *artist
= NULL
, *album
= NULL
;
199 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
202 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
203 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
205 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
206 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
208 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
209 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]));
210 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]));
211 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
213 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&album
,-1);
217 data
= magnatune_db_get_song_list(genre
, artist
, album
);
218 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(mt_store
), data
);
221 static void magnatune_show_artist_list(GtkTreeSelection
*selection
, gpointer user_data
)
224 MpdData
*data
= NULL
;
225 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
226 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
228 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
230 GList
*iter
,*list
= NULL
;
233 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
234 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
236 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
237 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
239 GList
*iter
,*list
= NULL
;
242 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
243 data
= magnatune_db_get_album_list(genre
,artist
);
244 gmpc_mpddata_model_set_request_artist(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]))),artist
);
249 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]))),data
);
252 static void magnatune_add_album_row_activated(GtkTreeView
*tree
, GtkTreePath
*path
, GtkTreeViewColumn
*col
, gpointer data
)
254 GtkTreeModel
*model
= gtk_tree_view_get_model(tree
);
257 if(gtk_tree_model_get_iter(model
, &iter_r
, path
))
260 gtk_tree_model_get(model
, &iter_r
, MPDDATA_MODEL_COL_PATH
, &path
, -1);
266 static gboolean
magnatune_search_equal_func(GtkTreeModel
*model
, int column
, const gchar
*key
, GtkTreeIter
*iter
, gpointer data
)
268 gchar
*compare
= NULL
;
269 gtk_tree_model_get(model
,iter
, column
, &compare
, -1);
271 gchar
*a
= g_utf8_casefold(key
, -1);
272 gchar
*b
= g_utf8_casefold(compare
, -1);
285 static void magnatune_search_activate(TreeSearch
*ts
)
287 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
288 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(ts
->treeview
));
289 if (gtk_tree_selection_count_selected_rows (selection
) == 1)
291 GList
*list
= gtk_tree_selection_get_selected_rows (selection
, &model
);
292 magnatune_add_album_row_activated(GTK_TREE_VIEW(ts
->treeview
),(GtkTreePath
*)list
->data
, NULL
,NULL
);
294 g_list_foreach (list
, (GFunc
) gtk_tree_path_free
, NULL
);
299 static void magnatune_init()
302 GtkWidget
*tree
= NULL
;
303 GtkWidget
*sw
= NULL
;
304 GtkCellRenderer
*renderer
= NULL
;
305 GtkWidget
*paned
= NULL
;
306 GtkWidget
*hbox
= NULL
;
307 GtkWidget
*vbox
= NULL
;
308 GtkTreeModel
*model
= NULL
;
309 GtkTreeViewColumn
*column
= NULL
;
310 int position
= cfg_get_single_value_as_int_with_default(config
, "magnatune", "pane-pos", 150);
311 magnatune_vbox
= gtk_vpaned_new();
312 gtk_paned_set_position(GTK_PANED(magnatune_vbox
), position
);
315 vbox
= gtk_vbox_new(FALSE
,6);
321 mt_store
= (GtkTreeModel
*)gmpc_mpddata_model_new();
324 paned
= gtk_hbox_new(TRUE
,6);
325 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
327 sw
= gtk_scrolled_window_new(NULL
, NULL
);
328 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
329 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
330 treeviews
[0] = gtk_tree_view_new_with_model(model
);
331 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[0]), MPDDATA_MODEL_COL_SONG_TITLE
);
332 g_signal_connect(G_OBJECT(treeviews
[0]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(0));
334 column
= gtk_tree_view_column_new();
335 gtk_tree_view_column_set_title(column
, "Genre");
338 renderer
= gtk_cell_renderer_pixbuf_new();
339 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
340 gtk_tree_view_column_add_attribute(column
, renderer
, "icon-name", MPDDATA_MODEL_COL_ICON_ID
);
341 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
342 renderer
= gtk_cell_renderer_text_new();
343 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
344 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
345 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[0]),column
, -1);
347 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[0]);
348 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
350 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]))), "changed", G_CALLBACK(magnatune_show_album_list
), NULL
);
353 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
354 sw
= gtk_scrolled_window_new(NULL
, NULL
);
355 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
356 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
357 treeviews
[1] = gtk_tree_view_new_with_model(model
);
359 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[1]), MPDDATA_MODEL_COL_SONG_TITLE
);
360 g_signal_connect(G_OBJECT(treeviews
[1]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(1));
362 column
= gtk_tree_view_column_new();
363 gtk_tree_view_column_set_title(column
, "Artist");
364 size
= cfg_get_single_value_as_int_with_default(config
, "gmpc-mpddata-model", "icon-size", 64);
365 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
366 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews
[1]), TRUE
);
369 renderer
= gtk_cell_renderer_pixbuf_new();
370 gtk_cell_renderer_set_fixed_size(renderer
, size
,size
);
372 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
373 gtk_tree_view_column_add_attribute(column
, renderer
, "pixbuf", MPDDATA_MODEL_META_DATA
);
374 renderer
= gtk_cell_renderer_text_new();
375 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
376 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
377 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[1]),column
, -1);
379 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[1]);
380 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
382 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]))), "changed", G_CALLBACK(magnatune_show_artist_list
), NULL
);
385 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
386 sw
= gtk_scrolled_window_new(NULL
, NULL
);
387 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
388 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
389 treeviews
[2] = gtk_tree_view_new_with_model(model
);
390 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[2]), MPDDATA_MODEL_COL_SONG_TITLE
);
392 g_signal_connect(G_OBJECT(treeviews
[2]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(2));
394 column
= gtk_tree_view_column_new();
395 gtk_tree_view_column_set_title(column
, "Album");
396 size
= cfg_get_single_value_as_int_with_default(config
, "gmpc-mpddata-model", "icon-size", 64);
397 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
398 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews
[2]), TRUE
);
401 renderer
= gtk_cell_renderer_pixbuf_new();
402 gtk_cell_renderer_set_fixed_size(renderer
, size
,size
);
404 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
405 gtk_tree_view_column_add_attribute(column
, renderer
, "pixbuf", MPDDATA_MODEL_META_DATA
);
406 renderer
= gtk_cell_renderer_text_new();
407 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
408 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
409 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[2]),column
, -1);
411 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[2]);
412 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
415 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
416 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
417 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
419 gtk_paned_add1(GTK_PANED(magnatune_vbox
), paned
);
420 gtk_widget_show_all(paned
);
424 sw
= gtk_scrolled_window_new(NULL
, NULL
);
425 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
426 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
429 tree
= (GtkWidget
*)gmpc_mpddata_treeview_new("magnatune",TRUE
,GTK_TREE_MODEL(mt_store
));
430 g_signal_connect(G_OBJECT(tree
), "row-activated", G_CALLBACK(magnatune_add_album_row_activated
), NULL
);
432 g_signal_connect(G_OBJECT(tree
), "button-press-event", G_CALLBACK(magnatune_button_release_event
), tree
);
433 g_signal_connect(G_OBJECT(tree
), "key-press-event", G_CALLBACK(magnatune_key_press
), NULL
);
435 gtk_container_add(GTK_CONTAINER(sw
), tree
);
436 gtk_box_pack_start(GTK_BOX(vbox
),sw
, TRUE
, TRUE
,0);
438 mt_tree_search
= (TreeSearch
*)treesearch_new(GTK_TREE_VIEW(tree
), MPDDATA_MODEL_COL_SONG_TITLE
);
439 gtk_box_pack_end(GTK_BOX(vbox
), GTK_WIDGET(mt_tree_search
), FALSE
, TRUE
, 0);
440 g_signal_connect(G_OBJECT(mt_tree_search
), "result-activate", G_CALLBACK(magnatune_search_activate
),NULL
);
443 gtk_widget_show_all(sw
);
444 gtk_widget_show(vbox
);
446 * Progress Bar for the bottom
448 magnatune_pb
= gtk_progress_bar_new();
449 gtk_box_pack_end(GTK_BOX(vbox
), magnatune_pb
, FALSE
, TRUE
, 0);
450 gtk_paned_add2(GTK_PANED(magnatune_vbox
), vbox
);
453 g_object_ref(magnatune_vbox
);
457 static void magnatune_selected(GtkWidget
*container
)
459 if(magnatune_vbox
== NULL
)
462 gtk_container_add(GTK_CONTAINER(container
), magnatune_vbox
);
463 gtk_widget_show(magnatune_vbox
);
464 if(!magnatune_db_has_data())
466 magnatune_download();
469 magnatune_get_genre_list();
471 gtk_container_add(GTK_CONTAINER(container
), magnatune_vbox
);
472 gtk_widget_show(magnatune_vbox
);
475 static void magnatune_unselected(GtkWidget
*container
)
477 gtk_container_remove(GTK_CONTAINER(container
), magnatune_vbox
);
480 int magnatune_end_download()
484 magnatune_get_genre_list();
485 gtk_widget_hide(magnatune_pb
);
486 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml
, "pl3_win"), TRUE
);
490 typedef struct _Pass
{
496 static int magnatune_download_xml_callback_real(Pass
*p
);
497 /* Move it to main thread, by pushing in idle */
498 static void magnatune_download_xml_callback(int download
, int total
,gpointer data
)
500 Pass
*p
= g_malloc0(sizeof(*p
));
502 p
->download
= download
;
504 g_idle_add(magnatune_download_xml_callback_real
, p
);
507 static int magnatune_download_xml_callback_real(Pass
*p
)
509 GtkWidget
*pb
= p
->pb
;
510 int download
= p
->download
;
511 int total
= p
->total
;
514 // gdk_threads_enter();
516 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb
), download
/(float)total
);
518 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pb
));
520 size
= g_format_size_for_display((goffset
)download
);
521 label
= g_strdup_printf("Downloading music catalog (%s done)",size
);
523 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pb
), label
);
525 // while(gtk_events_pending())
526 // gtk_main_iteration();
527 // gdk_threads_leave();
532 static void magnatune_download()
535 // gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), FALSE);
536 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]))),NULL
);
537 gtk_widget_show(magnatune_pb
);
538 magnatune_db_download_xml(magnatune_download_xml_callback
, magnatune_pb
);
539 // gtk_widget_hide(magnatune_pb);
540 // gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), TRUE);
543 static void magnatune_add(GtkWidget
*cat_tree
)
545 GtkTreePath
*path
= NULL
;
546 GtkTreeIter iter
,child
;
547 GtkTreeStore
*pl3_tree
= (GtkTreeStore
*)gtk_tree_view_get_model(GTK_TREE_VIEW(cat_tree
));
548 gint pos
= cfg_get_single_value_as_int_with_default(config
, "magnatune","position",20);
550 if(!cfg_get_single_value_as_int_with_default(config
, "magnatune", "enable", TRUE
)) return;
552 debug_printf(DEBUG_INFO
,"Adding at position: %i", pos
);
553 playlist3_insert_browser(&iter
, pos
);
554 gtk_list_store_set(pl3_tree
, &iter
,
555 PL3_CAT_TYPE
, plugin
.id
,
556 PL3_CAT_TITLE
, "Magnatune Browser",
558 PL3_CAT_ICON_ID
, "magnatune",
560 PL3_CAT_ICON_SIZE
,GTK_ICON_SIZE_DND
,-1);
562 * Clean up old row reference if it exists
566 gtk_tree_row_reference_free(magnatune_ref
);
567 magnatune_ref
= NULL
;
570 * create row reference
572 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter
);
575 magnatune_ref
= gtk_tree_row_reference_new(GTK_TREE_MODEL(playlist3_get_category_tree_store()), path
);
576 gtk_tree_path_free(path
);
580 static char * __magnatune_process_string(char *name
)
587 /* only gonna be smaller */
588 char *result
= g_malloc0((strlen(name
)+1+spaces
*2)*sizeof(char));
589 for(i
=0; i
< strlen(name
);i
++)
591 if(name
[i
] == '(' || name
[i
] == '[') depth
++;
592 else if (name
[i
] == ')' || name
[i
] == ']') depth
--;
599 for(i
=j
-1;i
>0 && result
[i
] == ' ';i
--)
607 static int magnatune_fetch_cover_priority(void){
608 return cfg_get_single_value_as_int_with_default(config
, "magnatune", "priority", 80);
610 static void magnatune_fetch_cover_priority_set(int priority
){
611 cfg_set_single_value_as_int(config
, "magnatune", "priority", priority
);
613 static int magnatune_fetch_get_image(mpd_Song
*song
,MetaDataType type
, char **path
)
616 if(magnatune_db_has_data() == FALSE
)
617 return META_DATA_UNAVAILABLE
;
618 if(type
== META_ARTIST_ART
&& song
->artist
)
620 char *artist
= __magnatune_process_string(song
->artist
);
621 char *value
= magnatune_db_get_value(artist
,NULL
,META_ARTIST_ART
);
624 gmpc_easy_download_struct dld
= {NULL
, 0, -1, NULL
,NULL
};
625 *path
= gmpc_get_metadata_filename(META_ARTIST_ART
, song
, NULL
);
626 if(gmpc_easy_download(value
, &dld
))
628 g_file_set_contents(*path
, dld
.data
, dld
.size
, NULL
);
629 return META_DATA_AVAILABLE
;
631 gmpc_easy_download_clean(&dld
);
637 else if(type
== META_ALBUM_ART
&& song
->artist
&& song
->album
)
639 char *artist
= __magnatune_process_string(song
->artist
);
640 char *album
= __magnatune_process_string(song
->album
);
641 char *value
= magnatune_db_get_value(artist
,album
,META_ALBUM_ART
);
644 gmpc_easy_download_struct dld
= {NULL
, 0, -1, NULL
,NULL
};
646 *path
= gmpc_get_metadata_filename(META_ALBUM_ART
, song
, NULL
);
647 if(gmpc_easy_download(value
, &dld
))
649 g_file_set_contents(*path
, dld
.data
, dld
.size
, NULL
);
650 return META_DATA_AVAILABLE
;
652 gmpc_easy_download_clean(&dld
);
658 return META_DATA_UNAVAILABLE
;
660 static void magnatune_redownload_reload_db()
663 GtkTreeModel
*model
= gtk_tree_row_reference_get_model(magnatune_ref
);
664 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
665 if(path
&& gtk_tree_model_get_iter(model
, &iter
, path
))
668 while(gtk_tree_model_iter_children(model
, &citer
,&iter
))
670 gtk_list_store_remove(GTK_LIST_STORE(model
), &citer
);
672 magnatune_download();
673 //magnatune_get_genre_list();
676 gtk_tree_path_free(path
);
679 static void magnatune_cat_menu_add()
682 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(playlist3_get_category_tree_view());
683 GtkTreeModel
*model
= (GtkTreeModel
*)playlist3_get_category_tree_store();
686 if(!gtk_tree_selection_get_selected(sel
,&model
,&citer
))
691 * Get the level we are on.
693 tpath
= gtk_tree_model_get_path(model
, &citer
);
694 depth
= gtk_tree_path_get_depth(tpath
);
695 gtk_tree_path_free(tpath
);
701 gtk_tree_model_get(model
, &citer
, PL3_CAT_INT_ID
,&genre
, -1);
704 list
= magnatune_db_get_url_list(genre
, NULL
,NULL
);
705 for(node
= list
; node
; node
= node
->next
)
707 mpd_playlist_queue_add(connection
, node
->data
);
709 mpd_playlist_queue_commit(connection
);
710 g_list_foreach(list
, (GFunc
)g_free
, NULL
);
721 if(gtk_tree_model_iter_parent(model
, &iter
, &citer
))
724 gtk_tree_model_get(model
, &iter
, PL3_CAT_INT_ID
,&genre
, -1);
725 gtk_tree_model_get(model
, &citer
, PL3_CAT_INT_ID
,&artist
, -1);
726 list
= magnatune_db_get_url_list(genre
, artist
,NULL
);
727 for(node
= list
; node
; node
= node
->next
)
729 mpd_playlist_queue_add(connection
, node
->data
);
731 mpd_playlist_queue_commit(connection
);
732 g_list_foreach(list
, (GFunc
)g_free
, NULL
);
744 static void magnatune_cat_menu_replace()
746 mpd_playlist_clear(connection
);
747 magnatune_cat_menu_add();
748 mpd_player_play(connection
);
752 static int magnatune_cat_menu_popup(GtkWidget
*menu
, int type
, GtkWidget
*tree
, GdkEventButton
*event
)
755 if(type
!= plugin
.id
) return 0;
756 else if (!downloading
)
758 /* add the clear widget */
759 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_REFRESH
,NULL
);
760 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
761 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_redownload_reload_db
), NULL
);
767 static void magnatune_add_selected(GtkWidget
*button
, GtkTreeView
*tree
)
769 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
770 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
771 GList
*list
= gtk_tree_selection_get_selected_rows(sel
,&model
);
775 for(node
= list
; node
; node
= g_list_next(node
))
778 if(gtk_tree_model_get_iter(model
, &iter
, node
->data
))
781 gtk_tree_model_get(model
, &iter
, MPDDATA_MODEL_COL_PATH
, &path
, -1);
782 mpd_playlist_queue_add(connection
, path
);
786 mpd_playlist_queue_commit(connection
);
787 g_list_foreach (list
, (GFunc
)gtk_tree_path_free
, NULL
);
791 static void magnatune_replace_selected(GtkWidget
*button
, GtkTreeView
*tree
)
793 mpd_playlist_clear(connection
);
794 magnatune_add_selected(button
, tree
);
795 mpd_player_play(connection
);
799 static void magnatune_list_edit_columns(GtkMenuItem
*item
, GtkWidget
*widget
)
801 gmpc_mpddata_treeview_edit_columns(GMPC_MPDDATA_TREEVIEW(widget
));
803 static int magnatune_button_handle_release_event_tag_add(GtkWidget
*button
, gpointer userdata
)
807 int position
= GPOINTER_TO_INT(userdata
);
808 gchar
*genre
=NULL
, *artist
=NULL
, *album
=NULL
;
809 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
810 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
812 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
814 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
818 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
819 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
820 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
822 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
827 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]));
828 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]));
829 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
831 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&album
,-1);
834 list
= magnatune_db_get_url_list(genre
, artist
, album
);
835 for(;list
; list
= list
->next
)
837 mpd_playlist_queue_add(connection
, list
->data
);
839 mpd_playlist_queue_commit(connection
);
842 g_list_foreach(list
, g_free
, NULL
);
854 static int magnatune_button_handle_release_event_tag_replace(GtkWidget
*button
, gpointer userdata
)
856 mpd_playlist_clear(connection
);
857 magnatune_button_handle_release_event_tag_add(button
,userdata
);
858 mpd_player_play(connection
);
862 static int magnatune_button_handle_release_event_tag(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
)
865 int position
= GPOINTER_TO_INT(data
);
866 if(event
->button
!= 3) return FALSE
;
869 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
870 if(gtk_tree_selection_count_selected_rows(sel
)> 0)
872 GtkWidget
*menu
= gtk_menu_new();
876 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD
,NULL
);
877 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
), item
);
878 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_add
), data
);
880 item
= gtk_image_menu_item_new_with_label("Replace");
881 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
882 gtk_image_new_from_stock(GTK_STOCK_REDO
, GTK_ICON_SIZE_MENU
));
883 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
884 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_replace
), data
);
885 gtk_widget_show_all(menu
);
886 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
,NULL
, NULL
, event
->button
, event
->time
);
892 static int magnatune_button_release_event(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
)
894 if(event
->button
!= 3) return FALSE
;
897 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
899 if(gtk_tree_selection_count_selected_rows(sel
)> 0)
901 GtkWidget
*menu
= gtk_menu_new();
902 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
904 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD
,NULL
);
905 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
), item
);
906 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_add_selected
), tree
);
908 item
= gtk_image_menu_item_new_with_label("Replace");
909 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
910 gtk_image_new_from_stock(GTK_STOCK_REDO
, GTK_ICON_SIZE_MENU
));
911 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
913 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_replace_selected
), tree
);
916 item
= gtk_separator_menu_item_new();
917 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
919 item
= gtk_image_menu_item_new_with_label(("Edit Columns"));
920 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
921 gtk_image_new_from_stock(GTK_STOCK_EDIT
, GTK_ICON_SIZE_MENU
));
922 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
923 g_signal_connect(G_OBJECT(item
), "activate",
924 G_CALLBACK(magnatune_list_edit_columns
), tree
);
926 gtk_widget_show_all(menu
);
928 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
,NULL
, NULL
, event
->button
, event
->time
);
934 static void magnatune_cat_key_press(GtkWidget
*tree
, GdkEventKey
*event
, int selected_type
)
936 if(selected_type
!= plugin
.id
) return;
937 if(event
->state
&GDK_CONTROL_MASK
&& event
->keyval
== GDK_Insert
)
939 magnatune_cat_menu_replace();
941 else if(event
->keyval
== GDK_Insert
)
943 magnatune_cat_menu_add();
948 static int magnatune_key_press(GtkWidget
*tree
, GdkEventKey
*event
)
950 if(event
->state
&GDK_CONTROL_MASK
&& event
->keyval
== GDK_Insert
)
952 magnatune_replace_selected(NULL
, GTK_TREE_VIEW(tree
));
954 else if(event
->keyval
== GDK_Insert
)
956 magnatune_add_selected(NULL
, GTK_TREE_VIEW(tree
));
958 else if (event
->keyval
== GDK_f
&& event
->state
&GDK_CONTROL_MASK
)
960 treesearch_start(mt_tree_search
);
963 else if((event
->state
&(GDK_CONTROL_MASK
|GDK_MOD1_MASK
)) == 0 &&
964 ((event
->keyval
>= GDK_space
&& event
->keyval
<= GDK_z
)))
967 data
[0] = (char)gdk_keyval_to_unicode(event
->keyval
);
969 treesearch_start(TREESEARCH(mt_tree_search
));
970 gtk_entry_set_text(GTK_ENTRY(TREESEARCH(mt_tree_search
)->entry
),data
);
971 gtk_editable_set_position(GTK_EDITABLE(TREESEARCH(mt_tree_search
)->entry
),1);
976 static void magnatune_save_myself(void)
980 int position
= gtk_paned_get_position(GTK_PANED(magnatune_vbox
));
981 cfg_set_single_value_as_int(config
, "magnatune", "pane-pos", position
);
985 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
988 gint
*indices
= gtk_tree_path_get_indices(path
);
989 debug_printf(DEBUG_INFO
,"Saving myself to position: %i\n", indices
[0]);
990 cfg_set_single_value_as_int(config
, "magnatune","position",indices
[0]);
991 gtk_tree_path_free(path
);
996 static void magnatune_destroy(void)
998 magnatune_db_destroy();
1000 gtk_widget_destroy(magnatune_vbox
);
1003 gmpcMetaDataPlugin magnatune_cover
= {
1004 .get_priority
= magnatune_fetch_cover_priority
,
1005 .set_priority
= magnatune_fetch_cover_priority_set
,
1006 .get_image
= magnatune_fetch_get_image
1010 /* Needed plugin_wp stuff */
1011 gmpcPlBrowserPlugin magnatune_gbp
= {
1012 .add
= magnatune_add
,
1013 .selected
= magnatune_selected
,
1014 .unselected
= magnatune_unselected
,
1015 .cat_right_mouse_menu
= magnatune_cat_menu_popup
,
1016 .cat_key_press
= magnatune_cat_key_press
1019 int plugin_api_version
= PLUGIN_API_VERSION
;
1021 gmpcPlugin plugin
= {
1022 .name
= "Magnatune Stream Browser",
1023 .version
= {PLUGIN_MAJOR_VERSION
,PLUGIN_MINOR_VERSION
,PLUGIN_MICRO_VERSION
},
1024 .plugin_type
= GMPC_PLUGIN_PL_BROWSER
|GMPC_PLUGIN_META_DATA
,
1025 /* Creation and destruction */
1026 .init
= magnatune_logo_init
,
1027 .destroy
= magnatune_destroy
,
1028 .save_yourself
= magnatune_save_myself
,
1029 .mpd_status_changed
= magnatune_mpd_status_changed
,
1031 /* Browser extention */
1032 .browser
= &magnatune_gbp
,
1033 .metadata
= &magnatune_cover
,
1035 /* get/set enabled */
1036 .get_enabled
= magnatune_get_enabled
,
1037 .set_enabled
= magnatune_set_enabled