X-Git-Url: https://git.0d.be/?p=empathy.git;a=blobdiff_plain;f=src%2Fempathy-preferences.c;h=6775d4a245bb5f7c88a00e3a5cfe9c3abd57c6ee;hp=77f0bec4033f1285c5e779ce6fec599ec1d6a4e6;hb=4f470e26bafd3d2717b20af5e8846c114a2785d7;hpb=07c4d259ee11c288908a20f8541c3264a2e62d32 diff --git a/src/empathy-preferences.c b/src/empathy-preferences.c index 77f0bec4..6775d4a2 100644 --- a/src/empathy-preferences.c +++ b/src/empathy-preferences.c @@ -20,39 +20,57 @@ * Authors: Mikael Hallendal * Richard Hult * Martyn Russell + * Danielle Madeley */ #include #include +#include #include #include +#include +#include +#include #include -#include #include #include #include -#include #include +#include #include "empathy-preferences.h" -typedef struct { - GtkWidget *dialog; +#define DEBUG_FLAG EMPATHY_DEBUG_OTHER +#include + +G_DEFINE_TYPE (EmpathyPreferences, empathy_preferences, GTK_TYPE_DIALOG); + +#define GET_PRIV(self) ((EmpathyPreferencesPriv *)((EmpathyPreferences *) self)->priv) + +static const gchar * empathy_preferences_tabs[] = +{ + "general", + "notifications", + "sounds", + "calls", + "location", + "spell", + "themes", +}; +struct _EmpathyPreferencesPriv { GtkWidget *notebook; - GtkWidget *checkbutton_show_avatars; - GtkWidget *checkbutton_compact_contact_list; GtkWidget *checkbutton_show_smileys; - GtkWidget *combobox_chat_theme; + GtkWidget *checkbutton_show_contacts_in_rooms; GtkWidget *checkbutton_separate_chat_windows; + GtkWidget *checkbutton_events_notif_area; GtkWidget *checkbutton_autoconnect; - GtkWidget *radiobutton_contact_list_sort_by_name; - GtkWidget *radiobutton_contact_list_sort_by_state; + GtkWidget *checkbutton_logging; GtkWidget *checkbutton_sounds_enabled; GtkWidget *checkbutton_sounds_disabled_away; @@ -61,11 +79,36 @@ typedef struct { GtkWidget *checkbutton_notifications_enabled; GtkWidget *checkbutton_notifications_disabled_away; GtkWidget *checkbutton_notifications_focus; + GtkWidget *checkbutton_notifications_contact_signin; + GtkWidget *checkbutton_notifications_contact_signout; + + GtkWidget *echo_cancellation; GtkWidget *treeview_spell_checker; - GList *notify_ids; -} EmpathyPreferences; + GtkWidget *checkbutton_location_publish; + GtkWidget *checkbutton_location_reduce_accuracy; + GtkWidget *checkbutton_location_resource_network; + GtkWidget *checkbutton_location_resource_cell; + GtkWidget *checkbutton_location_resource_gps; + + GtkWidget *vbox_chat_theme; + GtkWidget *combobox_chat_theme; + GtkWidget *combobox_chat_theme_variant; + GtkWidget *hbox_chat_theme_variant; + GtkWidget *sw_chat_theme_preview; + EmpathyChatView *chat_theme_preview; + EmpathyThemeManager *theme_manager; + + GSettings *gsettings; + GSettings *gsettings_chat; + GSettings *gsettings_call; + GSettings *gsettings_loc; + GSettings *gsettings_notify; + GSettings *gsettings_sound; + GSettings *gsettings_ui; + GSettings *gsettings_logger; +}; static void preferences_setup_widgets (EmpathyPreferences *preferences); static void preferences_languages_setup (EmpathyPreferences *preferences); @@ -79,52 +122,10 @@ static void preferences_languages_load (EmpathyPreferences static gboolean preferences_languages_load_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, - gchar **languages); + GList *languages); static void preferences_languages_cell_toggled_cb (GtkCellRendererToggle *cell, gchar *path_string, EmpathyPreferences *preferences); -static void preferences_themes_setup (EmpathyPreferences *preferences); -static void preferences_widget_sync_bool (const gchar *key, - GtkWidget *widget); -static void preferences_widget_sync_string (const gchar *key, - GtkWidget *widget); -static void preferences_widget_sync_string_combo (const gchar *key, - GtkWidget *widget); -static void preferences_notify_string_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data); -static void preferences_notify_string_combo_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data); -static void preferences_notify_bool_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data); -static void preferences_notify_sensitivity_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data); -static void preferences_hookup_toggle_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget); -static void preferences_hookup_radio_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget); -static void preferences_hookup_string_combo (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget); -static void preferences_hookup_sensitivity (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget); -static void preferences_toggle_button_toggled_cb (GtkWidget *button, - gpointer user_data); -static void preferences_radio_button_toggled_cb (GtkWidget *button, - gpointer user_data); -static void preferences_string_combo_changed_cb (GtkWidget *button, - gpointer user_data); -static void preferences_destroy_cb (GtkWidget *widget, - EmpathyPreferences *preferences); -static void preferences_response_cb (GtkWidget *widget, - gint response, - EmpathyPreferences *preferences); enum { COL_LANG_ENABLED, @@ -134,9 +135,18 @@ enum { }; enum { - COL_COMBO_VISIBLE_NAME, - COL_COMBO_NAME, - COL_COMBO_COUNT + COL_THEME_VISIBLE_NAME, + COL_THEME_NAME, + COL_THEME_IS_ADIUM, + COL_THEME_ADIUM_PATH, + COL_THEME_ADIUM_INFO, + COL_THEME_COUNT +}; + +enum { + COL_VARIANT_NAME, + COL_VARIANT_DEFAULT, + COL_VARIANT_COUNT }; enum { @@ -162,101 +172,170 @@ static SoundEventEntry sound_entries [] = { { N_("Account disconnected"), EMPATHY_PREFS_SOUNDS_SERVICE_LOGOUT } }; -static void -preferences_add_id (EmpathyPreferences *preferences, guint id) -{ - preferences->notify_ids = g_list_prepend (preferences->notify_ids, - GUINT_TO_POINTER (id)); -} - -static void -preferences_compact_contact_list_changed_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - EmpathyPreferences *preferences = user_data; - gboolean value; - - if (empathy_conf_get_bool (empathy_conf_get (), key, &value)) { - gtk_widget_set_sensitive (preferences->checkbutton_show_avatars, - !value); - } -} - static void preferences_setup_widgets (EmpathyPreferences *preferences) { - guint id; - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - preferences->checkbutton_notifications_enabled); - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_NOTIFICATIONS_DISABLED_AWAY, - preferences->checkbutton_notifications_disabled_away); - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_NOTIFICATIONS_FOCUS, - preferences->checkbutton_notifications_focus); - - preferences_hookup_sensitivity (preferences, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - preferences->checkbutton_notifications_disabled_away); - preferences_hookup_sensitivity (preferences, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - preferences->checkbutton_notifications_focus); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_SOUNDS_ENABLED, - preferences->checkbutton_sounds_enabled); - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_SOUNDS_DISABLED_AWAY, - preferences->checkbutton_sounds_disabled_away); - - preferences_hookup_sensitivity (preferences, - EMPATHY_PREFS_SOUNDS_ENABLED, - preferences->checkbutton_sounds_disabled_away); - preferences_hookup_sensitivity (preferences, - EMPATHY_PREFS_SOUNDS_ENABLED, - preferences->treeview_sounds); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS, - preferences->checkbutton_separate_chat_windows); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_UI_SHOW_AVATARS, - preferences->checkbutton_show_avatars); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - preferences->checkbutton_compact_contact_list); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_CHAT_SHOW_SMILEYS, - preferences->checkbutton_show_smileys); - - preferences_hookup_string_combo (preferences, - EMPATHY_PREFS_CHAT_THEME, - preferences->combobox_chat_theme); - - preferences_hookup_radio_button (preferences, - EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, - preferences->radiobutton_contact_list_sort_by_name); - - preferences_hookup_toggle_button (preferences, - EMPATHY_PREFS_AUTOCONNECT, - preferences->checkbutton_autoconnect); - - id = empathy_conf_notify_add (empathy_conf_get (), - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - preferences_compact_contact_list_changed_cb, - preferences); - if (id) { - preferences_add_id (preferences, id); - } - preferences_compact_contact_list_changed_cb (empathy_conf_get (), - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - preferences); + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_ENABLED, + priv->checkbutton_notifications_enabled, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_DISABLED_AWAY, + priv->checkbutton_notifications_disabled_away, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_FOCUS, + priv->checkbutton_notifications_focus, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNIN, + priv->checkbutton_notifications_contact_signin, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNOUT, + priv->checkbutton_notifications_contact_signout, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_ENABLED, + priv->checkbutton_notifications_disabled_away, + "sensitive", + G_SETTINGS_BIND_GET); + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_ENABLED, + priv->checkbutton_notifications_focus, + "sensitive", + G_SETTINGS_BIND_GET); + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_ENABLED, + priv->checkbutton_notifications_contact_signin, + "sensitive", + G_SETTINGS_BIND_GET); + g_settings_bind (priv->gsettings_notify, + EMPATHY_PREFS_NOTIFICATIONS_ENABLED, + priv->checkbutton_notifications_contact_signout, + "sensitive", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->gsettings_sound, + EMPATHY_PREFS_SOUNDS_ENABLED, + priv->checkbutton_sounds_enabled, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_sound, + EMPATHY_PREFS_SOUNDS_DISABLED_AWAY, + priv->checkbutton_sounds_disabled_away, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (priv->gsettings_sound, + EMPATHY_PREFS_SOUNDS_ENABLED, + priv->checkbutton_sounds_disabled_away, + "sensitive", + G_SETTINGS_BIND_GET); + g_settings_bind (priv->gsettings_sound, + EMPATHY_PREFS_SOUNDS_ENABLED, + priv->treeview_sounds, + "sensitive", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->gsettings_ui, + EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS, + priv->checkbutton_separate_chat_windows, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (priv->gsettings_ui, + EMPATHY_PREFS_UI_EVENTS_NOTIFY_AREA, + priv->checkbutton_events_notif_area, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_SHOW_SMILEYS, + priv->checkbutton_show_smileys, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_SHOW_CONTACTS_IN_ROOMS, + priv->checkbutton_show_contacts_in_rooms, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (priv->gsettings_call, + EMPATHY_PREFS_CALL_ECHO_CANCELLATION, + priv->echo_cancellation, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (priv->gsettings, + EMPATHY_PREFS_AUTOCONNECT, + priv->checkbutton_autoconnect, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_PUBLISH, + priv->checkbutton_location_publish, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK, + priv->checkbutton_location_resource_network, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_PUBLISH, + priv->checkbutton_location_resource_network, + "sensitive", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_RESOURCE_CELL, + priv->checkbutton_location_resource_cell, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_PUBLISH, + priv->checkbutton_location_resource_cell, + "sensitive", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_RESOURCE_GPS, + priv->checkbutton_location_resource_gps, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_PUBLISH, + priv->checkbutton_location_resource_gps, + "sensitive", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY, + priv->checkbutton_location_reduce_accuracy, + "active", + G_SETTINGS_BIND_DEFAULT); + g_settings_bind (priv->gsettings_loc, + EMPATHY_PREFS_LOCATION_PUBLISH, + priv->checkbutton_location_reduce_accuracy, + "sensitive", + G_SETTINGS_BIND_GET); + + g_settings_bind (priv->gsettings_logger, + EMPATHY_PREFS_LOGGER_ENABLED, + priv->checkbutton_logging, + "active", + G_SETTINGS_BIND_DEFAULT); } static void @@ -264,18 +343,18 @@ preferences_sound_cell_toggled_cb (GtkCellRendererToggle *toggle, char *path_string, EmpathyPreferences *preferences) { + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkTreePath *path; - gboolean toggled, instore; + gboolean instore; GtkTreeIter iter; GtkTreeView *view; GtkTreeModel *model; char *key; - view = GTK_TREE_VIEW (preferences->treeview_sounds); + view = GTK_TREE_VIEW (priv->treeview_sounds); model = gtk_tree_view_get_model (view); path = gtk_tree_path_new_from_string (path_string); - toggled = gtk_cell_renderer_toggle_get_active (toggle); gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get (model, &iter, COL_SOUND_KEY, &key, @@ -286,7 +365,7 @@ preferences_sound_cell_toggled_cb (GtkCellRendererToggle *toggle, gtk_list_store_set (GTK_LIST_STORE (model), &iter, COL_SOUND_ENABLED, instore, -1); - empathy_conf_set_bool (empathy_conf_get (), key, instore); + g_settings_set_boolean (priv->gsettings_sound, key, instore); g_free (key); gtk_tree_path_free (path); @@ -295,19 +374,19 @@ preferences_sound_cell_toggled_cb (GtkCellRendererToggle *toggle, static void preferences_sound_load (EmpathyPreferences *preferences) { - int i; + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + guint i; GtkTreeView *view; GtkListStore *store; GtkTreeIter iter; gboolean set; - EmpathyConf *conf; - view = GTK_TREE_VIEW (preferences->treeview_sounds); + view = GTK_TREE_VIEW (priv->treeview_sounds); store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); - conf = empathy_conf_get (); for (i = 0; i < G_N_ELEMENTS (sound_entries); i++) { - empathy_conf_get_bool (conf, sound_entries[i].key, &set); + set = g_settings_get_boolean (priv->gsettings_sound, + sound_entries[i].key); gtk_list_store_insert_with_values (store, &iter, i, COL_SOUND_NAME, gettext (sound_entries[i].name), @@ -319,12 +398,13 @@ preferences_sound_load (EmpathyPreferences *preferences) static void preferences_sound_setup (EmpathyPreferences *preferences) { + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkTreeView *view; GtkListStore *store; GtkCellRenderer *renderer; GtkTreeViewColumn *column; - view = GTK_TREE_VIEW (preferences->treeview_sounds); + view = GTK_TREE_VIEW (priv->treeview_sounds); store = gtk_list_store_new (COL_SOUND_COUNT, G_TYPE_BOOLEAN, /* enabled */ @@ -359,15 +439,15 @@ preferences_sound_setup (EmpathyPreferences *preferences) static void preferences_languages_setup (EmpathyPreferences *preferences) { + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkTreeView *view; GtkListStore *store; GtkTreeSelection *selection; - GtkTreeModel *model; GtkTreeViewColumn *column; GtkCellRenderer *renderer; guint col_offset; - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); + view = GTK_TREE_VIEW (priv->treeview_spell_checker); store = gtk_list_store_new (COL_LANG_COUNT, G_TYPE_BOOLEAN, /* enabled */ @@ -379,8 +459,6 @@ preferences_languages_setup (EmpathyPreferences *preferences) selection = gtk_tree_view_get_selection (view); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - model = GTK_TREE_MODEL (store); - renderer = gtk_cell_renderer_toggle_new (); g_signal_connect (renderer, "toggled", G_CALLBACK (preferences_languages_cell_toggled_cb), @@ -413,21 +491,19 @@ preferences_languages_setup (EmpathyPreferences *preferences) static void preferences_languages_add (EmpathyPreferences *preferences) { + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkTreeView *view; GtkListStore *store; GList *codes, *l; - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); + view = GTK_TREE_VIEW (priv->treeview_spell_checker); store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); codes = empathy_spell_get_language_codes (); - empathy_conf_set_bool (empathy_conf_get(), - EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED, - codes != NULL); if (!codes) { - gtk_widget_set_sensitive (preferences->treeview_spell_checker, FALSE); - } + gtk_widget_set_sensitive (priv->treeview_spell_checker, FALSE); + } for (l = codes; l; l = l->next) { GtkTreeIter iter; @@ -453,12 +529,13 @@ preferences_languages_add (EmpathyPreferences *preferences) static void preferences_languages_save (EmpathyPreferences *preferences) { + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkTreeView *view; GtkTreeModel *model; gchar *languages = NULL; - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); + view = GTK_TREE_VIEW (priv->treeview_spell_checker); model = gtk_tree_view_get_model (view); gtk_tree_model_foreach (model, @@ -466,13 +543,13 @@ preferences_languages_save (EmpathyPreferences *preferences) &languages); /* if user selects no languages, we don't want spell check */ - empathy_conf_set_bool (empathy_conf_get (), - EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED, - languages != NULL); + g_settings_set_boolean (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED, + languages != NULL); - empathy_conf_set_string (empathy_conf_get (), - EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES, - languages ? languages : ""); + g_settings_set_string (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES, + languages != NULL ? languages : ""); g_free (languages); } @@ -516,39 +593,37 @@ preferences_languages_save_foreach (GtkTreeModel *model, static void preferences_languages_load (EmpathyPreferences *preferences) { + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkTreeView *view; GtkTreeModel *model; - gchar *value; - gchar **vlanguages; + GList *enabled_codes; - if (!empathy_conf_get_string (empathy_conf_get (), - EMPATHY_PREFS_CHAT_SPELL_CHECKER_LANGUAGES, - &value) || !value) { - return; - } + enabled_codes = empathy_spell_get_enabled_language_codes (); + + g_settings_set_boolean (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED, + enabled_codes != NULL); - vlanguages = g_strsplit (value, ",", -1); - g_free (value); + if (enabled_codes == NULL) + return; - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); + view = GTK_TREE_VIEW (priv->treeview_spell_checker); model = gtk_tree_view_get_model (view); gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) preferences_languages_load_foreach, - vlanguages); + enabled_codes); - g_strfreev (vlanguages); + g_list_free (enabled_codes); } static gboolean preferences_languages_load_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, - gchar **languages) + GList *languages) { gchar *code; - gchar *lang; - gint i; gboolean found = FALSE; if (!languages) { @@ -560,10 +635,8 @@ preferences_languages_load_foreach (GtkTreeModel *model, return FALSE; } - for (i = 0, lang = languages[i]; lang; lang = languages[++i]) { - if (strcmp (lang, code) == 0) { - found = TRUE; - } + if (g_list_find_custom (languages, code, (GCompareFunc) strcmp)) { + found = TRUE; } g_free (code); @@ -576,6 +649,7 @@ preferences_languages_cell_toggled_cb (GtkCellRendererToggle *cell, gchar *path_string, EmpathyPreferences *preferences) { + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkTreeView *view; GtkTreeModel *model; GtkListStore *store; @@ -583,7 +657,7 @@ preferences_languages_cell_toggled_cb (GtkCellRendererToggle *cell, GtkTreeIter iter; gboolean enabled; - view = GTK_TREE_VIEW (preferences->treeview_spell_checker); + view = GTK_TREE_VIEW (priv->treeview_spell_checker); model = gtk_tree_view_get_model (view); store = GTK_LIST_STORE (model); @@ -601,510 +675,543 @@ preferences_languages_cell_toggled_cb (GtkCellRendererToggle *cell, } static void -preferences_themes_setup (EmpathyPreferences *preferences) +preferences_preview_theme_append_message (EmpathyChatView *view, + EmpathyContact *sender, + EmpathyContact *receiver, + const gchar *text) { - GtkComboBox *combo; - GtkCellLayout *cell_layout; - GtkCellRenderer *renderer; - GtkListStore *store; - const gchar **themes; - gint i; + EmpathyMessage *message; - combo = GTK_COMBO_BOX (preferences->combobox_chat_theme); - cell_layout = GTK_CELL_LAYOUT (combo); - - /* Create the model */ - store = gtk_list_store_new (COL_COMBO_COUNT, - G_TYPE_STRING, /* Display name */ - G_TYPE_STRING); /* Theme name */ - - /* Fill the model */ - themes = empathy_theme_manager_get_themes (); - for (i = 0; themes[i]; i += 2) { - gtk_list_store_insert_with_values (store, NULL, -1, - COL_COMBO_VISIBLE_NAME, _(themes[i + 1]), - COL_COMBO_NAME, themes[i], - -1); - } - - /* Add cell renderer */ - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); - gtk_cell_layout_set_attributes (cell_layout, renderer, - "text", COL_COMBO_VISIBLE_NAME, NULL); + message = g_object_new (EMPATHY_TYPE_MESSAGE, + "sender", sender, + "receiver", receiver, + "body", text, + NULL); - gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store)); - g_object_unref (store); + empathy_chat_view_append_message (view, message); + g_object_unref (message); } static void -preferences_widget_sync_bool (const gchar *key, GtkWidget *widget) +preferences_preview_theme_changed_cb (EmpathyThemeManager *manager, + EmpathyPreferences *preferences) { - gboolean value; - - if (empathy_conf_get_bool (empathy_conf_get (), key, &value)) { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value); - } -} + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + TpDBusDaemon *dbus; + TpAccount *account; + EmpathyContact *juliet; + EmpathyContact *romeo; -static void -preferences_widget_sync_string (const gchar *key, GtkWidget *widget) -{ - gchar *value; - - if (empathy_conf_get_string (empathy_conf_get (), key, &value) && value) { - if (GTK_IS_ENTRY (widget)) { - gtk_entry_set_text (GTK_ENTRY (widget), value); - } else if (GTK_IS_RADIO_BUTTON (widget)) { - if (strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0) { - GType type; - GEnumClass *enum_class; - GEnumValue *enum_value; - GSList *list; - GtkWidget *toggle_widget; - - /* Get index from new string */ - type = empathy_contact_list_store_sort_get_type (); - enum_class = G_ENUM_CLASS (g_type_class_peek (type)); - enum_value = g_enum_get_value_by_nick (enum_class, value); - - if (enum_value) { - list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget)); - toggle_widget = g_slist_nth_data (list, enum_value->value); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_widget), TRUE); - } - } else { - g_warning ("Unhandled key:'%s' just had string change", key); - } - } + DEBUG ("Theme changed, update preview widget"); - g_free (value); + if (priv->chat_theme_preview != NULL) { + gtk_widget_destroy (GTK_WIDGET (priv->chat_theme_preview)); } + priv->chat_theme_preview = empathy_theme_manager_create_view (manager); + gtk_container_add (GTK_CONTAINER (priv->sw_chat_theme_preview), + GTK_WIDGET (priv->chat_theme_preview)); + gtk_widget_show (GTK_WIDGET (priv->chat_theme_preview)); + + /* FIXME: It is ugly to add a fake conversation like that. + * Would be cool if we could request a TplLogManager for a fake + * conversation */ + dbus = tp_dbus_daemon_dup (NULL); + account = tp_account_new (dbus, + TP_ACCOUNT_OBJECT_PATH_BASE "cm/jabber/account", NULL); + juliet = g_object_new (EMPATHY_TYPE_CONTACT, + "account", account, + "id", "juliet", + /* translators: Contact name for the chat theme preview */ + "alias", _("Juliet"), + "is-user", FALSE, + NULL); + romeo = g_object_new (EMPATHY_TYPE_CONTACT, + "account", account, + "id", "romeo", + /* translators: Contact name for the chat theme preview */ + "alias", _("Romeo"), + "is-user", TRUE, + NULL); + + preferences_preview_theme_append_message (priv->chat_theme_preview, + /* translators: Quote from Romeo & Julier, for chat theme preview */ + juliet, romeo, _("O Romeo, Romeo, wherefore art thou Romeo?")); + preferences_preview_theme_append_message (priv->chat_theme_preview, + /* translators: Quote from Romeo & Julier, for chat theme preview */ + juliet, romeo, _("Deny thy father and refuse thy name;")); + preferences_preview_theme_append_message (priv->chat_theme_preview, + /* translators: Quote from Romeo & Julier, for chat theme preview */ + juliet, romeo, _("Or if thou wilt not, be but sworn my love")); + preferences_preview_theme_append_message (priv->chat_theme_preview, + /* translators: Quote from Romeo & Julier, for chat theme preview */ + juliet, romeo, _("And I'll no longer be a Capulet.")); + preferences_preview_theme_append_message (priv->chat_theme_preview, + /* translators: Quote from Romeo & Julier, for chat theme preview */ + romeo, juliet, _("Shall I hear more, or shall I speak at this?")); + + /* translators: Quote from Romeo & Julier, for chat theme preview */ + empathy_chat_view_append_event (priv->chat_theme_preview, _("Juliet has disconnected")); + + g_object_unref (juliet); + g_object_unref (romeo); + g_object_unref (account); + g_object_unref (dbus); } static void -preferences_widget_sync_string_combo (const gchar *key, GtkWidget *widget) +preferences_theme_variant_changed_cb (GtkComboBox *combo, + EmpathyPreferences *preferences) { - gchar *value; - GtkTreeModel *model; + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); GtkTreeIter iter; - gboolean found; - - if (!empathy_conf_get_string (empathy_conf_get (), key, &value)) { - return; - } - model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + if (gtk_combo_box_get_active_iter (combo, &iter)) { + GtkTreeModel *model; + gchar *name; - found = FALSE; - if (value && gtk_tree_model_get_iter_first (model, &iter)) { - - do { - gchar *name; - gtk_tree_model_get (model, &iter, - COL_COMBO_NAME, &name, - -1); - - if (strcmp (name, value) == 0) { - found = TRUE; - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &iter); - } + model = gtk_combo_box_get_model (combo); + gtk_tree_model_get (model, &iter, + COL_VARIANT_NAME, &name, + -1); - g_free (name); - } while (!found && gtk_tree_model_iter_next (model, &iter)); - } + g_settings_set_string (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_THEME_VARIANT, + name); - /* Fallback to the first one. */ - if (!found) { - if (gtk_tree_model_get_iter_first (model, &iter)) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &iter); - } + g_free (name); } - - g_free (value); -} - -static void -preferences_notify_string_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - preferences_widget_sync_string (key, user_data); } static void -preferences_notify_string_combo_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) +preferences_theme_variant_notify_cb (GSettings *gsettings, + const gchar *key, + gpointer user_data) { - preferences_widget_sync_string_combo (key, user_data); -} + EmpathyPreferences *preferences = user_data; + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + GtkComboBox *combo; + gchar *conf_name; + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreeIter default_iter; + gboolean found_default = FALSE; + gboolean found = FALSE; + gboolean ok; + + conf_name = g_settings_get_string (gsettings, EMPATHY_PREFS_CHAT_THEME_VARIANT); + combo = GTK_COMBO_BOX (priv->combobox_chat_theme_variant); + model = gtk_combo_box_get_model (combo); + + for (ok = gtk_tree_model_get_iter_first (model, &iter); + ok && !found; + ok = gtk_tree_model_iter_next (model, &iter)) { + gchar *name; + gboolean is_default; -static void -preferences_notify_bool_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - preferences_widget_sync_bool (key, user_data); -} + gtk_tree_model_get (model, &iter, + COL_VARIANT_NAME, &name, + COL_VARIANT_DEFAULT, &is_default, + -1); -static void -preferences_notify_sensitivity_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - gboolean value; + if (!tp_strdiff (name, conf_name)) { + found = TRUE; + gtk_combo_box_set_active_iter (combo, &iter); + } + if (is_default) { + found_default = TRUE; + default_iter = iter; + } - if (empathy_conf_get_bool (conf, key, &value)) { - gtk_widget_set_sensitive (GTK_WIDGET (user_data), value); + g_free (name); } -} - -#if 0 -static void -preferences_widget_sync_int (const gchar *key, GtkWidget *widget) -{ - gint value; - if (empathy_conf_get_int (empathy_conf_get (), key, &value)) { - if (GTK_IS_SPIN_BUTTON (widget)) { - gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value); + /* Fallback to the first one. */ + if (!found) { + if (found_default) { + gtk_combo_box_set_active_iter (combo, &default_iter); + } else if (gtk_tree_model_get_iter_first (model, &iter)) { + gtk_combo_box_set_active_iter (combo, &iter); } } -} -static void -preferences_notify_int_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) -{ - preferences_widget_sync_int (key, user_data); + g_free (conf_name); } -static void -preferences_hookup_spin_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) +/* return TRUE if we added at least one variant */ +static gboolean +preferences_theme_variants_fill (EmpathyPreferences *preferences, + GHashTable *info) { - guint id; + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + GtkTreeModel *model; + GtkListStore *store; + GPtrArray *variants; + const gchar *default_variant; + guint i; + gboolean result = FALSE; - preferences_widget_sync_int (key, widget); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combobox_chat_theme_variant)); + store = GTK_LIST_STORE (model); + gtk_list_store_clear (store); - g_object_set_data_full (G_OBJECT (widget), "key", - g_strdup (key), g_free); + variants = empathy_adium_info_get_available_variants (info); + default_variant = empathy_adium_info_get_default_variant (info); + for (i = 0; i < variants->len; i++) { + gchar *name = g_ptr_array_index (variants, i); - g_signal_connect (widget, - "value_changed", - G_CALLBACK (preferences_spin_button_value_changed_cb), - NULL); + gtk_list_store_insert_with_values (store, NULL, -1, + COL_VARIANT_NAME, name, + COL_VARIANT_DEFAULT, !tp_strdiff (name, default_variant), + -1); - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_int_cb, - widget); - if (id) { - preferences_add_id (preferences, id); + result = TRUE; } -} -static void -preferences_hookup_entry (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) -{ - guint id; - - preferences_widget_sync_string (key, widget); - - g_object_set_data_full (G_OBJECT (widget), "key", - g_strdup (key), g_free); + /* Select the variant from the GSetting key */ + preferences_theme_variant_notify_cb (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_THEME_VARIANT, + preferences); - g_signal_connect (widget, - "changed", - G_CALLBACK (preferences_entry_value_changed_cb), - NULL); - - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_string_cb, - widget); - if (id) { - preferences_add_id (preferences, id); - } + return result; } static void -preferences_spin_button_value_changed_cb (GtkWidget *button, - gpointer user_data) +preferences_theme_variants_setup (EmpathyPreferences *preferences) { - const gchar *key; + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + GtkComboBox *combo; + GtkCellLayout *cell_layout; + GtkCellRenderer *renderer; + GtkListStore *store; - key = g_object_get_data (G_OBJECT (button), "key"); + combo = GTK_COMBO_BOX (priv->combobox_chat_theme_variant); + cell_layout = GTK_CELL_LAYOUT (combo); - empathy_conf_set_int (empathy_conf_get (), - key, - gtk_spin_button_get_value (GTK_SPIN_BUTTON (button))); -} + /* Create the model */ + store = gtk_list_store_new (COL_VARIANT_COUNT, + G_TYPE_STRING, /* name */ + G_TYPE_BOOLEAN); /* is default */ + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), + COL_VARIANT_NAME, GTK_SORT_ASCENDING); -static void -preferences_entry_value_changed_cb (GtkWidget *entry, - gpointer user_data) -{ - const gchar *key; + /* Add cell renderer */ + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); + gtk_cell_layout_set_attributes (cell_layout, renderer, + "text", COL_VARIANT_NAME, NULL); + + gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store)); + g_object_unref (store); - key = g_object_get_data (G_OBJECT (entry), "key"); + g_signal_connect (combo, "changed", + G_CALLBACK (preferences_theme_variant_changed_cb), + preferences); - empathy_conf_set_string (empathy_conf_get (), - key, - gtk_entry_get_text (GTK_ENTRY (entry))); + /* Track changes of the GSetting key */ + g_signal_connect (priv->gsettings_chat, + "changed::" EMPATHY_PREFS_CHAT_THEME_VARIANT, + G_CALLBACK (preferences_theme_variant_notify_cb), + preferences); } -#endif static void -preferences_hookup_toggle_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) +preferences_theme_changed_cb (GtkComboBox *combo, + EmpathyPreferences *preferences) { - guint id; + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + GtkTreeIter iter; - preferences_widget_sync_bool (key, widget); + if (gtk_combo_box_get_active_iter (combo, &iter)) { + GtkTreeModel *model; + gboolean is_adium; + gchar *name; + gchar *path; + GHashTable *info; - g_object_set_data_full (G_OBJECT (widget), "key", - g_strdup (key), g_free); + model = gtk_combo_box_get_model (combo); + gtk_tree_model_get (model, &iter, + COL_THEME_IS_ADIUM, &is_adium, + COL_THEME_NAME, &name, + COL_THEME_ADIUM_PATH, &path, + COL_THEME_ADIUM_INFO, &info, + -1); - g_signal_connect (widget, - "toggled", - G_CALLBACK (preferences_toggle_button_toggled_cb), - NULL); + g_settings_set_string (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_THEME, + name); + if (is_adium) { + gboolean variant; - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_bool_cb, - widget); - if (id) { - preferences_add_id (preferences, id); + g_settings_set_string (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_ADIUM_PATH, + path); + + variant = preferences_theme_variants_fill (preferences, info); + gtk_widget_set_visible (priv->hbox_chat_theme_variant, variant); + } else { + gtk_widget_hide (priv->hbox_chat_theme_variant); + } + g_free (name); + g_free (path); + tp_clear_pointer (&info, g_hash_table_unref); } } static void -preferences_hookup_radio_button (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) +preferences_theme_notify_cb (GSettings *gsettings, + const gchar *key, + gpointer user_data) { - GSList *group, *l; - guint id; + EmpathyPreferences *preferences = user_data; + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + GtkComboBox *combo; + gchar *conf_name; + gchar *conf_path; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean found = FALSE; + gboolean ok; + + conf_name = g_settings_get_string (gsettings, EMPATHY_PREFS_CHAT_THEME); + conf_path = g_settings_get_string (gsettings, EMPATHY_PREFS_CHAT_ADIUM_PATH); + + combo = GTK_COMBO_BOX (priv->combobox_chat_theme); + model = gtk_combo_box_get_model (combo); + for (ok = gtk_tree_model_get_iter_first (model, &iter); + ok && !found; + ok = gtk_tree_model_iter_next (model, &iter)) { + gboolean is_adium; + gchar *name; + gchar *path; - preferences_widget_sync_string (key, widget); + gtk_tree_model_get (model, &iter, + COL_THEME_IS_ADIUM, &is_adium, + COL_THEME_NAME, &name, + COL_THEME_ADIUM_PATH, &path, + -1); - group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget)); - for (l = group; l; l = l->next) { - g_signal_connect (l->data, - "toggled", - G_CALLBACK (preferences_radio_button_toggled_cb), - NULL); + if (!tp_strdiff (name, conf_name) && + (!is_adium || !tp_strdiff (path, conf_path))) { + found = TRUE; + gtk_combo_box_set_active_iter (combo, &iter); + } - g_object_set_data_full (G_OBJECT (l->data), "key", - g_strdup (key), g_free); + g_free (name); + g_free (path); } - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_string_cb, - widget); - if (id) { - preferences_add_id (preferences, id); + /* Fallback to the first one. */ + if (!found) { + if (gtk_tree_model_get_iter_first (model, &iter)) { + gtk_combo_box_set_active_iter (combo, &iter); + } } + + g_free (conf_name); + g_free (conf_path); } static void -preferences_hookup_string_combo (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) +preferences_themes_setup (EmpathyPreferences *preferences) { - guint id; + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); + GtkComboBox *combo; + GtkCellLayout *cell_layout; + GtkCellRenderer *renderer; + GtkListStore *store; + const gchar **themes; + GList *adium_themes; + gint i; - preferences_widget_sync_string_combo (key, widget); + preferences_theme_variants_setup (preferences); - g_object_set_data_full (G_OBJECT (widget), "key", - g_strdup (key), g_free); + combo = GTK_COMBO_BOX (priv->combobox_chat_theme); + cell_layout = GTK_CELL_LAYOUT (combo); - g_signal_connect (widget, - "changed", - G_CALLBACK (preferences_string_combo_changed_cb), - NULL); + /* Create the model */ + store = gtk_list_store_new (COL_THEME_COUNT, + G_TYPE_STRING, /* Display name */ + G_TYPE_STRING, /* Theme name */ + G_TYPE_BOOLEAN, /* Is an Adium theme */ + G_TYPE_STRING, /* Adium theme path */ + G_TYPE_HASH_TABLE); /* Adium theme info */ + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), + COL_THEME_VISIBLE_NAME, GTK_SORT_ASCENDING); - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_string_combo_cb, - widget); - if (id) { - preferences_add_id (preferences, id); + /* Fill the model */ + themes = empathy_theme_manager_get_themes (); + for (i = 0; themes[i]; i += 2) { + gtk_list_store_insert_with_values (store, NULL, -1, + COL_THEME_VISIBLE_NAME, _(themes[i + 1]), + COL_THEME_NAME, themes[i], + COL_THEME_IS_ADIUM, FALSE, + -1); } -} -static void -preferences_hookup_sensitivity (EmpathyPreferences *preferences, - const gchar *key, - GtkWidget *widget) -{ - gboolean value; - guint id; - - if (empathy_conf_get_bool (empathy_conf_get (), key, &value)) { - gtk_widget_set_sensitive (widget, value); + adium_themes = empathy_theme_manager_get_adium_themes (); + while (adium_themes != NULL) { + GHashTable *info; + const gchar *name; + const gchar *path; + + info = adium_themes->data; + name = tp_asv_get_string (info, "CFBundleName"); + path = tp_asv_get_string (info, "path"); + + if (name != NULL && path != NULL) { + gtk_list_store_insert_with_values (store, NULL, -1, + COL_THEME_VISIBLE_NAME, name, + COL_THEME_NAME, "adium", + COL_THEME_IS_ADIUM, TRUE, + COL_THEME_ADIUM_PATH, path, + COL_THEME_ADIUM_INFO, info, + -1); + } + g_hash_table_unref (info); + adium_themes = g_list_delete_link (adium_themes, adium_themes); } - id = empathy_conf_notify_add (empathy_conf_get (), - key, - preferences_notify_sensitivity_cb, - widget); - if (id) { - preferences_add_id (preferences, id); - } -} + /* Add cell renderer */ + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (cell_layout, renderer, TRUE); + gtk_cell_layout_set_attributes (cell_layout, renderer, + "text", COL_THEME_VISIBLE_NAME, NULL); -static void -preferences_toggle_button_toggled_cb (GtkWidget *button, - gpointer user_data) -{ - const gchar *key; + gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store)); + g_object_unref (store); - key = g_object_get_data (G_OBJECT (button), "key"); + g_signal_connect (combo, "changed", + G_CALLBACK (preferences_theme_changed_cb), + preferences); - empathy_conf_set_bool (empathy_conf_get (), - key, - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))); + /* Select the theme from the GSetting key and track changes */ + preferences_theme_notify_cb (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_THEME, + preferences); + g_signal_connect (priv->gsettings_chat, + "changed::" EMPATHY_PREFS_CHAT_THEME, + G_CALLBACK (preferences_theme_notify_cb), + preferences); + + g_signal_connect (priv->gsettings_chat, + "changed::" EMPATHY_PREFS_CHAT_ADIUM_PATH, + G_CALLBACK (preferences_theme_notify_cb), + preferences); } static void -preferences_radio_button_toggled_cb (GtkWidget *button, - gpointer user_data) +empathy_preferences_response (GtkDialog *widget, + gint response) { - const gchar *key; - const gchar *value = NULL; - - if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) { - return; - } - - key = g_object_get_data (G_OBJECT (button), "key"); - - if (key && strcmp (key, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM) == 0) { - GSList *group; - GType type; - GEnumClass *enum_class; - GEnumValue *enum_value; - - group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)); - - /* Get string from index */ - type = empathy_contact_list_store_sort_get_type (); - enum_class = G_ENUM_CLASS (g_type_class_peek (type)); - enum_value = g_enum_get_value (enum_class, g_slist_index (group, button)); - - if (!enum_value) { - g_warning ("No GEnumValue for EmpathyContactListSort with GtkRadioButton index:%d", - g_slist_index (group, button)); - return; - } - - value = enum_value->value_nick; - } - - empathy_conf_set_string (empathy_conf_get (), key, value); + gtk_widget_destroy (GTK_WIDGET (widget)); } static void -preferences_string_combo_changed_cb (GtkWidget *combo, - gpointer user_data) +empathy_preferences_finalize (GObject *self) { - const gchar *key; - GtkTreeModel *model; - GtkTreeIter iter; - gchar *name; + EmpathyPreferencesPriv *priv = GET_PRIV (self); - key = g_object_get_data (G_OBJECT (combo), "key"); + g_object_unref (priv->theme_manager); - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) { - model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); - - gtk_tree_model_get (model, &iter, - COL_COMBO_NAME, &name, - -1); - empathy_conf_set_string (empathy_conf_get (), key, name); - g_free (name); - } -} + g_object_unref (priv->gsettings); + g_object_unref (priv->gsettings_chat); + g_object_unref (priv->gsettings_call); + g_object_unref (priv->gsettings_loc); + g_object_unref (priv->gsettings_notify); + g_object_unref (priv->gsettings_sound); + g_object_unref (priv->gsettings_ui); + g_object_unref (priv->gsettings_logger); -static void -preferences_response_cb (GtkWidget *widget, - gint response, - EmpathyPreferences *preferences) -{ - gtk_widget_destroy (widget); + G_OBJECT_CLASS (empathy_preferences_parent_class)->finalize (self); } static void -preferences_destroy_cb (GtkWidget *widget, - EmpathyPreferences *preferences) +empathy_preferences_class_init (EmpathyPreferencesClass *klass) { - GList *l; + GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - for (l = preferences->notify_ids; l; l = l->next) { - guint id; + dialog_class->response = empathy_preferences_response; - id = GPOINTER_TO_UINT (l->data); - empathy_conf_notify_remove (empathy_conf_get (), id); - } + object_class->finalize = empathy_preferences_finalize; - g_list_free (preferences->notify_ids); - g_free (preferences); + g_type_class_add_private (object_class, + sizeof (EmpathyPreferencesPriv)); } -GtkWidget * -empathy_preferences_show (GtkWindow *parent) +static void +empathy_preferences_init (EmpathyPreferences *preferences) { - static EmpathyPreferences *preferences; + EmpathyPreferencesPriv *priv; GtkBuilder *gui; gchar *filename; + GtkWidget *page; - if (preferences) { - gtk_window_present (GTK_WINDOW (preferences->dialog)); - return preferences->dialog; - } + priv = preferences->priv = G_TYPE_INSTANCE_GET_PRIVATE (preferences, + EMPATHY_TYPE_PREFERENCES, EmpathyPreferencesPriv); + + gtk_dialog_add_button (GTK_DIALOG (preferences), + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); - preferences = g_new0 (EmpathyPreferences, 1); + gtk_container_set_border_width (GTK_CONTAINER (preferences), 5); + gtk_window_set_title (GTK_WINDOW (preferences), _("Preferences")); + gtk_window_set_role (GTK_WINDOW (preferences), "preferences"); + gtk_window_set_position (GTK_WINDOW (preferences), + GTK_WIN_POS_CENTER_ON_PARENT); + gtk_window_set_icon_name (GTK_WINDOW (preferences), "gtk-preferences"); filename = empathy_file_lookup ("empathy-preferences.ui", "src"); gui = empathy_builder_get_file (filename, - "preferences_dialog", &preferences->dialog, - "notebook", &preferences->notebook, - "checkbutton_show_avatars", &preferences->checkbutton_show_avatars, - "checkbutton_compact_contact_list", &preferences->checkbutton_compact_contact_list, - "checkbutton_show_smileys", &preferences->checkbutton_show_smileys, - "combobox_chat_theme", &preferences->combobox_chat_theme, - "checkbutton_separate_chat_windows", &preferences->checkbutton_separate_chat_windows, - "checkbutton_autoconnect", &preferences->checkbutton_autoconnect, - "radiobutton_contact_list_sort_by_name", &preferences->radiobutton_contact_list_sort_by_name, - "radiobutton_contact_list_sort_by_state", &preferences->radiobutton_contact_list_sort_by_state, - "checkbutton_notifications_enabled", &preferences->checkbutton_notifications_enabled, - "checkbutton_notifications_disabled_away", &preferences->checkbutton_notifications_disabled_away, - "checkbutton_notifications_focus", &preferences->checkbutton_notifications_focus, - "checkbutton_sounds_enabled", &preferences->checkbutton_sounds_enabled, - "checkbutton_sounds_disabled_away", &preferences->checkbutton_sounds_disabled_away, - "treeview_sounds", &preferences->treeview_sounds, - "treeview_spell_checker", &preferences->treeview_spell_checker, + "notebook", &priv->notebook, + "checkbutton_show_smileys", &priv->checkbutton_show_smileys, + "checkbutton_show_contacts_in_rooms", &priv->checkbutton_show_contacts_in_rooms, + "vbox_chat_theme", &priv->vbox_chat_theme, + "combobox_chat_theme", &priv->combobox_chat_theme, + "combobox_chat_theme_variant", &priv->combobox_chat_theme_variant, + "hbox_chat_theme_variant", &priv->hbox_chat_theme_variant, + "sw_chat_theme_preview", &priv->sw_chat_theme_preview, + "checkbutton_separate_chat_windows", &priv->checkbutton_separate_chat_windows, + "checkbutton_events_notif_area", &priv->checkbutton_events_notif_area, + "checkbutton_autoconnect", &priv->checkbutton_autoconnect, + "checkbutton_logging", &priv->checkbutton_logging, + "checkbutton_notifications_enabled", &priv->checkbutton_notifications_enabled, + "checkbutton_notifications_disabled_away", &priv->checkbutton_notifications_disabled_away, + "checkbutton_notifications_focus", &priv->checkbutton_notifications_focus, + "checkbutton_notifications_contact_signin", &priv->checkbutton_notifications_contact_signin, + "checkbutton_notifications_contact_signout", &priv->checkbutton_notifications_contact_signout, + "checkbutton_sounds_enabled", &priv->checkbutton_sounds_enabled, + "checkbutton_sounds_disabled_away", &priv->checkbutton_sounds_disabled_away, + "treeview_sounds", &priv->treeview_sounds, + "treeview_spell_checker", &priv->treeview_spell_checker, + "checkbutton_location_publish", &priv->checkbutton_location_publish, + "checkbutton_location_reduce_accuracy", &priv->checkbutton_location_reduce_accuracy, + "checkbutton_location_resource_network", &priv->checkbutton_location_resource_network, + "checkbutton_location_resource_cell", &priv->checkbutton_location_resource_cell, + "checkbutton_location_resource_gps", &priv->checkbutton_location_resource_gps, + "call_echo_cancellation", &priv->echo_cancellation, NULL); g_free (filename); - empathy_builder_connect (gui, preferences, - "preferences_dialog", "destroy", preferences_destroy_cb, - "preferences_dialog", "response", preferences_response_cb, - NULL); + gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (preferences))), priv->notebook); + gtk_widget_show (priv->notebook); g_object_unref (gui); - g_object_add_weak_pointer (G_OBJECT (preferences->dialog), (gpointer) &preferences); + priv->gsettings = g_settings_new (EMPATHY_PREFS_SCHEMA); + priv->gsettings_chat = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA); + priv->gsettings_call = g_settings_new (EMPATHY_PREFS_CALL_SCHEMA); + priv->gsettings_loc = g_settings_new (EMPATHY_PREFS_LOCATION_SCHEMA); + priv->gsettings_notify = g_settings_new (EMPATHY_PREFS_NOTIFICATIONS_SCHEMA); + priv->gsettings_sound = g_settings_new (EMPATHY_PREFS_SOUNDS_SCHEMA); + priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA); + priv->gsettings_logger = g_settings_new (EMPATHY_PREFS_LOGGER_SCHEMA); + + /* Create chat theme preview, and track changes */ + priv->theme_manager = empathy_theme_manager_dup_singleton (); + tp_g_signal_connect_object (priv->theme_manager, "theme-changed", + G_CALLBACK (preferences_preview_theme_changed_cb), + preferences, 0); + preferences_preview_theme_changed_cb (priv->theme_manager, preferences); preferences_themes_setup (preferences); @@ -1118,19 +1225,80 @@ empathy_preferences_show (GtkWindow *parent) preferences_sound_load (preferences); if (empathy_spell_supported ()) { - GtkWidget *page; - - page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (preferences->notebook), 2); + page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), EMPATHY_PREFERENCES_TAB_SPELL); gtk_widget_show (page); } - if (parent) { - gtk_window_set_transient_for (GTK_WINDOW (preferences->dialog), - GTK_WINDOW (parent)); + page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), EMPATHY_PREFERENCES_TAB_LOCATION); +#ifdef HAVE_GEOCLUE + gtk_widget_show (page); +#else + gtk_widget_hide (page); +#endif +} + +static EmpathyPreferencesTab +empathy_preferences_tab_from_string (const gchar *str) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (empathy_preferences_tabs); i++) + { + if (!tp_strdiff (str, empathy_preferences_tabs[i])) + return i; + } + + g_warn_if_reached (); + return -1; +} + +const gchar * +empathy_preferences_tab_to_string (EmpathyPreferencesTab tab) +{ + g_return_val_if_fail (tab < G_N_ELEMENTS (empathy_preferences_tabs), NULL); + + return empathy_preferences_tabs[tab]; +} + +GtkWidget * +empathy_preferences_new (GtkWindow *parent, + gboolean shell_running) +{ + GtkWidget *self; + EmpathyPreferencesPriv *priv; + GtkWidget *notif_page; + + g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL); + + self = g_object_new (EMPATHY_TYPE_PREFERENCES, NULL); + + if (parent != NULL) { + gtk_window_set_transient_for (GTK_WINDOW (self), + parent); } - gtk_widget_show (preferences->dialog); + /* when running in Gnome Shell we must hide these options since they + * are meaningless in that context: + * - 'Display incoming events in the notification area' (General->Behavior) + * - 'Notifications' tab + */ + priv = GET_PRIV (self); + if (shell_running) { + gtk_widget_hide (priv->checkbutton_events_notif_area); + notif_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), + EMPATHY_PREFERENCES_TAB_NOTIFICATIONS); + gtk_widget_hide (notif_page); + } - return preferences->dialog; + return self; } +void +empathy_preferences_show_tab (EmpathyPreferences *self, + const gchar *page) +{ + EmpathyPreferencesPriv *priv = GET_PRIV (self); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), + empathy_preferences_tab_from_string (page)); +}