Fix stupid wrong extern
[gmpc-magnatune.git] / src / plugin.c
blobcd44bda791c78b49eea304404b9435be4b5df02a
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 "magnatune.h"
13 extern GladeXML *pl3_xml;
15 gmpcPlugin plugin;
16 /**
17 * Function decleration
19 static void magnatune_selected(GtkWidget *container);
20 static void magnatune_unselected(GtkWidget *container);
21 static void magnatune_add(GtkWidget *cat_tree);
22 static void magnatune_download_xml_callback(int download, int total,gpointer data);
23 static void magnatune_download();
24 static void magnatune_mpd_status_changed(MpdObj *mi, ChangedStatusType what, void *data);
25 static int magnatune_fetch_cover_priority(void);
26 static int magnatune_fetch_get_image(mpd_Song *song,MetaDataType type, char **path);
27 static int magnatune_cat_menu_popup(GtkWidget *menu, int type, GtkWidget *tree, GdkEventButton *event);
29 static int magnatune_button_release_event(GtkWidget *tree, GdkEventButton *event,gpointer data);
30 static int magnatune_button_handle_release_event_tag(GtkWidget *tree, GdkEventButton *event,gpointer data);
32 static void magnatune_cat_key_press(GtkWidget *tree, GdkEventKey *event, int selected_type);
33 static int magnatune_key_press(GtkWidget *tree, GdkEventKey *event);
34 static void magnatune_show_album_list(GtkTreeSelection *selection, gpointer user_data);
35 static void magnatune_show_song_list(GtkTreeSelection *selection, gpointer user_data);
36 static int magnatune_button_handle_release_event_tag_add(GtkWidget *button, gpointer user_data);
38 /**
39 * Get set enabled
41 static int magnatune_get_enabled()
43 return cfg_get_single_value_as_int_with_default(config, "magnatune", "enable", TRUE);
45 static void magnatune_set_enabled(int enabled)
47 cfg_set_single_value_as_int(config, "magnatune", "enable", enabled);
54 /* Playlist window row reference */
55 static GtkTreeRowReference *magnatune_ref = NULL;
56 GtkWidget *magnatune_pb = NULL;
57 GtkWidget *magnatune_vbox = NULL;
58 GtkTreeModel *mt_store = NULL;
59 TreeSearch *mt_tree_search = NULL;
61 GtkWidget *treeviews[3] = {NULL, NULL,NULL};
63 static GtkWidget *magnatune_logo=NULL;
64 extern GladeXML *pl3_xml;
66 static void magnatune_buy_album()
68 gchar *uri = "http://www.magnatune.com/";
69 gchar *path = g_strdup_printf("%s%c%s%c%s '%s'",plugin.path,G_DIR_SEPARATOR, "magnatune",G_DIR_SEPARATOR,"xdg-open",uri);
70 g_spawn_command_line_async(path, NULL);
71 g_free(path);
74 static void magnatune_logo_add()
76 mpd_Song *song = mpd_playlist_get_current_song(connection);
77 GtkWidget *logo, *button;
78 GtkWidget *ali;
80 magnatune_logo = gtk_hbox_new(FALSE,6);
82 button = gtk_button_new_with_label("Buy this album\nfrom magnatune");
83 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
85 ali = gtk_alignment_new(0,0.5,0,1);
86 gtk_container_add(GTK_CONTAINER(ali), button);
87 logo = gtk_image_new_from_icon_name("magnatune", GTK_ICON_SIZE_DND);
88 gtk_button_set_image(GTK_BUTTON(button), logo);
89 gtk_box_pack_start(GTK_BOX(magnatune_logo), ali, TRUE, TRUE,0);
90 gtk_box_pack_end(GTK_BOX(glade_xml_get_widget(pl3_xml, "vbox5")), magnatune_logo, FALSE,FALSE,0);
91 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(magnatune_buy_album), NULL);
92 if(song) {
93 if(strstr(song->file,"magnatune.com"))
95 gtk_widget_show_all(magnatune_logo);
96 return;
103 static void magnatune_logo_init()
105 gchar *path = NULL;
107 path = g_strdup_printf("%s%c%s",plugin.path,G_DIR_SEPARATOR, "magnatune");
108 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default (),path);
109 g_free(path);
111 gtk_init_add((GtkFunction )magnatune_logo_add, NULL);
112 /**
113 * init the magnatune stuff
115 magnatune_db_init();
117 * open the db
119 magnatune_db_open();
123 static void magnatune_mpd_status_changed(MpdObj *mi, ChangedStatusType what, void *data)
125 if(!magnatune_logo)
126 return;
127 if(what&(MPD_CST_SONGID|MPD_CST_STATE))
129 mpd_Song *song = mpd_playlist_get_current_song(mi);
130 if(song) {
131 if(strstr(song->file,"magnatune.com"))
133 gtk_widget_show_all(magnatune_logo);
134 return;
137 gtk_widget_hide(magnatune_logo);
141 static void magnatune_get_genre_list()
143 MpdData *data = NULL;
144 data = magnatune_db_get_genre_list();
145 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]))),data);
148 static void magnatune_show_album_list(GtkTreeSelection *selection, gpointer user_data)
150 MpdData *data = NULL;
151 GtkTreeIter piter;
152 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
153 if(gtk_tree_selection_get_selected(selection, &model, &piter))
155 gchar *genre;
156 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
157 data= magnatune_db_get_artist_list(genre);
159 g_free(genre);
161 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]))),data);
164 static void magnatune_show_song_list(GtkTreeSelection *selection, gpointer user_data)
166 MpdData *data = NULL;
167 GtkTreeIter piter;
168 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
169 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
170 gchar *genre = NULL, *artist = NULL, *album = NULL;
171 if(gtk_tree_selection_get_selected(select, &model, &piter))
174 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
175 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
176 /* model */
177 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
178 if(gtk_tree_selection_get_selected(select, &model, &piter))
180 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
181 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]));
182 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]));
183 if(gtk_tree_selection_get_selected(select, &model, &piter))
185 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&album,-1);
189 data = magnatune_db_get_song_list(genre, artist, album);
190 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(mt_store), data);
193 static void magnatune_show_artist_list(GtkTreeSelection *selection, gpointer user_data)
195 GtkTreeIter piter;
196 MpdData *data = NULL;
197 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
198 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
200 if(gtk_tree_selection_get_selected(select, &model, &piter))
202 GList *iter,*list = NULL;
203 gchar *genre;
205 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
206 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
207 /* model */
208 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
209 if(gtk_tree_selection_get_selected(select, &model, &piter))
211 GList *iter,*list = NULL;
213 gchar *artist;
214 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
215 data = magnatune_db_get_album_list(genre ,artist);
216 gmpc_mpddata_model_set_request_artist(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]))),artist);
217 g_free(artist);
219 g_free(genre);
221 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]))),data);
224 static void magnatune_add_album_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
226 GtkTreeModel *model = gtk_tree_view_get_model(tree);
227 GtkTreeIter iter_r;
229 if(gtk_tree_model_get_iter(model, &iter_r, path))
231 gchar *path;
232 gtk_tree_model_get(model, &iter_r, MPDDATA_MODEL_COL_PATH, &path, -1);
233 play_path(path);
234 g_free(path);
238 static gboolean magnatune_search_equal_func(GtkTreeModel *model, int column, const gchar *key, GtkTreeIter *iter, gpointer data)
240 gchar *compare = NULL;
241 gtk_tree_model_get(model,iter, column, &compare, -1);
242 if(compare){
243 gchar *a = g_utf8_casefold(key, -1);
244 gchar *b = g_utf8_casefold(compare, -1);
245 if(strstr(b,a))
247 g_free(a);
248 g_free(b);
249 return FALSE;
251 g_free(a);
252 g_free(b);
254 return TRUE;
257 static void magnatune_search_activate(TreeSearch *ts)
259 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
260 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ts->treeview));
261 if (gtk_tree_selection_count_selected_rows (selection) == 1)
263 GList *list = gtk_tree_selection_get_selected_rows (selection, &model);
264 magnatune_add_album_row_activated(GTK_TREE_VIEW(ts->treeview),(GtkTreePath *)list->data, NULL,NULL);
265 /* free list */
266 g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
267 g_list_free (list);
271 static void magnatune_init()
273 int size;
274 GtkWidget *tree = NULL;
275 GtkWidget *sw = NULL;
276 GtkCellRenderer *renderer = NULL;
277 GtkWidget *paned = NULL;
278 GtkWidget *hbox = NULL;
279 GtkWidget *vbox = NULL;
280 GtkTreeModel *model = NULL;
281 GtkTreeViewColumn *column = NULL;
282 int position = cfg_get_single_value_as_int_with_default(config, "magnatune", "pane-pos", 150);
283 magnatune_vbox = gtk_vpaned_new();
284 gtk_paned_set_position(GTK_PANED(magnatune_vbox), position);
287 vbox = gtk_vbox_new(FALSE,6);
289 * Create list store
290 * 1. pointer
291 * 2. name
293 mt_store = (GtkTreeModel *)gmpc_mpddata_model_new();
295 /* Paned window */
296 paned = gtk_hbox_new(TRUE,6);
297 model = (GtkTreeModel *) gmpc_mpddata_model_new();
298 /* Genre list */
299 sw = gtk_scrolled_window_new(NULL, NULL);
300 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
301 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
302 treeviews[0] = gtk_tree_view_new_with_model(model);
303 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[0]), MPDDATA_MODEL_COL_SONG_TITLE);
304 g_signal_connect(G_OBJECT(treeviews[0]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(0));
305 /* Add column */
306 column = gtk_tree_view_column_new();
307 gtk_tree_view_column_set_title(column, "Genre");
310 renderer = gtk_cell_renderer_pixbuf_new();
311 gtk_tree_view_column_pack_start(column, renderer, FALSE);
312 gtk_tree_view_column_add_attribute(column, renderer, "icon-name", MPDDATA_MODEL_COL_ICON_ID);
313 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_AUTOSIZE);
314 renderer = gtk_cell_renderer_text_new();
315 gtk_tree_view_column_pack_start(column, renderer, TRUE);
316 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
317 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[0]),column, -1);
319 gtk_container_add(GTK_CONTAINER(sw), treeviews[0]);
320 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
322 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]))), "changed", G_CALLBACK(magnatune_show_album_list), NULL);
324 /* Artist list */
325 model = (GtkTreeModel *) gmpc_mpddata_model_new();
326 sw = gtk_scrolled_window_new(NULL, NULL);
327 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
328 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
329 treeviews[1] = gtk_tree_view_new_with_model(model);
331 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[1]), MPDDATA_MODEL_COL_SONG_TITLE);
332 g_signal_connect(G_OBJECT(treeviews[1]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(1));
333 /* Add column */
334 column = gtk_tree_view_column_new();
335 gtk_tree_view_column_set_title(column, "Artist");
336 size = cfg_get_single_value_as_int_with_default(config, "gmpc-mpddata-model", "icon-size", 64);
337 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_FIXED);
338 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews[1]), TRUE);
341 renderer = gtk_cell_renderer_pixbuf_new();
342 gtk_cell_renderer_set_fixed_size(renderer, size,size);
344 gtk_tree_view_column_pack_start(column, renderer, FALSE);
345 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", MPDDATA_MODEL_META_DATA);
346 renderer = gtk_cell_renderer_text_new();
347 gtk_tree_view_column_pack_start(column, renderer, TRUE);
348 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
349 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[1]),column, -1);
351 gtk_container_add(GTK_CONTAINER(sw), treeviews[1]);
352 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
354 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]))), "changed", G_CALLBACK(magnatune_show_artist_list), NULL);
356 /* Album list */
357 model = (GtkTreeModel *) gmpc_mpddata_model_new();
358 sw = gtk_scrolled_window_new(NULL, NULL);
359 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
360 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
361 treeviews[2] = gtk_tree_view_new_with_model(model);
362 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeviews[2]), MPDDATA_MODEL_COL_SONG_TITLE);
364 g_signal_connect(G_OBJECT(treeviews[2]), "button-press-event", G_CALLBACK(magnatune_button_handle_release_event_tag), GINT_TO_POINTER(2));
365 /* Add column */
366 column = gtk_tree_view_column_new();
367 gtk_tree_view_column_set_title(column, "Album");
368 size = cfg_get_single_value_as_int_with_default(config, "gmpc-mpddata-model", "icon-size", 64);
369 gtk_tree_view_column_set_sizing(column , GTK_TREE_VIEW_COLUMN_FIXED);
370 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(treeviews[2]), TRUE);
373 renderer = gtk_cell_renderer_pixbuf_new();
374 gtk_cell_renderer_set_fixed_size(renderer, size,size);
376 gtk_tree_view_column_pack_start(column, renderer, FALSE);
377 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", MPDDATA_MODEL_META_DATA);
378 renderer = gtk_cell_renderer_text_new();
379 gtk_tree_view_column_pack_start(column, renderer, TRUE);
380 gtk_tree_view_column_add_attribute(column, renderer, "text", MPDDATA_MODEL_COL_SONG_TITLE);
381 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeviews[2]),column, -1);
383 gtk_container_add(GTK_CONTAINER(sw), treeviews[2]);
384 gtk_box_pack_start(GTK_BOX(paned), sw, TRUE, TRUE, 0);
387 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
388 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
389 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]))), "changed", G_CALLBACK(magnatune_show_song_list), NULL);
391 gtk_paned_add1(GTK_PANED(magnatune_vbox), paned);
392 gtk_widget_show_all(paned);
394 * tree
396 sw = gtk_scrolled_window_new(NULL, NULL);
397 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
398 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
401 tree = (GtkWidget *)gmpc_mpddata_treeview_new("magnatune",TRUE,GTK_TREE_MODEL(mt_store));
402 g_signal_connect(G_OBJECT(tree), "row-activated", G_CALLBACK(magnatune_add_album_row_activated), NULL);
404 g_signal_connect(G_OBJECT(tree), "button-press-event", G_CALLBACK(magnatune_button_release_event), tree);
405 g_signal_connect(G_OBJECT(tree), "key-press-event", G_CALLBACK(magnatune_key_press), NULL);
407 gtk_container_add(GTK_CONTAINER(sw), tree);
408 gtk_box_pack_start(GTK_BOX(vbox),sw, TRUE, TRUE,0);
410 mt_tree_search = (TreeSearch *)treesearch_new(GTK_TREE_VIEW(tree), MPDDATA_MODEL_COL_SONG_TITLE);
411 gtk_box_pack_end(GTK_BOX(vbox), GTK_WIDGET(mt_tree_search), FALSE, TRUE, 0);
412 g_signal_connect(G_OBJECT(mt_tree_search), "result-activate", G_CALLBACK(magnatune_search_activate),NULL);
415 gtk_widget_show_all(sw);
416 gtk_widget_show(vbox);
418 * Progress Bar for the bottom
420 magnatune_pb = gtk_progress_bar_new();
421 gtk_box_pack_end(GTK_BOX(vbox), magnatune_pb, FALSE, TRUE, 0);
422 gtk_paned_add2(GTK_PANED(magnatune_vbox), vbox);
425 g_object_ref(magnatune_vbox);
429 static void magnatune_selected(GtkWidget *container)
431 if(magnatune_vbox == NULL)
433 magnatune_init();
434 gtk_container_add(GTK_CONTAINER(container), magnatune_vbox);
435 gtk_widget_show(magnatune_vbox);
436 if(!magnatune_db_has_data())
438 magnatune_download();
440 magnatune_get_genre_list();
441 } else {
442 gtk_container_add(GTK_CONTAINER(container), magnatune_vbox);
443 gtk_widget_show(magnatune_vbox);
446 static void magnatune_unselected(GtkWidget *container)
448 gtk_container_remove(GTK_CONTAINER(container), magnatune_vbox);
451 static void magnatune_download_xml_callback(int download, int total,gpointer data)
453 GtkWidget *pb = data;
454 gchar *label = NULL;
455 if(total > 0)
456 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pb), download/(float)total);
457 else
458 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pb));
459 if(download >> 20)
461 label = g_strdup_printf("%.2f mb",(download>>10)/1024.0);
463 else if (download>>10)
465 label = g_strdup_printf("%i kb",download>>10);
467 else
469 label = g_strdup_printf("%i b",download);
471 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pb), label);
472 g_free(label);
473 while(gtk_events_pending())
474 gtk_main_iteration();
477 static void magnatune_download()
479 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), FALSE);
480 gtk_widget_show(magnatune_pb);
481 magnatune_db_download_xml(magnatune_download_xml_callback, magnatune_pb);
482 gtk_widget_hide(magnatune_pb);
483 gtk_widget_set_sensitive(glade_xml_get_widget(pl3_xml, "pl3_win"), TRUE);
486 static void magnatune_add(GtkWidget *cat_tree)
488 GtkTreePath *path = NULL;
489 GtkTreeIter iter,child;
490 GtkTreeStore *pl3_tree = (GtkTreeStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(cat_tree));
491 gint pos = cfg_get_single_value_as_int_with_default(config, "magnatune","position",20);
493 if(!cfg_get_single_value_as_int_with_default(config, "magnatune", "enable", TRUE)) return;
496 playlist3_insert_browser(&iter, pos);
497 /*gtk_tree_store_append(pl3_tree, &iter, NULL);*/
498 gtk_tree_store_set(pl3_tree, &iter,
499 PL3_CAT_TYPE, plugin.id,
500 PL3_CAT_TITLE, "Magnatune Browser",
501 PL3_CAT_INT_ID, "",
502 PL3_CAT_ICON_ID, "magnatune",
503 PL3_CAT_PROC, TRUE,
504 PL3_CAT_ICON_SIZE,GTK_ICON_SIZE_DND,-1);
506 * Clean up old row reference if it exists
508 if (magnatune_ref)
510 gtk_tree_row_reference_free(magnatune_ref);
511 magnatune_ref = NULL;
514 * create row reference
516 path = gtk_tree_model_get_path(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter);
517 if (path)
519 magnatune_ref = gtk_tree_row_reference_new(GTK_TREE_MODEL(playlist3_get_category_tree_store()), path);
520 gtk_tree_path_free(path);
524 static char * __magnatune_process_string(char *name)
526 int i = 0;
527 int j = 0;
528 int depth = 0;
529 int spaces = 0;
531 /* only gonna be smaller */
532 char *result = g_malloc0((strlen(name)+1+spaces*2)*sizeof(char));
533 for(i=0; i < strlen(name);i++)
535 if(name[i] == '(' || name[i] == '[') depth++;
536 else if (name[i] == ')' || name[i] == ']') depth--;
537 else if(!depth)
539 result[j] = name[i];
540 j++;
543 for(i=j-1;i>0 && result[i] == ' ';i--)
545 result[i] = '\0';
547 return result;
550 /*** COVER STUFF */
551 static int magnatune_fetch_cover_priority(void){
552 return cfg_get_single_value_as_int_with_default(config, "magnatune", "priority", 80);
554 static int magnatune_fetch_get_image(mpd_Song *song,MetaDataType type, char **path)
556 int result = 0;
557 if(magnatune_db_has_data() == FALSE)
558 return META_DATA_UNAVAILABLE;
559 if(type == META_ARTIST_ART && song->artist)
561 char *artist = __magnatune_process_string(song->artist);
562 char *value = magnatune_db_get_value(artist,NULL,META_ARTIST_ART);
563 if(value)
565 gchar *filename = NULL;
566 gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL};
567 filename = g_strdup_printf("%s.jpg", artist);
568 *path = gmpc_get_covers_path(filename);
569 g_free(filename);
570 if(gmpc_easy_download(value, &dld))
572 g_file_set_contents(*path, dld.data, dld.size, NULL);
573 return META_DATA_AVAILABLE;
575 gmpc_easy_download_clean(&dld);
576 g_free(*path);
577 *path = NULL;
579 g_free(artist);
581 else if(type == META_ALBUM_ART && song->artist && song->album)
583 char *artist = __magnatune_process_string(song->artist);
584 char *album= __magnatune_process_string(song->album);
585 char *value = magnatune_db_get_value(artist,album,META_ALBUM_ART);
586 if(value)
588 gchar *filename;
589 gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL};
590 filename = g_strdup_printf("%s-%s.jpg", artist,album);
591 *path = gmpc_get_covers_path(filename);
592 g_free(filename);
593 if(gmpc_easy_download(value, &dld))
595 g_file_set_contents(*path, dld.data, dld.size, NULL);
596 return META_DATA_AVAILABLE;
598 gmpc_easy_download_clean(&dld);
599 g_free(*path);
600 *path = NULL;
602 g_free(artist);
604 return META_DATA_UNAVAILABLE;
606 static void magnatune_redownload_reload_db()
608 GtkTreeIter iter;
609 GtkTreeModel *model = gtk_tree_row_reference_get_model(magnatune_ref);
610 GtkTreePath *path = gtk_tree_row_reference_get_path(magnatune_ref);
611 if(path && gtk_tree_model_get_iter(model, &iter, path))
613 GtkTreeIter citer;
614 while(gtk_tree_model_iter_children(model, &citer,&iter))
616 gtk_tree_store_remove(GTK_TREE_STORE(model), &citer);
618 magnatune_download();
619 magnatune_get_genre_list();
621 if(path)
622 gtk_tree_path_free(path);
625 static void magnatune_cat_menu_add()
627 GtkTreeIter citer;
628 GtkTreeSelection *sel = gtk_tree_view_get_selection(playlist3_get_category_tree_view());
629 GtkTreeModel *model = (GtkTreeModel *)playlist3_get_category_tree_store();
630 GtkTreePath *tpath;
631 int depth = 0;
632 if(!gtk_tree_selection_get_selected(sel,&model,&citer))
634 return ;
637 * Get the level we are on.
639 tpath = gtk_tree_model_get_path(model, &citer);
640 depth = gtk_tree_path_get_depth(tpath);
641 gtk_tree_path_free(tpath);
642 /** Genre level */
643 if(depth == 2)
645 GList *list, *node;
646 gchar *genre;
647 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&genre, -1);
648 if(genre)
650 list = magnatune_db_get_url_list(genre, NULL ,NULL);
651 for(node = list; node; node = node->next)
653 mpd_playlist_queue_add(connection, node->data);
655 mpd_playlist_queue_commit(connection);
656 g_list_foreach(list, (GFunc)g_free, NULL);
657 g_list_free(list);
658 g_free(genre);
661 /** Artist */
662 else if(depth == 3)
664 gchar *artist;
665 gchar *genre;
666 GtkTreeIter iter;
667 if(gtk_tree_model_iter_parent(model, &iter, &citer))
669 GList *list, *node;
670 gtk_tree_model_get(model, &iter, PL3_CAT_INT_ID,&genre, -1);
671 gtk_tree_model_get(model, &citer, PL3_CAT_INT_ID,&artist, -1);
672 list = magnatune_db_get_url_list(genre, artist,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);
681 g_free(artist);
690 static void magnatune_cat_menu_replace()
692 mpd_playlist_clear(connection);
693 magnatune_cat_menu_add();
694 mpd_player_play(connection);
698 static int magnatune_cat_menu_popup(GtkWidget *menu, int type, GtkWidget *tree, GdkEventButton *event)
700 GtkWidget *item;
701 if(type != plugin.id) return 0;
702 else
704 /* add the clear widget */
705 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_REFRESH,NULL);
706 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
707 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_redownload_reload_db), NULL);
708 return 1;
710 return 0;
713 static void magnatune_add_selected(GtkWidget *button, GtkTreeView *tree)
715 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
716 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
717 GList *list = gtk_tree_selection_get_selected_rows(sel,&model);
718 if(list)
720 GList *node ;
721 for(node = list; node; node = g_list_next(node))
723 GtkTreeIter iter;
724 if(gtk_tree_model_get_iter(model, &iter, node->data))
726 gchar *path;
727 gtk_tree_model_get(model, &iter, MPDDATA_MODEL_COL_PATH, &path, -1);
728 mpd_playlist_queue_add(connection, path);
729 g_free(path);
732 mpd_playlist_queue_commit(connection);
733 g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
734 g_list_free (list);
737 static void magnatune_replace_selected(GtkWidget *button , GtkTreeView *tree)
739 mpd_playlist_clear(connection);
740 magnatune_add_selected(button, tree);
741 mpd_player_play(connection);
745 static void magnatune_list_edit_columns(GtkMenuItem *item, GtkWidget *widget)
747 gmpc_mpddata_treeview_edit_columns(GMPC_MPDDATA_TREEVIEW(widget));
749 static int magnatune_button_handle_release_event_tag_add(GtkWidget *button, gpointer userdata)
751 GList *list;
752 MpdData *data;
753 int position = GPOINTER_TO_INT(userdata);
754 gchar *genre=NULL, *artist=NULL, *album=NULL;
755 GtkTreeSelection *select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[0]));
756 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[0]));
757 GtkTreeIter piter;
758 if(gtk_tree_selection_get_selected(select, &model, &piter))
760 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&genre,-1);
762 if(position >= 1)
764 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[1]));
765 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[1]));
766 if(gtk_tree_selection_get_selected(select, &model, &piter))
768 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&artist,-1);
771 if(position >= 2)
773 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviews[2]));
774 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviews[2]));
775 if(gtk_tree_selection_get_selected(select, &model, &piter))
777 gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&album,-1);
780 list = magnatune_db_get_url_list(genre, artist, album);
781 for(;list; list = list->next)
783 mpd_playlist_queue_add(connection, list->data);
785 mpd_playlist_queue_commit(connection);
786 if(list)
788 g_list_foreach(list, g_free, NULL);
789 g_list_free(list);
791 if(genre)
792 g_free(genre);
793 if(artist)
794 g_free(artist);
795 if(album)
796 g_free(album);
800 static int magnatune_button_handle_release_event_tag_replace(GtkWidget *button, gpointer userdata)
802 mpd_playlist_clear(connection);
803 magnatune_button_handle_release_event_tag_add(button,userdata);
804 mpd_player_play(connection);
808 static int magnatune_button_handle_release_event_tag(GtkWidget *tree, GdkEventButton *event,gpointer data)
810 int i;
811 int position = GPOINTER_TO_INT(data);
812 if(event->button != 3) return FALSE;
813 GtkWidget *item;
815 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
816 if(gtk_tree_selection_count_selected_rows(sel)> 0)
818 GtkWidget *menu = gtk_menu_new();
821 /* Add */
822 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL);
823 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
824 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_add), data);
825 /* Replace */
826 item = gtk_image_menu_item_new_with_label("Replace");
827 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
828 gtk_image_new_from_stock(GTK_STOCK_REDO, GTK_ICON_SIZE_MENU));
829 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
830 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK( magnatune_button_handle_release_event_tag_replace), data);
831 gtk_widget_show_all(menu);
832 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,NULL, NULL, event->button, event->time);
833 return TRUE;
835 return FALSE;
838 static int magnatune_button_release_event(GtkWidget *tree, GdkEventButton *event,gpointer data)
840 if(event->button != 3) return FALSE;
841 GtkWidget *item;
843 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
845 if(gtk_tree_selection_count_selected_rows(sel)> 0)
847 GtkWidget *menu = gtk_menu_new();
848 GtkTreeModel *model = GTK_TREE_MODEL(mt_store);
849 /* Add */
850 item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL);
851 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item);
852 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_add_selected), tree);
853 /* Replace */
854 item = gtk_image_menu_item_new_with_label("Replace");
855 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
856 gtk_image_new_from_stock(GTK_STOCK_REDO, GTK_ICON_SIZE_MENU));
857 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
859 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(magnatune_replace_selected), tree);
861 /* Separator */
862 item = gtk_separator_menu_item_new();
863 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
864 /* Edit columns */
865 item = gtk_image_menu_item_new_with_label(("Edit Columns"));
866 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
867 gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU));
868 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
869 g_signal_connect(G_OBJECT(item), "activate",
870 G_CALLBACK(magnatune_list_edit_columns), tree);
872 gtk_widget_show_all(menu);
874 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,NULL, NULL, event->button, event->time);
875 return TRUE;
877 return FALSE;
880 static void magnatune_cat_key_press(GtkWidget *tree, GdkEventKey *event, int selected_type)
882 if(selected_type != plugin.id) return;
883 if(event->state&GDK_CONTROL_MASK && event->keyval == GDK_Insert)
885 magnatune_cat_menu_replace();
887 else if(event->keyval == GDK_Insert)
889 magnatune_cat_menu_add();
894 static int magnatune_key_press(GtkWidget *tree, GdkEventKey *event)
896 if(event->state&GDK_CONTROL_MASK && event->keyval == GDK_Insert)
898 magnatune_replace_selected(NULL, GTK_TREE_VIEW(tree));
900 else if(event->keyval == GDK_Insert)
902 magnatune_add_selected(NULL, GTK_TREE_VIEW(tree));
904 else if (event->keyval == GDK_f && event->state&GDK_CONTROL_MASK)
906 treesearch_start(mt_tree_search);
907 return TRUE;
909 else if((event->state&(GDK_CONTROL_MASK|GDK_MOD1_MASK)) == 0 &&
910 ((event->keyval >= GDK_space && event->keyval <= GDK_z)))
912 char data[2];
913 data[0] = (char)gdk_keyval_to_unicode(event->keyval);
914 data[1] = '\0';
915 treesearch_start(TREESEARCH(mt_tree_search));
916 gtk_entry_set_text(GTK_ENTRY(TREESEARCH(mt_tree_search)->entry),data);
917 gtk_editable_set_position(GTK_EDITABLE(TREESEARCH(mt_tree_search)->entry),1);
918 return TRUE;
920 return FALSE;
922 static void magnatune_save_myself(void)
924 if(magnatune_vbox)
926 int position = gtk_paned_get_position(GTK_PANED(magnatune_vbox));
927 cfg_set_single_value_as_int(config, "magnatune", "pane-pos", position);
929 if (magnatune_ref)
931 GtkTreePath *path = gtk_tree_row_reference_get_path(magnatune_ref);
932 if(path)
934 gint *indices = gtk_tree_path_get_indices(path);
935 debug_printf(DEBUG_INFO,"Saving myself to position: %i\n", indices[0]);
936 cfg_set_single_value_as_int(config, "magnatune","position",indices[0]);
937 gtk_tree_path_free(path);
942 static void magnatune_destroy(void)
944 magnatune_db_destroy();
945 if(magnatune_vbox)
946 gtk_widget_destroy(magnatune_vbox);
949 gmpcMetaDataPlugin magnatune_cover = {
950 magnatune_fetch_cover_priority,
951 magnatune_fetch_get_image
955 /* Needed plugin_wp stuff */
956 gmpcPlBrowserPlugin magnatune_gbp = {
957 .add = magnatune_add,
958 .selected = magnatune_selected,
959 .unselected = magnatune_unselected,
960 .cat_right_mouse_menu = magnatune_cat_menu_popup,
961 .cat_key_press = magnatune_cat_key_press
964 int plugin_api_version = PLUGIN_API_VERSION;
966 gmpcPlugin plugin = {
967 .name = "Magnatune Stream Browser",
968 .version = {0,15,0},
969 .plugin_type = GMPC_PLUGIN_PL_BROWSER|GMPC_PLUGIN_META_DATA,
970 /* Creation and destruction */
971 .init = magnatune_logo_init,
972 .destroy = magnatune_destroy,
973 .save_yourself = magnatune_save_myself,
974 .mpd_status_changed = magnatune_mpd_status_changed,
976 /* Browser extention */
977 .browser = &magnatune_gbp,
978 .metadata = &magnatune_cover,
980 /* get/set enabled */
981 .get_enabled = magnatune_get_enabled,
982 .set_enabled = magnatune_set_enabled