/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2006-2007 Imendio AB * Copyright (C) 2007 Collabora Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * Authors: Xavier Claessens * Martyn Russell */ #include #include #include #include #include #include #include #include "empathy-account-widget.h" #include "empathy-ui-utils.h" #define DEBUG_DOMAIN "AccountWidget" static gboolean account_widget_entry_focus_cb (GtkWidget *widget, GdkEventFocus *event, McAccount *account) { const gchar *str; const gchar *param_name; str = gtk_entry_get_text (GTK_ENTRY (widget)); param_name = g_object_get_data (G_OBJECT (widget), "param_name"); if (G_STR_EMPTY (str)) { gchar *value = NULL; mc_account_unset_param (account, param_name); mc_account_get_param_string (account, param_name, &value); empathy_debug (DEBUG_DOMAIN, "Unset %s and restore to %s", param_name, value); gtk_entry_set_text (GTK_ENTRY (widget), value ? value : ""); g_free (value); } else { empathy_debug (DEBUG_DOMAIN, "Setting %s to %s", param_name, str); mc_account_set_param_string (account, param_name, str); } return FALSE; } static void account_widget_int_changed_cb (GtkWidget *widget, McAccount *account) { const gchar *param_name; gint value; value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget)); param_name = g_object_get_data (G_OBJECT (widget), "param_name"); if (value == 0) { gint val; mc_account_unset_param (account, param_name); mc_account_get_param_int (account, param_name, &val); empathy_debug (DEBUG_DOMAIN, "Unset %s and restore to %d", param_name, val); gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), val); } else { empathy_debug (DEBUG_DOMAIN, "Setting %s to %d", param_name, (gint) value); mc_account_set_param_int (account, param_name, (gint) value); } } static void account_widget_checkbutton_toggled_cb (GtkWidget *widget, McAccount *account) { gboolean value; gboolean default_value; const gchar *param_name; value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); param_name = g_object_get_data (G_OBJECT (widget), "param_name"); /* FIXME: This is ugly! checkbox don't have a "not-set" value so we * always unset the param and set the value if different from the * default value. */ mc_account_unset_param (account, param_name); mc_account_get_param_boolean (account, param_name, &default_value); if (default_value == value) { empathy_debug (DEBUG_DOMAIN, "Unset %s and restore to %d", param_name, default_value); } else { empathy_debug (DEBUG_DOMAIN, "Setting %s to %d", param_name, value); mc_account_set_param_boolean (account, param_name, value); } } static void account_widget_forget_clicked_cb (GtkWidget *button, GtkWidget *entry) { McAccount *account; const gchar *param_name; param_name = g_object_get_data (G_OBJECT (entry), "param_name"); account = g_object_get_data (G_OBJECT (entry), "account"); empathy_debug (DEBUG_DOMAIN, "Unset %s", param_name); mc_account_unset_param (account, param_name); gtk_entry_set_text (GTK_ENTRY (entry), ""); } static void account_widget_password_changed_cb (GtkWidget *entry, GtkWidget *button) { const gchar *str; str = gtk_entry_get_text (GTK_ENTRY (entry)); gtk_widget_set_sensitive (button, !G_STR_EMPTY (str)); } static void account_widget_jabber_ssl_toggled_cb (GtkWidget *checkbutton_ssl, GtkWidget *spinbutton_port) { McAccount *account; gboolean value; gint port = 0; value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl)); account = g_object_get_data (G_OBJECT (spinbutton_port), "account"); mc_account_get_param_int (account, "port", &port); if (value) { if (port == 5222 || port == 0) { port = 5223; } } else { if (port == 5223 || port == 0) { port = 5222; } } gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton_port), port); } static void account_widget_destroy_cb (GtkWidget *widget, McAccount *account) { empathy_debug (DEBUG_DOMAIN, "destroyed!"); g_object_unref (account); } static void account_widget_setup_widget (GtkWidget *widget, McAccount *account, const gchar *param_name) { g_object_set_data_full (G_OBJECT (widget), "param_name", g_strdup (param_name), g_free); if (GTK_IS_SPIN_BUTTON (widget)) { gint value = 0; mc_account_get_param_int (account, param_name, &value); gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value); g_signal_connect (widget, "value-changed", G_CALLBACK (account_widget_int_changed_cb), account); } else if (GTK_IS_ENTRY (widget)) { gchar *str = NULL; mc_account_get_param_string (account, param_name, &str); gtk_entry_set_text (GTK_ENTRY (widget), str ? str : ""); g_free (str); if (strstr (param_name, "password")) { gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE); } g_signal_connect (widget, "focus-out-event", G_CALLBACK (account_widget_entry_focus_cb), account); } else if (GTK_IS_TOGGLE_BUTTON (widget)) { gboolean value = FALSE; mc_account_get_param_boolean (account, param_name, &value); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value); g_signal_connect (widget, "toggled", G_CALLBACK (account_widget_checkbutton_toggled_cb), account); } else { empathy_debug (DEBUG_DOMAIN, "Unknown type of widget for param %s", param_name); } } static gchar * account_widget_generic_format_param_name (const gchar *param_name) { gchar *str; gchar *p; str = g_strdup (param_name); if (str && g_ascii_isalpha (str[0])) { str[0] = g_ascii_toupper (str[0]); } while ((p = strchr (str, '-')) != NULL) { if (p[1] != '\0' && g_ascii_isalpha (p[1])) { p[0] = ' '; p[1] = g_ascii_toupper (p[1]); } p++; } return str; } static void accounts_widget_generic_setup (McAccount *account, GtkWidget *table_settings) { McProtocol *protocol; McProfile *profile; GSList *params, *l; guint n_rows = 0; profile = mc_account_get_profile (account); protocol = mc_profile_get_protocol (profile); if (!protocol) { /* The CM is not installed, MC shouldn't list them * see SF bug #1688779 * FIXME: We should display something asking the user to * install the CM */ g_object_unref (profile); return; } params = mc_protocol_get_params (protocol); for (l = params; l; l = l->next) { McProtocolParam *param; GtkWidget *widget = NULL; gchar *param_name_formatted; param = l->data; param_name_formatted = account_widget_generic_format_param_name (param->name); gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2); if (param->signature[0] == 's') { gchar *str; str = g_strdup_printf (_("%s:"), param_name_formatted); widget = gtk_label_new (str); gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5); g_free (str); gtk_table_attach (GTK_TABLE (table_settings), widget, 0, 1, n_rows - 1, n_rows, GTK_FILL, 0, 0, 0); widget = gtk_entry_new (); gtk_table_attach (GTK_TABLE (table_settings), widget, 1, 2, n_rows - 1, n_rows, GTK_FILL | GTK_EXPAND, 0, 0, 0); } /* int types: ynqiuxt. double type is 'd' */ else if (param->signature[0] == 'y' || param->signature[0] == 'n' || param->signature[0] == 'q' || param->signature[0] == 'i' || param->signature[0] == 'u' || param->signature[0] == 'x' || param->signature[0] == 't' || param->signature[0] == 'd') { gchar *str = NULL; gdouble minint = 0; gdouble maxint = 0; gdouble step = 1; switch (param->signature[0]) { case 'y': minint = G_MININT8; maxint = G_MAXINT8; break; case 'n': minint = G_MININT16; maxint = G_MAXINT16; break; case 'q': minint = 0; maxint = G_MAXUINT16; break; case 'i': minint = G_MININT32; maxint = G_MAXINT32; break; case 'u': minint = 0; maxint = G_MAXUINT32; break; case 'x': minint = G_MININT64; maxint = G_MAXINT64; break; case 't': minint = 0; maxint = G_MAXUINT64; break; case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break; } str = g_strdup_printf (_("%s:"), param_name_formatted); widget = gtk_label_new (str); gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5); g_free (str); gtk_table_attach (GTK_TABLE (table_settings), widget, 0, 1, n_rows - 1, n_rows, GTK_FILL, 0, 0, 0); widget = gtk_spin_button_new_with_range (minint, maxint, step); gtk_table_attach (GTK_TABLE (table_settings), widget, 1, 2, n_rows - 1, n_rows, GTK_FILL | GTK_EXPAND, 0, 0, 0); } else if (param->signature[0] == 'b') { widget = gtk_check_button_new_with_label (param_name_formatted); gtk_table_attach (GTK_TABLE (table_settings), widget, 0, 2, n_rows - 1, n_rows, GTK_FILL | GTK_EXPAND, 0, 0, 0); } else { empathy_debug (DEBUG_DOMAIN, "Unknown signature for param %s: %s", param_name_formatted, param->signature); } if (widget) { account_widget_setup_widget (widget, account, param->name); } g_free (param_name_formatted); } g_slist_free (params); g_object_unref (profile); g_object_unref (protocol); } static GtkWidget * account_widget_new_valist (McAccount *account, GladeXML *gui, const gchar *root, const gchar *first_widget_name, va_list args) { GtkWidget *widget; const gchar *widget_name; for (widget_name = first_widget_name; widget_name; widget_name = va_arg (args, gchar*)) { const gchar *param_name; param_name = va_arg (args, gchar*); widget = glade_xml_get_widget (gui, widget_name); if (!widget) { g_warning ("Glade is missing widget '%s'.", widget_name); continue; } account_widget_setup_widget (widget, account, param_name); } widget = glade_xml_get_widget (gui, root); g_signal_connect (widget, "destroy", G_CALLBACK (account_widget_destroy_cb), g_object_ref (account)); return widget; } GtkWidget * empathy_account_widget_new_with_glade (McAccount *account, GladeXML *gui, const gchar *root, const gchar *first_widget_name, ...) { GtkWidget *widget; va_list args; g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); va_start (args, first_widget_name); widget = account_widget_new_valist (account, gui, root, first_widget_name, args); va_end (args); return widget; } void emapthy_account_widget_add_forget_button (McAccount *account, GladeXML *glade, const gchar *button, const gchar *entry) { GtkWidget *button_forget; GtkWidget *entry_password; gchar *password = NULL; button_forget = glade_xml_get_widget (glade, button); entry_password = glade_xml_get_widget (glade, entry); mc_account_get_param_string (account, "password", &password); gtk_widget_set_sensitive (button_forget, !G_STR_EMPTY (password)); g_free (password); g_signal_connect (button_forget, "clicked", G_CALLBACK (account_widget_forget_clicked_cb), entry_password); g_signal_connect (entry_password, "changed", G_CALLBACK (account_widget_password_changed_cb), button_forget); g_object_set_data_full (G_OBJECT (entry_password), "account", g_object_ref (account), g_object_unref); } GtkWidget * empathy_account_widget_generic_new (McAccount *account) { GtkWidget *table_settings; GtkWidget *sw; g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); table_settings = gtk_table_new (0, 2, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table_settings), 6); gtk_table_set_col_spacings (GTK_TABLE (table_settings), 6); sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), table_settings); accounts_widget_generic_setup (account, table_settings); g_signal_connect (sw, "destroy", G_CALLBACK (account_widget_destroy_cb), g_object_ref (account)); gtk_widget_show_all (sw); return sw; } GtkWidget * empathy_account_widget_salut_new (McAccount *account) { GladeXML *glade; GtkWidget *widget; glade = empathy_glade_get ("empathy-account-widget-salut.glade", "vbox_salut_settings", NULL); widget = empathy_account_widget_new_with_glade (account, glade, "vbox_salut_settings", "entry_published", "published-name", "entry_nickname", "nickname", "entry_first_name", "first-name", "entry_last_name", "last-name", "entry_email", "email", "entry_jid", "jid", NULL); g_object_unref (glade); gtk_widget_show (widget); return widget; } GtkWidget * empathy_account_widget_msn_new (McAccount *account) { GladeXML *glade; GtkWidget *widget; glade = empathy_glade_get ("empathy-account-widget-msn.glade", "vbox_msn_settings", NULL); widget = empathy_account_widget_new_with_glade (account, glade, "vbox_msn_settings", "entry_id", "account", "entry_password", "password", "entry_server", "server", "spinbutton_port", "port", NULL); emapthy_account_widget_add_forget_button (account, glade, "button_forget", "entry_password"); g_object_unref (glade); gtk_widget_show (widget); return widget; } GtkWidget * empathy_account_widget_jabber_new (McAccount *account) { GladeXML *glade; GtkWidget *widget; GtkWidget *spinbutton_port; GtkWidget *checkbutton_ssl; glade = empathy_glade_get_file ("empathy-account-widget-jabber.glade", "vbox_jabber_settings", NULL, "spinbutton_port", &spinbutton_port, "checkbutton_ssl", &checkbutton_ssl, NULL); widget = empathy_account_widget_new_with_glade (account, glade, "vbox_jabber_settings", "entry_id", "account", "entry_password", "password", "entry_resource", "resource", "entry_server", "server", "spinbutton_port", "port", "spinbutton_priority", "priority", "checkbutton_ssl", "old-ssl", "checkbutton_ignore_ssl_errors", "ignore-ssl-errors", "checkbutton_encryption", "require-encryption", NULL); emapthy_account_widget_add_forget_button (account, glade, "button_forget", "entry_password"); g_signal_connect (checkbutton_ssl, "toggled", G_CALLBACK (account_widget_jabber_ssl_toggled_cb), spinbutton_port); g_object_set_data_full (G_OBJECT (spinbutton_port), "account", g_object_ref (account), g_object_unref); g_object_unref (glade); gtk_widget_show (widget); return widget; }