hmmm first move of a plugin
[gmpc-magnatune.git] / src / plugin.c
blobc2b003e0b45728d4fbe39defe8fbb6e780fb671a
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;
40 /**
41 * Get set enabled
43 static int magnatune_get_enabled()
45 return cfg_get_single_value_as_int_with_default(config, "magnatune", "enable", TRUE);
47 static void magnatune_set_enabled(int enabled)
49 cfg_set_single_value_as_int(config, "magnatune", "enable", enabled);
50 if (enabled)
52 if(magnatune_ref == NULL)
54 magnatune_add(GTK_WIDGET(playlist3_get_category_tree_view()));
57 else if (magnatune_ref)
59 GtkTreePath *path = gtk_tree_row_reference_get_path(magnatune_ref);
60 if (path){
61 GtkTreeIter iter;
62 magnatune_save_myself();
63 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter, path)){
64 gtk_tree_store_remove(playlist3_get_category_tree_store(), &iter);
66 gtk_tree_path_free(path);
67 gtk_tree_row_reference_free(magnatune_ref);
68 magnatune_ref = NULL;
71 pl3_update_go_menu();
78 /* Playlist window row reference */
80 GtkWidget *magnatune_pb = NULL;
81 GtkWidget *magnatune_vbox = NULL;
82 GtkTreeModel *mt_store = NULL;
83 TreeSearch *mt_tree_search = NULL;
85 GtkWidget *treeviews[3] = {NULL, NULL,NULL};
87 static GtkWidget *magnatune_logo=NULL;
88 extern GladeXML *pl3_xml;
90 static void magnatune_buy_album()
92 gchar *uri = "http://www.magnatune.com/";
93 gchar *path = g_strdup_printf("%s%c%s '%s'",DATA_DIR,G_DIR_SEPARATOR,"xdg-open",uri);
94 g_spawn_command_line_async(path, NULL);
95 g_free(path);
98 static void magnatune_logo_add()
100 mpd_Song *song = mpd_playlist_get_current_song(connection);
101 GtkWidget *logo, *button;
102 GtkWidget *ali;
104 magnatune_logo = gtk_hbox_new(FALSE,6);
106 button = gtk_button_new_with_label("Buy this album\nfrom magnatune");
107 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
109 ali = gtk_alignment_new(0,0.5,0,1);
110 gtk_container_add(GTK_CONTAINER(ali), button);
111 logo = gtk_image_new_from_icon_name("magnatune", GTK_ICON_SIZE_DND);
112 gtk_button_set_image(GTK_BUTTON(button), logo);
113 gtk_box_pack_start(GTK_BOX(magnatune_logo), ali, TRUE, TRUE,0);
114 gtk_box_pack_end(GTK_BOX(glade_xml_get_widget(pl3_xml, "vbox5")), magnatune_logo, FALSE,FALSE,0);
115 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(magnatune_buy_album), NULL);
116 if(song) {
117 if(strstr(song->file,"magnatune.com"))
119 gtk_widget_show_all(magnatune_logo);
120 return;
127 static void magnatune_logo_init()
129 gchar *path = NULL;
131 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default (),DATA_DIR);
133 gtk_init_add((GtkFunction )magnatune_logo_add, NULL);
134 /**
135 * init the magnatune stuff
137 magnatune_db_init();
139 * open the db
141 magnatune_db_open();
145 static void magnatune_mpd_status_changed(MpdObj *mi, ChangedStatusType what, void *data)
147 if(!magnatune_logo)
148 return;
149 if(what&(MPD_CST_SONGID|MPD_CST_STATE))
151 mpd_Song *song = mpd_playlist_get_current_song(mi);
152 if(song) {
153 if(strstr(song->file,"magnatune.com"))
155 gtk_widget_show_all(magnatune_logo);
156 return;
159 gtk_widget_hide(magnatune_logo);
163 static void magnatune_get_genre_list()
165 MpdData *data = NULL;
166 data = magnatune_db_get_genre_list();
167 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]))),data);
170 static void magnatune_show_album_list(GtkTreeSelection *selection, gpointer user_data)
172 MpdData *data = NULL;
173 GtkTreeIter piter;
174 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
175 if(gtk_tree_selection_get_selected(selection, &model, &piter))
177 gchar *genre;
178 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
179 data= magnatune_db_get_artist_list(genre);
181 g_free(genre);
183 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]))),data);
186 static void magnatune_show_song_list(GtkTreeSelection *selection, gpointer user_data)
188 MpdData *data = NULL;
189 GtkTreeIter piter;
190 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
191 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
192 gchar *genre = NULL, *artist = NULL, *album = NULL;
193 if(gtk_tree_selection_get_selected(select, &model, &piter))
196 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
197 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
198 /* model */
199 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
200 if(gtk_tree_selection_get_selected(select, &model, &piter))
202 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
203 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]));
204 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]));
205 if(gtk_tree_selection_get_selected(select, &model, &piter))
207 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&album,-1);
211 data = magnatune_db_get_song_list(genre, artist, album);
212 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(mt_store), data);
215 static void magnatune_show_artist_list(GtkTreeSelection *selection, gpointer user_data)
217 GtkTreeIter piter;
218 MpdData *data = NULL;
219 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
220 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
222 if(gtk_tree_selection_get_selected(select, &model, &piter))
224 GList *iter,*list = NULL;
225 gchar *genre;
227 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
228 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
229 /* model */
230 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
231 if(gtk_tree_selection_get_selected(select, &model, &piter))
233 GList *iter,*list = NULL;
235 gchar *artist;
236 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
237 data = magnatune_db_get_album_list(genre ,artist);
238 gmpc_mpddata_model_set_request_artist(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]))),artist);
239 g_free(artist);
241 g_free(genre);
243 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]))),data);
246 static void magnatune_add_album_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
248 GtkTreeModel *model = gtk_tree_view_get_model(tree);
249 GtkTreeIter iter_r;
251 if(gtk_tree_model_get_iter(model, &iter_r, path))
253 gchar *path;
254 gtk_tree_model_get(model, &iter_r, MPDDATA_MODEL_COL_PATH, &path, -1);
255 play_path(path);
256 g_free(path);
260 static gboolean magnatune_search_equal_func(GtkTreeModel *model, int column, const gchar *key, GtkTreeIter *iter, gpointer data)
262 gchar *compare = NULL;
263 gtk_tree_model_get(model,iter, column, &compare, -1);
264 if(compare){
265 gchar *a = g_utf8_casefold(key, -1);
266 gchar *b = g_utf8_casefold(compare, -1);
267 if(strstr(b,a))
269 g_free(a);
270 g_free(b);
271 return FALSE;
273 g_free(a);
274 g_free(b);
276 return TRUE;
279 static void magnatune_search_activate(TreeSearch *ts)
281 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
282 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ts->treeview));
283 if (gtk_tree_selection_count_selected_rows (selection) == 1)
285 GList *list = gtk_tree_selection_get_selected_rows (selection, &model);
286 magnatune_add_album_row_activated(GTK_TREE_VIEW(ts->treeview),(GtkTreePath *)list->data, NULL,NULL);
287 /* free list */
288 g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
289 g_list_free (list);
293 static void magnatune_init()
295 int size;
296 GtkWidget *tree = NULL;
297 GtkWidget *sw = NULL;
298 GtkCellRenderer *renderer = NULL;
299 GtkWidget *paned = NULL;
300 GtkWidget *hbox = NULL;
301 GtkWidget *vbox = NULL;
302 GtkTreeModel *model = NULL;
303 GtkTreeViewColumn *column = NULL;
304 int position = cfg_get_single_value_as_int_with_default(config, "magnatune", "pane-pos", 150);
305 magnatune_vbox = gtk_vpaned_new();
306 gtk_paned_set_position(GTK_PANED(magnatune_vbox), position);
309 vbox = gtk_vbox_new(FALSE,6);
311 * Create list store
312 * 1. pointer
313 * 2. name
315 mt_store = (GtkTreeModel *)gmpc_mpddata_model_new();
317 /* Paned window */
318 paned = gtk_hbox_new(TRUE,6);
319 model = (GtkTreeModel *) gmpc_mpddata_model_new();
320 /* Genre list */
321 sw = gtk_scrolled_window_new(NULL, NULL);
322 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
323 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
324 treeviews[0] = gtk_tree_view_new_with_model(model);
325 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[0]), MPDDATA_MODEL_COL_SONG_TITLE);
326 g_signal_connect(G_OBJECT(treeviews[0]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(0));
327 /* Add column */
328 column = gtk_tree_view_column_new();
329 gtk_tree_view_column_set_title(column, "Genre");
332 renderer = gtk_cell_renderer_pixbuf_new();
333 gtk_tree_view_column_pack_start(column, renderer, FALSE);
334 gtk_tree_view_column_add_attribute(column, renderer, "icon-name", MPDDATA_MODEL_COL_ICON_ID);
335 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_AUTOSIZE);
336 renderer = gtk_cell_renderer_text_new();
337 gtk_tree_view_column_pack_start(column, renderer, TRUE);
338 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
339 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[0]),column, -1);
341 gtk_container_add(GTK_CONTAINER(sw), treeviews[0]);
342 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
344 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]))), "changed", G_CALLBACK(magnatune_show_album_list), NULL);
346 /* Artist list */
347 model = (GtkTreeModel *) gmpc_mpddata_model_new();
348 sw = gtk_scrolled_window_new(NULL, NULL);
349 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
350 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
351 treeviews[1] = gtk_tree_view_new_with_model(model);
353 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[1]), MPDDATA_MODEL_COL_SONG_TITLE);
354 g_signal_connect(G_OBJECT(treeviews[1]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(1));
355 /* Add column */
356 column = gtk_tree_view_column_new();
357 gtk_tree_view_column_set_title(column, "Artist");
358 size = cfg_get_single_value_as_int_with_default(config, "gmpc-mpddata-model", "icon-size", 64);
359 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_FIXED);
360 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews[1]), TRUE);
363 renderer = gtk_cell_renderer_pixbuf_new();
364 gtk_cell_renderer_set_fixed_size(renderer, size,size);
366 gtk_tree_view_column_pack_start(column, renderer, FALSE);
367 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", MPDDATA_MODEL_META_DATA);
368 renderer = gtk_cell_renderer_text_new();
369 gtk_tree_view_column_pack_start(column, renderer, TRUE);
370 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
371 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[1]),column, -1);
373 gtk_container_add(GTK_CONTAINER(sw), treeviews[1]);
374 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
376 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]))), "changed", G_CALLBACK(magnatune_show_artist_list), NULL);
378 /* Album list */
379 model = (GtkTreeModel *) gmpc_mpddata_model_new();
380 sw = gtk_scrolled_window_new(NULL, NULL);
381 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
382 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
383 treeviews[2] = gtk_tree_view_new_with_model(model);
384 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[2]), MPDDATA_MODEL_COL_SONG_TITLE);
386 g_signal_connect(G_OBJECT(treeviews[2]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(2));
387 /* Add column */
388 column = gtk_tree_view_column_new();
389 gtk_tree_view_column_set_title(column, "Album");
390 size = cfg_get_single_value_as_int_with_default(config, "gmpc-mpddata-model", "icon-size", 64);
391 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_FIXED);
392 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews[2]), TRUE);
395 renderer = gtk_cell_renderer_pixbuf_new();
396 gtk_cell_renderer_set_fixed_size(renderer, size,size);
398 gtk_tree_view_column_pack_start(column, renderer, FALSE);
399 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", MPDDATA_MODEL_META_DATA);
400 renderer = gtk_cell_renderer_text_new();
401 gtk_tree_view_column_pack_start(column, renderer, TRUE);
402 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
403 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[2]),column, -1);
405 gtk_container_add(GTK_CONTAINER(sw), treeviews[2]);
406 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
409 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
410 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
411 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
413 gtk_paned_add1(GTK_PANED(magnatune_vbox), paned);
414 gtk_widget_show_all(paned);
416 * tree
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);
423 tree = (GtkWidget *)gmpc_mpddata_treeview_new("magnatune",TRUE,GTK_TREE_MODEL(mt_store));
424 g_signal_connect(G_OBJECT(tree), "row-activated", G_CALLBACK(magnatune_add_album_row_activated), NULL);
426 g_signal_connect(G_OBJECT(tree), "button-press-event", G_CALLBACK(magnatune_button_release_event), tree);
427 g_signal_connect(G_OBJECT(tree), "key-press-event", G_CALLBACK(magnatune_key_press), NULL);
429 gtk_container_add(GTK_CONTAINER(sw), tree);
430 gtk_box_pack_start(GTK_BOX(vbox),sw, TRUE, TRUE,0);
432 mt_tree_search = (TreeSearch *)treesearch_new(GTK_TREE_VIEW(tree), MPDDATA_MODEL_COL_SONG_TITLE);
433 gtk_box_pack_end(GTK_BOX(vbox), GTK_WIDGET(mt_tree_search), FALSE, TRUE, 0);
434 g_signal_connect(G_OBJECT(mt_tree_search), "result-activate", G_CALLBACK(magnatune_search_activate),NULL);
437 gtk_widget_show_all(sw);
438 gtk_widget_show(vbox);
440 * Progress Bar for the bottom
442 magnatune_pb = gtk_progress_bar_new();
443 gtk_box_pack_end(GTK_BOX(vbox), magnatune_pb, FALSE, TRUE, 0);
444 gtk_paned_add2(GTK_PANED(magnatune_vbox), vbox);
447 g_object_ref(magnatune_vbox);
451 static void magnatune_selected(GtkWidget *container)
453 if(magnatune_vbox == NULL)
455 magnatune_init();
456 gtk_container_add(GTK_CONTAINER(container), magnatune_vbox);
457 gtk_widget_show(magnatune_vbox);
458 if(!magnatune_db_has_data())
460 magnatune_download();
462 magnatune_get_genre_list();
463 } else {
464 gtk_container_add(GTK_CONTAINER(container), magnatune_vbox);
465 gtk_widget_show(magnatune_vbox);
468 static void magnatune_unselected(GtkWidget *container)
470 gtk_container_remove(GTK_CONTAINER(container), magnatune_vbox);
473 static void magnatune_download_xml_callback(int download, int total,gpointer data)
475 GtkWidget *pb = data;
476 gchar *label = NULL;
477 if(total > 0)
478 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb), download/(float)total);
479 else
480 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pb));
481 if(download >> 20)
483 label = g_strdup_printf("%.2f mb",(download>>10)/1024.0);
485 else if (download>>10)
487 label = g_strdup_printf("%i kb",download>>10);
489 else
491 label = g_strdup_printf("%i b",download);
493 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pb), label);
494 g_free(label);
495 while(gtk_events_pending())
496 gtk_main_iteration();
499 static void magnatune_download()
501 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), FALSE);
502 gtk_widget_show(magnatune_pb);
503 magnatune_db_download_xml(magnatune_download_xml_callback, magnatune_pb);
504 gtk_widget_hide(magnatune_pb);
505 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), TRUE);
508 static void magnatune_add(GtkWidget *cat_tree)
510 GtkTreePath *path = NULL;
511 GtkTreeIter iter,child;
512 GtkTreeStore *pl3_tree = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(cat_tree));
513 gint pos = cfg_get_single_value_as_int_with_default(config, "magnatune","position",20);
515 if(!cfg_get_single_value_as_int_with_default(config, "magnatune", "enable", TRUE)) return;
517 debug_printf(DEBUG_INFO,"Adding at position: %i", pos);
518 playlist3_insert_browser(&iter, pos);
519 /*gtk_tree_store_append(pl3_tree, &iter, NULL);*/
520 gtk_tree_store_set(pl3_tree, &iter,
521 PL3_CAT_TYPE, plugin.id,
522 PL3_CAT_TITLE, "Magnatune Browser",
523 PL3_CAT_INT_ID, "",
524 PL3_CAT_ICON_ID, "magnatune",
525 PL3_CAT_PROC, TRUE,
526 PL3_CAT_ICON_SIZE,GTK_ICON_SIZE_DND,-1);
528 * Clean up old row reference if it exists
530 if (magnatune_ref)
532 gtk_tree_row_reference_free(magnatune_ref);
533 magnatune_ref = NULL;
536 * create row reference
538 path = gtk_tree_model_get_path(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter);
539 if (path)
541 magnatune_ref = gtk_tree_row_reference_new(GTK_TREE_MODEL(playlist3_get_category_tree_store()), path);
542 gtk_tree_path_free(path);
546 static char * __magnatune_process_string(char *name)
548 int i = 0;
549 int j = 0;
550 int depth = 0;
551 int spaces = 0;
553 /* only gonna be smaller */
554 char *result = g_malloc0((strlen(name)+1+spaces*2)*sizeof(char));
555 for(i=0; i < strlen(name);i++)
557 if(name[i] == '(' || name[i] == '[') depth++;
558 else if (name[i] == ')' || name[i] == ']') depth--;
559 else if(!depth)
561 result[j] = name[i];
562 j++;
565 for(i=j-1;i>0 && result[i] == ' ';i--)
567 result[i] = '\0';
569 return result;
572 /*** COVER STUFF */
573 static int magnatune_fetch_cover_priority(void){
574 return cfg_get_single_value_as_int_with_default(config, "magnatune", "priority", 80);
576 static int magnatune_fetch_get_image(mpd_Song *song,MetaDataType type, char **path)
578 int result = 0;
579 if(magnatune_db_has_data() == FALSE)
580 return META_DATA_UNAVAILABLE;
581 if(type == META_ARTIST_ART && song->artist)
583 char *artist = __magnatune_process_string(song->artist);
584 char *value = magnatune_db_get_value(artist,NULL,META_ARTIST_ART);
585 if(value)
587 gchar *filename = NULL;
588 gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL};
589 filename = g_strdup_printf("%s.jpg", artist);
590 *path = gmpc_get_covers_path(filename);
591 g_free(filename);
592 if(gmpc_easy_download(value, &dld))
594 g_file_set_contents(*path, dld.data, dld.size, NULL);
595 return META_DATA_AVAILABLE;
597 gmpc_easy_download_clean(&dld);
598 g_free(*path);
599 *path = NULL;
601 g_free(artist);
603 else if(type == META_ALBUM_ART && song->artist && song->album)
605 char *artist = __magnatune_process_string(song->artist);
606 char *album= __magnatune_process_string(song->album);
607 char *value = magnatune_db_get_value(artist,album,META_ALBUM_ART);
608 if(value)
610 gchar *filename;
611 gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL};
612 filename = g_strdup_printf("%s-%s.jpg", artist,album);
613 *path = gmpc_get_covers_path(filename);
614 g_free(filename);
615 if(gmpc_easy_download(value, &dld))
617 g_file_set_contents(*path, dld.data, dld.size, NULL);
618 return META_DATA_AVAILABLE;
620 gmpc_easy_download_clean(&dld);
621 g_free(*path);
622 *path = NULL;
624 g_free(artist);
626 return META_DATA_UNAVAILABLE;
628 static void magnatune_redownload_reload_db()
630 GtkTreeIter iter;
631 GtkTreeModel *model = gtk_tree_row_reference_get_model(magnatune_ref);
632 GtkTreePath *path = gtk_tree_row_reference_get_path(magnatune_ref);
633 if(path && gtk_tree_model_get_iter(model, &iter, path))
635 GtkTreeIter citer;
636 while(gtk_tree_model_iter_children(model, &citer,&iter))
638 gtk_tree_store_remove(GTK_TREE_STORE(model), &citer);
640 magnatune_download();
641 magnatune_get_genre_list();
643 if(path)
644 gtk_tree_path_free(path);
647 static void magnatune_cat_menu_add()
649 GtkTreeIter citer;
650 GtkTreeSelection *sel = gtk_tree_view_get_selection(playlist3_get_category_tree_view());
651 GtkTreeModel *model = (GtkTreeModel *)playlist3_get_category_tree_store();
652 GtkTreePath *tpath;
653 int depth = 0;
654 if(!gtk_tree_selection_get_selected(sel,&model,&citer))
656 return ;
659 * Get the level we are on.
661 tpath = gtk_tree_model_get_path(model, &citer);
662 depth = gtk_tree_path_get_depth(tpath);
663 gtk_tree_path_free(tpath);
664 /** Genre level */
665 if(depth == 2)
667 GList *list, *node;
668 gchar *genre;
669 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&genre, -1);
670 if(genre)
672 list = magnatune_db_get_url_list(genre, NULL ,NULL);
673 for(node = list; node; node = node->next)
675 mpd_playlist_queue_add(connection, node->data);
677 mpd_playlist_queue_commit(connection);
678 g_list_foreach(list, (GFunc)g_free, NULL);
679 g_list_free(list);
680 g_free(genre);
683 /** Artist */
684 else if(depth == 3)
686 gchar *artist;
687 gchar *genre;
688 GtkTreeIter iter;
689 if(gtk_tree_model_iter_parent(model, &iter, &citer))
691 GList *list, *node;
692 gtk_tree_model_get(model, &iter, PL3_CAT_INT_ID,&genre, -1);
693 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&artist, -1);
694 list = magnatune_db_get_url_list(genre, artist,NULL);
695 for(node = list; node; node = node->next)
697 mpd_playlist_queue_add(connection, node->data);
699 mpd_playlist_queue_commit(connection);
700 g_list_foreach(list, (GFunc)g_free, NULL);
701 g_list_free(list);
702 g_free(genre);
703 g_free(artist);
712 static void magnatune_cat_menu_replace()
714 mpd_playlist_clear(connection);
715 magnatune_cat_menu_add();
716 mpd_player_play(connection);
720 static int magnatune_cat_menu_popup(GtkWidget *menu, int type, GtkWidget *tree, GdkEventButton *event)
722 GtkWidget *item;
723 if(type != plugin.id) return 0;
724 else
726 /* add the clear widget */
727 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REFRESH,NULL);
728 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
729 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_redownload_reload_db), NULL);
730 return 1;
732 return 0;
735 static void magnatune_add_selected(GtkWidget *button, GtkTreeView *tree)
737 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
738 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
739 GList *list = gtk_tree_selection_get_selected_rows(sel,&model);
740 if(list)
742 GList *node ;
743 for(node = list; node; node = g_list_next(node))
745 GtkTreeIter iter;
746 if(gtk_tree_model_get_iter(model, &iter, node->data))
748 gchar *path;
749 gtk_tree_model_get(model, &iter, MPDDATA_MODEL_COL_PATH, &path, -1);
750 mpd_playlist_queue_add(connection, path);
751 g_free(path);
754 mpd_playlist_queue_commit(connection);
755 g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
756 g_list_free (list);
759 static void magnatune_replace_selected(GtkWidget *button , GtkTreeView *tree)
761 mpd_playlist_clear(connection);
762 magnatune_add_selected(button, tree);
763 mpd_player_play(connection);
767 static void magnatune_list_edit_columns(GtkMenuItem *item, GtkWidget *widget)
769 gmpc_mpddata_treeview_edit_columns(GMPC_MPDDATA_TREEVIEW(widget));
771 static int magnatune_button_handle_release_event_tag_add(GtkWidget *button, gpointer userdata)
773 GList *list;
774 MpdData *data;
775 int position = GPOINTER_TO_INT(userdata);
776 gchar *genre=NULL, *artist=NULL, *album=NULL;
777 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
778 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
779 GtkTreeIter piter;
780 if(gtk_tree_selection_get_selected(select, &model, &piter))
782 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
784 if(position >= 1)
786 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
787 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
788 if(gtk_tree_selection_get_selected(select, &model, &piter))
790 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
793 if(position >= 2)
795 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]));
796 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]));
797 if(gtk_tree_selection_get_selected(select, &model, &piter))
799 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&album,-1);
802 list = magnatune_db_get_url_list(genre, artist, album);
803 for(;list; list = list->next)
805 mpd_playlist_queue_add(connection, list->data);
807 mpd_playlist_queue_commit(connection);
808 if(list)
810 g_list_foreach(list, g_free, NULL);
811 g_list_free(list);
813 if(genre)
814 g_free(genre);
815 if(artist)
816 g_free(artist);
817 if(album)
818 g_free(album);
822 static int magnatune_button_handle_release_event_tag_replace(GtkWidget *button, gpointer userdata)
824 mpd_playlist_clear(connection);
825 magnatune_button_handle_release_event_tag_add(button,userdata);
826 mpd_player_play(connection);
830 static int magnatune_button_handle_release_event_tag(GtkWidget *tree, GdkEventButton *event,gpointer data)
832 int i;
833 int position = GPOINTER_TO_INT(data);
834 if(event->button != 3) return FALSE;
835 GtkWidget *item;
837 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
838 if(gtk_tree_selection_count_selected_rows(sel)> 0)
840 GtkWidget *menu = gtk_menu_new();
843 /* Add */
844 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL);
845 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
846 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_add), data);
847 /* Replace */
848 item = gtk_image_menu_item_new_with_label("Replace");
849 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
850 gtk_image_new_from_stock(GTK_STOCK_REDO, GTK_ICON_SIZE_MENU));
851 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
852 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_replace), data);
853 gtk_widget_show_all(menu);
854 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,NULL, NULL, event->button, event->time);
855 return TRUE;
857 return FALSE;
860 static int magnatune_button_release_event(GtkWidget *tree, GdkEventButton *event,gpointer data)
862 if(event->button != 3) return FALSE;
863 GtkWidget *item;
865 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
867 if(gtk_tree_selection_count_selected_rows(sel)> 0)
869 GtkWidget *menu = gtk_menu_new();
870 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
871 /* Add */
872 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL);
873 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
874 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_add_selected), tree);
875 /* Replace */
876 item = gtk_image_menu_item_new_with_label("Replace");
877 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
878 gtk_image_new_from_stock(GTK_STOCK_REDO, GTK_ICON_SIZE_MENU));
879 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
881 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_replace_selected), tree);
883 /* Separator */
884 item = gtk_separator_menu_item_new();
885 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
886 /* Edit columns */
887 item = gtk_image_menu_item_new_with_label(("Edit Columns"));
888 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
889 gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU));
890 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
891 g_signal_connect(G_OBJECT(item), "activate",
892 G_CALLBACK(magnatune_list_edit_columns), tree);
894 gtk_widget_show_all(menu);
896 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,NULL, NULL, event->button, event->time);
897 return TRUE;
899 return FALSE;
902 static void magnatune_cat_key_press(GtkWidget *tree, GdkEventKey *event, int selected_type)
904 if(selected_type != plugin.id) return;
905 if(event->state&GDK_CONTROL_MASK && event->keyval == GDK_Insert)
907 magnatune_cat_menu_replace();
909 else if(event->keyval == GDK_Insert)
911 magnatune_cat_menu_add();
916 static int magnatune_key_press(GtkWidget *tree, GdkEventKey *event)
918 if(event->state&GDK_CONTROL_MASK && event->keyval == GDK_Insert)
920 magnatune_replace_selected(NULL, GTK_TREE_VIEW(tree));
922 else if(event->keyval == GDK_Insert)
924 magnatune_add_selected(NULL, GTK_TREE_VIEW(tree));
926 else if (event->keyval == GDK_f && event->state&GDK_CONTROL_MASK)
928 treesearch_start(mt_tree_search);
929 return TRUE;
931 else if((event->state&(GDK_CONTROL_MASK|GDK_MOD1_MASK)) == 0 &&
932 ((event->keyval >= GDK_space && event->keyval <= GDK_z)))
934 char data[2];
935 data[0] = (char)gdk_keyval_to_unicode(event->keyval);
936 data[1] = '\0';
937 treesearch_start(TREESEARCH(mt_tree_search));
938 gtk_entry_set_text(GTK_ENTRY(TREESEARCH(mt_tree_search)->entry),data);
939 gtk_editable_set_position(GTK_EDITABLE(TREESEARCH(mt_tree_search)->entry),1);
940 return TRUE;
942 return FALSE;
944 static void magnatune_save_myself(void)
946 if(magnatune_vbox)
948 int position = gtk_paned_get_position(GTK_PANED(magnatune_vbox));
949 cfg_set_single_value_as_int(config, "magnatune", "pane-pos", position);
951 if (magnatune_ref)
953 GtkTreePath *path = gtk_tree_row_reference_get_path(magnatune_ref);
954 if(path)
956 gint *indices = gtk_tree_path_get_indices(path);
957 debug_printf(DEBUG_INFO,"Saving myself to position: %i\n", indices[0]);
958 cfg_set_single_value_as_int(config, "magnatune","position",indices[0]);
959 gtk_tree_path_free(path);
964 static void magnatune_destroy(void)
966 magnatune_db_destroy();
967 if(magnatune_vbox)
968 gtk_widget_destroy(magnatune_vbox);
971 gmpcMetaDataPlugin magnatune_cover = {
972 magnatune_fetch_cover_priority,
973 magnatune_fetch_get_image
977 /* Needed plugin_wp stuff */
978 gmpcPlBrowserPlugin magnatune_gbp = {
979 .add = magnatune_add,
980 .selected = magnatune_selected,
981 .unselected = magnatune_unselected,
982 .cat_right_mouse_menu = magnatune_cat_menu_popup,
983 .cat_key_press = magnatune_cat_key_press
986 int plugin_api_version = PLUGIN_API_VERSION;
988 gmpcPlugin plugin = {
989 .name = "Magnatune Stream Browser",
990 .version = {PLUGIN_MAJOR_VERSION,PLUGIN_MINOR_VERSION,PLUGIN_MICRO_VERSION},
991 .plugin_type = GMPC_PLUGIN_PL_BROWSER|GMPC_PLUGIN_META_DATA,
992 /* Creation and destruction */
993 .init = magnatune_logo_init,
994 .destroy = magnatune_destroy,
995 .save_yourself = magnatune_save_myself,
996 .mpd_status_changed = magnatune_mpd_status_changed,
998 /* Browser extention */
999 .browser = &magnatune_gbp,
1000 .metadata = &magnatune_cover,
1002 /* get/set enabled */
1003 .get_enabled = magnatune_get_enabled,
1004 .set_enabled = magnatune_set_enabled