2 * Copyright (C) 2006-2007 Imendio AB
3 * Copyright (C) 2007-2009 Collabora Ltd.
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: Xavier Claessens <xclaesse@gmail.com>
21 * Martyn Russell <martyn@imendio.com>
22 * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
23 * Jonathan Tellier <jonathan.tellier@gmail.com>
31 #include <glib/gi18n-lib.h>
34 #include <nbtk/nbtk-gtk.h>
37 #include <libempathy/empathy-utils.h>
38 #include <libempathy/empathy-idle.h>
40 #include <telepathy-glib/account.h>
41 #include <telepathy-glib/connection-manager.h>
42 #include <telepathy-glib/util.h>
43 #include <dbus/dbus-protocol.h>
45 #include "empathy-account-widget.h"
46 #include "empathy-account-widget-private.h"
47 #include "empathy-account-widget-sip.h"
48 #include "empathy-account-widget-irc.h"
49 #include "empathy-ui-utils.h"
51 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
52 #include <libempathy/empathy-debug.h>
54 G_DEFINE_TYPE (EmpathyAccountWidget, empathy_account_widget, G_TYPE_OBJECT)
57 EmpathyAccountSettings *settings;
59 GtkWidget *table_common_settings;
60 GtkWidget *apply_button;
61 GtkWidget *cancel_button;
62 GtkWidget *entry_password;
63 GtkWidget *button_forget;
64 GtkWidget *spinbutton_port;
65 GtkWidget *enabled_checkbox;
69 gboolean contains_pending_changes;
71 /* An EmpathyAccountWidget can be used to either create an account or
72 * modify it. When we are creating an account, this member is set to TRUE */
73 gboolean creating_account;
78 } EmpathyAccountWidgetPriv;
94 static guint signals[LAST_SIGNAL] = { 0 };
96 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountWidget)
97 #define CHANGED_TIMEOUT 300
100 account_widget_set_control_buttons_sensitivity (EmpathyAccountWidget *self,
103 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
107 gtk_widget_set_sensitive (priv->apply_button, sensitive);
108 gtk_widget_set_sensitive (
109 priv->cancel_button, sensitive || priv->creating_account);
111 priv->contains_pending_changes = sensitive;
116 account_widget_handle_control_buttons_sensitivity (EmpathyAccountWidget *self)
118 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
121 is_valid = empathy_account_settings_is_valid (priv->settings);
124 account_widget_set_control_buttons_sensitivity (self, is_valid);
126 g_signal_emit (self, signals[HANDLE_APPLY], 0, is_valid);
130 account_widget_entry_changed_common (EmpathyAccountWidget *self,
131 GtkEntry *entry, gboolean focus)
134 const gchar *param_name;
135 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
137 str = gtk_entry_get_text (entry);
138 param_name = g_object_get_data (G_OBJECT (entry), "param_name");
140 if (EMP_STR_EMPTY (str))
142 const gchar *value = NULL;
144 empathy_account_settings_unset (priv->settings, param_name);
148 value = empathy_account_settings_get_string (priv->settings,
150 DEBUG ("Unset %s and restore to %s", param_name, value);
151 gtk_entry_set_text (entry, value ? value : "");
156 DEBUG ("Setting %s to %s", param_name,
157 tp_strdiff (param_name, "password") ? str : "***");
158 empathy_account_settings_set_string (priv->settings, param_name, str);
163 account_widget_entry_changed_cb (GtkEditable *entry,
164 EmpathyAccountWidget *self)
166 account_widget_entry_changed_common (self, GTK_ENTRY (entry), FALSE);
167 account_widget_handle_control_buttons_sensitivity (self);
171 account_widget_int_changed_cb (GtkWidget *widget,
172 EmpathyAccountWidget *self)
174 const gchar *param_name;
176 const gchar *signature;
177 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
179 value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
180 param_name = g_object_get_data (G_OBJECT (widget), "param_name");
182 signature = empathy_account_settings_get_dbus_signature (priv->settings,
184 g_return_if_fail (signature != NULL);
186 DEBUG ("Setting %s to %d", param_name, value);
188 switch ((int)*signature)
190 case DBUS_TYPE_INT16:
191 case DBUS_TYPE_INT32:
192 empathy_account_settings_set_int32 (priv->settings, param_name, value);
194 case DBUS_TYPE_INT64:
195 empathy_account_settings_set_int64 (priv->settings, param_name, value);
197 case DBUS_TYPE_UINT16:
198 case DBUS_TYPE_UINT32:
199 empathy_account_settings_set_uint32 (priv->settings, param_name, value);
201 case DBUS_TYPE_UINT64:
202 empathy_account_settings_set_uint64 (priv->settings, param_name, value);
205 g_return_if_reached ();
208 account_widget_handle_control_buttons_sensitivity (self);
212 account_widget_checkbutton_toggled_cb (GtkWidget *widget,
213 EmpathyAccountWidget *self)
216 gboolean default_value;
217 const gchar *param_name;
218 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
220 value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
221 param_name = g_object_get_data (G_OBJECT (widget), "param_name");
223 /* FIXME: This is ugly! checkbox don't have a "not-set" value so we
224 * always unset the param and set the value if different from the
226 empathy_account_settings_unset (priv->settings, param_name);
227 default_value = empathy_account_settings_get_boolean (priv->settings,
230 if (default_value == value)
232 DEBUG ("Unset %s and restore to %d", param_name, default_value);
236 DEBUG ("Setting %s to %d", param_name, value);
237 empathy_account_settings_set_boolean (priv->settings, param_name, value);
240 account_widget_handle_control_buttons_sensitivity (self);
244 account_widget_forget_clicked_cb (GtkWidget *button,
245 EmpathyAccountWidget *self)
247 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
248 const gchar *param_name;
250 param_name = g_object_get_data (G_OBJECT (priv->entry_password),
253 DEBUG ("Unset %s", param_name);
254 empathy_account_settings_unset (priv->settings, param_name);
255 gtk_entry_set_text (GTK_ENTRY (priv->entry_password), "");
257 account_widget_handle_control_buttons_sensitivity (self);
261 account_widget_password_changed_cb (GtkWidget *entry,
262 EmpathyAccountWidget *self)
264 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
267 str = gtk_entry_get_text (GTK_ENTRY (entry));
268 gtk_widget_set_sensitive (priv->button_forget, !EMP_STR_EMPTY (str));
272 account_widget_jabber_ssl_toggled_cb (GtkWidget *checkbutton_ssl,
273 EmpathyAccountWidget *self)
275 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
279 value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl));
280 port = empathy_account_settings_get_uint32 (priv->settings, "port");
284 if (port == 5222 || port == 0)
289 if (port == 5223 || port == 0)
293 gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->spinbutton_port), port);
297 account_widget_setup_widget (EmpathyAccountWidget *self,
299 const gchar *param_name)
301 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
303 g_object_set_data_full (G_OBJECT (widget), "param_name",
304 g_strdup (param_name), g_free);
306 if (GTK_IS_SPIN_BUTTON (widget))
309 const gchar *signature;
311 signature = empathy_account_settings_get_dbus_signature (priv->settings,
313 g_return_if_fail (signature != NULL);
315 switch ((int)*signature)
317 case DBUS_TYPE_INT16:
318 case DBUS_TYPE_INT32:
319 value = empathy_account_settings_get_int32 (priv->settings,
322 case DBUS_TYPE_INT64:
323 value = empathy_account_settings_get_int64 (priv->settings,
326 case DBUS_TYPE_UINT16:
327 case DBUS_TYPE_UINT32:
328 value = empathy_account_settings_get_uint32 (priv->settings,
331 case DBUS_TYPE_UINT64:
332 value = empathy_account_settings_get_uint64 (priv->settings,
336 g_return_if_reached ();
339 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
341 g_signal_connect (widget, "value-changed",
342 G_CALLBACK (account_widget_int_changed_cb),
345 else if (GTK_IS_ENTRY (widget))
347 const gchar *str = NULL;
349 str = empathy_account_settings_get_string (priv->settings, param_name);
350 gtk_entry_set_text (GTK_ENTRY (widget), str ? str : "");
352 if (strstr (param_name, "password"))
354 gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
357 g_signal_connect (widget, "changed",
358 G_CALLBACK (account_widget_entry_changed_cb), self);
360 else if (GTK_IS_TOGGLE_BUTTON (widget))
362 gboolean value = FALSE;
364 value = empathy_account_settings_get_boolean (priv->settings,
366 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
368 g_signal_connect (widget, "toggled",
369 G_CALLBACK (account_widget_checkbutton_toggled_cb),
374 DEBUG ("Unknown type of widget for param %s", param_name);
379 account_widget_generic_format_param_name (const gchar *param_name)
384 str = g_strdup (param_name);
386 if (str && g_ascii_isalpha (str[0]))
387 str[0] = g_ascii_toupper (str[0]);
389 while ((p = strchr (str, '-')) != NULL)
391 if (p[1] != '\0' && g_ascii_isalpha (p[1]))
394 p[1] = g_ascii_toupper (p[1]);
404 accounts_widget_generic_setup (EmpathyAccountWidget *self,
405 GtkWidget *table_common_settings,
406 GtkWidget *table_advanced_settings)
408 TpConnectionManagerParam *params, *param;
409 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
411 params = empathy_account_settings_get_tp_params (priv->settings);
413 for (param = params; param != NULL && param->name != NULL; param++)
415 GtkWidget *table_settings;
417 GtkWidget *widget = NULL;
418 gchar *param_name_formatted;
420 if (param->flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED)
421 table_settings = table_common_settings;
422 else if (priv->simple)
425 table_settings = table_advanced_settings;
427 param_name_formatted = account_widget_generic_format_param_name
429 g_object_get (table_settings, "n-rows", &n_rows, NULL);
430 gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2);
432 if (param->dbus_signature[0] == 's')
436 str = g_strdup_printf (_("%s:"), param_name_formatted);
437 widget = gtk_label_new (str);
438 gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
441 gtk_table_attach (GTK_TABLE (table_settings),
447 gtk_widget_show (widget);
449 widget = gtk_entry_new ();
450 if (strcmp (param->name, "account") == 0)
452 g_signal_connect (widget, "realize",
453 G_CALLBACK (gtk_widget_grab_focus),
456 gtk_table_attach (GTK_TABLE (table_settings),
460 GTK_FILL | GTK_EXPAND, 0,
462 gtk_widget_show (widget);
464 /* int types: ynqiuxt. double type is 'd' */
465 else if (param->dbus_signature[0] == 'y' ||
466 param->dbus_signature[0] == 'n' ||
467 param->dbus_signature[0] == 'q' ||
468 param->dbus_signature[0] == 'i' ||
469 param->dbus_signature[0] == 'u' ||
470 param->dbus_signature[0] == 'x' ||
471 param->dbus_signature[0] == 't' ||
472 param->dbus_signature[0] == 'd')
479 switch (param->dbus_signature[0])
481 case 'y': minint = G_MININT8; maxint = G_MAXINT8; break;
482 case 'n': minint = G_MININT16; maxint = G_MAXINT16; break;
483 case 'q': minint = 0; maxint = G_MAXUINT16; break;
484 case 'i': minint = G_MININT32; maxint = G_MAXINT32; break;
485 case 'u': minint = 0; maxint = G_MAXUINT32; break;
486 case 'x': minint = G_MININT64; maxint = G_MAXINT64; break;
487 case 't': minint = 0; maxint = G_MAXUINT64; break;
488 case 'd': minint = G_MININT32; maxint = G_MAXINT32;
492 str = g_strdup_printf (_("%s:"), param_name_formatted);
493 widget = gtk_label_new (str);
494 gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
497 gtk_table_attach (GTK_TABLE (table_settings),
503 gtk_widget_show (widget);
505 widget = gtk_spin_button_new_with_range (minint, maxint, step);
506 gtk_table_attach (GTK_TABLE (table_settings),
510 GTK_FILL | GTK_EXPAND, 0,
512 gtk_widget_show (widget);
514 else if (param->dbus_signature[0] == 'b')
516 widget = gtk_check_button_new_with_label (param_name_formatted);
517 gtk_table_attach (GTK_TABLE (table_settings),
521 GTK_FILL | GTK_EXPAND, 0,
523 gtk_widget_show (widget);
527 DEBUG ("Unknown signature for param %s: %s",
528 param_name_formatted, param->dbus_signature);
532 account_widget_setup_widget (self, widget, param->name);
534 g_free (param_name_formatted);
539 account_widget_handle_params_valist (EmpathyAccountWidget *self,
540 const gchar *first_widget,
546 for (name = first_widget; name; name = va_arg (args, const gchar *))
548 const gchar *param_name;
550 param_name = va_arg (args, const gchar *);
551 object = gtk_builder_get_object (self->ui_details->gui, name);
555 g_warning ("Builder is missing object '%s'.", name);
559 account_widget_setup_widget (self, GTK_WIDGET (object), param_name);
564 account_widget_cancel_clicked_cb (GtkWidget *button,
565 EmpathyAccountWidget *self)
567 g_signal_emit (self, signals[CANCELLED], 0);
571 account_widget_account_enabled_cb (GObject *source_object,
575 GError *error = NULL;
576 TpAccount *account = TP_ACCOUNT (source_object);
577 EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
579 tp_account_set_enabled_finish (account, res, &error);
583 DEBUG ("Could not automatically enable new account: %s", error->message);
584 g_error_free (error);
588 g_signal_emit (widget, signals[ACCOUNT_CREATED], 0);
593 account_widget_applied_cb (GObject *source_object,
597 GError *error = NULL;
599 EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (source_object);
600 EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
601 EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
603 empathy_account_settings_apply_finish (settings, res, &error);
607 DEBUG ("Could not apply changes to account: %s", error->message);
608 g_error_free (error);
612 account = empathy_account_settings_get_account (priv->settings);
616 if (priv->creating_account)
618 /* By default, when an account is created, we enable it. */
619 tp_account_set_enabled_async (account, TRUE,
620 account_widget_account_enabled_cb, widget);
622 else if (priv->enabled_checkbox != NULL)
624 gboolean enabled_checked;
628 gtk_toggle_button_get_active (
629 GTK_TOGGLE_BUTTON (priv->enabled_checkbox));
631 nbtk_gtk_light_switch_get_active (
632 NBTK_GTK_LIGHT_SWITCH (priv->enabled_checkbox));
635 if (tp_account_is_enabled (account) && enabled_checked)
637 /* After having applied changes to a user account, we
638 * automatically reconnect it. This is done so the new
639 * information entered by the user is validated on the server. */
640 tp_account_reconnect_async (account, NULL, NULL);
645 account_widget_set_control_buttons_sensitivity (widget, FALSE);
649 account_widget_apply_clicked_cb (GtkWidget *button,
650 EmpathyAccountWidget *self)
652 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
654 empathy_account_settings_apply_async (priv->settings,
655 account_widget_applied_cb, self);
659 account_widget_setup_generic (EmpathyAccountWidget *self)
661 GtkWidget *table_common_settings;
662 GtkWidget *table_advanced_settings;
664 table_common_settings = GTK_WIDGET (gtk_builder_get_object
665 (self->ui_details->gui, "table_common_settings"));
666 table_advanced_settings = GTK_WIDGET (gtk_builder_get_object
667 (self->ui_details->gui, "table_advanced_settings"));
669 accounts_widget_generic_setup (self, table_common_settings,
670 table_advanced_settings);
672 g_object_unref (self->ui_details->gui);
676 account_widget_settings_ready_cb (EmpathyAccountSettings *settings,
680 EmpathyAccountWidget *self = user_data;
681 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
683 if (empathy_account_settings_is_ready (priv->settings))
684 account_widget_setup_generic (self);
688 account_widget_build_generic (EmpathyAccountWidget *self,
689 const char *filename)
691 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
692 GtkWidget *expander_advanced;
694 self->ui_details->gui = empathy_builder_get_file (filename,
695 "table_common_settings", &priv->table_common_settings,
696 "vbox_generic_settings", &self->ui_details->widget,
697 "expander_advanced_settings", &expander_advanced,
701 gtk_widget_hide (expander_advanced);
703 g_object_ref (self->ui_details->gui);
705 if (empathy_account_settings_is_ready (priv->settings))
706 account_widget_setup_generic (self);
708 g_signal_connect (priv->settings, "notify::ready",
709 G_CALLBACK (account_widget_settings_ready_cb), self);
713 account_widget_build_salut (EmpathyAccountWidget *self,
714 const char *filename)
716 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
718 self->ui_details->gui = empathy_builder_get_file (filename,
719 "table_common_settings", &priv->table_common_settings,
720 "vbox_salut_settings", &self->ui_details->widget,
723 empathy_account_widget_handle_params (self,
724 "entry_published", "published-name",
725 "entry_nickname", "nickname",
726 "entry_first_name", "first-name",
727 "entry_last_name", "last-name",
728 "entry_email", "email",
732 self->ui_details->default_focus = g_strdup ("entry_nickname");
736 account_widget_build_irc (EmpathyAccountWidget *self,
737 const char *filename)
739 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
740 empathy_account_widget_irc_build (self, filename,
741 &priv->table_common_settings);
745 account_widget_build_sip (EmpathyAccountWidget *self,
746 const char *filename)
748 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
749 empathy_account_widget_sip_build (self, filename,
750 &priv->table_common_settings);
754 account_widget_build_msn (EmpathyAccountWidget *self,
755 const char *filename)
757 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
761 self->ui_details->gui = empathy_builder_get_file (filename,
762 "vbox_msn_simple", &self->ui_details->widget,
765 empathy_account_widget_handle_params (self,
766 "entry_id_simple", "account",
767 "entry_password_simple", "password",
770 self->ui_details->default_focus = g_strdup ("entry_id_simple");
774 self->ui_details->gui = empathy_builder_get_file (filename,
775 "table_common_msn_settings", &priv->table_common_settings,
776 "vbox_msn_settings", &self->ui_details->widget,
779 empathy_account_widget_handle_params (self,
780 "entry_id", "account",
781 "entry_password", "password",
782 "entry_server", "server",
783 "spinbutton_port", "port",
786 self->ui_details->default_focus = g_strdup ("entry_id");
787 self->ui_details->add_forget = TRUE;
792 account_widget_build_jabber (EmpathyAccountWidget *self,
793 const char *filename)
795 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
796 GtkWidget *spinbutton_port;
797 GtkWidget *checkbutton_ssl;
798 GtkWidget *label_id, *label_password;
799 GtkWidget *label_id_create, *label_password_create;
800 GtkWidget *label_example_gtalk, *label_example_jabber;
803 is_gtalk = !tp_strdiff (
804 empathy_account_settings_get_icon_name (priv->settings),
807 if (priv->simple && !is_gtalk)
809 self->ui_details->gui = empathy_builder_get_file (filename,
810 "vbox_jabber_simple", &self->ui_details->widget,
811 "label_id_simple", &label_id,
812 "label_id_create", &label_id_create,
813 "label_password_simple", &label_password,
814 "label_password_create", &label_password_create,
817 if (empathy_account_settings_get_boolean (priv->settings, "register"))
819 gtk_widget_hide (label_id);
820 gtk_widget_hide (label_password);
821 gtk_widget_show (label_id_create);
822 gtk_widget_show (label_password_create);
825 empathy_account_widget_handle_params (self,
826 "entry_id_simple", "account",
827 "entry_password_simple", "password",
830 self->ui_details->default_focus = g_strdup ("entry_id_simple");
832 else if (priv->simple && is_gtalk)
834 self->ui_details->gui = empathy_builder_get_file (filename,
835 "vbox_gtalk_simple", &self->ui_details->widget,
838 empathy_account_widget_handle_params (self,
839 "entry_id_g_simple", "account",
840 "entry_password_g_simple", "password",
843 self->ui_details->default_focus = g_strdup ("entry_id_g_simple");
847 self->ui_details->gui = empathy_builder_get_file (filename,
848 "table_common_settings", &priv->table_common_settings,
849 "vbox_jabber_settings", &self->ui_details->widget,
850 "spinbutton_port", &spinbutton_port,
851 "checkbutton_ssl", &checkbutton_ssl,
852 "label_username_example", &label_example_jabber,
853 "label_username_g_example", &label_example_gtalk,
856 empathy_account_widget_handle_params (self,
857 "entry_id", "account",
858 "entry_password", "password",
859 "entry_resource", "resource",
860 "entry_server", "server",
861 "spinbutton_port", "port",
862 "spinbutton_priority", "priority",
863 "checkbutton_ssl", "old-ssl",
864 "checkbutton_ignore_ssl_errors", "ignore-ssl-errors",
865 "checkbutton_encryption", "require-encryption",
868 self->ui_details->default_focus = g_strdup ("entry_id");
869 self->ui_details->add_forget = TRUE;
870 priv->spinbutton_port = spinbutton_port;
872 g_signal_connect (checkbutton_ssl, "toggled",
873 G_CALLBACK (account_widget_jabber_ssl_toggled_cb),
878 gtk_widget_hide (label_example_jabber);
879 gtk_widget_show (label_example_gtalk);
885 account_widget_build_icq (EmpathyAccountWidget *self,
886 const char *filename)
888 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
889 GtkWidget *spinbutton_port;
893 self->ui_details->gui = empathy_builder_get_file (filename,
894 "vbox_icq_simple", &self->ui_details->widget,
897 empathy_account_widget_handle_params (self,
898 "entry_uin_simple", "account",
899 "entry_password_simple", "password",
902 self->ui_details->default_focus = g_strdup ("entry_uin_simple");
906 self->ui_details->gui = empathy_builder_get_file (filename,
907 "table_common_settings", &priv->table_common_settings,
908 "vbox_icq_settings", &self->ui_details->widget,
909 "spinbutton_port", &spinbutton_port,
912 empathy_account_widget_handle_params (self,
913 "entry_uin", "account",
914 "entry_password", "password",
915 "entry_server", "server",
916 "spinbutton_port", "port",
917 "entry_charset", "charset",
920 self->ui_details->default_focus = g_strdup ("entry_uin");
921 self->ui_details->add_forget = TRUE;
926 account_widget_build_aim (EmpathyAccountWidget *self,
927 const char *filename)
929 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
930 GtkWidget *spinbutton_port;
934 self->ui_details->gui = empathy_builder_get_file (filename,
935 "vbox_aim_simple", &self->ui_details->widget,
938 empathy_account_widget_handle_params (self,
939 "entry_screenname_simple", "account",
940 "entry_password_simple", "password",
943 self->ui_details->default_focus = g_strdup ("entry_screenname_simple");
947 self->ui_details->gui = empathy_builder_get_file (filename,
948 "table_common_settings", &priv->table_common_settings,
949 "vbox_aim_settings", &self->ui_details->widget,
950 "spinbutton_port", &spinbutton_port,
953 empathy_account_widget_handle_params (self,
954 "entry_screenname", "account",
955 "entry_password", "password",
956 "entry_server", "server",
957 "spinbutton_port", "port",
960 self->ui_details->default_focus = g_strdup ("entry_screenname");
961 self->ui_details->add_forget = TRUE;
966 account_widget_build_yahoo (EmpathyAccountWidget *self,
967 const char *filename)
969 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
973 self->ui_details->gui = empathy_builder_get_file (filename,
974 "vbox_yahoo_simple", &self->ui_details->widget,
977 empathy_account_widget_handle_params (self,
978 "entry_id_simple", "account",
979 "entry_password_simple", "password",
982 self->ui_details->default_focus = g_strdup ("entry_id_simple");
986 self->ui_details->gui = empathy_builder_get_file (filename,
987 "table_common_settings", &priv->table_common_settings,
988 "vbox_yahoo_settings", &self->ui_details->widget,
991 empathy_account_widget_handle_params (self,
992 "entry_id", "account",
993 "entry_password", "password",
994 "entry_server", "server",
995 "entry_locale", "room-list-locale",
996 "entry_charset", "charset",
997 "spinbutton_port", "port",
998 "checkbutton_yahoojp", "yahoojp",
999 "checkbutton_ignore_invites", "ignore-invites",
1002 self->ui_details->default_focus = g_strdup ("entry_id");
1003 self->ui_details->add_forget = TRUE;
1008 account_widget_build_groupwise (EmpathyAccountWidget *self,
1009 const char *filename)
1011 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1015 self->ui_details->gui = empathy_builder_get_file (filename,
1016 "vbox_groupwise_simple", &self->ui_details->widget,
1019 empathy_account_widget_handle_params (self,
1020 "entry_id_simple", "account",
1021 "entry_password_simple", "password",
1024 self->ui_details->default_focus = g_strdup ("entry_id_simple");
1028 self->ui_details->gui = empathy_builder_get_file (filename,
1029 "table_common_groupwise_settings", &priv->table_common_settings,
1030 "vbox_groupwise_settings", &self->ui_details->widget,
1033 empathy_account_widget_handle_params (self,
1034 "entry_id", "account",
1035 "entry_password", "password",
1036 "entry_server", "server",
1037 "spinbutton_port", "port",
1040 self->ui_details->default_focus = g_strdup ("entry_id");
1041 self->ui_details->add_forget = TRUE;
1046 account_widget_destroy_cb (GtkWidget *widget,
1047 EmpathyAccountWidget *self)
1049 g_object_unref (self);
1053 empathy_account_widget_enabled_cb (TpAccount *account,
1057 EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
1058 EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1059 gboolean enabled = tp_account_is_enabled (account);
1061 if (priv->enabled_checkbox != NULL)
1064 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->enabled_checkbox),
1067 nbtk_gtk_light_switch_set_active (
1068 NBTK_GTK_LIGHT_SWITCH (priv->enabled_checkbox),
1070 #endif /* HAVE_MOBLIN */
1076 account_widget_enabled_released_cb (GtkToggleButton *toggle_button,
1079 account_widget_switch_flipped_cb (NbtkGtkLightSwitch *sw,
1082 #endif /* HAVE_MOBLIN */
1084 EmpathyAccountWidgetPriv *priv = GET_PRIV (user_data);
1089 state = gtk_toggle_button_get_active (toggle_button);
1092 account = empathy_account_settings_get_account (priv->settings);
1094 /* Enable the account according to the value of the "Enabled" checkbox */
1095 tp_account_set_enabled_async (account, state, NULL, NULL);
1099 do_set_property (GObject *object,
1101 const GValue *value,
1104 EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
1109 priv->settings = g_value_dup_object (value);
1112 priv->simple = g_value_get_boolean (value);
1114 case PROP_CREATING_ACCOUNT:
1115 priv->creating_account = g_value_get_boolean (value);
1118 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1123 do_get_property (GObject *object,
1128 EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
1133 g_value_set_string (value,
1134 empathy_account_settings_get_protocol (priv->settings));
1137 g_value_set_object (value, priv->settings);
1140 g_value_set_boolean (value, priv->simple);
1142 case PROP_CREATING_ACCOUNT:
1143 g_value_set_boolean (value, priv->creating_account);
1146 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1150 #define WIDGET(cm, proto) \
1151 { #cm, #proto, "empathy-account-widget-"#proto".ui", \
1152 account_widget_build_##proto }
1155 do_constructed (GObject *obj)
1157 EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1158 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1160 const gchar *protocol, *cm_name;
1163 const gchar *cm_name;
1164 const gchar *protocol;
1166 void (*func)(EmpathyAccountWidget *self, const gchar *filename);
1168 { "salut", "local-xmpp", "empathy-account-widget-local-xmpp.ui",
1169 account_widget_build_salut },
1170 WIDGET (gabble, jabber),
1171 WIDGET (butterfly, msn),
1174 WIDGET (haze, yahoo),
1175 WIDGET (haze, groupwise),
1177 WIDGET (sofiasip, sip),
1180 cm_name = empathy_account_settings_get_cm (priv->settings);
1181 protocol = empathy_account_settings_get_protocol (priv->settings);
1183 for (i = 0 ; i < G_N_ELEMENTS (widgets); i++)
1185 if (!tp_strdiff (widgets[i].cm_name, cm_name) &&
1186 !tp_strdiff (widgets[i].protocol, protocol))
1190 filename = empathy_file_lookup (widgets[i].file,
1192 widgets[i].func (self, filename);
1199 if (i == G_N_ELEMENTS (widgets))
1201 gchar *filename = empathy_file_lookup (
1202 "empathy-account-widget-generic.ui", "libempathy-gtk");
1203 account_widget_build_generic (self, filename);
1207 /* handle default focus */
1208 if (self->ui_details->default_focus != NULL)
1210 GObject *default_focus_entry;
1212 default_focus_entry = gtk_builder_get_object
1213 (self->ui_details->gui, self->ui_details->default_focus);
1214 g_signal_connect (default_focus_entry, "realize",
1215 G_CALLBACK (gtk_widget_grab_focus),
1219 /* handle forget button */
1220 if (self->ui_details->add_forget)
1222 const gchar *password = NULL;
1224 priv->button_forget = GTK_WIDGET (gtk_builder_get_object
1225 (self->ui_details->gui, "button_forget"));
1226 priv->entry_password = GTK_WIDGET (gtk_builder_get_object
1227 (self->ui_details->gui, "entry_password"));
1229 password = empathy_account_settings_get_string (priv->settings,
1231 gtk_widget_set_sensitive (priv->button_forget,
1232 !EMP_STR_EMPTY (password));
1234 g_signal_connect (priv->button_forget, "clicked",
1235 G_CALLBACK (account_widget_forget_clicked_cb),
1237 g_signal_connect (priv->entry_password, "changed",
1238 G_CALLBACK (account_widget_password_changed_cb),
1242 /* handle apply and cancel button */
1245 GtkWidget *hbox = gtk_hbox_new (TRUE, 3);
1246 const gchar *apply_button_id;
1248 priv->cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
1250 if (priv->creating_account)
1252 TpConnectionPresenceType state;
1253 priv->idle = empathy_idle_dup_singleton ();
1255 state = empathy_idle_get_state (priv->idle);
1257 if (state > TP_CONNECTION_PRESENCE_TYPE_OFFLINE)
1259 /* We are online, display a Connect button */
1260 apply_button_id = GTK_STOCK_CONNECT;
1264 /* We are offline, display a Save button */
1265 apply_button_id = GTK_STOCK_SAVE;
1270 /* We are editing an existing account, display an Apply button */
1271 apply_button_id = GTK_STOCK_APPLY;
1274 priv->apply_button = gtk_button_new_from_stock (apply_button_id);
1277 if (priv->creating_account)
1278 /* Translators: this is used only when built on a moblin platform */
1279 gtk_button_set_label (GTK_BUTTON (priv->apply_button),
1283 gtk_box_pack_end (GTK_BOX (hbox), priv->apply_button, TRUE,
1285 gtk_box_pack_end (GTK_BOX (hbox), priv->cancel_button, TRUE,
1288 gtk_box_pack_end (GTK_BOX (self->ui_details->widget), hbox, FALSE,
1291 g_signal_connect (priv->cancel_button, "clicked",
1292 G_CALLBACK (account_widget_cancel_clicked_cb),
1294 g_signal_connect (priv->apply_button, "clicked",
1295 G_CALLBACK (account_widget_apply_clicked_cb),
1297 gtk_widget_show_all (hbox);
1299 if (priv->creating_account)
1300 /* When creating an account, the user might have nothing to enter.
1301 * That means that no control interaction might occur,
1302 * so we update the control button sensitivity manually.
1304 account_widget_handle_control_buttons_sensitivity (self);
1306 account_widget_set_control_buttons_sensitivity (self, FALSE);
1309 account = empathy_account_settings_get_account (priv->settings);
1311 if (account != NULL)
1313 g_signal_connect (account, "notify::enabled",
1314 G_CALLBACK (empathy_account_widget_enabled_cb), self);
1317 /* handle the "Enabled" checkbox. We only add it when modifying an account */
1318 if (!priv->creating_account && priv->table_common_settings != NULL)
1323 guint nb_rows, nb_columns;
1324 gboolean is_enabled;
1326 is_enabled = tp_account_is_enabled (account);
1329 priv->enabled_checkbox =
1330 gtk_check_button_new_with_label (_("Enabled"));
1332 gtk_toggle_button_set_active (
1333 GTK_TOGGLE_BUTTON (priv->enabled_checkbox), is_enabled);
1335 /* Translators: this is used only when built on a moblin platform */
1336 w = gtk_label_new (_("Account:"));
1337 gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
1339 priv->enabled_checkbox = nbtk_gtk_light_switch_new ();
1341 nbtk_gtk_light_switch_set_active (
1342 NBTK_GTK_LIGHT_SWITCH (priv->enabled_checkbox), is_enabled);
1344 gtk_widget_show (w);
1345 #endif /* HAVE_MOBLIN */
1347 g_object_get (priv->table_common_settings, "n-rows", &nb_rows,
1348 "n-columns", &nb_columns, NULL);
1350 gtk_table_resize (GTK_TABLE (priv->table_common_settings), ++nb_rows,
1354 gtk_table_attach (GTK_TABLE (priv->table_common_settings),
1355 priv->enabled_checkbox,
1356 0, nb_columns, nb_rows - 1, nb_rows,
1357 GTK_EXPAND | GTK_FILL, 0, 0, 0);
1359 gtk_table_attach (GTK_TABLE (priv->table_common_settings),
1361 0, 1, nb_rows - 1, nb_rows,
1363 gtk_table_attach (GTK_TABLE (priv->table_common_settings),
1364 priv->enabled_checkbox,
1365 1, nb_columns, nb_rows - 1, nb_rows,
1366 GTK_EXPAND | GTK_FILL, 0, 0, 0);
1367 #endif /* HAVE_MOBLIN */
1369 gtk_widget_show (priv->enabled_checkbox);
1372 g_signal_connect (G_OBJECT (priv->enabled_checkbox), "released",
1373 G_CALLBACK (account_widget_enabled_released_cb), self);
1375 g_signal_connect (G_OBJECT (priv->enabled_checkbox), "switch-flipped",
1376 G_CALLBACK (account_widget_switch_flipped_cb), self);
1377 #endif /* HAVE_MOBLIN */
1380 /* hook up to widget destruction to unref ourselves */
1381 g_signal_connect (self->ui_details->widget, "destroy",
1382 G_CALLBACK (account_widget_destroy_cb), self);
1384 empathy_builder_unref_and_keep_widget (self->ui_details->gui,
1385 self->ui_details->widget);
1386 self->ui_details->gui = NULL;
1390 do_dispose (GObject *obj)
1392 EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1393 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1395 if (priv->dispose_run)
1398 priv->dispose_run = TRUE;
1400 empathy_account_settings_is_ready (priv->settings);
1402 if (priv->settings != NULL)
1405 account = empathy_account_settings_get_account (priv->settings);
1407 if (account != NULL)
1409 g_signal_handlers_disconnect_by_func (account,
1410 empathy_account_widget_enabled_cb, self);
1413 g_object_unref (priv->settings);
1414 priv->settings = NULL;
1417 if (priv->idle != NULL)
1419 g_object_unref (priv->idle);
1423 if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose != NULL)
1424 G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose (obj);
1428 do_finalize (GObject *obj)
1430 EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1432 g_free (self->ui_details->default_focus);
1433 g_slice_free (EmpathyAccountWidgetUIDetails, self->ui_details);
1435 if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize != NULL)
1436 G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize (obj);
1440 empathy_account_widget_class_init (EmpathyAccountWidgetClass *klass)
1442 GObjectClass *oclass = G_OBJECT_CLASS (klass);
1443 GParamSpec *param_spec;
1445 oclass->get_property = do_get_property;
1446 oclass->set_property = do_set_property;
1447 oclass->constructed = do_constructed;
1448 oclass->dispose = do_dispose;
1449 oclass->finalize = do_finalize;
1451 param_spec = g_param_spec_string ("protocol",
1452 "protocol", "The protocol of the account",
1454 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
1455 g_object_class_install_property (oclass, PROP_PROTOCOL, param_spec);
1457 param_spec = g_param_spec_object ("settings",
1458 "settings", "The settings of the account",
1459 EMPATHY_TYPE_ACCOUNT_SETTINGS,
1460 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1461 g_object_class_install_property (oclass, PROP_SETTINGS, param_spec);
1463 param_spec = g_param_spec_boolean ("simple",
1464 "simple", "Whether the account widget is a simple or an advanced one",
1466 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1467 g_object_class_install_property (oclass, PROP_SIMPLE, param_spec);
1469 param_spec = g_param_spec_boolean ("creating-account",
1471 "TRUE if we're creating an account, FALSE if we're modifying it",
1473 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1474 g_object_class_install_property (oclass, PROP_CREATING_ACCOUNT, param_spec);
1476 signals[HANDLE_APPLY] =
1477 g_signal_new ("handle-apply", G_TYPE_FROM_CLASS (klass),
1478 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1479 g_cclosure_marshal_VOID__BOOLEAN,
1483 /* This signal is emitted when an account has been created and enabled. */
1484 signals[ACCOUNT_CREATED] =
1485 g_signal_new ("account-created", G_TYPE_FROM_CLASS (klass),
1486 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1487 g_cclosure_marshal_VOID__VOID,
1491 signals[CANCELLED] =
1492 g_signal_new ("cancelled", G_TYPE_FROM_CLASS (klass),
1493 G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1494 g_cclosure_marshal_VOID__VOID,
1498 g_type_class_add_private (klass, sizeof (EmpathyAccountWidgetPriv));
1502 empathy_account_widget_init (EmpathyAccountWidget *self)
1504 EmpathyAccountWidgetPriv *priv =
1505 G_TYPE_INSTANCE_GET_PRIVATE ((self), EMPATHY_TYPE_ACCOUNT_WIDGET,
1506 EmpathyAccountWidgetPriv);
1509 priv->dispose_run = FALSE;
1511 self->ui_details = g_slice_new0 (EmpathyAccountWidgetUIDetails);
1514 /* public methods */
1517 empathy_account_widget_discard_pending_changes
1518 (EmpathyAccountWidget *widget)
1520 EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1522 empathy_account_settings_discard_changes (priv->settings);
1523 priv->contains_pending_changes = FALSE;
1527 empathy_account_widget_contains_pending_changes (EmpathyAccountWidget *widget)
1529 EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1531 return priv->contains_pending_changes;
1535 empathy_account_widget_handle_params (EmpathyAccountWidget *self,
1536 const gchar *first_widget,
1541 va_start (args, first_widget);
1542 account_widget_handle_params_valist (self, first_widget, args);
1547 empathy_account_widget_get_widget (EmpathyAccountWidget *widget)
1549 return widget->ui_details->widget;
1552 EmpathyAccountWidget *
1553 empathy_account_widget_new_for_protocol (EmpathyAccountSettings *settings,
1556 EmpathyAccountWidget *self;
1558 g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), NULL);
1561 (EMPATHY_TYPE_ACCOUNT_WIDGET,
1562 "settings", settings, "simple", simple,
1564 empathy_account_settings_get_account (settings) == NULL,