Support new api (20)
[gmpc-magnatune.git] / src / plugin.c
blob9d7bc032f4ff9a939439f27e82111ece5d79548b
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 = NULL;
134 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default (),DATA_DIR);
136 gtk_init_add((GtkFunction )magnatune_logo_add, NULL);
137 /**
138 * init the magnatune stuff
140 magnatune_db_init();
142 * open the db
144 magnatune_db_open();
148 static void magnatune_mpd_status_changed(MpdObj *mi, ChangedStatusType what, void *data)
150 if(!magnatune_logo)
151 return;
152 if(what&(MPD_CST_SONGID|MPD_CST_STATE))
154 mpd_Song *song = mpd_playlist_get_current_song(mi);
155 if(song) {
156 if(strstr(song->file,"magnatune.com"))
158 gtk_widget_show_all(magnatune_logo);
159 return;
162 gtk_widget_hide(magnatune_logo);
166 void magnatune_get_genre_list()
168 MpdData *data = NULL;
169 data = magnatune_db_get_genre_list();
170 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]))),data);
173 static void magnatune_show_album_list(GtkTreeSelection *selection, gpointer user_data)
175 MpdData *data = NULL;
176 GtkTreeIter piter;
177 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
178 if(gtk_tree_selection_get_selected(selection, &model, &piter))
180 gchar *genre;
181 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
182 data= magnatune_db_get_artist_list(genre);
184 g_free(genre);
186 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]))),data);
189 static void magnatune_show_song_list(GtkTreeSelection *selection, gpointer user_data)
191 MpdData *data = NULL;
192 GtkTreeIter piter;
193 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
194 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
195 gchar *genre = NULL, *artist = NULL, *album = NULL;
196 if(gtk_tree_selection_get_selected(select, &model, &piter))
199 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
200 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
201 /* model */
202 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
203 if(gtk_tree_selection_get_selected(select, &model, &piter))
205 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
206 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]));
207 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]));
208 if(gtk_tree_selection_get_selected(select, &model, &piter))
210 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&album,-1);
214 data = magnatune_db_get_song_list(genre, artist, album);
215 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(mt_store), data);
218 static void magnatune_show_artist_list(GtkTreeSelection *selection, gpointer user_data)
220 GtkTreeIter piter;
221 MpdData *data = NULL;
222 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
223 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
225 if(gtk_tree_selection_get_selected(select, &model, &piter))
227 GList *iter,*list = NULL;
228 gchar *genre;
230 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
231 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
232 /* model */
233 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
234 if(gtk_tree_selection_get_selected(select, &model, &piter))
236 GList *iter,*list = NULL;
238 gchar *artist;
239 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
240 data = magnatune_db_get_album_list(genre ,artist);
241 gmpc_mpddata_model_set_request_artist(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]))),artist);
242 g_free(artist);
244 g_free(genre);
246 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]))),data);
249 static void magnatune_add_album_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
251 GtkTreeModel *model = gtk_tree_view_get_model(tree);
252 GtkTreeIter iter_r;
254 if(gtk_tree_model_get_iter(model, &iter_r, path))
256 gchar *path;
257 gtk_tree_model_get(model, &iter_r, MPDDATA_MODEL_COL_PATH, &path, -1);
258 play_path(path);
259 g_free(path);
263 static gboolean magnatune_search_equal_func(GtkTreeModel *model, int column, const gchar *key, GtkTreeIter *iter, gpointer data)
265 gchar *compare = NULL;
266 gtk_tree_model_get(model,iter, column, &compare, -1);
267 if(compare){
268 gchar *a = g_utf8_casefold(key, -1);
269 gchar *b = g_utf8_casefold(compare, -1);
270 if(strstr(b,a))
272 g_free(a);
273 g_free(b);
274 return FALSE;
276 g_free(a);
277 g_free(b);
279 return TRUE;
282 static void magnatune_search_activate(TreeSearch *ts)
284 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
285 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ts->treeview));
286 if (gtk_tree_selection_count_selected_rows (selection) == 1)
288 GList *list = gtk_tree_selection_get_selected_rows (selection, &model);
289 magnatune_add_album_row_activated(GTK_TREE_VIEW(ts->treeview),(GtkTreePath *)list->data, NULL,NULL);
290 /* free list */
291 g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
292 g_list_free (list);
296 static void magnatune_init()
298 int size;
299 GtkWidget *tree = NULL;
300 GtkWidget *sw = NULL;
301 GtkCellRenderer *renderer = NULL;
302 GtkWidget *paned = NULL;
303 GtkWidget *hbox = NULL;
304 GtkWidget *vbox = NULL;
305 GtkTreeModel *model = NULL;
306 GtkTreeViewColumn *column = NULL;
307 int position = cfg_get_single_value_as_int_with_default(config, "magnatune", "pane-pos", 150);
308 magnatune_vbox = gtk_vpaned_new();
309 gtk_paned_set_position(GTK_PANED(magnatune_vbox), position);
312 vbox = gtk_vbox_new(FALSE,6);
314 * Create list store
315 * 1. pointer
316 * 2. name
318 mt_store = (GtkTreeModel *)gmpc_mpddata_model_new();
320 /* Paned window */
321 paned = gtk_hbox_new(TRUE,6);
322 model = (GtkTreeModel *) gmpc_mpddata_model_new();
323 /* Genre list */
324 sw = gtk_scrolled_window_new(NULL, NULL);
325 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
326 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
327 treeviews[0] = gtk_tree_view_new_with_model(model);
328 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[0]), MPDDATA_MODEL_COL_SONG_TITLE);
329 g_signal_connect(G_OBJECT(treeviews[0]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(0));
330 /* Add column */
331 column = gtk_tree_view_column_new();
332 gtk_tree_view_column_set_title(column, "Genre");
335 renderer = gtk_cell_renderer_pixbuf_new();
336 gtk_tree_view_column_pack_start(column, renderer, FALSE);
337 gtk_tree_view_column_add_attribute(column, renderer, "icon-name", MPDDATA_MODEL_COL_ICON_ID);
338 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_AUTOSIZE);
339 renderer = gtk_cell_renderer_text_new();
340 gtk_tree_view_column_pack_start(column, renderer, TRUE);
341 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
342 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[0]),column, -1);
344 gtk_container_add(GTK_CONTAINER(sw), treeviews[0]);
345 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
347 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]))), "changed", G_CALLBACK(magnatune_show_album_list), NULL);
349 /* Artist list */
350 model = (GtkTreeModel *) gmpc_mpddata_model_new();
351 sw = gtk_scrolled_window_new(NULL, NULL);
352 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
353 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
354 treeviews[1] = gtk_tree_view_new_with_model(model);
356 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[1]), MPDDATA_MODEL_COL_SONG_TITLE);
357 g_signal_connect(G_OBJECT(treeviews[1]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(1));
358 /* Add column */
359 column = gtk_tree_view_column_new();
360 gtk_tree_view_column_set_title(column, "Artist");
361 size = cfg_get_single_value_as_int_with_default(config, "gmpc-mpddata-model", "icon-size", 64);
362 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_FIXED);
363 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews[1]), TRUE);
366 renderer = gtk_cell_renderer_pixbuf_new();
367 gtk_cell_renderer_set_fixed_size(renderer, size,size);
369 gtk_tree_view_column_pack_start(column, renderer, FALSE);
370 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", MPDDATA_MODEL_META_DATA);
371 renderer = gtk_cell_renderer_text_new();
372 gtk_tree_view_column_pack_start(column, renderer, TRUE);
373 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
374 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[1]),column, -1);
376 gtk_container_add(GTK_CONTAINER(sw), treeviews[1]);
377 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
379 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]))), "changed", G_CALLBACK(magnatune_show_artist_list), NULL);
381 /* Album list */
382 model = (GtkTreeModel *) gmpc_mpddata_model_new();
383 sw = gtk_scrolled_window_new(NULL, NULL);
384 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
385 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
386 treeviews[2] = gtk_tree_view_new_with_model(model);
387 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[2]), MPDDATA_MODEL_COL_SONG_TITLE);
389 g_signal_connect(G_OBJECT(treeviews[2]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(2));
390 /* Add column */
391 column = gtk_tree_view_column_new();
392 gtk_tree_view_column_set_title(column, "Album");
393 size = cfg_get_single_value_as_int_with_default(config, "gmpc-mpddata-model", "icon-size", 64);
394 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_FIXED);
395 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews[2]), TRUE);
398 renderer = gtk_cell_renderer_pixbuf_new();
399 gtk_cell_renderer_set_fixed_size(renderer, size,size);
401 gtk_tree_view_column_pack_start(column, renderer, FALSE);
402 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", MPDDATA_MODEL_META_DATA);
403 renderer = gtk_cell_renderer_text_new();
404 gtk_tree_view_column_pack_start(column, renderer, TRUE);
405 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
406 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[2]),column, -1);
408 gtk_container_add(GTK_CONTAINER(sw), treeviews[2]);
409 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
412 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
413 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
414 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
416 gtk_paned_add1(GTK_PANED(magnatune_vbox), paned);
417 gtk_widget_show_all(paned);
419 * tree
421 sw = gtk_scrolled_window_new(NULL, NULL);
422 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
423 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
426 tree = (GtkWidget *)gmpc_mpddata_treeview_new("magnatune",TRUE,GTK_TREE_MODEL(mt_store));
427 g_signal_connect(G_OBJECT(tree), "row-activated", G_CALLBACK(magnatune_add_album_row_activated), NULL);
429 g_signal_connect(G_OBJECT(tree), "button-press-event", G_CALLBACK(magnatune_button_release_event), tree);
430 g_signal_connect(G_OBJECT(tree), "key-press-event", G_CALLBACK(magnatune_key_press), NULL);
432 gtk_container_add(GTK_CONTAINER(sw), tree);
433 gtk_box_pack_start(GTK_BOX(vbox),sw, TRUE, TRUE,0);
435 mt_tree_search = (TreeSearch *)treesearch_new(GTK_TREE_VIEW(tree), MPDDATA_MODEL_COL_SONG_TITLE);
436 gtk_box_pack_end(GTK_BOX(vbox), GTK_WIDGET(mt_tree_search), FALSE, TRUE, 0);
437 g_signal_connect(G_OBJECT(mt_tree_search), "result-activate", G_CALLBACK(magnatune_search_activate),NULL);
440 gtk_widget_show_all(sw);
441 gtk_widget_show(vbox);
443 * Progress Bar for the bottom
445 magnatune_pb = gtk_progress_bar_new();
446 gtk_box_pack_end(GTK_BOX(vbox), magnatune_pb, FALSE, TRUE, 0);
447 gtk_paned_add2(GTK_PANED(magnatune_vbox), vbox);
450 g_object_ref(magnatune_vbox);
454 static void magnatune_selected(GtkWidget *container)
456 if(magnatune_vbox == NULL)
458 magnatune_init();
459 gtk_container_add(GTK_CONTAINER(container), magnatune_vbox);
460 gtk_widget_show(magnatune_vbox);
461 if(!magnatune_db_has_data())
463 magnatune_download();
465 else
466 magnatune_get_genre_list();
467 } else {
468 gtk_container_add(GTK_CONTAINER(container), magnatune_vbox);
469 gtk_widget_show(magnatune_vbox);
472 static void magnatune_unselected(GtkWidget *container)
474 gtk_container_remove(GTK_CONTAINER(container), magnatune_vbox);
477 void magnatune_end_download()
479 downloading = FALSE;
481 magnatune_get_genre_list();
482 gtk_widget_hide(magnatune_pb);
483 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), TRUE);
485 static void magnatune_download_xml_callback(int download, int total,gpointer data)
487 GtkWidget *pb = data;
488 gchar *label = NULL;
489 gdk_threads_enter();
490 if(total > 0)
491 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb), download/(float)total);
492 else
493 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pb));
494 if(download >> 20)
496 label = g_strdup_printf("%.2f mb",(download>>10)/1024.0);
498 else if (download>>10)
500 label = g_strdup_printf("%i kb",download>>10);
502 else
504 label = g_strdup_printf("%i b",download);
506 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pb), label);
507 g_free(label);
508 // while(gtk_events_pending())
509 // gtk_main_iteration();
510 gdk_threads_leave();
513 static void magnatune_download()
515 downloading = TRUE;
516 // gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), FALSE);
517 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]))),NULL);
518 gtk_widget_show(magnatune_pb);
519 magnatune_db_download_xml(magnatune_download_xml_callback, magnatune_pb);
520 // gtk_widget_hide(magnatune_pb);
521 // gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), TRUE);
524 static void magnatune_add(GtkWidget *cat_tree)
526 GtkTreePath *path = NULL;
527 GtkTreeIter iter,child;
528 GtkTreeStore *pl3_tree = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(cat_tree));
529 gint pos = cfg_get_single_value_as_int_with_default(config, "magnatune","position",20);
531 if(!cfg_get_single_value_as_int_with_default(config, "magnatune", "enable", TRUE)) return;
533 debug_printf(DEBUG_INFO,"Adding at position: %i", pos);
534 playlist3_insert_browser(&iter, pos);
535 gtk_list_store_set(pl3_tree, &iter,
536 PL3_CAT_TYPE, plugin.id,
537 PL3_CAT_TITLE, "Magnatune Browser",
538 PL3_CAT_INT_ID, "",
539 PL3_CAT_ICON_ID, "magnatune",
540 PL3_CAT_PROC, TRUE,
541 PL3_CAT_ICON_SIZE,GTK_ICON_SIZE_DND,-1);
543 * Clean up old row reference if it exists
545 if (magnatune_ref)
547 gtk_tree_row_reference_free(magnatune_ref);
548 magnatune_ref = NULL;
551 * create row reference
553 path = gtk_tree_model_get_path(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter);
554 if (path)
556 magnatune_ref = gtk_tree_row_reference_new(GTK_TREE_MODEL(playlist3_get_category_tree_store()), path);
557 gtk_tree_path_free(path);
561 static char * __magnatune_process_string(char *name)
563 int i = 0;
564 int j = 0;
565 int depth = 0;
566 int spaces = 0;
568 /* only gonna be smaller */
569 char *result = g_malloc0((strlen(name)+1+spaces*2)*sizeof(char));
570 for(i=0; i < strlen(name);i++)
572 if(name[i] == '(' || name[i] == '[') depth++;
573 else if (name[i] == ')' || name[i] == ']') depth--;
574 else if(!depth)
576 result[j] = name[i];
577 j++;
580 for(i=j-1;i>0 && result[i] == ' ';i--)
582 result[i] = '\0';
584 return result;
587 /*** COVER STUFF */
588 static int magnatune_fetch_cover_priority(void){
589 return cfg_get_single_value_as_int_with_default(config, "magnatune", "priority", 80);
591 static void magnatune_fetch_cover_priority_set(int priority){
592 cfg_set_single_value_as_int(config, "magnatune", "priority", priority);
594 static int magnatune_fetch_get_image(mpd_Song *song,MetaDataType type, char **path)
596 int result = 0;
597 if(magnatune_db_has_data() == FALSE)
598 return META_DATA_UNAVAILABLE;
599 if(type == META_ARTIST_ART && song->artist)
601 char *artist = __magnatune_process_string(song->artist);
602 char *value = magnatune_db_get_value(artist,NULL,META_ARTIST_ART);
603 if(value)
605 gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL};
606 *path = gmpc_get_metadata_filename(META_ARTIST_ART, song, NULL);
607 if(gmpc_easy_download(value, &dld))
609 g_file_set_contents(*path, dld.data, dld.size, NULL);
610 return META_DATA_AVAILABLE;
612 gmpc_easy_download_clean(&dld);
613 g_free(*path);
614 *path = NULL;
616 g_free(artist);
618 else if(type == META_ALBUM_ART && song->artist && song->album)
620 char *artist = __magnatune_process_string(song->artist);
621 char *album= __magnatune_process_string(song->album);
622 char *value = magnatune_db_get_value(artist,album,META_ALBUM_ART);
623 if(value)
625 gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL};
627 *path = gmpc_get_metadata_filename(META_ALBUM_ART, song, NULL);
628 if(gmpc_easy_download(value, &dld))
630 g_file_set_contents(*path, dld.data, dld.size, NULL);
631 return META_DATA_AVAILABLE;
633 gmpc_easy_download_clean(&dld);
634 g_free(*path);
635 *path = NULL;
637 g_free(artist);
639 return META_DATA_UNAVAILABLE;
641 static void magnatune_redownload_reload_db()
643 GtkTreeIter iter;
644 GtkTreeModel *model = gtk_tree_row_reference_get_model(magnatune_ref);
645 GtkTreePath *path = gtk_tree_row_reference_get_path(magnatune_ref);
646 if(path && gtk_tree_model_get_iter(model, &iter, path))
648 GtkTreeIter citer;
649 while(gtk_tree_model_iter_children(model, &citer,&iter))
651 gtk_list_store_remove(GTK_LIST_STORE(model), &citer);
653 magnatune_download();
654 //magnatune_get_genre_list();
656 if(path)
657 gtk_tree_path_free(path);
660 static void magnatune_cat_menu_add()
662 GtkTreeIter citer;
663 GtkTreeSelection *sel = gtk_tree_view_get_selection(playlist3_get_category_tree_view());
664 GtkTreeModel *model = (GtkTreeModel *)playlist3_get_category_tree_store();
665 GtkTreePath *tpath;
666 int depth = 0;
667 if(!gtk_tree_selection_get_selected(sel,&model,&citer))
669 return ;
672 * Get the level we are on.
674 tpath = gtk_tree_model_get_path(model, &citer);
675 depth = gtk_tree_path_get_depth(tpath);
676 gtk_tree_path_free(tpath);
677 /** Genre level */
678 if(depth == 2)
680 GList *list, *node;
681 gchar *genre;
682 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&genre, -1);
683 if(genre)
685 list = magnatune_db_get_url_list(genre, NULL ,NULL);
686 for(node = list; node; node = node->next)
688 mpd_playlist_queue_add(connection, node->data);
690 mpd_playlist_queue_commit(connection);
691 g_list_foreach(list, (GFunc)g_free, NULL);
692 g_list_free(list);
693 g_free(genre);
696 /** Artist */
697 else if(depth == 3)
699 gchar *artist;
700 gchar *genre;
701 GtkTreeIter iter;
702 if(gtk_tree_model_iter_parent(model, &iter, &citer))
704 GList *list, *node;
705 gtk_tree_model_get(model, &iter, PL3_CAT_INT_ID,&genre, -1);
706 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&artist, -1);
707 list = magnatune_db_get_url_list(genre, artist,NULL);
708 for(node = list; node; node = node->next)
710 mpd_playlist_queue_add(connection, node->data);
712 mpd_playlist_queue_commit(connection);
713 g_list_foreach(list, (GFunc)g_free, NULL);
714 g_list_free(list);
715 g_free(genre);
716 g_free(artist);
725 static void magnatune_cat_menu_replace()
727 mpd_playlist_clear(connection);
728 magnatune_cat_menu_add();
729 mpd_player_play(connection);
733 static int magnatune_cat_menu_popup(GtkWidget *menu, int type, GtkWidget *tree, GdkEventButton *event)
735 GtkWidget *item;
736 if(type != plugin.id) return 0;
737 else if (!downloading)
739 /* add the clear widget */
740 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REFRESH,NULL);
741 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
742 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_redownload_reload_db), NULL);
743 return 1;
745 return 0;
748 static void magnatune_add_selected(GtkWidget *button, GtkTreeView *tree)
750 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
751 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
752 GList *list = gtk_tree_selection_get_selected_rows(sel,&model);
753 if(list)
755 GList *node ;
756 for(node = list; node; node = g_list_next(node))
758 GtkTreeIter iter;
759 if(gtk_tree_model_get_iter(model, &iter, node->data))
761 gchar *path;
762 gtk_tree_model_get(model, &iter, MPDDATA_MODEL_COL_PATH, &path, -1);
763 mpd_playlist_queue_add(connection, path);
764 g_free(path);
767 mpd_playlist_queue_commit(connection);
768 g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
769 g_list_free (list);
772 static void magnatune_replace_selected(GtkWidget *button , GtkTreeView *tree)
774 mpd_playlist_clear(connection);
775 magnatune_add_selected(button, tree);
776 mpd_player_play(connection);
780 static void magnatune_list_edit_columns(GtkMenuItem *item, GtkWidget *widget)
782 gmpc_mpddata_treeview_edit_columns(GMPC_MPDDATA_TREEVIEW(widget));
784 static int magnatune_button_handle_release_event_tag_add(GtkWidget *button, gpointer userdata)
786 GList *list;
787 MpdData *data;
788 int position = GPOINTER_TO_INT(userdata);
789 gchar *genre=NULL, *artist=NULL, *album=NULL;
790 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
791 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
792 GtkTreeIter piter;
793 if(gtk_tree_selection_get_selected(select, &model, &piter))
795 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
797 if(position >= 1)
799 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
800 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
801 if(gtk_tree_selection_get_selected(select, &model, &piter))
803 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
806 if(position >= 2)
808 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]));
809 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]));
810 if(gtk_tree_selection_get_selected(select, &model, &piter))
812 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&album,-1);
815 list = magnatune_db_get_url_list(genre, artist, album);
816 for(;list; list = list->next)
818 mpd_playlist_queue_add(connection, list->data);
820 mpd_playlist_queue_commit(connection);
821 if(list)
823 g_list_foreach(list, g_free, NULL);
824 g_list_free(list);
826 if(genre)
827 g_free(genre);
828 if(artist)
829 g_free(artist);
830 if(album)
831 g_free(album);
835 static int magnatune_button_handle_release_event_tag_replace(GtkWidget *button, gpointer userdata)
837 mpd_playlist_clear(connection);
838 magnatune_button_handle_release_event_tag_add(button,userdata);
839 mpd_player_play(connection);
843 static int magnatune_button_handle_release_event_tag(GtkWidget *tree, GdkEventButton *event,gpointer data)
845 int i;
846 int position = GPOINTER_TO_INT(data);
847 if(event->button != 3) return FALSE;
848 GtkWidget *item;
850 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
851 if(gtk_tree_selection_count_selected_rows(sel)> 0)
853 GtkWidget *menu = gtk_menu_new();
856 /* Add */
857 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL);
858 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
859 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_add), data);
860 /* Replace */
861 item = gtk_image_menu_item_new_with_label("Replace");
862 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
863 gtk_image_new_from_stock(GTK_STOCK_REDO, GTK_ICON_SIZE_MENU));
864 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
865 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_replace), data);
866 gtk_widget_show_all(menu);
867 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,NULL, NULL, event->button, event->time);
868 return TRUE;
870 return FALSE;
873 static int magnatune_button_release_event(GtkWidget *tree, GdkEventButton *event,gpointer data)
875 if(event->button != 3) return FALSE;
876 GtkWidget *item;
878 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
880 if(gtk_tree_selection_count_selected_rows(sel)> 0)
882 GtkWidget *menu = gtk_menu_new();
883 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
884 /* Add */
885 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL);
886 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
887 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_add_selected), tree);
888 /* Replace */
889 item = gtk_image_menu_item_new_with_label("Replace");
890 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
891 gtk_image_new_from_stock(GTK_STOCK_REDO, GTK_ICON_SIZE_MENU));
892 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
894 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_replace_selected), tree);
896 /* Separator */
897 item = gtk_separator_menu_item_new();
898 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
899 /* Edit columns */
900 item = gtk_image_menu_item_new_with_label(("Edit Columns"));
901 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
902 gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU));
903 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
904 g_signal_connect(G_OBJECT(item), "activate",
905 G_CALLBACK(magnatune_list_edit_columns), tree);
907 gtk_widget_show_all(menu);
909 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,NULL, NULL, event->button, event->time);
910 return TRUE;
912 return FALSE;
915 static void magnatune_cat_key_press(GtkWidget *tree, GdkEventKey *event, int selected_type)
917 if(selected_type != plugin.id) return;
918 if(event->state&GDK_CONTROL_MASK && event->keyval == GDK_Insert)
920 magnatune_cat_menu_replace();
922 else if(event->keyval == GDK_Insert)
924 magnatune_cat_menu_add();
929 static int magnatune_key_press(GtkWidget *tree, GdkEventKey *event)
931 if(event->state&GDK_CONTROL_MASK && event->keyval == GDK_Insert)
933 magnatune_replace_selected(NULL, GTK_TREE_VIEW(tree));
935 else if(event->keyval == GDK_Insert)
937 magnatune_add_selected(NULL, GTK_TREE_VIEW(tree));
939 else if (event->keyval == GDK_f && event->state&GDK_CONTROL_MASK)
941 treesearch_start(mt_tree_search);
942 return TRUE;
944 else if((event->state&(GDK_CONTROL_MASK|GDK_MOD1_MASK)) == 0 &&
945 ((event->keyval >= GDK_space && event->keyval <= GDK_z)))
947 char data[2];
948 data[0] = (char)gdk_keyval_to_unicode(event->keyval);
949 data[1] = '\0';
950 treesearch_start(TREESEARCH(mt_tree_search));
951 gtk_entry_set_text(GTK_ENTRY(TREESEARCH(mt_tree_search)->entry),data);
952 gtk_editable_set_position(GTK_EDITABLE(TREESEARCH(mt_tree_search)->entry),1);
953 return TRUE;
955 return FALSE;
957 static void magnatune_save_myself(void)
959 if(magnatune_vbox)
961 int position = gtk_paned_get_position(GTK_PANED(magnatune_vbox));
962 cfg_set_single_value_as_int(config, "magnatune", "pane-pos", position);
964 if (magnatune_ref)
966 GtkTreePath *path = gtk_tree_row_reference_get_path(magnatune_ref);
967 if(path)
969 gint *indices = gtk_tree_path_get_indices(path);
970 debug_printf(DEBUG_INFO,"Saving myself to position: %i\n", indices[0]);
971 cfg_set_single_value_as_int(config, "magnatune","position",indices[0]);
972 gtk_tree_path_free(path);
977 static void magnatune_destroy(void)
979 magnatune_db_destroy();
980 if(magnatune_vbox)
981 gtk_widget_destroy(magnatune_vbox);
984 gmpcMetaDataPlugin magnatune_cover = {
985 .get_priority = magnatune_fetch_cover_priority,
986 .set_priority = magnatune_fetch_cover_priority_set,
987 .get_image = magnatune_fetch_get_image
991 /* Needed plugin_wp stuff */
992 gmpcPlBrowserPlugin magnatune_gbp = {
993 .add = magnatune_add,
994 .selected = magnatune_selected,
995 .unselected = magnatune_unselected,
996 .cat_right_mouse_menu = magnatune_cat_menu_popup,
997 .cat_key_press = magnatune_cat_key_press
1000 int plugin_api_version = PLUGIN_API_VERSION;
1002 gmpcPlugin plugin = {
1003 .name = "Magnatune Stream Browser",
1004 .version = {PLUGIN_MAJOR_VERSION,PLUGIN_MINOR_VERSION,PLUGIN_MICRO_VERSION},
1005 .plugin_type = GMPC_PLUGIN_PL_BROWSER|GMPC_PLUGIN_META_DATA,
1006 /* Creation and destruction */
1007 .init = magnatune_logo_init,
1008 .destroy = magnatune_destroy,
1009 .save_yourself = magnatune_save_myself,
1010 .mpd_status_changed = magnatune_mpd_status_changed,
1012 /* Browser extention */
1013 .browser = &magnatune_gbp,
1014 .metadata = &magnatune_cover,
1016 /* get/set enabled */
1017 .get_enabled = magnatune_get_enabled,
1018 .set_enabled = magnatune_set_enabled