1 /* gmpc-magnatune (GMPC plugin)
2 * Copyright (C) 2006-2009 Qball Cow <qball@sarine.nl>
3 * Project homepage: http://gmpcwiki.sarine.nl/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <gdk/gdkkeysyms.h>
23 #include <glade/glade.h>
24 #include <gmpc/plugin.h>
25 #include <gmpc/gmpc_easy_download.h>
26 #include <gmpc/metadata.h>
27 #include <gmpc/gmpc-mpddata-model.h>
28 #include <gmpc/gmpc-mpddata-treeview.h>
29 #include <gmpc/TreeSearchWidget.h>
31 #include "magnatune.h"
33 extern GladeXML
*pl3_xml
;
37 * Function decleration
39 static void magnatune_selected(GtkWidget
*container
);
40 static void magnatune_unselected(GtkWidget
*container
);
41 static void magnatune_add(GtkWidget
*cat_tree
);
42 static void magnatune_download_xml_callback(int download
, int total
,gpointer data
);
43 static void magnatune_download();
44 static void magnatune_mpd_status_changed(MpdObj
*mi
, ChangedStatusType what
, void *data
);
45 static int magnatune_fetch_cover_priority(void);
46 static int magnatune_fetch_get_image(mpd_Song
*song
,MetaDataType type
, char **path
);
47 static int magnatune_cat_menu_popup(GtkWidget
*menu
, int type
, GtkWidget
*tree
, GdkEventButton
*event
);
49 static int magnatune_button_release_event(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
);
50 static int magnatune_button_handle_release_event_tag(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
);
52 static int magnatune_key_press(GtkWidget
*tree
, GdkEventKey
*event
);
53 static void magnatune_show_album_list(GtkTreeSelection
*selection
, gpointer user_data
);
54 static void magnatune_show_song_list(GtkTreeSelection
*selection
, gpointer user_data
);
55 static int magnatune_button_handle_release_event_tag_add(GtkWidget
*button
, gpointer user_data
);
56 static void magnatune_save_myself(void);
57 static GtkTreeRowReference
*magnatune_ref
= NULL
;
58 static void magnatune_download_cancel(GtkWidget
*button
);
60 static int downloading
= FALSE
;
64 static int magnatune_get_enabled()
66 return cfg_get_single_value_as_int_with_default(config
, "magnatune", "enable", TRUE
);
68 static void magnatune_set_enabled(int enabled
)
70 cfg_set_single_value_as_int(config
, "magnatune", "enable", enabled
);
73 if(magnatune_ref
== NULL
)
75 magnatune_add(GTK_WIDGET(playlist3_get_category_tree_view()));
78 else if (magnatune_ref
)
80 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
83 magnatune_save_myself();
84 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter
, path
)){
85 gtk_list_store_remove(playlist3_get_category_tree_store(), &iter
);
87 gtk_tree_path_free(path
);
88 gtk_tree_row_reference_free(magnatune_ref
);
99 /* Playlist window row reference */
101 GtkWidget
*magnatune_pb
= NULL
, *magnatune_cancel
= NULL
;
102 GtkWidget
*magnatune_vbox
= NULL
;
103 GtkTreeModel
*mt_store
= NULL
;
104 TreeSearch
*mt_tree_search
= NULL
;
106 GtkWidget
*treeviews
[3] = {NULL
, NULL
,NULL
};
108 static GtkWidget
*magnatune_logo
=NULL
;
109 extern GladeXML
*pl3_xml
;
111 static void magnatune_buy_album()
114 mpd_Song
*song
= NULL
;
118 if(mpd_check_connected(connection
))
120 song
= mpd_playlist_get_current_song(connection
);
121 artist
= __magnatune_process_string(song
->artist
);
122 album
= __magnatune_process_string(song
->album
);
123 uri
= g_strconcat("http://www.magnatune.com/buy/choose?artist=",artist
,"&album=",album
,NULL
);
131 static void magnatune_logo_add()
133 mpd_Song
*song
= NULL
;
134 GtkWidget
*logo
, *button
;
136 if(mpd_check_connected(connection
))
137 song
= mpd_playlist_get_current_song(connection
);
139 magnatune_logo
= gtk_hbox_new(FALSE
,6);
141 button
= gtk_button_new_with_label("Buy this album\nfrom magnatune");
142 gtk_button_set_relief(GTK_BUTTON(button
), GTK_RELIEF_NONE
);
144 ali
= gtk_alignment_new(0,0.5,0,1);
145 gtk_container_add(GTK_CONTAINER(ali
), button
);
146 logo
= gtk_image_new_from_icon_name("magnatune", GTK_ICON_SIZE_DND
);
147 gtk_button_set_image(GTK_BUTTON(button
), logo
);
148 gtk_box_pack_start(GTK_BOX(magnatune_logo
), ali
, TRUE
, TRUE
,0);
149 gtk_box_pack_end(GTK_BOX(glade_xml_get_widget(pl3_xml
, "vbox5")), magnatune_logo
, FALSE
,FALSE
,0);
150 g_signal_connect(G_OBJECT(button
), "clicked", G_CALLBACK(magnatune_buy_album
), NULL
);
152 if(strstr(song
->file
,"magnatune.com"))
154 gtk_widget_show_all(magnatune_logo
);
162 static void magnatune_logo_init()
164 gchar
*path
= gmpc_plugin_get_data_path(&plugin
);
165 gchar
*url
= g_build_path(G_DIR_SEPARATOR_S
,path
, "magnatune", NULL
);
166 debug_printf(DEBUG_WARNING
,"Found url: %s\n", url
);
167 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default (),url
);
171 gtk_init_add((GtkFunction
)magnatune_logo_add
, NULL
);
173 * init the magnatune stuff
183 static void magnatune_mpd_status_changed(MpdObj
*mi
, ChangedStatusType what
, void *data
)
187 if(what
&(MPD_CST_SONGID
|MPD_CST_STATE
))
189 mpd_Song
*song
= mpd_playlist_get_current_song(mi
);
190 if(song
&& mpd_player_get_state(mi
) == MPD_STATUS_STATE_PLAY
) {
191 if(strstr(song
->file
,"magnatune.com"))
193 gtk_widget_show_all(magnatune_logo
);
197 gtk_widget_hide(magnatune_logo
);
201 void magnatune_get_genre_list()
203 MpdData
*data
= NULL
;
204 data
= magnatune_db_get_genre_list();
205 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]))),data
);
208 static void magnatune_show_album_list(GtkTreeSelection
*selection
, gpointer user_data
)
210 MpdData
*data
= NULL
;
212 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
213 if(gtk_tree_selection_get_selected(selection
, &model
, &piter
))
216 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
217 data
= magnatune_db_get_artist_list(genre
);
221 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]))),data
);
224 static void magnatune_show_song_list(GtkTreeSelection
*selection
, gpointer user_data
)
226 MpdData
*data
= NULL
;
228 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
229 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
230 gchar
*genre
= NULL
, *artist
= NULL
, *album
= NULL
;
231 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
234 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
235 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
237 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
238 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
240 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
241 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]));
242 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]));
243 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
245 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&album
,-1);
249 data
= magnatune_db_get_song_list(genre
, artist
, album
,TRUE
);
250 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(mt_store
), data
);
253 static void magnatune_show_artist_list(GtkTreeSelection
*selection
, gpointer user_data
)
256 MpdData
*data
= NULL
;
257 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
258 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
260 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
262 GList
*iter
,*list
= NULL
;
265 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
266 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
268 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
269 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
271 GList
*iter
,*list
= NULL
;
274 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
275 data
= magnatune_db_get_album_list(genre
,artist
);
276 gmpc_mpddata_model_set_request_artist(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]))),artist
);
281 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]))),data
);
284 static void magnatune_add_album_row_activated(GtkTreeView
*tree
, GtkTreePath
*path
, GtkTreeViewColumn
*col
, gpointer data
)
286 GtkTreeModel
*model
= gtk_tree_view_get_model(tree
);
289 if(gtk_tree_model_get_iter(model
, &iter_r
, path
))
292 gtk_tree_model_get(model
, &iter_r
, MPDDATA_MODEL_COL_PATH
, &path
, -1);
298 static gboolean
magnatune_search_equal_func(GtkTreeModel
*model
, int column
, const gchar
*key
, GtkTreeIter
*iter
, gpointer data
)
300 gchar
*compare
= NULL
;
301 gtk_tree_model_get(model
,iter
, column
, &compare
, -1);
303 gchar
*a
= g_utf8_casefold(key
, -1);
304 gchar
*b
= g_utf8_casefold(compare
, -1);
317 static void magnatune_search_activate(TreeSearch
*ts
)
319 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
320 GtkTreeSelection
*selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(ts
->treeview
));
321 if (gtk_tree_selection_count_selected_rows (selection
) == 1)
323 GList
*list
= gtk_tree_selection_get_selected_rows (selection
, &model
);
324 magnatune_add_album_row_activated(GTK_TREE_VIEW(ts
->treeview
),(GtkTreePath
*)list
->data
, NULL
,NULL
);
326 g_list_foreach (list
, (GFunc
) gtk_tree_path_free
, NULL
);
331 static void magnatune_init()
334 GtkWidget
*tree
= NULL
;
335 GtkWidget
*sw
= NULL
;
336 GtkCellRenderer
*renderer
= NULL
;
337 GtkWidget
*paned
= NULL
;
338 GtkWidget
*hbox
= NULL
;
339 GtkWidget
*vbox
= NULL
;
340 GtkTreeModel
*model
= NULL
;
341 GtkTreeViewColumn
*column
= NULL
;
342 int position
= cfg_get_single_value_as_int_with_default(config
, "magnatune", "pane-pos", 150);
343 magnatune_vbox
= gtk_vpaned_new();
344 gtk_paned_set_position(GTK_PANED(magnatune_vbox
), position
);
347 vbox
= gtk_vbox_new(FALSE
,6);
353 mt_store
= (GtkTreeModel
*)gmpc_mpddata_model_new();
356 paned
= gtk_hbox_new(TRUE
,6);
357 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
359 sw
= gtk_scrolled_window_new(NULL
, NULL
);
360 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
361 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
362 treeviews
[0] = gtk_tree_view_new_with_model(model
);
363 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[0]), MPDDATA_MODEL_COL_SONG_TITLE
);
364 g_signal_connect(G_OBJECT(treeviews
[0]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(0));
366 column
= gtk_tree_view_column_new();
367 gtk_tree_view_column_set_title(column
, "Genre");
370 renderer
= gtk_cell_renderer_pixbuf_new();
371 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
372 gtk_tree_view_column_add_attribute(column
, renderer
, "icon-name", MPDDATA_MODEL_COL_ICON_ID
);
373 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
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
[0]),column
, -1);
379 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[0]);
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
[0]))), "changed", G_CALLBACK(magnatune_show_album_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
[1] = gtk_tree_view_new_with_model(model
);
391 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[1]), MPDDATA_MODEL_COL_SONG_TITLE
);
392 g_signal_connect(G_OBJECT(treeviews
[1]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(1));
394 column
= gtk_tree_view_column_new();
395 gtk_tree_view_column_set_title(column
, "Artist");
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
[1]), 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
[1]),column
, -1);
411 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[1]);
412 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
414 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]))), "changed", G_CALLBACK(magnatune_show_artist_list
), NULL
);
417 model
= (GtkTreeModel
*) gmpc_mpddata_model_new();
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
);
421 treeviews
[2] = gtk_tree_view_new_with_model(model
);
422 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews
[2]), MPDDATA_MODEL_COL_SONG_TITLE
);
424 g_signal_connect(G_OBJECT(treeviews
[2]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag
), GINT_TO_POINTER(2));
426 column
= gtk_tree_view_column_new();
427 gtk_tree_view_column_set_title(column
, "Album");
428 size
= cfg_get_single_value_as_int_with_default(config
, "gmpc-mpddata-model", "icon-size", 64);
429 gtk_tree_view_column_set_sizing(column
, GTK_TREE_VIEW_COLUMN_FIXED
);
430 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews
[2]), TRUE
);
433 renderer
= gtk_cell_renderer_pixbuf_new();
434 gtk_cell_renderer_set_fixed_size(renderer
, size
,size
);
436 gtk_tree_view_column_pack_start(column
, renderer
, FALSE
);
437 gtk_tree_view_column_add_attribute(column
, renderer
, "pixbuf", MPDDATA_MODEL_META_DATA
);
438 renderer
= gtk_cell_renderer_text_new();
439 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
440 gtk_tree_view_column_add_attribute(column
, renderer
, "text", MPDDATA_MODEL_COL_SONG_TITLE
);
441 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews
[2]),column
, -1);
443 gtk_container_add(GTK_CONTAINER(sw
), treeviews
[2]);
444 gtk_box_pack_start(GTK_BOX(paned
), sw
, TRUE
, TRUE
, 0);
447 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
448 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
449 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]))), "changed", G_CALLBACK(magnatune_show_song_list
), NULL
);
451 gtk_paned_add1(GTK_PANED(magnatune_vbox
), paned
);
452 gtk_widget_show_all(paned
);
456 sw
= gtk_scrolled_window_new(NULL
, NULL
);
457 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw
), GTK_SHADOW_ETCHED_IN
);
458 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
461 tree
= (GtkWidget
*)gmpc_mpddata_treeview_new("magnatune",TRUE
,GTK_TREE_MODEL(mt_store
));
462 g_signal_connect(G_OBJECT(tree
), "row-activated", G_CALLBACK(magnatune_add_album_row_activated
), NULL
);
464 g_signal_connect(G_OBJECT(tree
), "button-press-event", G_CALLBACK(magnatune_button_release_event
), tree
);
465 g_signal_connect(G_OBJECT(tree
), "key-press-event", G_CALLBACK(magnatune_key_press
), NULL
);
467 gtk_container_add(GTK_CONTAINER(sw
), tree
);
468 gtk_box_pack_start(GTK_BOX(vbox
),sw
, TRUE
, TRUE
,0);
470 mt_tree_search
= (TreeSearch
*)treesearch_new(GTK_TREE_VIEW(tree
), MPDDATA_MODEL_COL_SONG_TITLE
);
471 gtk_box_pack_end(GTK_BOX(vbox
), GTK_WIDGET(mt_tree_search
), FALSE
, TRUE
, 0);
472 g_signal_connect(G_OBJECT(mt_tree_search
), "result-activate", G_CALLBACK(magnatune_search_activate
),NULL
);
475 gtk_widget_show_all(sw
);
476 gtk_widget_show(vbox
);
478 * Progress Bar for the bottom
480 hbox
= gtk_hbox_new(FALSE
, 6);
481 magnatune_cancel
= gtk_button_new_from_stock(GTK_STOCK_CANCEL
);
482 g_signal_connect(G_OBJECT(magnatune_cancel
), "clicked", G_CALLBACK(magnatune_download_cancel
), NULL
);
483 magnatune_pb
= gtk_progress_bar_new();
484 gtk_box_pack_start(GTK_BOX(hbox
), magnatune_pb
, TRUE
, TRUE
, 0);
485 gtk_box_pack_start(GTK_BOX(hbox
), magnatune_cancel
, FALSE
, TRUE
, 0);
486 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, TRUE
, 0);
487 gtk_paned_add2(GTK_PANED(magnatune_vbox
), vbox
);
490 g_object_ref(magnatune_vbox
);
494 static void magnatune_selected(GtkWidget
*container
)
496 if(magnatune_vbox
== NULL
)
499 gtk_container_add(GTK_CONTAINER(container
), magnatune_vbox
);
500 gtk_widget_show(magnatune_vbox
);
501 if(!magnatune_db_has_data())
503 magnatune_download();
506 magnatune_get_genre_list();
508 gtk_container_add(GTK_CONTAINER(container
), magnatune_vbox
);
509 gtk_widget_show(magnatune_vbox
);
512 static void magnatune_unselected(GtkWidget
*container
)
514 gtk_container_remove(GTK_CONTAINER(container
), magnatune_vbox
);
516 static void magnatune_download_cancel(GtkWidget
*button
)
518 GEADAsyncHandler
*handle
= g_object_get_data(G_OBJECT(button
), "handle");
521 gmpc_easy_async_cancel(handle
);
522 g_object_set_data(G_OBJECT(button
), "handle", NULL
);
525 static void magnatune_download_callback(GEADAsyncHandler
*handle
, const GEADStatus status
, gpointer user_data
)
527 GtkWidget
*pb
= user_data
;
528 gchar
*uri
= gmpc_easy_handler_get_uri(handle
);
529 if(status
== GEAD_DONE
)
532 const char *data
= gmpc_easy_handler_get_data(handle
, &length
);
534 magnatune_db_load_data(data
, length
);
535 gtk_widget_hide(gtk_widget_get_parent(pb
));
536 magnatune_get_genre_list();
537 gmpc_easy_async_free_handler(handle
);
541 else if (status
== GEAD_CANCELLED
)
543 gtk_widget_hide(gtk_widget_get_parent(pb
));
544 gmpc_easy_async_free_handler(handle
);
545 magnatune_get_genre_list();
548 else if (status
== GEAD_PROGRESS
)
551 goffset total
= gmpc_easy_handler_get_content_size(handle
);
552 /* Get downloaded length */
553 gmpc_easy_handler_get_data(handle
, &length
);
556 double fraction
= (100*length
)/(total
);
557 gchar
*size
= g_format_size_for_display((goffset
)length
);
558 gchar
*strtotal
= g_format_size_for_display((goffset
)total
);
559 gchar
*label
= g_strdup_printf("Downloading music catalog (%s of %s done)",size
,strtotal
);
562 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pb
), label
);
564 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb
),fraction
/100.0);
568 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pb
));
572 static void magnatune_download()
575 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]))),NULL
);
576 gtk_widget_show_all(gtk_widget_get_parent(magnatune_pb
));
577 const char *url
= "http://he3.magnatune.com/info/sqlite_magnatune.db";
578 GEADAsyncHandler
*handle
= gmpc_easy_async_downloader(url
, magnatune_download_callback
,magnatune_pb
);
579 g_object_set_data(G_OBJECT(magnatune_cancel
), "handle", handle
);
582 static void magnatune_add(GtkWidget
*cat_tree
)
584 GtkTreePath
*path
= NULL
;
585 GtkTreeIter iter
,child
;
586 GtkListStore
*pl3_tree
= (GtkListStore
*)gtk_tree_view_get_model(GTK_TREE_VIEW(cat_tree
));
587 gint pos
= cfg_get_single_value_as_int_with_default(config
, "magnatune","position",20);
589 if(!cfg_get_single_value_as_int_with_default(config
, "magnatune", "enable", TRUE
)) return;
591 debug_printf(DEBUG_INFO
,"Adding at position: %i", pos
);
592 playlist3_insert_browser(&iter
, pos
);
593 gtk_list_store_set(GTK_LIST_STORE(pl3_tree
), &iter
,
594 PL3_CAT_TYPE
, plugin
.id
,
595 PL3_CAT_TITLE
, "Magnatune Browser",
597 PL3_CAT_ICON_ID
, "magnatune",
599 PL3_CAT_ICON_SIZE
,GTK_ICON_SIZE_DND
,-1);
601 * Clean up old row reference if it exists
605 gtk_tree_row_reference_free(magnatune_ref
);
606 magnatune_ref
= NULL
;
609 * create row reference
611 path
= gtk_tree_model_get_path(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter
);
614 magnatune_ref
= gtk_tree_row_reference_new(GTK_TREE_MODEL(playlist3_get_category_tree_store()), path
);
615 gtk_tree_path_free(path
);
619 char * __magnatune_process_string(const char *name
)
626 /* only gonna be smaller */
627 char *result
= g_malloc0((strlen(name
)+1+spaces
*2)*sizeof(char));
628 for(i
=0; i
< strlen(name
);i
++)
630 if(name
[i
] == '(' || name
[i
] == '[') depth
++;
631 else if (name
[i
] == ')' || name
[i
] == ']') depth
--;
638 for(i
=j
-1;i
>0 && result
[i
] == ' ';i
--)
646 static int magnatune_fetch_cover_priority(void){
647 return cfg_get_single_value_as_int_with_default(config
, "magnatune", "priority", 80);
649 static void magnatune_fetch_cover_priority_set(int priority
){
650 cfg_set_single_value_as_int(config
, "magnatune", "priority", priority
);
653 static int magnatune_fetch_get_image(mpd_Song
*song
,MetaDataType type
, char **path
)
657 if(type == META_ARTIST_ART && song->artist)
659 char *value = magnatune_get_artist_image(song->artist);
662 if(strlen(value) > 0)
664 gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL};
665 printf("artist image: %s\n", value);
666 *path = gmpc_get_metadata_filename(META_ARTIST_ART, song, NULL);
667 if(gmpc_easy_download(value, &dld))
669 g_file_set_contents(*path, dld.data, dld.size, NULL);
671 gmpc_easy_download_clean(&dld);
672 return META_DATA_AVAILABLE;
674 gmpc_easy_download_clean(&dld);
683 if(type
== META_ARTIST_ART
&& song
->artist
)
685 char *value
= magnatune_get_artist_image(song
->artist
);
688 gmpc_easy_download_struct dld
= {NULL
, 0, -1, NULL
,NULL
};
689 *path
= gmpc_get_metadata_filename(META_ARTIST_ART
,song
, NULL
);
690 if(gmpc_easy_download(value
, &dld
))
692 g_file_set_contents(*path
, dld
.data
, dld
.size
, NULL
);
694 gmpc_easy_download_clean(&dld
);
695 if(gdk_pixbuf_get_file_info(*path
, NULL
, NULL
) == NULL
)
699 return META_DATA_UNAVAILABLE
;
701 return META_DATA_AVAILABLE
;
703 gmpc_easy_download_clean(&dld
);
709 else if(type
== META_ALBUM_ART
&& song
->artist
&& song
->album
)
711 char *value
= magnatune_get_album_image(song
->artist
,song
->album
);
714 gmpc_easy_download_struct dld
= {NULL
, 0, -1, NULL
,NULL
};
715 *path
= gmpc_get_metadata_filename(META_ALBUM_ART
, song
, NULL
);
716 if(gmpc_easy_download(value
, &dld
))
718 g_file_set_contents(*path
, dld
.data
, dld
.size
, NULL
);
720 gmpc_easy_download_clean(&dld
);
721 if(gdk_pixbuf_get_file_info(*path
, NULL
, NULL
) == NULL
)
725 return META_DATA_UNAVAILABLE
;
727 return META_DATA_AVAILABLE
;
729 gmpc_easy_download_clean(&dld
);
735 return META_DATA_UNAVAILABLE
;
738 static void magnatune_redownload_reload_db()
741 GtkTreeModel
*model
= gtk_tree_row_reference_get_model(magnatune_ref
);
742 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
743 if(path
&& gtk_tree_model_get_iter(model
, &iter
, path
))
746 while(gtk_tree_model_iter_children(model
, &citer
,&iter
))
748 gtk_list_store_remove(GTK_LIST_STORE(model
), &citer
);
750 magnatune_download();
751 //magnatune_get_genre_list();
754 gtk_tree_path_free(path
);
757 static void magnatune_cat_menu_add()
760 GtkTreeSelection *sel = gtk_tree_view_get_selection(playlist3_get_category_tree_view());
761 GtkTreeModel *model = (GtkTreeModel *)playlist3_get_category_tree_store();
764 if(!gtk_tree_selection_get_selected(sel,&model,&citer))
769 * Get the level we are on.
771 /* tpath = gtk_tree_model_get_path(model, &citer);
772 depth = gtk_tree_path_get_depth(tpath);
773 gtk_tree_path_free(tpath);
774 */ /** Genre level */
779 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&genre, -1);
782 list = magnatune_db_get_url_list(genre, NULL ,NULL);
783 for(node = list; node; node = node->next)
785 mpd_playlist_queue_add(connection, node->data);
787 mpd_playlist_queue_commit(connection);
788 g_list_foreach(list, (GFunc)g_free, NULL);
794 /* else if(depth == 3)
799 if(gtk_tree_model_iter_parent(model, &iter, &citer))
802 gtk_tree_model_get(model, &iter, PL3_CAT_INT_ID,&genre, -1);
803 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&artist, -1);
804 list = magnatune_db_get_url_list(genre, artist,NULL);
805 for(node = list; node; node = node->next)
807 mpd_playlist_queue_add(connection, node->data);
809 mpd_playlist_queue_commit(connection);
810 g_list_foreach(list, (GFunc)g_free, NULL);
823 static void magnatune_cat_menu_replace()
825 mpd_playlist_clear(connection);
826 magnatune_cat_menu_add();
827 mpd_player_play(connection);
831 static int magnatune_cat_menu_popup(GtkWidget
*menu
, int type
, GtkWidget
*tree
, GdkEventButton
*event
)
834 if(type
!= plugin
.id
) return 0;
835 else if (!downloading
)
837 /* add the clear widget */
838 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_REFRESH
,NULL
);
839 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
840 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_redownload_reload_db
), NULL
);
846 static void magnatune_add_selected(GtkWidget
*button
, GtkTreeView
*tree
)
848 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
849 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
850 GList
*list
= gtk_tree_selection_get_selected_rows(sel
,&model
);
854 for(node
= list
; node
; node
= g_list_next(node
))
857 if(gtk_tree_model_get_iter(model
, &iter
, node
->data
))
860 gtk_tree_model_get(model
, &iter
, MPDDATA_MODEL_COL_PATH
, &path
, -1);
861 mpd_playlist_queue_add(connection
, path
);
865 mpd_playlist_queue_commit(connection
);
866 g_list_foreach (list
, (GFunc
)gtk_tree_path_free
, NULL
);
870 static void magnatune_replace_selected(GtkWidget
*button
, GtkTreeView
*tree
)
872 mpd_playlist_clear(connection
);
873 magnatune_add_selected(button
, tree
);
874 mpd_player_play(connection
);
878 static int magnatune_button_handle_release_event_tag_add(GtkWidget
*button
, gpointer userdata
)
882 int position
= GPOINTER_TO_INT(userdata
);
883 gchar
*genre
=NULL
, *artist
=NULL
, *album
=NULL
;
884 GtkTreeSelection
*select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[0]));
885 GtkTreeModel
*model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[0]));
887 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
889 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&genre
,-1);
893 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[1]));
894 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[1]));
895 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
897 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&artist
,-1);
902 select
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews
[2]));
903 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews
[2]));
904 if(gtk_tree_selection_get_selected(select
, &model
, &piter
))
906 gtk_tree_model_get(model
, &piter
, MPDDATA_MODEL_COL_SONG_TITLE
,&album
,-1);
910 list = magnatune_db_get_url_list(genre, artist, album);
911 for(;list; list = list->next)
913 mpd_playlist_queue_add(connection, list->data);
917 data
= magnatune_db_get_song_list(genre
,artist
,album
, TRUE
);
918 for(data
= mpd_data_get_first(data
);data
;data
= mpd_data_get_next(data
)) {
919 mpd_playlist_queue_add(connection
, data
->song
->file
);
921 mpd_playlist_queue_commit(connection
);
925 g_list_foreach(list, (GFunc)g_free, NULL);
938 static int magnatune_button_handle_release_event_tag_replace(GtkWidget
*button
, gpointer userdata
)
940 mpd_playlist_clear(connection
);
941 magnatune_button_handle_release_event_tag_add(button
,userdata
);
942 mpd_player_play(connection
);
946 static int magnatune_button_handle_release_event_tag(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
)
949 int position
= GPOINTER_TO_INT(data
);
950 if(event
->button
!= 3) return FALSE
;
953 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
954 if(gtk_tree_selection_count_selected_rows(sel
)> 0)
956 GtkWidget
*menu
= gtk_menu_new();
960 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD
,NULL
);
961 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
), item
);
962 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_add
), data
);
964 item
= gtk_image_menu_item_new_with_label("Replace");
965 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
966 gtk_image_new_from_stock(GTK_STOCK_REDO
, GTK_ICON_SIZE_MENU
));
967 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
968 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_replace
), data
);
969 gtk_widget_show_all(menu
);
970 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
,NULL
, NULL
, event
->button
, event
->time
);
976 static int magnatune_button_release_event(GtkWidget
*tree
, GdkEventButton
*event
,gpointer data
)
978 if(event
->button
!= 3) return FALSE
;
981 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tree
));
983 if(gtk_tree_selection_count_selected_rows(sel
)> 0)
985 GtkWidget
*menu
= gtk_menu_new();
986 GtkTreeModel
*model
= GTK_TREE_MODEL(mt_store
);
988 item
= gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD
,NULL
);
989 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
), item
);
990 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_add_selected
), tree
);
992 item
= gtk_image_menu_item_new_with_label("Replace");
993 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item
),
994 gtk_image_new_from_stock(GTK_STOCK_REDO
, GTK_ICON_SIZE_MENU
));
995 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
997 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(magnatune_replace_selected
), tree
);
999 gmpc_mpddata_treeview_right_mouse_intergration(GMPC_MPDDATA_TREEVIEW(tree
), GTK_MENU(menu
));
1001 gtk_widget_show_all(menu
);
1003 gtk_menu_popup(GTK_MENU(menu
), NULL
, NULL
,NULL
, NULL
, event
->button
, event
->time
);
1009 static void magnatune_cat_key_press(GtkWidget *tree, GdkEventKey *event, int selected_type)
1011 if(selected_type != plugin.id) return;
1012 if(event->state&GDK_CONTROL_MASK && event->keyval == GDK_Insert)
1014 magnatune_cat_menu_replace();
1016 else if(event->keyval == GDK_Insert)
1018 magnatune_cat_menu_add();
1023 static int magnatune_key_press(GtkWidget
*tree
, GdkEventKey
*event
)
1025 if(event
->state
&GDK_CONTROL_MASK
&& event
->keyval
== GDK_Insert
)
1027 magnatune_replace_selected(NULL
, GTK_TREE_VIEW(tree
));
1029 else if(event
->keyval
== GDK_Insert
)
1031 magnatune_add_selected(NULL
, GTK_TREE_VIEW(tree
));
1033 else if (event
->keyval
== GDK_f
&& event
->state
&GDK_CONTROL_MASK
)
1035 treesearch_start(mt_tree_search
);
1038 else if((event
->state
&(GDK_CONTROL_MASK
|GDK_MOD1_MASK
)) == 0 &&
1039 ((event
->keyval
>= GDK_space
&& event
->keyval
<= GDK_z
)))
1042 data
[0] = (char)gdk_keyval_to_unicode(event
->keyval
);
1044 treesearch_start(TREESEARCH(mt_tree_search
));
1045 gtk_entry_set_text(GTK_ENTRY(TREESEARCH(mt_tree_search
)->entry
),data
);
1046 gtk_editable_set_position(GTK_EDITABLE(TREESEARCH(mt_tree_search
)->entry
),1);
1051 static void magnatune_save_myself(void)
1055 int position
= gtk_paned_get_position(GTK_PANED(magnatune_vbox
));
1056 cfg_set_single_value_as_int(config
, "magnatune", "pane-pos", position
);
1060 GtkTreePath
*path
= gtk_tree_row_reference_get_path(magnatune_ref
);
1063 gint
*indices
= gtk_tree_path_get_indices(path
);
1064 debug_printf(DEBUG_INFO
,"Saving myself to position: %i\n", indices
[0]);
1065 cfg_set_single_value_as_int(config
, "magnatune","position",indices
[0]);
1066 gtk_tree_path_free(path
);
1071 static void magnatune_destroy(void)
1073 magnatune_db_destroy();
1075 gtk_widget_destroy(magnatune_vbox
);
1078 static gboolean
magnatune_integrate_search_field_supported(const int search_field
)
1080 switch(search_field
)
1082 case MPD_TAG_ITEM_ARTIST
:
1083 case MPD_TAG_ITEM_ALBUM
:
1084 case MPD_TAG_ITEM_GENRE
:
1085 case MPD_TAG_ITEM_TITLE
:
1091 static MpdData
* magnatune_integrate_search(const int search_field
, const gchar
*query
,GError
**error
)
1093 const gchar
*genre
= NULL
, *artist
=NULL
, *album
=NULL
;
1094 if(!magnatune_get_enabled()) return NULL
;
1095 if(!magnatune_db_has_data()){
1096 g_set_error(error
, 0,0, "Music catalog not yet available, please open magnatune browser first");
1099 switch(search_field
){
1100 case MPD_TAG_ITEM_ARTIST
:
1103 case MPD_TAG_ITEM_ALBUM
:
1106 case MPD_TAG_ITEM_GENRE
:
1109 case MPD_TAG_ITEM_TITLE
:
1110 return magnatune_db_search_title(query
);
1113 g_set_error(error
, 0,0, "This type of search query is not supported");
1117 return magnatune_db_get_song_list(genre
, artist
, album
,FALSE
);
1120 gmpcMetaDataPlugin magnatune_cover
= {
1121 .get_priority
= magnatune_fetch_cover_priority
,
1122 .set_priority
= magnatune_fetch_cover_priority_set
,
1123 .get_image
= magnatune_fetch_get_image
1127 /* Needed plugin_wp stuff */
1128 gmpcPlBrowserPlugin magnatune_gbp
= {
1129 .add
= magnatune_add
,
1130 .selected
= magnatune_selected
,
1131 .unselected
= magnatune_unselected
,
1132 .cat_right_mouse_menu
= magnatune_cat_menu_popup
,
1133 .integrate_search
= magnatune_integrate_search
,
1134 .integrate_search_field_supported
= magnatune_integrate_search_field_supported
1137 int plugin_api_version
= PLUGIN_API_VERSION
;
1139 gmpcPlugin plugin
= {
1140 .name
= "Magnatune Stream Browser",
1141 .version
= {PLUGIN_MAJOR_VERSION
,PLUGIN_MINOR_VERSION
,PLUGIN_MICRO_VERSION
},
1142 .plugin_type
= GMPC_PLUGIN_PL_BROWSER
|GMPC_PLUGIN_META_DATA
,
1143 /* Creation and destruction */
1144 .init
= magnatune_logo_init
,
1145 .destroy
= magnatune_destroy
,
1146 .save_yourself
= magnatune_save_myself
,
1147 .mpd_status_changed
= magnatune_mpd_status_changed
,
1149 /* Browser extention */
1150 .browser
= &magnatune_gbp
,
1151 .metadata
= &magnatune_cover
,
1153 /* get/set enabled */
1154 .get_enabled
= magnatune_get_enabled
,
1155 .set_enabled
= magnatune_set_enabled