Updates
[gmpc-tagedit.git] / src / plugin.c
blob9e64d5d77ba7c5c7b99574c7c41da1a05d233abf
1 #include <config.h>
2 #include <string.h>
3 #include <gdk/gdkkeysyms.h>
4 #include <gmpc/plugin.h>
5 #include <libmpd/libmpd.h>
6 #include <glib.h>
7 #include <tag_c.h>
9 #define CONFIG_NAME "tagedit"
12 static void __save_myself(void);
13 /* The plugin structure */
14 gmpcPlugin plugin;
17 GtkTreeRowReference *te_ref = NULL;
18 /**
19 * Preferences
21 void music_dir_cover_art_enable_toggle(GtkWidget *wid)
23 int kk = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wid));
24 cfg_set_single_value_as_int(config, CONFIG_NAME, "enable", kk);
26 static void info_entry_edited(GtkWidget *entry)
28 const char *str = gtk_entry_get_text(GTK_ENTRY(entry));
29 if(str)
31 cfg_set_single_value_as_string(config, CONFIG_NAME, "music_root",(char *)str);
35 static void __pref_destroy(GtkWidget *container)
37 gtk_widget_destroy(gtk_bin_get_child(GTK_BIN(container)));
39 void __pref_construct(GtkWidget *container)
41 GtkWidget *enable_cg = gtk_check_button_new_with_mnemonic("_Enable mpd's music dir as cover art source");
42 GtkWidget *entry = NULL;
43 char *entry_str = cfg_get_single_value_as_string(config, CONFIG_NAME, "music_root");
44 GtkWidget *vbox = gtk_vbox_new(FALSE,6);
46 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enable_cg),
47 cfg_get_single_value_as_int_with_default(config, CONFIG_NAME, "enable", TRUE));
49 g_signal_connect(G_OBJECT(enable_cg), "toggled", G_CALLBACK(music_dir_cover_art_enable_toggle), NULL);
50 gtk_box_pack_start(GTK_BOX(vbox), enable_cg, FALSE, FALSE, 0);
51 gtk_container_add(GTK_CONTAINER(container), vbox);
53 entry = gtk_entry_new();
54 if(entry_str)
56 gtk_entry_set_text(GTK_ENTRY(entry), entry_str);
57 cfg_free_string(entry_str);
59 gtk_box_pack_start(GTK_BOX(vbox), gtk_label_new("Music Root:"), FALSE, FALSE,0);
60 gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE,0);
61 g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(info_entry_edited), NULL);
63 gtk_widget_show_all(container);
67 /**
68 * Taglib functions
71 mpd_Song * get_song_from_file(const char *root, const char *filename)
73 TagLib_File *file;
74 TagLib_Tag *tag;
75 mpd_Song *song = NULL;
76 gchar *url = g_build_path(G_DIR_SEPARATOR_S, root, filename,NULL);
78 file = taglib_file_new(url);
79 if(file)
81 char *a = NULL;
82 song = mpd_newSong();
83 song->file = g_strdup(filename);
84 tag = taglib_file_tag(file);
85 if(tag)
87 if((a = taglib_tag_title(tag)) && a[0] != '\0')
88 song->title = g_strdup(a);
89 if((a = taglib_tag_album(tag)) && a[0] != '\0')
90 song->album = g_strdup(a);
91 if((a = taglib_tag_artist(tag)) && a[0] != '\0')
92 song->artist = g_strdup(a);
93 if(taglib_tag_track(tag) > 0)
94 song->track = g_strdup_printf("%i", taglib_tag_track(tag));
95 if((a = taglib_tag_genre(tag)) && a[0] != '\0')
96 song->genre = g_strdup(a);
97 if((a = taglib_tag_comment(tag)) && a[0] != '\0')
98 song->comment = g_strdup(a);
99 if(taglib_tag_year(tag) > 0)
100 song->date = g_strdup_printf("%i", taglib_tag_year(tag));
103 taglib_tag_free_strings();
105 taglib_file_free(file);
107 g_free(url);
108 return song;
110 static gboolean __timeout_mpd_update(gchar *url)
112 printf("update: %s\n",url);
113 mpd_database_update_dir(connection, url);
115 return FALSE;
118 void save_song_to_file(const char *root, const mpd_Song *song)
120 TagLib_File *file;
121 TagLib_Tag *tag;
123 gchar *url = g_build_path(G_DIR_SEPARATOR_S, root, song->file,NULL);
124 file = taglib_file_new(url);
125 if(file)
127 tag = taglib_file_tag(file);
128 if(song->title) taglib_tag_set_title(tag, song->title);
129 if(song->artist) taglib_tag_set_artist(tag, song->artist);
130 if(song->album) taglib_tag_set_album(tag, song->album);
131 if(song->genre) taglib_tag_set_genre(tag, song->genre);
132 if(song->comment) taglib_tag_set_comment(tag, song->comment);
133 if(song->track){
134 guint track = (guint) g_ascii_strtoll(song->track, NULL, 10);
135 taglib_tag_set_track(tag, track);
137 if(song->date){
138 guint year = (guint) g_ascii_strtoll(song->date, NULL, 10);
139 taglib_tag_set_year(tag, year);
141 taglib_file_save(file);
142 taglib_tag_free_strings();
143 taglib_file_free(file);
144 g_timeout_add_seconds_full(G_PRIORITY_DEFAULT ,1, (GSourceFunc)__timeout_mpd_update, g_strdup(song->file), g_free);
145 // g_timeout_add_seconds_full(G_PRIORITY_DEFAULT ,4, (GSourceFunc)__timeout_mpd_update, g_strdup(song->file), g_free);
148 g_free(url);
155 * Browser View
157 static GtkWidget *browser_box = NULL;
158 static GtkWidget *browser_tree = NULL;
159 static GtkTreeModel *browser_model = NULL;
160 static GtkWidget *entries[7];
161 static gulong signal_entries[7];
162 static void queue_selected_songs_for_edit(GtkMenuItem *item, GmpcMpdDataTreeview *tree)
164 char *root = cfg_get_single_value_as_string(config, CONFIG_NAME, "music_root");
165 MpdData *data = NULL;
166 GList *selected = NULL;
167 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
168 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
169 if(!browser_model)
170 browser_model = (GtkTreeModel *)gmpc_mpddata_model_new();
171 data = gmpc_mpddata_model_steal_mpd_data(GMPC_MPDDATA_MODEL(browser_model));
172 selected = gtk_tree_selection_get_selected_rows(selection, &model);
173 if(selected)
175 GList *iter = g_list_first(selected);
176 for(;iter; iter = g_list_next(iter))
178 GtkTreeIter titer;
180 if(gtk_tree_model_get_iter(model, &titer, iter->data))
182 mpd_Song *song = NULL;
183 gtk_tree_model_get(model, &titer, MPDDATA_MODEL_COL_MPDSONG, &song, -1);
184 if(song && song->file)
186 mpd_Song *edited = get_song_from_file(root, song->file);
187 printf("adding: %s\n", song->file);
188 if(edited)
190 data = mpd_new_data_struct_append(data);
191 data->type = MPD_DATA_TYPE_SONG;
192 data->song = edited;
197 g_list_foreach (selected, (GFunc)gtk_tree_path_free, NULL);
198 g_list_free (selected);
200 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(browser_model),data);
201 g_free(root);
204 static int __song_list_option_menu ( GmpcMpdDataTreeview *tree, GtkMenu *menu)
206 GtkWidget *item;
207 char *entry_str = cfg_get_single_value_as_string(config, CONFIG_NAME, "music_root");
208 if(entry_str)
210 item = gtk_image_menu_item_new_with_label("Queue songs for tag edit");
211 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
212 gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU));
213 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
214 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(queue_selected_songs_for_edit), tree);
215 g_free(entry_str);
217 return 1;
219 static void browser_selection_changed(GtkTreeSelection *selec, gpointer data)
221 GList *selected = gtk_tree_selection_get_selected_rows(selec, &browser_model);
222 int i =0;
223 for(i=0;i< 6;i++)
225 if(signal_entries[i])
226 g_signal_handler_block(G_OBJECT(entries[i]), signal_entries[i]);
227 if(i<4) gtk_entry_set_text(GTK_ENTRY(entries[i]), "");
228 else gtk_spin_button_set_value(GTK_SPIN_BUTTON(entries[i]), 0.0);
230 if(selected)
232 GList *iter = g_list_first(selected);
233 for(;iter; iter = g_list_next(iter))
235 GtkTreeIter titer;
236 if(gtk_tree_model_get_iter(browser_model, &titer, iter->data))
238 mpd_Song *song = NULL;
239 gtk_tree_model_get(browser_model, &titer, MPDDATA_MODEL_COL_MPDSONG, &song, -1);
240 if(song)
242 if(song->title)
244 if(strlen(gtk_entry_get_text(GTK_ENTRY(entries[0]))) == 0)
245 gtk_entry_set_text(GTK_ENTRY(entries[0]), song->title);
247 if(song->artist)
249 if(strlen(gtk_entry_get_text(GTK_ENTRY(entries[1]))) == 0)
250 gtk_entry_set_text(GTK_ENTRY(entries[1]), song->artist);
252 if(song->album)
254 if(strlen(gtk_entry_get_text(GTK_ENTRY(entries[2]))) == 0)
255 gtk_entry_set_text(GTK_ENTRY(entries[2]), song->album);
257 if(song->genre)
259 if(strlen(gtk_entry_get_text(GTK_ENTRY(entries[3]))) == 0)
260 gtk_entry_set_text(GTK_ENTRY(entries[3]), song->genre);
262 if(song->date)
264 guint year = (guint) g_ascii_strtoll(song->date, NULL, 10);
265 if(year && gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(entries[4])) == 0)
266 gtk_spin_button_set_value(GTK_SPIN_BUTTON(entries[4]), (gdouble) year);
268 if(song->track)
270 guint track = (guint) g_ascii_strtoll(song->track, NULL, 10);
271 if(track && gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(entries[5])) == 0)
272 gtk_spin_button_set_value(GTK_SPIN_BUTTON(entries[5]), (gdouble) track);
278 g_list_foreach (selected, (GFunc)gtk_tree_path_free, NULL);
279 g_list_free (selected);
281 for(i=0;i<6;i++)
283 if(signal_entries[i])
284 g_signal_handler_unblock(G_OBJECT(entries[i]), signal_entries[i]);
289 static void __field_changed(GtkWidget *entry, gpointer data)
291 int id = GPOINTER_TO_INT(data);
293 const gchar *text = NULL;
294 gint value = 0;
295 GList *selected = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(browser_tree)), &browser_model);
296 printf("changed: %i\n", id);
297 if(id < 4)
299 text = gtk_entry_get_text(GTK_ENTRY(entry));
301 else if (id < 6)
303 value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(entry));
305 if(selected)
307 GList *iter = g_list_first(selected);
308 for(;iter; iter = g_list_next(iter))
310 GtkTreeIter titer;
311 if(gtk_tree_model_get_iter(browser_model, &titer, iter->data))
313 mpd_Song *song = NULL;
314 gtk_tree_model_get(browser_model, &titer, MPDDATA_MODEL_COL_MPDSONG, &song, -1);
315 if(song)
317 if(id == 0) {
318 if(song->title == NULL || strcmp(song->title, text) != 0)
320 if(song->title) g_free(song->title);
321 song->title = g_strdup(text);
322 gtk_tree_model_row_changed(browser_model, (GtkTreePath *)iter->data, &titer);
323 if(!song->name)
324 song->name= g_strdup("changed");
327 else if(id == 1) {
328 if(song->artist == NULL || strcmp(song->artist, text) != 0)
330 if(song->artist) g_free(song->artist);
331 song->artist = g_strdup(text);
332 gtk_tree_model_row_changed(browser_model, (GtkTreePath *)iter->data, &titer);
333 if(!song->name)
334 song->name= g_strdup("changed");
337 else if(id == 2) {
338 if(song->album == NULL || strcmp(song->album, text) != 0)
340 if(song->album) g_free(song->album);
341 song->album = g_strdup(text);
342 gtk_tree_model_row_changed(browser_model, (GtkTreePath *)iter->data, &titer);
343 if(!song->name)
344 song->name= g_strdup("changed");
347 else if(id == 3) {
348 if(song->genre == NULL || strcmp(song->genre, text) != 0)
350 if(song->genre) g_free(song->genre);
351 song->genre = g_strdup(text);
352 gtk_tree_model_row_changed(browser_model, (GtkTreePath *)iter->data, &titer);
353 if(!song->name)
354 song->name= g_strdup("changed");
357 else if (id == 4) {
358 if(song->date ) g_free(song->date );
359 if(value > 0)
360 song->date = g_strdup_printf("%i", value);
361 else
362 song->date = NULL;
363 if(!song->name)
364 song->name= g_strdup("changed");
365 gtk_tree_model_row_changed(browser_model, (GtkTreePath *)iter->data, &titer);
367 else if (id == 5) {
368 if(song->track) g_free(song->track);
369 if(value > 0)
370 song->track = g_strdup_printf("%i", value);
371 else
372 song->track = NULL;
373 if(!song->name)
374 song->name= g_strdup("changed");
375 gtk_tree_model_row_changed(browser_model, (GtkTreePath *)iter->data, &titer);
380 g_list_foreach (selected, (GFunc)gtk_tree_path_free, NULL);
381 g_list_free (selected);
385 static void save_all(GtkWidget *button, gpointer data)
387 char *root = cfg_get_single_value_as_string(config, CONFIG_NAME, "music_root");
388 GtkTreeIter iter;
389 if(root && gtk_tree_model_get_iter_first(browser_model, &iter))
392 mpd_Song *song = NULL;
393 gtk_tree_model_get(browser_model, &iter, MPDDATA_MODEL_COL_MPDSONG, &song, -1);
394 if(song)
396 /* check if song changed */
397 if(song->name)
399 save_song_to_file(root, song);
400 g_free(song->name);
401 song->name = NULL;
404 }while(gtk_tree_model_iter_next(browser_model, &iter));
406 if(root)g_free(root);
408 static void clear_all(GtkWidget *button, gpointer data)
410 gmpc_mpddata_model_set_mpd_data(GMPC_MPDDATA_MODEL(browser_model), NULL);
413 static void __edit_columns(void)
415 gmpc_mpddata_treeview_edit_columns(GMPC_MPDDATA_TREEVIEW(browser_tree));
417 static int __button_release_event(GtkTreeView *tree, GdkEventButton *event)
419 if(event->button == 3)
421 /* del, crop */
422 GtkWidget *item;
423 GtkWidget *menu = gtk_menu_new();
424 item = gtk_image_menu_item_new_with_label(("Edit Columns"));
425 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
426 gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU));
427 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
428 g_signal_connect(G_OBJECT(item), "activate",
429 G_CALLBACK(__edit_columns), NULL);
431 gtk_widget_show_all(menu);
432 gtk_menu_popup(GTK_MENU(menu), NULL, NULL,NULL, NULL,0, event->time);
433 return TRUE;
435 return FALSE;
438 static int __key_release_event(GtkWidget *box , GdkEventKey *event, gpointer data)
440 if(event->keyval == GDK_Page_Up||event->keyval == GDK_Page_Down)
442 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(browser_tree));
443 if(gtk_tree_selection_count_selected_rows(selection) == 1)
445 GList *list = gtk_tree_selection_get_selected_rows(selection, &browser_model);
446 if(list)
448 GtkTreePath *path = list->data;
449 if(event->keyval == GDK_Page_Up)
451 if(gtk_tree_path_prev(path)){
452 gtk_tree_selection_unselect_all(selection);
453 gtk_tree_selection_select_path(selection, path);
455 }else{
456 gtk_tree_path_next(path);
457 gtk_tree_selection_unselect_all(selection);
458 gtk_tree_selection_select_path(selection, path);
461 g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
462 g_list_free (list);
464 return TRUE;
466 return FALSE;
469 static void __browser_init ( )
471 GtkWidget *sw = NULL, *label;
472 GtkWidget *table = NULL;
473 browser_box = gtk_vbox_new(FALSE, 6);
474 if(!browser_model)
475 browser_model = (GtkTreeModel *)gmpc_mpddata_model_new();
476 sw = gtk_scrolled_window_new(NULL, NULL);
477 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
478 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
479 browser_tree = gmpc_mpddata_treeview_new(CONFIG_NAME, TRUE, browser_model);
480 gmpc_mpddata_treeview_enable_click_fix(GMPC_MPDDATA_TREEVIEW(browser_tree));
481 gtk_container_add(GTK_CONTAINER(sw), browser_tree);
482 gtk_box_pack_start(GTK_BOX(browser_box), sw, TRUE, TRUE,0);
484 g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(browser_tree))),
485 "changed", G_CALLBACK(browser_selection_changed), NULL);
486 /** Add all the fill in fields */
487 table = gtk_table_new(4,6,FALSE);
488 /* title */
489 label = gtk_label_new("Title:");
490 gtk_misc_set_alignment(GTK_MISC(label), 1.0,0.5);
491 gtk_table_attach(GTK_TABLE(table),label, 0,1,0,1,GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
492 entries[0] = gtk_entry_new();
493 gtk_table_attach(GTK_TABLE(table),entries[0], 1,2,0,1,GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
494 signal_entries[0] = g_signal_connect(G_OBJECT(entries[0]), "changed", G_CALLBACK(__field_changed), GINT_TO_POINTER(0));
495 /* artist */
496 label = gtk_label_new("Artist:");
497 gtk_misc_set_alignment(GTK_MISC(label), 1.0,0.5);
498 gtk_table_attach(GTK_TABLE(table),label, 0,1,1,2,GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
499 entries[1] = gtk_entry_new();
500 gtk_table_attach(GTK_TABLE(table),entries[1], 1,2,1,2,GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
501 signal_entries[1] = g_signal_connect(G_OBJECT(entries[1]), "changed", G_CALLBACK(__field_changed), GINT_TO_POINTER(1));
502 /* album */
503 label = gtk_label_new("Album:");
504 gtk_misc_set_alignment(GTK_MISC(label), 1.0,0.5);
505 gtk_table_attach(GTK_TABLE(table),label, 0,1,2,3,GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
506 entries[2] = gtk_entry_new();
507 gtk_table_attach(GTK_TABLE(table),entries[2], 1,2,2,3,GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
508 signal_entries[2] = g_signal_connect(G_OBJECT(entries[2]), "changed", G_CALLBACK(__field_changed), GINT_TO_POINTER(2));
509 /* album */
510 label = gtk_label_new("Genre:");
511 gtk_misc_set_alignment(GTK_MISC(label), 1.0,0.5);
512 gtk_table_attach(GTK_TABLE(table),label, 0,1,3,4,GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
513 entries[3] = gtk_entry_new();
514 gtk_table_attach(GTK_TABLE(table),entries[3], 1,2,3,4,GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
515 signal_entries[3] = g_signal_connect(G_OBJECT(entries[3]), "changed", G_CALLBACK(__field_changed), GINT_TO_POINTER(3));
516 /* album */
517 label = gtk_label_new("Year:");
518 gtk_misc_set_alignment(GTK_MISC(label), 1.0,0.5);
519 gtk_table_attach(GTK_TABLE(table),label, 3,4,0,1,GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
520 entries[4] = gtk_spin_button_new_with_range(0, 3000,1);
521 gtk_table_attach(GTK_TABLE(table),entries[4], 4,5,0,1,GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
522 signal_entries[4] = g_signal_connect(G_OBJECT(entries[4]), "value-changed", G_CALLBACK(__field_changed), GINT_TO_POINTER(4));
523 g_signal_connect(G_OBJECT(entries[4]), "key-press-event", G_CALLBACK(__key_release_event), NULL);
524 /* album */
525 label = gtk_label_new("Track:");
526 gtk_misc_set_alignment(GTK_MISC(label), 1.0,0.5);
527 gtk_table_attach(GTK_TABLE(table),label, 3,4,1,2,GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
528 entries[5] = gtk_spin_button_new_with_range(0, 3000,1);
529 gtk_table_attach(GTK_TABLE(table),entries[5], 4,5,1,2,GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
530 signal_entries[5] = g_signal_connect(G_OBJECT(entries[5]), "value-changed", G_CALLBACK(__field_changed), GINT_TO_POINTER(5));
532 g_signal_connect(G_OBJECT(entries[5]), "key-press-event", G_CALLBACK(__key_release_event), NULL);
536 label = gtk_button_new_from_stock(GTK_STOCK_SAVE);
537 gtk_table_attach(GTK_TABLE(table),label, 5,6,2,3,GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
538 g_signal_connect(G_OBJECT(label), "clicked", G_CALLBACK(save_all), NULL);
540 label = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
541 gtk_table_attach(GTK_TABLE(table),label, 4,5,2,3,GTK_SHRINK|GTK_FILL, GTK_SHRINK|GTK_FILL, 0,0);
542 g_signal_connect(G_OBJECT(label), "clicked", G_CALLBACK(clear_all), NULL);
544 gtk_box_pack_start(GTK_BOX(browser_box), table, FALSE, TRUE,0);
546 g_signal_connect(G_OBJECT(browser_tree), "button-release-event", G_CALLBACK(__button_release_event), NULL);
548 g_signal_connect(G_OBJECT(browser_box), "key-press-event", G_CALLBACK(__key_release_event), NULL);
549 gtk_widget_show_all(browser_box);
550 g_object_ref(browser_box);
552 static void __browser_add ( GtkWidget *cat_tree)
554 GtkTreePath *path = NULL;
555 GtkTreeIter iter;
556 GtkListStore *pl3_tree = (GtkListStore *)gtk_tree_view_get_model(GTK_TREE_VIEW(cat_tree));
557 gint pos = cfg_get_single_value_as_int_with_default(config, CONFIG_NAME,"position",20);
559 if(!cfg_get_single_value_as_int_with_default(config, CONFIG_NAME, "enable", TRUE)) return;
561 debug_printf(DEBUG_INFO,"Adding at position: %i", pos);
562 playlist3_insert_browser(&iter, pos);
563 gtk_list_store_set(GTK_LIST_STORE(pl3_tree), &iter,
564 PL3_CAT_TYPE, plugin.id,
565 PL3_CAT_TITLE, "Tag editor",
566 PL3_CAT_INT_ID, "",
567 PL3_CAT_ICON_ID, "gtk-edit",
568 PL3_CAT_PROC, TRUE,
569 PL3_CAT_ICON_SIZE,GTK_ICON_SIZE_DND,-1);
571 * Clean up old row reference if it exists
573 if (te_ref)
575 gtk_tree_row_reference_free(te_ref);
576 te_ref = NULL;
579 * create row reference
581 path = gtk_tree_model_get_path(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter);
582 if (path)
584 te_ref = gtk_tree_row_reference_new(GTK_TREE_MODEL(playlist3_get_category_tree_store()), path);
585 gtk_tree_path_free(path);
589 static void __browser_selected (GtkWidget *container)
591 if(browser_box == NULL)
593 __browser_init();
595 gtk_container_add(GTK_CONTAINER(container), browser_box);
597 static void __browser_unselected ( GtkWidget *container)
599 gtk_container_remove(GTK_CONTAINER(container), gtk_bin_get_child(GTK_BIN(container)));
602 static void __destroy()
604 if(browser_box)
605 g_object_unref(browser_box);
609 * Get/Set enabled
611 static int ___get_enabled()
613 return cfg_get_single_value_as_int_with_default(config, CONFIG_NAME, "enable", TRUE);
615 static void ___set_enabled(int enabled)
617 if(enabled)
619 /* Add the browser to the left pane, if there is none to begin with */
620 if(te_ref == NULL)
622 __browser_add(GTK_WIDGET(playlist3_get_category_tree_view()));
625 else if (te_ref)
627 /* Remove it from the left pane */
628 GtkTreePath *path = gtk_tree_row_reference_get_path(te_ref);
629 if (path){
630 GtkTreeIter iter;
631 /* for a save of myself */
632 __save_myself();
633 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(playlist3_get_category_tree_store()), &iter, path)){
634 gtk_list_store_remove(playlist3_get_category_tree_store(), &iter);
636 gtk_tree_path_free(path);
637 gtk_tree_row_reference_free(te_ref);
638 te_ref = NULL;
641 cfg_set_single_value_as_int(config, CONFIG_NAME, "enable", enabled);
643 static void __save_myself(void)
645 /* Save the position in the left tree */
646 if (te_ref)
648 GtkTreePath *path = gtk_tree_row_reference_get_path(te_ref);
649 if(path)
651 gint *indices = gtk_tree_path_get_indices(path);
652 debug_printf(DEBUG_INFO,"Saving myself '%s' to position: %i\n",plugin.name, indices[0]);
653 cfg_set_single_value_as_int(config, CONFIG_NAME,"position",indices[0]);
654 gtk_tree_path_free(path);
658 int plugin_api_version = PLUGIN_API_VERSION;
660 gmpcPlBrowserPlugin __browser = {
661 /* browser */
662 .add = __browser_add,
663 .selected = __browser_selected,
664 .unselected = __browser_unselected,
665 .song_list_option_menu = __song_list_option_menu
667 gmpcPrefPlugin __pref = {
668 .construct = __pref_construct,
669 .destroy = __pref_destroy
671 gmpcPlugin plugin = {
672 .name = "Tag Edit",
673 .version = {PLUGIN_MAJOR_VERSION,PLUGIN_MINOR_VERSION,PLUGIN_MICRO_VERSION},
674 .plugin_type = GMPC_PLUGIN_PL_BROWSER,
676 .save_yourself = __save_myself,
677 .destroy = __destroy,
678 .pref = &__pref,
679 .browser = &__browser,
680 .set_enabled = ___set_enabled,
681 .get_enabled = ___get_enabled