Updated German help translation
[empathy/ppotvin.git] / src / empathy-preferences.c
blob993cf77d4a783b98dc7de03d064b3f03cce94b52
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2003-2007 Imendio AB
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (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 GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301 USA
20 * Authors: Mikael Hallendal <micke@imendio.com>
21 * Richard Hult <richard@imendio.com>
22 * Martyn Russell <martyn@imendio.com>
25 #include <config.h>
27 #include <string.h>
29 #include <gtk/gtk.h>
30 #include <glib/gi18n.h>
31 #include <telepathy-glib/dbus.h>
32 #include <telepathy-glib/util.h>
34 #include <libempathy/empathy-utils.h>
36 #include <libempathy-gtk/empathy-conf.h>
37 #include <libempathy-gtk/empathy-ui-utils.h>
38 #include <libempathy-gtk/empathy-theme-manager.h>
39 #include <libempathy-gtk/empathy-spell.h>
40 #include <libempathy-gtk/empathy-contact-list-store.h>
41 #include <libempathy-gtk/empathy-gtk-enum-types.h>
43 #ifdef HAVE_WEBKIT
44 #include <libempathy-gtk/empathy-theme-adium.h>
45 #endif
47 #include "empathy-preferences.h"
49 typedef struct {
50 GtkWidget *dialog;
52 GtkWidget *notebook;
54 GtkWidget *checkbutton_show_smileys;
55 GtkWidget *checkbutton_show_contacts_in_rooms;
56 GtkWidget *combobox_chat_theme;
57 GtkWidget *checkbutton_separate_chat_windows;
58 GtkWidget *checkbutton_autoconnect;
60 GtkWidget *checkbutton_sounds_enabled;
61 GtkWidget *checkbutton_sounds_disabled_away;
62 GtkWidget *treeview_sounds;
64 GtkWidget *checkbutton_notifications_enabled;
65 GtkWidget *checkbutton_notifications_disabled_away;
66 GtkWidget *checkbutton_notifications_focus;
67 GtkWidget *checkbutton_notifications_contact_signin;
68 GtkWidget *checkbutton_notifications_contact_signout;
70 GtkWidget *treeview_spell_checker;
72 GtkWidget *checkbutton_location_publish;
73 GtkWidget *checkbutton_location_reduce_accuracy;
74 GtkWidget *checkbutton_location_resource_network;
75 GtkWidget *checkbutton_location_resource_cell;
76 GtkWidget *checkbutton_location_resource_gps;
78 GList *notify_ids;
79 } EmpathyPreferences;
81 static void preferences_setup_widgets (EmpathyPreferences *preferences);
82 static void preferences_languages_setup (EmpathyPreferences *preferences);
83 static void preferences_languages_add (EmpathyPreferences *preferences);
84 static void preferences_languages_save (EmpathyPreferences *preferences);
85 static gboolean preferences_languages_save_foreach (GtkTreeModel *model,
86 GtkTreePath *path,
87 GtkTreeIter *iter,
88 gchar **languages);
89 static void preferences_languages_load (EmpathyPreferences *preferences);
90 static gboolean preferences_languages_load_foreach (GtkTreeModel *model,
91 GtkTreePath *path,
92 GtkTreeIter *iter,
93 gchar **languages);
94 static void preferences_languages_cell_toggled_cb (GtkCellRendererToggle *cell,
95 gchar *path_string,
96 EmpathyPreferences *preferences);
97 static void preferences_widget_sync_bool (const gchar *key,
98 GtkWidget *widget);
99 static void preferences_notify_bool_cb (EmpathyConf *conf,
100 const gchar *key,
101 gpointer user_data);
102 static void preferences_notify_sensitivity_cb (EmpathyConf *conf,
103 const gchar *key,
104 gpointer user_data);
105 static void preferences_hookup_toggle_button (EmpathyPreferences *preferences,
106 const gchar *key,
107 GtkWidget *widget);
108 static void preferences_hookup_sensitivity (EmpathyPreferences *preferences,
109 const gchar *key,
110 GtkWidget *widget);
111 static void preferences_toggle_button_toggled_cb (GtkWidget *button,
112 gpointer user_data);
113 static void preferences_destroy_cb (GtkWidget *widget,
114 EmpathyPreferences *preferences);
115 static void preferences_response_cb (GtkWidget *widget,
116 gint response,
117 EmpathyPreferences *preferences);
119 enum {
120 COL_LANG_ENABLED,
121 COL_LANG_CODE,
122 COL_LANG_NAME,
123 COL_LANG_COUNT
126 enum {
127 COL_COMBO_IS_ADIUM,
128 COL_COMBO_VISIBLE_NAME,
129 COL_COMBO_NAME,
130 COL_COMBO_PATH,
131 COL_COMBO_COUNT
134 enum {
135 COL_SOUND_ENABLED,
136 COL_SOUND_NAME,
137 COL_SOUND_KEY,
138 COL_SOUND_COUNT
141 typedef struct {
142 const char *name;
143 const char *key;
144 } SoundEventEntry;
146 /* TODO: add phone related sounds also? */
147 static SoundEventEntry sound_entries [] = {
148 { N_("Message received"), EMPATHY_PREFS_SOUNDS_INCOMING_MESSAGE },
149 { N_("Message sent"), EMPATHY_PREFS_SOUNDS_OUTGOING_MESSAGE },
150 { N_("New conversation"), EMPATHY_PREFS_SOUNDS_NEW_CONVERSATION },
151 { N_("Contact goes online"), EMPATHY_PREFS_SOUNDS_CONTACT_LOGIN },
152 { N_("Contact goes offline"), EMPATHY_PREFS_SOUNDS_CONTACT_LOGOUT },
153 { N_("Account connected"), EMPATHY_PREFS_SOUNDS_SERVICE_LOGIN },
154 { N_("Account disconnected"), EMPATHY_PREFS_SOUNDS_SERVICE_LOGOUT }
157 static void
158 preferences_add_id (EmpathyPreferences *preferences, guint id)
160 preferences->notify_ids = g_list_prepend (preferences->notify_ids,
161 GUINT_TO_POINTER (id));
164 static void
165 preferences_setup_widgets (EmpathyPreferences *preferences)
167 preferences_hookup_toggle_button (preferences,
168 EMPATHY_PREFS_NOTIFICATIONS_ENABLED,
169 preferences->checkbutton_notifications_enabled);
170 preferences_hookup_toggle_button (preferences,
171 EMPATHY_PREFS_NOTIFICATIONS_DISABLED_AWAY,
172 preferences->checkbutton_notifications_disabled_away);
173 preferences_hookup_toggle_button (preferences,
174 EMPATHY_PREFS_NOTIFICATIONS_FOCUS,
175 preferences->checkbutton_notifications_focus);
176 preferences_hookup_toggle_button (preferences,
177 EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNIN,
178 preferences->checkbutton_notifications_contact_signin);
179 preferences_hookup_toggle_button (preferences,
180 EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNOUT,
181 preferences->checkbutton_notifications_contact_signout);
183 preferences_hookup_sensitivity (preferences,
184 EMPATHY_PREFS_NOTIFICATIONS_ENABLED,
185 preferences->checkbutton_notifications_disabled_away);
186 preferences_hookup_sensitivity (preferences,
187 EMPATHY_PREFS_NOTIFICATIONS_ENABLED,
188 preferences->checkbutton_notifications_focus);
189 preferences_hookup_sensitivity (preferences,
190 EMPATHY_PREFS_NOTIFICATIONS_ENABLED,
191 preferences->checkbutton_notifications_contact_signin);
192 preferences_hookup_sensitivity (preferences,
193 EMPATHY_PREFS_NOTIFICATIONS_ENABLED,
194 preferences->checkbutton_notifications_contact_signout);
196 preferences_hookup_toggle_button (preferences,
197 EMPATHY_PREFS_SOUNDS_ENABLED,
198 preferences->checkbutton_sounds_enabled);
199 preferences_hookup_toggle_button (preferences,
200 EMPATHY_PREFS_SOUNDS_DISABLED_AWAY,
201 preferences->checkbutton_sounds_disabled_away);
203 preferences_hookup_sensitivity (preferences,
204 EMPATHY_PREFS_SOUNDS_ENABLED,
205 preferences->checkbutton_sounds_disabled_away);
206 preferences_hookup_sensitivity (preferences,
207 EMPATHY_PREFS_SOUNDS_ENABLED,
208 preferences->treeview_sounds);
210 preferences_hookup_toggle_button (preferences,
211 EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS,
212 preferences->checkbutton_separate_chat_windows);
214 preferences_hookup_toggle_button (preferences,
215 EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
216 preferences->checkbutton_show_smileys);
218 preferences_hookup_toggle_button (preferences,
219 EMPATHY_PREFS_CHAT_SHOW_CONTACTS_IN_ROOMS,
220 preferences->checkbutton_show_contacts_in_rooms);
222 preferences_hookup_toggle_button (preferences,
223 EMPATHY_PREFS_AUTOCONNECT,
224 preferences->checkbutton_autoconnect);
226 preferences_hookup_toggle_button (preferences,
227 EMPATHY_PREFS_LOCATION_PUBLISH,
228 preferences->checkbutton_location_publish);
230 preferences_hookup_toggle_button (preferences,
231 EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK,
232 preferences->checkbutton_location_resource_network);
233 preferences_hookup_sensitivity (preferences,
234 EMPATHY_PREFS_LOCATION_PUBLISH,
235 preferences->checkbutton_location_resource_network);
237 preferences_hookup_toggle_button (preferences,
238 EMPATHY_PREFS_LOCATION_RESOURCE_CELL,
239 preferences->checkbutton_location_resource_cell);
240 preferences_hookup_sensitivity (preferences,
241 EMPATHY_PREFS_LOCATION_PUBLISH,
242 preferences->checkbutton_location_resource_cell);
244 preferences_hookup_toggle_button (preferences,
245 EMPATHY_PREFS_LOCATION_RESOURCE_GPS,
246 preferences->checkbutton_location_resource_gps);
247 preferences_hookup_sensitivity (preferences,
248 EMPATHY_PREFS_LOCATION_PUBLISH,
249 preferences->checkbutton_location_resource_gps);
251 preferences_hookup_toggle_button (preferences,
252 EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY,
253 preferences->checkbutton_location_reduce_accuracy);
254 preferences_hookup_sensitivity (preferences,
255 EMPATHY_PREFS_LOCATION_PUBLISH,
256 preferences->checkbutton_location_reduce_accuracy);
259 static void
260 preferences_sound_cell_toggled_cb (GtkCellRendererToggle *toggle,
261 char *path_string,
262 EmpathyPreferences *preferences)
264 GtkTreePath *path;
265 gboolean toggled, instore;
266 GtkTreeIter iter;
267 GtkTreeView *view;
268 GtkTreeModel *model;
269 char *key;
271 view = GTK_TREE_VIEW (preferences->treeview_sounds);
272 model = gtk_tree_view_get_model (view);
274 path = gtk_tree_path_new_from_string (path_string);
275 toggled = gtk_cell_renderer_toggle_get_active (toggle);
277 gtk_tree_model_get_iter (model, &iter, path);
278 gtk_tree_model_get (model, &iter, COL_SOUND_KEY, &key,
279 COL_SOUND_ENABLED, &instore, -1);
281 instore ^= 1;
283 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
284 COL_SOUND_ENABLED, instore, -1);
286 empathy_conf_set_bool (empathy_conf_get (), key, instore);
288 g_free (key);
289 gtk_tree_path_free (path);
292 static void
293 preferences_sound_load (EmpathyPreferences *preferences)
295 guint i;
296 GtkTreeView *view;
297 GtkListStore *store;
298 GtkTreeIter iter;
299 gboolean set;
300 EmpathyConf *conf;
302 view = GTK_TREE_VIEW (preferences->treeview_sounds);
303 store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
304 conf = empathy_conf_get ();
306 for (i = 0; i < G_N_ELEMENTS (sound_entries); i++) {
307 empathy_conf_get_bool (conf, sound_entries[i].key, &set);
309 gtk_list_store_insert_with_values (store, &iter, i,
310 COL_SOUND_NAME, gettext (sound_entries[i].name),
311 COL_SOUND_KEY, sound_entries[i].key,
312 COL_SOUND_ENABLED, set, -1);
316 static void
317 preferences_sound_setup (EmpathyPreferences *preferences)
319 GtkTreeView *view;
320 GtkListStore *store;
321 GtkCellRenderer *renderer;
322 GtkTreeViewColumn *column;
324 view = GTK_TREE_VIEW (preferences->treeview_sounds);
326 store = gtk_list_store_new (COL_SOUND_COUNT,
327 G_TYPE_BOOLEAN, /* enabled */
328 G_TYPE_STRING, /* name */
329 G_TYPE_STRING); /* key */
331 gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
333 renderer = gtk_cell_renderer_toggle_new ();
334 g_signal_connect (renderer, "toggled",
335 G_CALLBACK (preferences_sound_cell_toggled_cb),
336 preferences);
338 column = gtk_tree_view_column_new ();
339 gtk_tree_view_column_pack_start (column, renderer, FALSE);
340 gtk_tree_view_column_add_attribute (column, renderer,
341 "active", COL_SOUND_ENABLED);
343 renderer = gtk_cell_renderer_text_new ();
344 gtk_tree_view_column_pack_start (column, renderer, FALSE);
345 gtk_tree_view_column_add_attribute (column, renderer,
346 "text", COL_SOUND_NAME);
348 gtk_tree_view_append_column (view, column);
350 gtk_tree_view_column_set_resizable (column, FALSE);
351 gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
353 g_object_unref (store);
356 static void
357 preferences_languages_setup (EmpathyPreferences *preferences)
359 GtkTreeView *view;
360 GtkListStore *store;
361 GtkTreeSelection *selection;
362 GtkTreeModel *model;
363 GtkTreeViewColumn *column;
364 GtkCellRenderer *renderer;
365 guint col_offset;
367 view = GTK_TREE_VIEW (preferences->treeview_spell_checker);
369 store = gtk_list_store_new (COL_LANG_COUNT,
370 G_TYPE_BOOLEAN, /* enabled */
371 G_TYPE_STRING, /* code */
372 G_TYPE_STRING); /* name */
374 gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
376 selection = gtk_tree_view_get_selection (view);
377 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
379 model = GTK_TREE_MODEL (store);
381 renderer = gtk_cell_renderer_toggle_new ();
382 g_signal_connect (renderer, "toggled",
383 G_CALLBACK (preferences_languages_cell_toggled_cb),
384 preferences);
386 column = gtk_tree_view_column_new_with_attributes (NULL, renderer,
387 "active", COL_LANG_ENABLED,
388 NULL);
390 gtk_tree_view_append_column (view, column);
392 renderer = gtk_cell_renderer_text_new ();
393 col_offset = gtk_tree_view_insert_column_with_attributes (view,
394 -1, _("Language"),
395 renderer,
396 "text", COL_LANG_NAME,
397 NULL);
399 g_object_set_data (G_OBJECT (renderer),
400 "column", GINT_TO_POINTER (COL_LANG_NAME));
402 column = gtk_tree_view_get_column (view, col_offset - 1);
403 gtk_tree_view_column_set_sort_column_id (column, COL_LANG_NAME);
404 gtk_tree_view_column_set_resizable (column, FALSE);
405 gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
407 g_object_unref (store);
410 static void
411 preferences_languages_add (EmpathyPreferences *preferences)
413 GtkTreeView *view;
414 GtkListStore *store;
415 GList *codes, *l;
417 view = GTK_TREE_VIEW (preferences->treeview_spell_checker);
418 store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
420 codes = empathy_spell_get_language_codes ();
422 empathy_conf_set_bool (empathy_conf_get (),
423 EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED,
424 codes != NULL);
425 if (!codes) {
426 gtk_widget_set_sensitive (preferences->treeview_spell_checker, FALSE);
429 for (l = codes; l; l = l->next) {
430 GtkTreeIter iter;
431 const gchar *code;
432 const gchar *name;
434 code = l->data;
435 name = empathy_spell_get_language_name (code);
436 if (!name) {
437 continue;
440 gtk_list_store_append (store, &iter);
441 gtk_list_store_set (store, &iter,
442 COL_LANG_CODE, code,
443 COL_LANG_NAME, name,
444 -1);
447 empathy_spell_free_language_codes (codes);
450 static void
451 preferences_languages_save (EmpathyPreferences *preferences)
453 GtkTreeView *view;
454 GtkTreeModel *model;
456 gchar *languages = NULL;
458 view = GTK_TREE_VIEW (preferences->treeview_spell_checker);
459 model = gtk_tree_view_get_model (view);
461 gtk_tree_model_foreach (model,
462 (GtkTreeModelForeachFunc) preferences_languages_save_foreach,
463 &languages);
465 /* if user selects no languages, we don't want spell check */
466 empathy_conf_set_bool (empathy_conf_get (),
467 EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED,
468 languages != NULL);
470 empathy_conf_set_string (empathy_conf_get (),
471 EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES,
472 languages ? languages : "");
474 g_free (languages);
477 static gboolean
478 preferences_languages_save_foreach (GtkTreeModel *model,
479 GtkTreePath *path,
480 GtkTreeIter *iter,
481 gchar **languages)
483 gboolean enabled;
484 gchar *code;
486 if (!languages) {
487 return TRUE;
490 gtk_tree_model_get (model, iter, COL_LANG_ENABLED, &enabled, -1);
491 if (!enabled) {
492 return FALSE;
495 gtk_tree_model_get (model, iter, COL_LANG_CODE, &code, -1);
496 if (!code) {
497 return FALSE;
500 if (!(*languages)) {
501 *languages = g_strdup (code);
502 } else {
503 gchar *str = *languages;
504 *languages = g_strdup_printf ("%s,%s", str, code);
505 g_free (str);
508 g_free (code);
510 return FALSE;
513 static void
514 preferences_languages_load (EmpathyPreferences *preferences)
516 GtkTreeView *view;
517 GtkTreeModel *model;
518 gchar *value;
519 gchar **vlanguages;
521 if (!empathy_conf_get_string (empathy_conf_get (),
522 EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES,
523 &value) || !value) {
524 return;
527 vlanguages = g_strsplit (value, ",", -1);
528 g_free (value);
530 view = GTK_TREE_VIEW (preferences->treeview_spell_checker);
531 model = gtk_tree_view_get_model (view);
533 gtk_tree_model_foreach (model,
534 (GtkTreeModelForeachFunc) preferences_languages_load_foreach,
535 vlanguages);
537 g_strfreev (vlanguages);
540 static gboolean
541 preferences_languages_load_foreach (GtkTreeModel *model,
542 GtkTreePath *path,
543 GtkTreeIter *iter,
544 gchar **languages)
546 gchar *code;
547 gchar *lang;
548 gint i;
549 gboolean found = FALSE;
551 if (!languages) {
552 return TRUE;
555 gtk_tree_model_get (model, iter, COL_LANG_CODE, &code, -1);
556 if (!code) {
557 return FALSE;
560 for (i = 0, lang = languages[i]; lang; lang = languages[++i]) {
561 if (!tp_strdiff (lang, code)) {
562 found = TRUE;
566 g_free (code);
567 gtk_list_store_set (GTK_LIST_STORE (model), iter, COL_LANG_ENABLED, found, -1);
568 return FALSE;
571 static void
572 preferences_languages_cell_toggled_cb (GtkCellRendererToggle *cell,
573 gchar *path_string,
574 EmpathyPreferences *preferences)
576 GtkTreeView *view;
577 GtkTreeModel *model;
578 GtkListStore *store;
579 GtkTreePath *path;
580 GtkTreeIter iter;
581 gboolean enabled;
583 view = GTK_TREE_VIEW (preferences->treeview_spell_checker);
584 model = gtk_tree_view_get_model (view);
585 store = GTK_LIST_STORE (model);
587 path = gtk_tree_path_new_from_string (path_string);
589 gtk_tree_model_get_iter (model, &iter, path);
590 gtk_tree_model_get (model, &iter, COL_LANG_ENABLED, &enabled, -1);
592 enabled ^= 1;
594 gtk_list_store_set (store, &iter, COL_LANG_ENABLED, enabled, -1);
595 gtk_tree_path_free (path);
597 preferences_languages_save (preferences);
600 static void
601 preferences_widget_sync_bool (const gchar *key, GtkWidget *widget)
603 gboolean value;
605 if (empathy_conf_get_bool (empathy_conf_get (), key, &value)) {
606 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
610 #if 0
611 static void
612 preferences_widget_sync_string (const gchar *key, GtkWidget *widget)
614 gchar *value;
616 if (empathy_conf_get_string (empathy_conf_get (), key, &value) && value) {
617 if (GTK_IS_ENTRY (widget)) {
618 gtk_entry_set_text (GTK_ENTRY (widget), value);
619 } else if (GTK_IS_RADIO_BUTTON (widget)) {
620 if (!tp_strdiff (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM)) {
621 GType type;
622 GEnumClass *enum_class;
623 GEnumValue *enum_value;
624 GSList *list;
625 GtkWidget *toggle_widget;
627 /* Get index from new string */
628 type = empathy_contact_list_store_sort_get_type ();
629 enum_class = G_ENUM_CLASS (g_type_class_peek (type));
630 enum_value = g_enum_get_value_by_nick (enum_class, value);
632 if (enum_value) {
633 list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
634 toggle_widget = g_slist_nth_data (list, enum_value->value);
635 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_widget), TRUE);
637 } else {
638 g_warning ("Unhandled key:'%s' just had string change", key);
642 g_free (value);
646 static void
647 preferences_notify_string_cb (EmpathyConf *conf,
648 const gchar *key,
649 gpointer user_data)
651 preferences_widget_sync_string (key, user_data);
653 #endif
655 static void
656 preferences_notify_bool_cb (EmpathyConf *conf,
657 const gchar *key,
658 gpointer user_data)
660 preferences_widget_sync_bool (key, user_data);
663 static void
664 preferences_notify_sensitivity_cb (EmpathyConf *conf,
665 const gchar *key,
666 gpointer user_data)
668 gboolean value;
670 if (empathy_conf_get_bool (conf, key, &value)) {
671 gtk_widget_set_sensitive (GTK_WIDGET (user_data), value);
675 #if 0
676 static void
677 preferences_widget_sync_int (const gchar *key, GtkWidget *widget)
679 gint value;
681 if (empathy_conf_get_int (empathy_conf_get (), key, &value)) {
682 if (GTK_IS_SPIN_BUTTON (widget)) {
683 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
688 static void
689 preferences_notify_int_cb (EmpathyConf *conf,
690 const gchar *key,
691 gpointer user_data)
693 preferences_widget_sync_int (key, user_data);
696 static void
697 preferences_hookup_spin_button (EmpathyPreferences *preferences,
698 const gchar *key,
699 GtkWidget *widget)
701 guint id;
703 preferences_widget_sync_int (key, widget);
705 g_object_set_data_full (G_OBJECT (widget), "key",
706 g_strdup (key), g_free);
708 g_signal_connect (widget,
709 "value_changed",
710 G_CALLBACK (preferences_spin_button_value_changed_cb),
711 NULL);
713 id = empathy_conf_notify_add (empathy_conf_get (),
714 key,
715 preferences_notify_int_cb,
716 widget);
717 if (id) {
718 preferences_add_id (preferences, id);
722 static void
723 preferences_hookup_entry (EmpathyPreferences *preferences,
724 const gchar *key,
725 GtkWidget *widget)
727 guint id;
729 preferences_widget_sync_string (key, widget);
731 g_object_set_data_full (G_OBJECT (widget), "key",
732 g_strdup (key), g_free);
734 g_signal_connect (widget,
735 "changed",
736 G_CALLBACK (preferences_entry_value_changed_cb),
737 NULL);
739 id = empathy_conf_notify_add (empathy_conf_get (),
740 key,
741 preferences_notify_string_cb,
742 widget);
743 if (id) {
744 preferences_add_id (preferences, id);
748 static void
749 preferences_spin_button_value_changed_cb (GtkWidget *button,
750 gpointer user_data)
752 const gchar *key;
754 key = g_object_get_data (G_OBJECT (button), "key");
756 empathy_conf_set_int (empathy_conf_get (),
757 key,
758 gtk_spin_button_get_value (GTK_SPIN_BUTTON (button)));
761 static void
762 preferences_entry_value_changed_cb (GtkWidget *entry,
763 gpointer user_data)
765 const gchar *key;
767 key = g_object_get_data (G_OBJECT (entry), "key");
769 empathy_conf_set_string (empathy_conf_get (),
770 key,
771 gtk_entry_get_text (GTK_ENTRY (entry)));
773 #endif
775 static void
776 preferences_hookup_toggle_button (EmpathyPreferences *preferences,
777 const gchar *key,
778 GtkWidget *widget)
780 guint id;
782 preferences_widget_sync_bool (key, widget);
784 g_object_set_data_full (G_OBJECT (widget), "key",
785 g_strdup (key), g_free);
787 g_signal_connect (widget,
788 "toggled",
789 G_CALLBACK (preferences_toggle_button_toggled_cb),
790 NULL);
792 id = empathy_conf_notify_add (empathy_conf_get (),
793 key,
794 preferences_notify_bool_cb,
795 widget);
796 if (id) {
797 preferences_add_id (preferences, id);
801 #if 0
802 static void
803 preferences_hookup_radio_button (EmpathyPreferences *preferences,
804 const gchar *key,
805 GtkWidget *widget)
807 GSList *group, *l;
808 guint id;
810 preferences_widget_sync_string (key, widget);
812 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
813 for (l = group; l; l = l->next) {
814 g_signal_connect (l->data,
815 "toggled",
816 G_CALLBACK (preferences_radio_button_toggled_cb),
817 NULL);
819 g_object_set_data_full (G_OBJECT (l->data), "key",
820 g_strdup (key), g_free);
823 id = empathy_conf_notify_add (empathy_conf_get (),
824 key,
825 preferences_notify_string_cb,
826 widget);
827 if (id) {
828 preferences_add_id (preferences, id);
831 #endif
833 static void
834 preferences_hookup_sensitivity (EmpathyPreferences *preferences,
835 const gchar *key,
836 GtkWidget *widget)
838 gboolean value;
839 guint id;
841 if (empathy_conf_get_bool (empathy_conf_get (), key, &value)) {
842 gtk_widget_set_sensitive (widget, value);
845 id = empathy_conf_notify_add (empathy_conf_get (),
846 key,
847 preferences_notify_sensitivity_cb,
848 widget);
849 if (id) {
850 preferences_add_id (preferences, id);
854 static void
855 preferences_toggle_button_toggled_cb (GtkWidget *button,
856 gpointer user_data)
858 const gchar *key;
860 key = g_object_get_data (G_OBJECT (button), "key");
862 empathy_conf_set_bool (empathy_conf_get (),
863 key,
864 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)));
867 #if 0
868 static void
869 preferences_radio_button_toggled_cb (GtkWidget *button,
870 gpointer user_data)
872 const gchar *key;
873 const gchar *value = NULL;
875 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
876 return;
879 key = g_object_get_data (G_OBJECT (button), "key");
881 if (!tp_strdiff (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM)) {
882 GSList *group;
883 GType type;
884 GEnumClass *enum_class;
885 GEnumValue *enum_value;
887 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
889 /* Get string from index */
890 type = empathy_contact_list_store_sort_get_type ();
891 enum_class = G_ENUM_CLASS (g_type_class_peek (type));
892 enum_value = g_enum_get_value (enum_class, g_slist_index (group, button));
894 if (!enum_value) {
895 g_warning ("No GEnumValue for EmpathyContactListSort with GtkRadioButton index:%d",
896 g_slist_index (group, button));
897 return;
900 value = enum_value->value_nick;
901 } else if (!tp_strdiff (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM)) {
902 return;
905 empathy_conf_set_string (empathy_conf_get (), key, value);
907 #endif
909 static void
910 preferences_theme_notify_cb (EmpathyConf *conf,
911 const gchar *key,
912 gpointer user_data)
914 EmpathyPreferences *preferences = user_data;
915 GtkComboBox *combo;
916 gchar *conf_name;
917 gchar *conf_path;
918 GtkTreeModel *model;
919 GtkTreeIter iter;
920 gboolean found = FALSE;
922 if (!empathy_conf_get_string (conf, EMPATHY_PREFS_CHAT_THEME, &conf_name)) {
923 return;
926 if (!empathy_conf_get_string (conf, EMPATHY_PREFS_CHAT_ADIUM_PATH, &conf_path)) {
927 g_free (conf_name);
928 return;
931 combo = GTK_COMBO_BOX (preferences->combobox_chat_theme);
932 model = gtk_combo_box_get_model (combo);
933 if (gtk_tree_model_get_iter_first (model, &iter)) {
934 gboolean is_adium;
935 gchar *name;
936 gchar *path;
938 do {
939 gtk_tree_model_get (model, &iter,
940 COL_COMBO_IS_ADIUM, &is_adium,
941 COL_COMBO_NAME, &name,
942 COL_COMBO_PATH, &path,
943 -1);
945 if (!tp_strdiff (name, conf_name)) {
946 if (tp_strdiff (name, "adium") ||
947 !tp_strdiff (path, conf_path)) {
948 found = TRUE;
949 gtk_combo_box_set_active_iter (combo, &iter);
950 g_free (name);
951 g_free (path);
952 break;
956 g_free (name);
957 g_free (path);
958 } while (gtk_tree_model_iter_next (model, &iter));
961 /* Fallback to the first one. */
962 if (!found) {
963 if (gtk_tree_model_get_iter_first (model, &iter)) {
964 gtk_combo_box_set_active_iter (combo, &iter);
968 g_free (conf_name);
969 g_free (conf_path);
972 static void
973 preferences_theme_changed_cb (GtkComboBox *combo,
974 EmpathyPreferences *preferences)
976 GtkTreeModel *model;
977 GtkTreeIter iter;
978 gboolean is_adium;
979 gchar *name;
980 gchar *path;
982 if (gtk_combo_box_get_active_iter (combo, &iter)) {
983 model = gtk_combo_box_get_model (combo);
985 gtk_tree_model_get (model, &iter,
986 COL_COMBO_IS_ADIUM, &is_adium,
987 COL_COMBO_NAME, &name,
988 COL_COMBO_PATH, &path,
989 -1);
991 empathy_conf_set_string (empathy_conf_get (),
992 EMPATHY_PREFS_CHAT_THEME,
993 name);
994 if (is_adium == TRUE)
995 empathy_conf_set_string (empathy_conf_get (),
996 EMPATHY_PREFS_CHAT_ADIUM_PATH,
997 path);
998 g_free (name);
999 g_free (path);
1003 static void
1004 preferences_themes_setup (EmpathyPreferences *preferences)
1006 GtkComboBox *combo;
1007 GtkCellLayout *cell_layout;
1008 GtkCellRenderer *renderer;
1009 GtkListStore *store;
1010 const gchar **themes;
1011 GList *adium_themes;
1012 gint i;
1013 guint id;
1015 combo = GTK_COMBO_BOX (preferences->combobox_chat_theme);
1016 cell_layout = GTK_CELL_LAYOUT (combo);
1018 /* Create the model */
1019 store = gtk_list_store_new (COL_COMBO_COUNT,
1020 G_TYPE_BOOLEAN, /* Is an Adium theme */
1021 G_TYPE_STRING, /* Display name */
1022 G_TYPE_STRING, /* Theme name */
1023 G_TYPE_STRING); /* Theme path */
1024 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
1025 COL_COMBO_VISIBLE_NAME, GTK_SORT_ASCENDING);
1027 /* Fill the model */
1028 themes = empathy_theme_manager_get_themes ();
1029 for (i = 0; themes[i]; i += 2) {
1030 gtk_list_store_insert_with_values (store, NULL, -1,
1031 COL_COMBO_IS_ADIUM, FALSE,
1032 COL_COMBO_VISIBLE_NAME, _(themes[i + 1]),
1033 COL_COMBO_NAME, themes[i],
1034 COL_COMBO_PATH, NULL,
1035 -1);
1038 adium_themes = empathy_theme_manager_get_adium_themes ();
1039 while (adium_themes != NULL) {
1040 GHashTable *info;
1041 const gchar *name;
1042 const gchar *path;
1044 info = adium_themes->data;
1045 name = tp_asv_get_string (info, "CFBundleName");
1046 path = tp_asv_get_string (info, "path");
1048 if (name != NULL && path != NULL) {
1049 gtk_list_store_insert_with_values (store, NULL, -1,
1050 COL_COMBO_IS_ADIUM, TRUE,
1051 COL_COMBO_VISIBLE_NAME, name,
1052 COL_COMBO_NAME, "adium",
1053 COL_COMBO_PATH, path,
1054 -1);
1056 g_hash_table_unref (info);
1057 adium_themes = g_list_delete_link (adium_themes, adium_themes);
1060 /* Add cell renderer */
1061 renderer = gtk_cell_renderer_text_new ();
1062 gtk_cell_layout_pack_start (cell_layout, renderer, TRUE);
1063 gtk_cell_layout_set_attributes (cell_layout, renderer,
1064 "text", COL_COMBO_VISIBLE_NAME, NULL);
1066 gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store));
1067 g_object_unref (store);
1069 g_signal_connect (combo, "changed",
1070 G_CALLBACK (preferences_theme_changed_cb),
1071 preferences);
1073 /* Select the theme from the gconf key and track changes */
1074 preferences_theme_notify_cb (empathy_conf_get (),
1075 EMPATHY_PREFS_CHAT_THEME,
1076 preferences);
1077 id = empathy_conf_notify_add (empathy_conf_get (),
1078 EMPATHY_PREFS_CHAT_THEME,
1079 preferences_theme_notify_cb,
1080 preferences);
1081 if (id) {
1082 preferences_add_id (preferences, id);
1085 id = empathy_conf_notify_add (empathy_conf_get (),
1086 EMPATHY_PREFS_CHAT_ADIUM_PATH,
1087 preferences_theme_notify_cb,
1088 preferences);
1089 if (id) {
1090 preferences_add_id (preferences, id);
1094 static void
1095 preferences_response_cb (GtkWidget *widget,
1096 gint response,
1097 EmpathyPreferences *preferences)
1099 gtk_widget_destroy (widget);
1102 static void
1103 preferences_destroy_cb (GtkWidget *widget,
1104 EmpathyPreferences *preferences)
1106 GList *l;
1108 for (l = preferences->notify_ids; l; l = l->next) {
1109 guint id;
1111 id = GPOINTER_TO_UINT (l->data);
1112 empathy_conf_notify_remove (empathy_conf_get (), id);
1115 g_list_free (preferences->notify_ids);
1116 g_free (preferences);
1119 GtkWidget *
1120 empathy_preferences_show (GtkWindow *parent)
1122 static EmpathyPreferences *preferences;
1123 GtkBuilder *gui;
1124 gchar *filename;
1125 GtkWidget *page;
1127 if (preferences) {
1128 gtk_window_present (GTK_WINDOW (preferences->dialog));
1129 return preferences->dialog;
1132 preferences = g_new0 (EmpathyPreferences, 1);
1134 filename = empathy_file_lookup ("empathy-preferences.ui", "src");
1135 gui = empathy_builder_get_file (filename,
1136 "preferences_dialog", &preferences->dialog,
1137 "notebook", &preferences->notebook,
1138 "checkbutton_show_smileys", &preferences->checkbutton_show_smileys,
1139 "checkbutton_show_contacts_in_rooms", &preferences->checkbutton_show_contacts_in_rooms,
1140 "combobox_chat_theme", &preferences->combobox_chat_theme,
1141 "checkbutton_separate_chat_windows", &preferences->checkbutton_separate_chat_windows,
1142 "checkbutton_autoconnect", &preferences->checkbutton_autoconnect,
1143 "checkbutton_notifications_enabled", &preferences->checkbutton_notifications_enabled,
1144 "checkbutton_notifications_disabled_away", &preferences->checkbutton_notifications_disabled_away,
1145 "checkbutton_notifications_focus", &preferences->checkbutton_notifications_focus,
1146 "checkbutton_notifications_contact_signin", &preferences->checkbutton_notifications_contact_signin,
1147 "checkbutton_notifications_contact_signout", &preferences->checkbutton_notifications_contact_signout,
1148 "checkbutton_sounds_enabled", &preferences->checkbutton_sounds_enabled,
1149 "checkbutton_sounds_disabled_away", &preferences->checkbutton_sounds_disabled_away,
1150 "treeview_sounds", &preferences->treeview_sounds,
1151 "treeview_spell_checker", &preferences->treeview_spell_checker,
1152 "checkbutton_location_publish", &preferences->checkbutton_location_publish,
1153 "checkbutton_location_reduce_accuracy", &preferences->checkbutton_location_reduce_accuracy,
1154 "checkbutton_location_resource_network", &preferences->checkbutton_location_resource_network,
1155 "checkbutton_location_resource_cell", &preferences->checkbutton_location_resource_cell,
1156 "checkbutton_location_resource_gps", &preferences->checkbutton_location_resource_gps,
1157 NULL);
1158 g_free (filename);
1160 empathy_builder_connect (gui, preferences,
1161 "preferences_dialog", "destroy", preferences_destroy_cb,
1162 "preferences_dialog", "response", preferences_response_cb,
1163 NULL);
1165 g_object_unref (gui);
1167 g_object_add_weak_pointer (G_OBJECT (preferences->dialog), (gpointer) &preferences);
1169 preferences_themes_setup (preferences);
1171 preferences_setup_widgets (preferences);
1173 preferences_languages_setup (preferences);
1174 preferences_languages_add (preferences);
1175 preferences_languages_load (preferences);
1177 preferences_sound_setup (preferences);
1178 preferences_sound_load (preferences);
1180 if (empathy_spell_supported ()) {
1181 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (preferences->notebook), 2);
1182 gtk_widget_show (page);
1185 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (preferences->notebook), 3);
1186 #if HAVE_GEOCLUE
1187 gtk_widget_show (page);
1188 #else
1189 gtk_widget_hide (page);
1190 #endif
1193 if (parent) {
1194 gtk_window_set_transient_for (GTK_WINDOW (preferences->dialog),
1195 GTK_WINDOW (parent));
1198 gtk_widget_show (preferences->dialog);
1200 return preferences->dialog;