Show what you are downloading and use glib for formatting string
[gmpc-magnatune.git] / src / plugin.c
blob6121282bd03505390723e7ce82b02eb235ab9d16
1 #include <stdio.h>
2 #include <string.h>
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>
11 #include <config.h>
12 #include "magnatune.h"
14 extern GladeXML *pl3_xml;
16 gmpcPlugin plugin;
17 /**
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;
43 /**
44 * Get set enabled
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);
53 if (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);
63 if (path){
64 GtkTreeIter iter;
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);
71 magnatune_ref = NULL;
74 pl3_update_go_menu();
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);
98 g_free(path);
101 static void magnatune_logo_add()
103 mpd_Song *song = mpd_playlist_get_current_song(connection);
104 GtkWidget *logo, *button;
105 GtkWidget *ali;
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);
119 if(song) {
120 if(strstr(song->file,"magnatune.com"))
122 gtk_widget_show_all(magnatune_logo);
123 return;
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);
136 g_free(url);
137 g_free(path);
139 gtk_init_add((GtkFunction )magnatune_logo_add, NULL);
140 /**
141 * init the magnatune stuff
143 magnatune_db_init();
145 * open the db
147 magnatune_db_open();
151 static void magnatune_mpd_status_changed(MpdObj *mi, ChangedStatusType what, void *data)
153 if(!magnatune_logo)
154 return;
155 if(what&(MPD_CST_SONGID|MPD_CST_STATE))
157 mpd_Song *song = mpd_playlist_get_current_song(mi);
158 if(song) {
159 if(strstr(song->file,"magnatune.com"))
161 gtk_widget_show_all(magnatune_logo);
162 return;
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;
179 GtkTreeIter piter;
180 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
181 if(gtk_tree_selection_get_selected(selection, &model, &piter))
183 gchar *genre;
184 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
185 data= magnatune_db_get_artist_list(genre);
187 g_free(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;
195 GtkTreeIter piter;
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);
204 /* model */
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)
223 GtkTreeIter piter;
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;
231 gchar *genre;
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);
235 /* model */
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;
241 gchar *artist;
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);
245 g_free(artist);
247 g_free(genre);
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);
255 GtkTreeIter iter_r;
257 if(gtk_tree_model_get_iter(model, &iter_r, path))
259 gchar *path;
260 gtk_tree_model_get(model, &iter_r, MPDDATA_MODEL_COL_PATH, &path, -1);
261 play_path(path);
262 g_free(path);
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);
270 if(compare){
271 gchar *a = g_utf8_casefold(key, -1);
272 gchar *b = g_utf8_casefold(compare, -1);
273 if(strstr(b,a))
275 g_free(a);
276 g_free(b);
277 return FALSE;
279 g_free(a);
280 g_free(b);
282 return TRUE;
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);
293 /* free list */
294 g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
295 g_list_free (list);
299 static void magnatune_init()
301 int size;
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);
317 * Create list store
318 * 1. pointer
319 * 2. name
321 mt_store = (GtkTreeModel *)gmpc_mpddata_model_new();
323 /* Paned window */
324 paned = gtk_hbox_new(TRUE,6);
325 model = (GtkTreeModel *) gmpc_mpddata_model_new();
326 /* Genre list */
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));
333 /* Add column */
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);
352 /* Artist list */
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));
361 /* Add column */
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);
384 /* Album list */
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));
393 /* Add column */
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);
422 * tree
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)
461 magnatune_init();
462 gtk_container_add(GTK_CONTAINER(container), magnatune_vbox);
463 gtk_widget_show(magnatune_vbox);
464 if(!magnatune_db_has_data())
466 magnatune_download();
468 else
469 magnatune_get_genre_list();
470 } else {
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()
482 downloading = FALSE;
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);
487 return FALSE;
490 typedef struct _Pass{
491 GtkWidget *pb;
492 int download;
493 int total;
494 }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));
501 p->pb = data;
502 p->download = download;
503 p->total =total;
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;
512 gchar *label = NULL;
513 gchar *size = NULL;
514 // gdk_threads_enter();
515 if(total > 0)
516 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb), download/(float)total);
517 else
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);
522 g_free(size);
523 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pb), label);
524 g_free(label);
525 // while(gtk_events_pending())
526 // gtk_main_iteration();
527 // gdk_threads_leave();
528 g_free(p);
529 return FALSE;
532 static void magnatune_download()
534 downloading = TRUE;
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",
557 PL3_CAT_INT_ID, "",
558 PL3_CAT_ICON_ID, "magnatune",
559 PL3_CAT_PROC, TRUE,
560 PL3_CAT_ICON_SIZE,GTK_ICON_SIZE_DND,-1);
562 * Clean up old row reference if it exists
564 if (magnatune_ref)
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);
573 if (path)
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)
582 int i = 0;
583 int j = 0;
584 int depth = 0;
585 int spaces = 0;
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--;
593 else if(!depth)
595 result[j] = name[i];
596 j++;
599 for(i=j-1;i>0 && result[i] == ' ';i--)
601 result[i] = '\0';
603 return result;
606 /*** COVER STUFF */
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)
615 int result = 0;
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);
622 if(value)
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);
632 g_free(*path);
633 *path = NULL;
635 g_free(artist);
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);
642 if(value)
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);
653 g_free(*path);
654 *path = NULL;
656 g_free(artist);
658 return META_DATA_UNAVAILABLE;
660 static void magnatune_redownload_reload_db()
662 GtkTreeIter iter;
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))
667 GtkTreeIter citer;
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();
675 if(path)
676 gtk_tree_path_free(path);
679 static void magnatune_cat_menu_add()
681 GtkTreeIter citer;
682 GtkTreeSelection *sel = gtk_tree_view_get_selection(playlist3_get_category_tree_view());
683 GtkTreeModel *model = (GtkTreeModel *)playlist3_get_category_tree_store();
684 GtkTreePath *tpath;
685 int depth = 0;
686 if(!gtk_tree_selection_get_selected(sel,&model,&citer))
688 return ;
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);
696 /** Genre level */
697 if(depth == 2)
699 GList *list, *node;
700 gchar *genre;
701 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&genre, -1);
702 if(genre)
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);
711 g_list_free(list);
712 g_free(genre);
715 /** Artist */
716 else if(depth == 3)
718 gchar *artist;
719 gchar *genre;
720 GtkTreeIter iter;
721 if(gtk_tree_model_iter_parent(model, &iter, &citer))
723 GList *list, *node;
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);
733 g_list_free(list);
734 g_free(genre);
735 g_free(artist);
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)
754 GtkWidget *item;
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);
762 return 1;
764 return 0;
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);
772 if(list)
774 GList *node ;
775 for(node = list; node; node = g_list_next(node))
777 GtkTreeIter iter;
778 if(gtk_tree_model_get_iter(model, &iter, node->data))
780 gchar *path;
781 gtk_tree_model_get(model, &iter, MPDDATA_MODEL_COL_PATH, &path, -1);
782 mpd_playlist_queue_add(connection, path);
783 g_free(path);
786 mpd_playlist_queue_commit(connection);
787 g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
788 g_list_free (list);
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)
805 GList *list;
806 MpdData *data;
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]));
811 GtkTreeIter piter;
812 if(gtk_tree_selection_get_selected(select, &model, &piter))
814 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
816 if(position >= 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);
825 if(position >= 2)
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);
840 if(list)
842 g_list_foreach(list, g_free, NULL);
843 g_list_free(list);
845 if(genre)
846 g_free(genre);
847 if(artist)
848 g_free(artist);
849 if(album)
850 g_free(album);
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)
864 int i;
865 int position = GPOINTER_TO_INT(data);
866 if(event->button != 3) return FALSE;
867 GtkWidget *item;
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();
875 /* Add */
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);
879 /* Replace */
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);
887 return TRUE;
889 return FALSE;
892 static int magnatune_button_release_event(GtkWidget *tree, GdkEventButton *event,gpointer data)
894 if(event->button != 3) return FALSE;
895 GtkWidget *item;
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);
903 /* Add */
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);
907 /* Replace */
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);
915 /* Separator */
916 item = gtk_separator_menu_item_new();
917 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
918 /* Edit columns */
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);
929 return TRUE;
931 return FALSE;
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);
961 return TRUE;
963 else if((event->state&(GDK_CONTROL_MASK|GDK_MOD1_MASK)) == 0 &&
964 ((event->keyval >= GDK_space && event->keyval <= GDK_z)))
966 char data[2];
967 data[0] = (char)gdk_keyval_to_unicode(event->keyval);
968 data[1] = '\0';
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);
972 return TRUE;
974 return FALSE;
976 static void magnatune_save_myself(void)
978 if(magnatune_vbox)
980 int position = gtk_paned_get_position(GTK_PANED(magnatune_vbox));
981 cfg_set_single_value_as_int(config, "magnatune", "pane-pos", position);
983 if (magnatune_ref)
985 GtkTreePath *path = gtk_tree_row_reference_get_path(magnatune_ref);
986 if(path)
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();
999 if(magnatune_vbox)
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