Add invalid-tags cover icon.
[gmpc.git] / src / preferences.c
blobad819bb97ff50786a7252fe6ab8ea39e3d845d20
1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2012 Qball Cow <qball@gmpclient.org>
3 * Project homepage: http://gmpclient.org/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <gtk/gtk.h>
21 #include <string.h>
22 #include <time.h>
23 #include <config.h>
24 #include "main.h"
25 #include "playlist3.h"
26 #include "misc.h"
27 #include "preferences.h"
29 #define LOG_DOMAIN "Preferences"
30 #define PLUGIN_STATS -200
31 void preferences_show_pref_window(int plugin_id);
32 static void plugin_stats_construct(GtkWidget *);
33 static void plugin_stats_destroy(GtkWidget *);
34 GtkBuilder *plugin_stat_xml = NULL;
35 /* About "plugin" */
37 /* End About */
38 GtkListStore *plugin_store_unfiltered = NULL;
39 GtkTreeModel *plugin_store= NULL;
41 GtkBuilder *xml_preferences_window = NULL;
42 gboolean running = 0;
44 /* Glade Prototypes, without glade these would be static */
45 void preferences_window_connect(GtkWidget * but);
46 void preferences_window_disconnect(GtkWidget * but);
47 void auth_enable_toggled(GtkToggleButton * but);
48 void entry_auth_changed(GtkEntry * entry);
49 void create_preferences_window(void);
50 void preferences_window_destroy(void);
52 int plugin_last;
55 static void pref_plugin_changed(void)
57 GtkTreeSelection *sel =
58 gtk_tree_view_get_selection(GTK_TREE_VIEW(gtk_builder_get_object(xml_preferences_window, "plugin_tree")));
59 GtkTreeModel *model = GTK_TREE_MODEL(plugin_store);
60 GtkTreeIter iter;
61 int id = 0;
62 if (plugin_last >= 0)
64 gmpc_plugin_preferences_destroy(plugins[plugin_last],
65 (GtkWidget *) gtk_builder_get_object(xml_preferences_window,
66 "plugin_container"));
67 plugin_last = -1;
69 } else if (plugin_last == PLUGIN_STATS)
71 plugin_stats_destroy((GtkWidget *) gtk_builder_get_object(xml_preferences_window, "plugin_container"));
73 if (gtk_tree_selection_get_selected(sel, &model, &iter))
75 gtk_tree_model_get(GTK_TREE_MODEL(plugin_store), &iter, 0, &id, -1);
76 if (id >= 0 && gmpc_plugin_has_preferences(plugins[id]))
78 char *buf = NULL;
79 const gchar *translation_domain = gmpc_plugin_get_translation_domain(plugins[id]);
80 if (!gmpc_plugin_is_internal(plugins[id]))
82 const int *version = gmpc_plugin_get_version(plugins[id]);
83 if (version != NULL)
85 buf = g_strdup_printf("<span size=\"xx-large\"><b>%s</b></span>\n<i>%s: %i.%i.%i</i>",
86 #if defined(ENABLE_NLS) && GLIB_CHECK_VERSION(2,18,0)
87 g_dgettext(translation_domain, gmpc_plugin_get_name(plugins[id])),
88 #else
89 gmpc_plugin_get_name(plugins[id]),
90 #endif
91 _("Plugin version"), version[0], version[1], version[2]);
92 } else
93 buf = g_strdup_printf("<span size=\"xx-large\"><b>%s</b></span>",
94 gmpc_plugin_get_name(plugins[id]));
96 } else
98 buf = g_strdup_printf("<span size=\"xx-large\"><b>%s</b></span>",
99 N_(gmpc_plugin_get_name(plugins[id])));
102 gmpc_plugin_preferences_construct(plugins[id],
103 (GtkWidget *) gtk_builder_get_object(xml_preferences_window,
104 "plugin_container"));
105 plugin_last = id;
106 gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(xml_preferences_window, "plugin_label")), buf);
107 q_free(buf);
108 return;
109 } else if (id == PLUGIN_STATS)
111 gchar *value = g_markup_printf_escaped("<span size=\"xx-large\" weight=\"bold\">%s</span>", _("Plugins"));
112 gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(xml_preferences_window, "plugin_label")), value);
113 g_free(value);
115 plugin_stats_construct((GtkWidget *) gtk_builder_get_object(xml_preferences_window, "plugin_container"));
116 plugin_last = id;
117 return;
120 gtk_label_set_markup(GTK_LABEL(gtk_builder_get_object(xml_preferences_window, "plugin_label")),
121 "<span size=\"xx-large\"><b>Nothing Selected</b></span>");
125 * Filter out disable drows
127 static gboolean pref_model_filter_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
129 int plugin_index = -1;
130 gtk_tree_model_get(model, iter, 0, &plugin_index, -1);
131 if(plugin_index >=0 )
133 g_assert(plugin_index < num_plugins);
134 if(gmpc_plugin_has_preferences(plugins[plugin_index]))
136 if(gmpc_plugin_get_enabled(plugins[plugin_index]))
138 return TRUE;
142 /* Special case */
143 else if(plugin_index == PLUGIN_STATS)
145 return TRUE;
147 return FALSE;
151 * If a plugin state changed (enabled/disable) this forces the preferences
152 * window to update
153 * the list.
155 void preferences_window_update(void)
157 if(xml_preferences_window != NULL)
159 gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(plugin_store));
163 void create_preferences_window(void)
165 GError *error = NULL;
166 GtkWidget *pl3_win = playlist3_get_window();
167 GtkWidget *dialog;
168 GtkCellRenderer *renderer;
169 GtkTreeViewColumn *column;
170 GtkWidget *label;
171 int i = 0;
172 char *string = NULL;
174 if (running)
176 if (xml_preferences_window == NULL)
178 running = 0;
179 } else
181 dialog = (GtkWidget *) gtk_builder_get_object(xml_preferences_window, "preferences_window");
182 gtk_window_present(GTK_WINDOW(dialog));
183 return;
186 plugin_last = -1;
187 string = gmpc_get_full_glade_path("preferences.ui");
188 xml_preferences_window = gtk_builder_new();
189 gtk_builder_add_from_file(xml_preferences_window, string, &error);
190 q_free(string);
191 if (error)
193 g_log(LOG_DOMAIN, G_LOG_LEVEL_ERROR, "Failed to load preferences.ui: %s", error->message);
194 g_error_free(error);
196 /* set info from struct */
197 /* hostname */
198 dialog = (GtkWidget *) gtk_builder_get_object(xml_preferences_window, "preferences_window");
199 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(pl3_win));
200 gtk_widget_show_all(GTK_WIDGET(dialog));
201 running = 1;
203 plugin_store_unfiltered = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
204 /* Create a filtered list that hides the disabled plugins */
205 plugin_store = gtk_tree_model_filter_new(GTK_TREE_MODEL(plugin_store_unfiltered), NULL);
207 gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(plugin_store),
208 pref_model_filter_func, NULL, NULL);
210 column = gtk_tree_view_column_new();
211 gtk_tree_view_column_set_title(column, _("Plugins"));
212 renderer = gtk_cell_renderer_text_new();
213 gtk_tree_view_column_pack_start(column, renderer, TRUE);
214 gtk_tree_view_column_set_attributes(column, renderer, "markup", 1, NULL);
215 gtk_tree_view_append_column(GTK_TREE_VIEW(gtk_builder_get_object(xml_preferences_window, "plugin_tree")), column);
217 g_signal_connect(G_OBJECT
218 (gtk_tree_view_get_selection
219 (GTK_TREE_VIEW(gtk_builder_get_object(xml_preferences_window, "plugin_tree")))), "changed",
220 G_CALLBACK(pref_plugin_changed), NULL);
221 gtk_tree_view_set_model(GTK_TREE_VIEW(gtk_builder_get_object(xml_preferences_window, "plugin_tree")),
222 GTK_TREE_MODEL(plugin_store));
224 /* internals */
225 for (i = 0; i < num_plugins; i++)
227 if (gmpc_plugin_has_preferences(plugins[i]))
229 if (gmpc_plugin_is_internal(plugins[i]))
231 GtkTreeIter iter;
232 gtk_list_store_append(GTK_LIST_STORE(plugin_store_unfiltered), &iter);
233 gtk_list_store_set(GTK_LIST_STORE(plugin_store_unfiltered), &iter, 0, i,
234 #if defined(ENABLE_NLS) && GLIB_CHECK_VERSION(2,18,0)
235 1, _(gmpc_plugin_get_name(plugins[i])),
236 #else
237 1, gmpc_plugin_get_name(plugins[i]),
238 #endif
239 -1);
243 // Select the first row
244 // TODO: Move this outside the loop.
245 if (gtk_tree_selection_count_selected_rows
246 (gtk_tree_view_get_selection
247 (GTK_TREE_VIEW(gtk_builder_get_object(xml_preferences_window, "plugin_tree")))) == 0)
249 GtkTreeIter iter;
250 if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(plugin_store), &iter))
252 gtk_tree_selection_select_iter(gtk_tree_view_get_selection
253 (GTK_TREE_VIEW
254 (gtk_builder_get_object(xml_preferences_window, "plugin_tree"))),
255 &iter);
258 /* plugins */
260 GtkTreeIter iter;
261 gchar *value = g_markup_printf_escaped("<b>%s:</b>", _("Plugins"));
263 gtk_list_store_append(GTK_LIST_STORE(plugin_store_unfiltered), &iter);
264 gtk_list_store_set(GTK_LIST_STORE(plugin_store_unfiltered), &iter, 0, PLUGIN_STATS, 1, value, -1);
265 g_free(value);
266 for (i = 0; i < num_plugins; i++)
268 if (gmpc_plugin_has_preferences(plugins[i]) && !gmpc_plugin_is_internal(plugins[i]))
270 const gchar *translation_domain = gmpc_plugin_get_translation_domain(plugins[i]);
271 gtk_list_store_append(GTK_LIST_STORE(plugin_store_unfiltered), &iter);
272 gtk_list_store_set(GTK_LIST_STORE(plugin_store_unfiltered), &iter, 0, i,
273 #if defined(ENABLE_NLS) && GLIB_CHECK_VERSION(2,18,0)
274 1, g_dgettext(translation_domain, gmpc_plugin_get_name(plugins[i])),
275 #else
276 1, gmpc_plugin_get_name(plugins[i]),
277 #endif
278 -1);
284 GtkWidget *widget = (GtkWidget *) gtk_builder_get_object(xml_preferences_window,
285 "eventbox_background");
287 gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &(dialog->style->base[GTK_STATE_NORMAL]));
290 label = (GtkWidget *) gtk_builder_get_object(xml_preferences_window, "plugin_label_box");
291 gtk_widget_set_app_paintable(label, TRUE);
292 g_signal_connect(G_OBJECT(label), "expose-event", G_CALLBACK(misc_header_expose_event), NULL);
293 gtk_widget_set_state(GTK_WIDGET(label), GTK_STATE_SELECTED);
295 gtk_widget_show(dialog);
296 gtk_builder_connect_signals(xml_preferences_window, NULL);
300 /* destory the preferences window */
301 G_MODULE_EXPORT void preferences_window_destroy(void)
303 GtkWidget *dialog = (GtkWidget *) gtk_builder_get_object(xml_preferences_window, "preferences_window");
304 if (plugin_last >= 0)
306 gmpc_plugin_preferences_destroy(plugins[plugin_last],
307 (GtkWidget *) gtk_builder_get_object(xml_preferences_window,
308 "plugin_container"));
309 plugin_last = -1;
311 } else if (plugin_last == PLUGIN_STATS)
313 plugin_stats_destroy((GtkWidget *) gtk_builder_get_object(xml_preferences_window, "plugin_container"));
315 gtk_widget_destroy(dialog);
316 g_object_unref(xml_preferences_window);
317 g_object_unref(plugin_store);
318 plugin_store = NULL;
319 xml_preferences_window = NULL;
320 running = 0;
324 static void pref_plugin_enabled(GtkCellRendererToggle * rend, gchar * path, GtkListStore * store)
326 GtkTreeIter iter;
327 if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path))
329 int toggled;
330 gmpcPluginParent *plug = NULL;
331 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &toggled, 3, &plug, -1);
333 gmpc_plugin_set_enabled(plug, !toggled);
335 if (GMPC_PLUGIN_IS_SIDEBAR_IFACE(plug->new))
337 if (gmpc_plugin_get_enabled(plug)) {
338 gmpc_sidebar_plugins_enable((GmpcPluginSidebarIface*)plug->new);
340 else
342 gmpc_sidebar_plugins_disable((GmpcPluginSidebarIface*)plug->new);
348 preferences_window_update();
349 gtk_list_store_set(store, &iter, 0, gmpc_plugin_get_enabled(plug), -1);
355 static void plugin_stats_construct(GtkWidget * container)
357 gchar *path = gmpc_get_full_glade_path("preferences-plugins.ui");
358 plugin_stat_xml = gtk_builder_new();
359 gtk_builder_add_from_file(plugin_stat_xml, path, NULL);
360 q_free(path);
361 if (plugin_stat_xml)
363 GtkWidget *tree = (GtkWidget *) gtk_builder_get_object(plugin_stat_xml, "plugin_stats_tree");
364 GtkListStore *store = NULL;
365 GtkTreeIter iter;
366 GtkCellRenderer *renderer = NULL;
367 int i = 0;
368 GtkWidget *vbox = (GtkWidget *) gtk_builder_get_object(plugin_stat_xml, "plugin_stats_vbox");
371 * new
373 store = gtk_list_store_new(5, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING);
375 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
376 renderer = gtk_cell_renderer_toggle_new();
377 g_object_set_data(G_OBJECT(renderer), "editable", GINT_TO_POINTER(1));
378 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, _("Enabled"), renderer, "active", 0, NULL);
379 g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(pref_plugin_enabled), store);
380 renderer = gtk_cell_renderer_text_new();
381 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, _("Name"), renderer, "text", 1, NULL);
382 renderer = gtk_cell_renderer_text_new();
383 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, _("Function"), renderer, "text", 2, NULL);
384 renderer = gtk_cell_renderer_text_new();
385 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, _("Version"), renderer, "text", 4, NULL);
386 for (i = 0; i < num_plugins; i++)
388 if (!gmpc_plugin_is_internal(plugins[i]))
390 const gchar *translation_domain = gmpc_plugin_get_translation_domain(plugins[i]);
391 const int *ver = gmpc_plugin_get_version(plugins[i]);
392 gchar *version = (ver) ? g_strdup_printf("%i.%i.%i", ver[0], ver[1], ver[2]) : g_strdup("n/a");
393 gtk_list_store_append(store, &iter);
394 gtk_list_store_set(store, &iter, 0, TRUE,
395 #if defined(ENABLE_NLS) && GLIB_CHECK_VERSION(2,18,0)
396 1, g_dgettext(translation_domain, gmpc_plugin_get_name(plugins[i])),
397 #else
398 1, gmpc_plugin_get_name(plugins[i]),
399 #endif
400 3, (plugins[i]), 4, version, -1);
401 g_free(version);
402 if (gmpc_plugin_get_enabled(plugins[i]))
404 gtk_list_store_set(store, &iter, 0, TRUE, -1);
405 } else
406 gtk_list_store_set(store, &iter, 0, FALSE, -1);
407 switch (gmpc_plugin_get_type(plugins[i]))
409 case GMPC_PLUGIN_DUMMY:
410 gtk_list_store_set(store, &iter, 2, _("Dummy"), -1);
411 break;
412 case GMPC_PLUGIN_PL_BROWSER:
413 gtk_list_store_set(store, &iter, 2, _("Browser Extension"), -1);
414 break;
415 case GMPC_PLUGIN_NO_GUI:
416 gtk_list_store_set(store, &iter, 2, _("Misc."), -1);
417 break;
418 case GMPC_INTERNALL:
419 case GMPC_DEPRECATED:
420 default:
421 gtk_list_store_set(store, &iter, 2, _("Unknown"), -1);
422 break;
425 if (GMPC_PLUGIN_IS_SIDEBAR_IFACE((plugins[i])->new))
427 gtk_list_store_set(store, &iter, 2, _("Sidebar Extension"), -1);
433 gtk_container_add(GTK_CONTAINER(container), vbox);
439 static void plugin_stats_destroy(GtkWidget * container)
441 if (plugin_stat_xml)
443 GtkWidget *vbox = (GtkWidget *) gtk_builder_get_object(plugin_stat_xml, "plugin_stats_vbox");
444 GtkTreeModel *model =
445 gtk_tree_view_get_model(GTK_TREE_VIEW(gtk_builder_get_object(plugin_stat_xml, "plugin_stats_tree")));
446 gtk_container_remove(GTK_CONTAINER(container), vbox);
447 if (model)
448 g_object_unref(model);
449 g_object_unref(plugin_stat_xml);
450 plugin_stat_xml = NULL;
455 void preferences_show_pref_window(int plugin_id)
457 GtkTreeIter iter;
458 if (xml_preferences_window == NULL)
459 create_preferences_window();
460 if (plugin_store)
462 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(plugin_store), &iter))
466 int pos;
467 gtk_tree_model_get(GTK_TREE_MODEL(plugin_store), &iter, 0, &pos, -1);
468 if (pos == plugin_get_pos(plugin_id))
470 GtkTreeSelection *sel =
471 gtk_tree_view_get_selection(GTK_TREE_VIEW
472 (gtk_builder_get_object(xml_preferences_window, "plugin_tree")));
473 gtk_tree_selection_select_iter(sel, &iter);
474 return;
476 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(plugin_store), &iter));