small updates
[gmpc.git] / src / preferences.c
blobee8fb70efed82f741b607a34b6053c5db0e0105b
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");
286 GtkStyleContext *sc = gtk_widget_get_style_context(widget);
287 gtk_style_context_add_class(sc, GTK_STYLE_CLASS_VIEW);
289 widget = (GtkWidget *) gtk_builder_get_object(xml_preferences_window,
290 "plugin_label_box");
291 sc = gtk_widget_get_style_context(widget);
292 gtk_style_context_add_class(sc, GTK_STYLE_CLASS_HIGHLIGHT);
294 widget = (GtkWidget *) gtk_builder_get_object(xml_preferences_window,
295 "plugin_label");
296 sc = gtk_widget_get_style_context(widget);
297 gtk_style_context_add_class(sc, GTK_STYLE_CLASS_HIGHLIGHT);
299 widget = (GtkWidget *) gtk_builder_get_object(xml_preferences_window,
300 "plugin_tree");
301 sc = gtk_widget_get_style_context(widget);
302 gtk_style_context_add_class(sc, GTK_STYLE_CLASS_SIDEBAR);
305 gtk_widget_show(dialog);
306 gtk_builder_connect_signals(xml_preferences_window, NULL);
310 /* destory the preferences window */
311 G_MODULE_EXPORT void preferences_window_destroy(void)
313 GtkWidget *dialog = (GtkWidget *) gtk_builder_get_object(xml_preferences_window, "preferences_window");
314 if (plugin_last >= 0)
316 gmpc_plugin_preferences_destroy(plugins[plugin_last],
317 (GtkWidget *) gtk_builder_get_object(xml_preferences_window,
318 "plugin_container"));
319 plugin_last = -1;
321 } else if (plugin_last == PLUGIN_STATS)
323 plugin_stats_destroy((GtkWidget *) gtk_builder_get_object(xml_preferences_window, "plugin_container"));
325 gtk_widget_destroy(dialog);
326 g_object_unref(xml_preferences_window);
327 g_object_unref(plugin_store);
328 plugin_store = NULL;
329 xml_preferences_window = NULL;
330 running = 0;
334 static void pref_plugin_enabled(GtkCellRendererToggle * rend, gchar * path, GtkListStore * store)
336 GtkTreeIter iter;
337 if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path))
339 int toggled;
340 gmpcPluginParent *plug = NULL;
341 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &toggled, 3, &plug, -1);
343 gmpc_plugin_set_enabled(plug, !toggled);
345 if (GMPC_PLUGIN_IS_SIDEBAR_IFACE(plug->new))
347 if (gmpc_plugin_get_enabled(plug)) {
348 gmpc_sidebar_plugins_enable((GmpcPluginSidebarIface*)plug->new);
350 else
352 gmpc_sidebar_plugins_disable((GmpcPluginSidebarIface*)plug->new);
358 preferences_window_update();
359 gtk_list_store_set(store, &iter, 0, gmpc_plugin_get_enabled(plug), -1);
365 static void plugin_stats_construct(GtkWidget * container)
367 gchar *path = gmpc_get_full_glade_path("preferences-plugins.ui");
368 plugin_stat_xml = gtk_builder_new();
369 gtk_builder_add_from_file(plugin_stat_xml, path, NULL);
370 q_free(path);
371 if (plugin_stat_xml)
373 GtkWidget *tree = (GtkWidget *) gtk_builder_get_object(plugin_stat_xml, "plugin_stats_tree");
374 GtkListStore *store = NULL;
375 GtkTreeIter iter;
376 GtkCellRenderer *renderer = NULL;
377 int i = 0;
378 GtkWidget *vbox = (GtkWidget *) gtk_builder_get_object(plugin_stat_xml, "plugin_stats_vbox");
381 * new
383 store = gtk_list_store_new(5, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING);
385 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
386 renderer = gtk_cell_renderer_toggle_new();
387 g_object_set_data(G_OBJECT(renderer), "editable", GINT_TO_POINTER(1));
388 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, _("Enabled"), renderer, "active", 0, NULL);
389 g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(pref_plugin_enabled), store);
390 renderer = gtk_cell_renderer_text_new();
391 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, _("Name"), renderer, "text", 1, NULL);
392 renderer = gtk_cell_renderer_text_new();
393 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, _("Function"), renderer, "text", 2, NULL);
394 renderer = gtk_cell_renderer_text_new();
395 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, _("Version"), renderer, "text", 4, NULL);
396 for (i = 0; i < num_plugins; i++)
398 if (!gmpc_plugin_is_internal(plugins[i]))
400 const gchar *translation_domain = gmpc_plugin_get_translation_domain(plugins[i]);
401 const int *ver = gmpc_plugin_get_version(plugins[i]);
402 gchar *version = (ver) ? g_strdup_printf("%i.%i.%i", ver[0], ver[1], ver[2]) : g_strdup("n/a");
403 gtk_list_store_append(store, &iter);
404 gtk_list_store_set(store, &iter, 0, TRUE,
405 #if defined(ENABLE_NLS) && GLIB_CHECK_VERSION(2,18,0)
406 1, g_dgettext(translation_domain, gmpc_plugin_get_name(plugins[i])),
407 #else
408 1, gmpc_plugin_get_name(plugins[i]),
409 #endif
410 3, (plugins[i]), 4, version, -1);
411 g_free(version);
412 if (gmpc_plugin_get_enabled(plugins[i]))
414 gtk_list_store_set(store, &iter, 0, TRUE, -1);
415 } else
416 gtk_list_store_set(store, &iter, 0, FALSE, -1);
417 switch (gmpc_plugin_get_type(plugins[i]))
419 case GMPC_PLUGIN_DUMMY:
420 gtk_list_store_set(store, &iter, 2, _("Dummy"), -1);
421 break;
422 case GMPC_PLUGIN_PL_BROWSER:
423 gtk_list_store_set(store, &iter, 2, _("Browser Extension"), -1);
424 break;
425 case GMPC_PLUGIN_NO_GUI:
426 gtk_list_store_set(store, &iter, 2, _("Misc."), -1);
427 break;
428 case GMPC_INTERNALL:
429 case GMPC_DEPRECATED:
430 default:
431 gtk_list_store_set(store, &iter, 2, _("Unknown"), -1);
432 break;
435 if (GMPC_PLUGIN_IS_SIDEBAR_IFACE((plugins[i])->new))
437 gtk_list_store_set(store, &iter, 2, _("Sidebar Extension"), -1);
443 gtk_container_add(GTK_CONTAINER(container), vbox);
449 static void plugin_stats_destroy(GtkWidget * container)
451 if (plugin_stat_xml)
453 GtkWidget *vbox = (GtkWidget *) gtk_builder_get_object(plugin_stat_xml, "plugin_stats_vbox");
454 GtkTreeModel *model =
455 gtk_tree_view_get_model(GTK_TREE_VIEW(gtk_builder_get_object(plugin_stat_xml, "plugin_stats_tree")));
456 gtk_container_remove(GTK_CONTAINER(container), vbox);
457 if (model)
458 g_object_unref(model);
459 g_object_unref(plugin_stat_xml);
460 plugin_stat_xml = NULL;
465 void preferences_show_pref_window(int plugin_id)
467 GtkTreeIter iter;
468 if (xml_preferences_window == NULL)
469 create_preferences_window();
470 if (plugin_store)
472 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(plugin_store), &iter))
476 int pos;
477 gtk_tree_model_get(GTK_TREE_MODEL(plugin_store), &iter, 0, &pos, -1);
478 if (pos == plugin_get_pos(plugin_id))
480 GtkTreeSelection *sel =
481 gtk_tree_view_get_selection(GTK_TREE_VIEW
482 (gtk_builder_get_object(xml_preferences_window, "plugin_tree")));
483 gtk_tree_selection_select_iter(sel, &iter);
484 return;
486 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(plugin_store), &iter));