]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-account-widget.c
Merge commit 'staz/dnd'
[empathy.git] / libempathy-gtk / empathy-account-widget.c
1 /*
2  * Copyright (C) 2006-2007 Imendio AB
3  * Copyright (C) 2007-2009 Collabora Ltd.
4  *
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.
9  *
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.
14  *
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
19  *
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>
24  */
25
26 #include <config.h>
27
28 #include <string.h>
29
30 #include <gtk/gtk.h>
31 #include <glib/gi18n-lib.h>
32
33 #ifdef HAVE_MEEGO
34 #include <mx/mx-gtk.h>
35 #endif /* HAVE_MEEGO */
36
37 #include <libempathy/empathy-utils.h>
38
39 #include <telepathy-glib/account.h>
40 #include <telepathy-glib/account-manager.h>
41 #include <telepathy-glib/connection-manager.h>
42 #include <telepathy-glib/util.h>
43 #include <dbus/dbus-protocol.h>
44
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"
50
51 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
52 #include <libempathy/empathy-debug.h>
53
54 G_DEFINE_TYPE (EmpathyAccountWidget, empathy_account_widget, G_TYPE_OBJECT)
55
56 typedef struct {
57   EmpathyAccountSettings *settings;
58
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;
66   GtkWidget *radiobutton_reuse;
67
68   gboolean simple;
69
70   gboolean contains_pending_changes;
71
72   /* An EmpathyAccountWidget can be used to either create an account or
73    * modify it. When we are creating an account, this member is set to TRUE */
74   gboolean creating_account;
75
76   /* whether there are any other real accounts. Necessary so we know whether
77    * it's safe to dismiss this widget in some cases (eg, whether the Cancel
78    * button should be sensitive) */
79   gboolean other_accounts_exist;
80
81   /* if TRUE, the GTK+ destroy signal has been fired and so the widgets
82    * embedded in this account widget can't be used any more
83    * workaround because some async callbacks can be called after the
84    * widget has been destroyed */
85   gboolean destroyed;
86
87   TpAccountManager *account_manager;
88
89   GtkWidget *param_account_widget;
90   GtkWidget *param_password_widget;
91
92   gboolean dispose_run;
93 } EmpathyAccountWidgetPriv;
94
95 enum {
96   PROP_PROTOCOL = 1,
97   PROP_SETTINGS,
98   PROP_SIMPLE,
99   PROP_CREATING_ACCOUNT,
100   PROP_OTHER_ACCOUNTS_EXIST,
101 };
102
103 enum {
104   HANDLE_APPLY,
105   ACCOUNT_CREATED,
106   CANCELLED,
107   LAST_SIGNAL
108 };
109
110 static guint signals[LAST_SIGNAL] = { 0 };
111
112 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountWidget)
113 #define CHANGED_TIMEOUT 300
114
115 static void
116 account_widget_set_control_buttons_sensitivity (EmpathyAccountWidget *self,
117     gboolean sensitive)
118 {
119   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
120
121   if (!priv->simple)
122     {
123       /* we hit this case because of the 'other-accounts-exist' property handler
124        * being called during init (before constructed()) */
125       if (priv->apply_button == NULL || priv->cancel_button == NULL)
126         return;
127
128       gtk_widget_set_sensitive (priv->apply_button, sensitive);
129       gtk_widget_set_sensitive (priv->cancel_button,
130           (sensitive || priv->creating_account) && priv->other_accounts_exist);
131     }
132 }
133
134 static void
135 account_widget_handle_control_buttons_sensitivity (EmpathyAccountWidget *self)
136 {
137   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
138   gboolean is_valid;
139
140   is_valid = empathy_account_settings_is_valid (priv->settings);
141
142   if (!priv->simple)
143       account_widget_set_control_buttons_sensitivity (self, is_valid);
144
145   g_signal_emit (self, signals[HANDLE_APPLY], 0, is_valid);
146 }
147
148 static void
149 account_widget_entry_changed_common (EmpathyAccountWidget *self,
150     GtkEntry *entry, gboolean focus)
151 {
152   const gchar *str;
153   const gchar *param_name;
154   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
155
156   str = gtk_entry_get_text (entry);
157   param_name = g_object_get_data (G_OBJECT (entry), "param_name");
158
159   if (EMP_STR_EMPTY (str))
160     {
161       const gchar *value = NULL;
162
163       empathy_account_settings_unset (priv->settings, param_name);
164
165       if (focus)
166         {
167           value = empathy_account_settings_get_string (priv->settings,
168               param_name);
169           DEBUG ("Unset %s and restore to %s", param_name, value);
170           gtk_entry_set_text (entry, value ? value : "");
171         }
172     }
173   else
174     {
175       DEBUG ("Setting %s to %s", param_name,
176           tp_strdiff (param_name, "password") ? str : "***");
177       empathy_account_settings_set_string (priv->settings, param_name, str);
178     }
179 }
180
181 static void
182 account_widget_entry_changed_cb (GtkEditable *entry,
183     EmpathyAccountWidget *self)
184 {
185   account_widget_entry_changed_common (self, GTK_ENTRY (entry), FALSE);
186   empathy_account_widget_changed (self);
187 }
188
189 static void
190 account_widget_int_changed_cb (GtkWidget *widget,
191     EmpathyAccountWidget *self)
192 {
193   const gchar *param_name;
194   gint value;
195   const gchar *signature;
196   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
197
198   value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
199   param_name = g_object_get_data (G_OBJECT (widget), "param_name");
200
201   signature = empathy_account_settings_get_dbus_signature (priv->settings,
202     param_name);
203   g_return_if_fail (signature != NULL);
204
205   DEBUG ("Setting %s to %d", param_name, value);
206
207   switch ((int)*signature)
208     {
209     case DBUS_TYPE_INT16:
210     case DBUS_TYPE_INT32:
211       empathy_account_settings_set_int32 (priv->settings, param_name, value);
212       break;
213     case DBUS_TYPE_INT64:
214       empathy_account_settings_set_int64 (priv->settings, param_name, value);
215       break;
216     case DBUS_TYPE_UINT16:
217     case DBUS_TYPE_UINT32:
218       empathy_account_settings_set_uint32 (priv->settings, param_name, value);
219       break;
220     case DBUS_TYPE_UINT64:
221       empathy_account_settings_set_uint64 (priv->settings, param_name, value);
222       break;
223     default:
224       g_return_if_reached ();
225     }
226
227   empathy_account_widget_changed (self);
228 }
229
230 static void
231 account_widget_checkbutton_toggled_cb (GtkWidget *widget,
232     EmpathyAccountWidget *self)
233 {
234   gboolean     value;
235   gboolean     default_value;
236   const gchar *param_name;
237   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
238
239   value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
240   param_name = g_object_get_data (G_OBJECT (widget), "param_name");
241
242   /* FIXME: This is ugly! checkbox don't have a "not-set" value so we
243    * always unset the param and set the value if different from the
244    * default value. */
245   empathy_account_settings_unset (priv->settings, param_name);
246   default_value = empathy_account_settings_get_boolean (priv->settings,
247       param_name);
248
249   if (default_value == value)
250     {
251       DEBUG ("Unset %s and restore to %d", param_name, default_value);
252     }
253   else
254     {
255       DEBUG ("Setting %s to %d", param_name, value);
256       empathy_account_settings_set_boolean (priv->settings, param_name, value);
257     }
258
259   empathy_account_widget_changed (self);
260 }
261
262 static void
263 account_widget_forget_clicked_cb (GtkWidget *button,
264     EmpathyAccountWidget *self)
265 {
266   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
267   const gchar *param_name;
268
269   param_name = g_object_get_data (G_OBJECT (priv->entry_password),
270       "param_name");
271
272   DEBUG ("Unset %s", param_name);
273   empathy_account_settings_unset (priv->settings, param_name);
274   gtk_entry_set_text (GTK_ENTRY (priv->entry_password), "");
275
276   empathy_account_widget_changed (self);
277 }
278
279 static void
280 account_widget_password_changed_cb (GtkWidget *entry,
281     EmpathyAccountWidget *self)
282 {
283   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
284   const gchar *str;
285
286   str = gtk_entry_get_text (GTK_ENTRY (entry));
287   gtk_widget_set_sensitive (priv->button_forget, !EMP_STR_EMPTY (str));
288
289   priv->contains_pending_changes = TRUE;
290 }
291
292 static void
293 account_widget_jabber_ssl_toggled_cb (GtkWidget *checkbutton_ssl,
294     EmpathyAccountWidget *self)
295 {
296   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
297   gboolean   value;
298   gint32       port = 0;
299
300   value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl));
301   port = empathy_account_settings_get_uint32 (priv->settings, "port");
302
303   if (value)
304     {
305       if (port == 5222 || port == 0)
306         port = 5223;
307     }
308   else
309     {
310       if (port == 5223 || port == 0)
311         port = 5222;
312     }
313
314   gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->spinbutton_port), port);
315
316   priv->contains_pending_changes = TRUE;
317 }
318
319 static void
320 account_widget_combobox_changed_cb (GtkWidget *widget,
321     EmpathyAccountWidget *self)
322 {
323   GtkTreeIter iter;
324   GtkTreeModel *model;
325   const gchar *value;
326   const GValue *v;
327   const gchar *default_value = NULL;
328   const gchar *param_name;
329   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
330
331   if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter))
332     return;
333
334   model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
335   /* the param value is stored in the first column */
336   gtk_tree_model_get (model, &iter, 0, &value, -1);
337
338   param_name = g_object_get_data (G_OBJECT (widget), "param_name");
339
340   v = empathy_account_settings_get_default (priv->settings, param_name);
341   if (v != NULL)
342     default_value = g_value_get_string (v);
343
344   if (!tp_strdiff (value, default_value))
345     {
346       DEBUG ("Unset %s and restore to %s", param_name, default_value);
347       empathy_account_settings_unset (priv->settings, param_name);
348     }
349   else
350     {
351       DEBUG ("Setting %s to %s", param_name, value);
352       empathy_account_settings_set_string (priv->settings, param_name, value);
353     }
354
355   empathy_account_widget_changed (self);
356 }
357
358 void
359 empathy_account_widget_setup_widget (EmpathyAccountWidget *self,
360     GtkWidget *widget,
361     const gchar *param_name)
362 {
363   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
364
365   g_object_set_data_full (G_OBJECT (widget), "param_name",
366       g_strdup (param_name), g_free);
367
368   if (GTK_IS_SPIN_BUTTON (widget))
369     {
370       gint value = 0;
371       const gchar *signature;
372
373       signature = empathy_account_settings_get_dbus_signature (priv->settings,
374           param_name);
375       g_return_if_fail (signature != NULL);
376
377       switch ((int)*signature)
378         {
379           case DBUS_TYPE_INT16:
380           case DBUS_TYPE_INT32:
381             value = empathy_account_settings_get_int32 (priv->settings,
382               param_name);
383             break;
384           case DBUS_TYPE_INT64:
385             value = empathy_account_settings_get_int64 (priv->settings,
386               param_name);
387             break;
388           case DBUS_TYPE_UINT16:
389           case DBUS_TYPE_UINT32:
390             value = empathy_account_settings_get_uint32 (priv->settings,
391               param_name);
392             break;
393           case DBUS_TYPE_UINT64:
394             value = empathy_account_settings_get_uint64 (priv->settings,
395                 param_name);
396             break;
397           default:
398             g_return_if_reached ();
399         }
400
401       gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
402
403       g_signal_connect (widget, "value-changed",
404           G_CALLBACK (account_widget_int_changed_cb),
405           self);
406     }
407   else if (GTK_IS_ENTRY (widget))
408     {
409       const gchar *str = NULL;
410
411       str = empathy_account_settings_get_string (priv->settings, param_name);
412       gtk_entry_set_text (GTK_ENTRY (widget), str ? str : "");
413
414       if (!tp_strdiff (param_name, "account"))
415         priv->param_account_widget = widget;
416       else if (!tp_strdiff (param_name, "password"))
417         priv->param_password_widget = widget;
418
419       if (strstr (param_name, "password"))
420         {
421           gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
422         }
423
424       g_signal_connect (widget, "changed",
425           G_CALLBACK (account_widget_entry_changed_cb), self);
426     }
427   else if (GTK_IS_TOGGLE_BUTTON (widget))
428     {
429       gboolean value = FALSE;
430
431       value = empathy_account_settings_get_boolean (priv->settings,
432           param_name);
433       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
434
435       g_signal_connect (widget, "toggled",
436           G_CALLBACK (account_widget_checkbutton_toggled_cb),
437           self);
438     }
439   else if (GTK_IS_COMBO_BOX (widget))
440     {
441       /* The combo box's model has to contain the param value in its first
442        * column (as a string) */
443       const gchar *str;
444       GtkTreeModel *model;
445       GtkTreeIter iter;
446       gboolean valid;
447
448       str = empathy_account_settings_get_string (priv->settings, param_name);
449       model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
450
451       valid = gtk_tree_model_get_iter_first (model, &iter);
452       while (valid)
453         {
454           gchar *name;
455
456           gtk_tree_model_get (model, &iter, 0, &name, -1);
457           if (!tp_strdiff (name, str))
458             {
459               gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &iter);
460               valid = FALSE;
461             }
462           else
463             {
464               valid = gtk_tree_model_iter_next (model, &iter);
465             }
466
467           g_free (name);
468         }
469
470       g_signal_connect (widget, "changed",
471           G_CALLBACK (account_widget_combobox_changed_cb),
472           self);
473     }
474   else
475     {
476       DEBUG ("Unknown type of widget for param %s", param_name);
477     }
478 }
479
480 static gchar *
481 account_widget_generic_format_param_name (const gchar *param_name)
482 {
483   gchar *str;
484   gchar *p;
485
486   str = g_strdup (param_name);
487
488   if (str && g_ascii_isalpha (str[0]))
489     str[0] = g_ascii_toupper (str[0]);
490
491   while ((p = strchr (str, '-')) != NULL)
492     {
493       if (p[1] != '\0' && g_ascii_isalpha (p[1]))
494         {
495           p[0] = ' ';
496           p[1] = g_ascii_toupper (p[1]);
497         }
498
499       p++;
500     }
501
502   return str;
503 }
504
505 static void
506 accounts_widget_generic_setup (EmpathyAccountWidget *self,
507     GtkWidget *table_common_settings,
508     GtkWidget *table_advanced_settings)
509 {
510   TpConnectionManagerParam *params, *param;
511   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
512
513   params = empathy_account_settings_get_tp_params (priv->settings);
514
515   for (param = params; param != NULL && param->name != NULL; param++)
516     {
517       GtkWidget       *table_settings;
518       guint            n_rows = 0;
519       GtkWidget       *widget = NULL;
520       gchar           *param_name_formatted;
521
522       if (param->flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED)
523         table_settings = table_common_settings;
524       else if (priv->simple)
525         return;
526       else
527         table_settings = table_advanced_settings;
528
529       param_name_formatted = account_widget_generic_format_param_name
530         (param->name);
531       g_object_get (table_settings, "n-rows", &n_rows, NULL);
532       gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2);
533
534       if (param->dbus_signature[0] == 's')
535         {
536           gchar *str;
537
538           str = g_strdup_printf (_("%s:"), param_name_formatted);
539           widget = gtk_label_new (str);
540           gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
541           g_free (str);
542
543           gtk_table_attach (GTK_TABLE (table_settings),
544               widget,
545               0, 1,
546               n_rows - 1, n_rows,
547               GTK_FILL, 0,
548               0, 0);
549           gtk_widget_show (widget);
550
551           widget = gtk_entry_new ();
552           if (strcmp (param->name, "account") == 0)
553             {
554               g_signal_connect (widget, "realize",
555                   G_CALLBACK (gtk_widget_grab_focus),
556                   NULL);
557             }
558           gtk_table_attach (GTK_TABLE (table_settings),
559               widget,
560               1, 2,
561               n_rows - 1, n_rows,
562               GTK_FILL | GTK_EXPAND, 0,
563               0, 0);
564           gtk_widget_show (widget);
565         }
566       /* int types: ynqiuxt. double type is 'd' */
567       else if (param->dbus_signature[0] == 'y' ||
568           param->dbus_signature[0] == 'n' ||
569           param->dbus_signature[0] == 'q' ||
570           param->dbus_signature[0] == 'i' ||
571           param->dbus_signature[0] == 'u' ||
572           param->dbus_signature[0] == 'x' ||
573           param->dbus_signature[0] == 't' ||
574           param->dbus_signature[0] == 'd')
575         {
576           gchar   *str = NULL;
577           gdouble  minint = 0;
578           gdouble  maxint = 0;
579           gdouble  step = 1;
580
581           switch (param->dbus_signature[0])
582             {
583             case 'y': minint = G_MININT8;  maxint = G_MAXINT8;   break;
584             case 'n': minint = G_MININT16; maxint = G_MAXINT16;  break;
585             case 'q': minint = 0;          maxint = G_MAXUINT16; break;
586             case 'i': minint = G_MININT32; maxint = G_MAXINT32;  break;
587             case 'u': minint = 0;          maxint = G_MAXUINT32; break;
588             case 'x': minint = G_MININT64; maxint = G_MAXINT64;  break;
589             case 't': minint = 0;          maxint = G_MAXUINT64; break;
590             case 'd': minint = G_MININT32; maxint = G_MAXINT32;
591               step = 0.1; break;
592             }
593
594           str = g_strdup_printf (_("%s:"), param_name_formatted);
595           widget = gtk_label_new (str);
596           gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
597           g_free (str);
598
599           gtk_table_attach (GTK_TABLE (table_settings),
600               widget,
601               0, 1,
602               n_rows - 1, n_rows,
603               GTK_FILL, 0,
604               0, 0);
605           gtk_widget_show (widget);
606
607           widget = gtk_spin_button_new_with_range (minint, maxint, step);
608           gtk_table_attach (GTK_TABLE (table_settings),
609               widget,
610               1, 2,
611               n_rows - 1, n_rows,
612               GTK_FILL | GTK_EXPAND, 0,
613               0, 0);
614           gtk_widget_show (widget);
615         }
616       else if (param->dbus_signature[0] == 'b')
617         {
618           widget = gtk_check_button_new_with_label (param_name_formatted);
619           gtk_table_attach (GTK_TABLE (table_settings),
620               widget,
621               0, 2,
622               n_rows - 1, n_rows,
623               GTK_FILL | GTK_EXPAND, 0,
624               0, 0);
625           gtk_widget_show (widget);
626         }
627       else
628         {
629           DEBUG ("Unknown signature for param %s: %s",
630               param_name_formatted, param->dbus_signature);
631         }
632
633       if (widget)
634         empathy_account_widget_setup_widget (self, widget, param->name);
635
636       g_free (param_name_formatted);
637     }
638 }
639
640 static void
641 account_widget_handle_params_valist (EmpathyAccountWidget *self,
642     const gchar *first_widget,
643     va_list args)
644 {
645   GObject *object;
646   const gchar *name;
647
648   for (name = first_widget; name; name = va_arg (args, const gchar *))
649     {
650       const gchar *param_name;
651
652       param_name = va_arg (args, const gchar *);
653       object = gtk_builder_get_object (self->ui_details->gui, name);
654
655       if (!object)
656         {
657           g_warning ("Builder is missing object '%s'.", name);
658           continue;
659         }
660
661       empathy_account_widget_setup_widget (self, GTK_WIDGET (object),
662           param_name);
663     }
664 }
665
666 static void
667 account_widget_cancel_clicked_cb (GtkWidget *button,
668     EmpathyAccountWidget *self)
669 {
670   g_signal_emit (self, signals[CANCELLED], 0);
671 }
672
673 static void
674 account_widget_account_enabled_cb (GObject *source_object,
675     GAsyncResult *res,
676     gpointer user_data)
677 {
678   GError *error = NULL;
679   TpAccount *account = TP_ACCOUNT (source_object);
680   EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
681   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
682
683   tp_account_set_enabled_finish (account, res, &error);
684
685   if (error != NULL)
686     {
687       DEBUG ("Could not enable the account: %s", error->message);
688       g_error_free (error);
689     }
690   else
691     {
692       empathy_connect_new_account (account, priv->account_manager);
693     }
694
695   /* unref widget - part of the workaround */
696   g_object_unref (widget);
697 }
698
699 static void
700 account_widget_applied_cb (GObject *source_object,
701     GAsyncResult *res,
702     gpointer user_data)
703 {
704   GError *error = NULL;
705   TpAccount *account;
706   EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (source_object);
707   EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
708   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
709
710   empathy_account_settings_apply_finish (settings, res, &error);
711
712   if (error != NULL)
713     {
714       DEBUG ("Could not apply changes to account: %s", error->message);
715       g_error_free (error);
716       return;
717     }
718
719   account = empathy_account_settings_get_account (priv->settings);
720
721   if (account != NULL)
722     {
723       if (priv->creating_account)
724         {
725           /* By default, when an account is created, we enable it. */
726
727           /* workaround to keep widget alive during async call */
728           g_object_ref (widget);
729
730           tp_account_set_enabled_async (account, TRUE,
731               account_widget_account_enabled_cb, widget);
732           g_signal_emit (widget, signals[ACCOUNT_CREATED], 0, account);
733         }
734       else if (priv->enabled_checkbox != NULL)
735         {
736           gboolean enabled_checked;
737
738           enabled_checked =
739 #ifdef HAVE_MEEGO
740             mx_gtk_light_switch_get_active (
741                 MX_GTK_LIGHT_SWITCH (priv->enabled_checkbox));
742 #else
743             gtk_toggle_button_get_active (
744                 GTK_TOGGLE_BUTTON (priv->enabled_checkbox));
745 #endif /* HAVE_MEEGO */
746
747           if (tp_account_is_enabled (account) && enabled_checked)
748             {
749               /* After having applied changes to a user account, we
750                * automatically reconnect it. This is done so the new
751                * information entered by the user is validated on the server. */
752               tp_account_reconnect_async (account, NULL, NULL);
753             }
754         }
755     }
756
757   if (!priv->destroyed)
758     account_widget_set_control_buttons_sensitivity (widget, FALSE);
759
760   priv->contains_pending_changes = FALSE;
761
762   /* unref the widget - part of the workaround */
763   g_object_unref (widget);
764 }
765
766 static void
767 account_widget_apply_clicked_cb (GtkWidget *button,
768     EmpathyAccountWidget *self)
769 {
770   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
771   gboolean display_name_overridden;
772
773   if (priv->radiobutton_reuse != NULL)
774     {
775       gboolean reuse = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
776             priv->radiobutton_reuse));
777
778       DEBUG ("Set register param: %d", !reuse);
779       empathy_account_settings_set_boolean (priv->settings, "register", !reuse);
780     }
781
782   g_object_get (priv->settings,
783       "display-name-overridden", &display_name_overridden, NULL);
784
785   if (priv->creating_account || !display_name_overridden)
786     {
787       gchar *display_name;
788
789       /* set default display name for new accounts or update if user didn't
790        * manually override it. */
791       display_name = empathy_account_widget_get_default_display_name (self);
792
793       empathy_account_settings_set_display_name_async (priv->settings,
794           display_name, NULL, NULL);
795
796       g_free (display_name);
797     }
798
799   /* workaround to keep widget alive during async call */
800   g_object_ref (self);
801   empathy_account_settings_apply_async (priv->settings,
802       account_widget_applied_cb, self);
803 }
804
805 static void
806 account_widget_setup_generic (EmpathyAccountWidget *self)
807 {
808   GtkWidget *table_common_settings;
809   GtkWidget *table_advanced_settings;
810
811   table_common_settings = GTK_WIDGET (gtk_builder_get_object
812       (self->ui_details->gui, "table_common_settings"));
813   table_advanced_settings = GTK_WIDGET (gtk_builder_get_object
814       (self->ui_details->gui, "table_advanced_settings"));
815
816   accounts_widget_generic_setup (self, table_common_settings,
817       table_advanced_settings);
818
819   g_object_unref (self->ui_details->gui);
820 }
821
822 static void
823 account_widget_settings_ready_cb (EmpathyAccountSettings *settings,
824     GParamSpec *pspec,
825     gpointer user_data)
826 {
827   EmpathyAccountWidget *self = user_data;
828   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
829
830   if (empathy_account_settings_is_ready (priv->settings))
831     account_widget_setup_generic (self);
832 }
833
834 static void
835 account_widget_build_generic (EmpathyAccountWidget *self,
836     const char *filename)
837 {
838   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
839   GtkWidget *expander_advanced;
840
841   self->ui_details->gui = empathy_builder_get_file (filename,
842       "table_common_settings", &priv->table_common_settings,
843       "vbox_generic_settings", &self->ui_details->widget,
844       "expander_advanced_settings", &expander_advanced,
845       NULL);
846
847   if (priv->simple)
848     gtk_widget_hide (expander_advanced);
849
850   g_object_ref (self->ui_details->gui);
851
852   if (empathy_account_settings_is_ready (priv->settings))
853     account_widget_setup_generic (self);
854   else
855     g_signal_connect (priv->settings, "notify::ready",
856         G_CALLBACK (account_widget_settings_ready_cb), self);
857 }
858
859 static void
860 account_widget_build_salut (EmpathyAccountWidget *self,
861     const char *filename)
862 {
863   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
864   GtkWidget *expander_advanced;
865
866   self->ui_details->gui = empathy_builder_get_file (filename,
867       "table_common_settings", &priv->table_common_settings,
868       "vbox_salut_settings", &self->ui_details->widget,
869       "expander_advanced_settings", &expander_advanced,
870       NULL);
871
872   empathy_account_widget_handle_params (self,
873       "entry_published", "published-name",
874       "entry_nickname", "nickname",
875       "entry_first_name", "first-name",
876       "entry_last_name", "last-name",
877       "entry_email", "email",
878       "entry_jid", "jid",
879       NULL);
880
881   if (priv->simple)
882     gtk_widget_hide (expander_advanced);
883
884   self->ui_details->default_focus = g_strdup ("entry_first_name");
885 }
886
887 static void
888 account_widget_build_irc (EmpathyAccountWidget *self,
889   const char *filename)
890 {
891   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
892   empathy_account_widget_irc_build (self, filename,
893     &priv->table_common_settings);
894 }
895
896 static void
897 account_widget_build_sip (EmpathyAccountWidget *self,
898   const char *filename)
899 {
900   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
901   empathy_account_widget_sip_build (self, filename,
902     &priv->table_common_settings);
903 }
904
905 static void
906 account_widget_build_msn (EmpathyAccountWidget *self,
907     const char *filename)
908 {
909   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
910
911   if (priv->simple)
912     {
913       self->ui_details->gui = empathy_builder_get_file (filename,
914           "vbox_msn_simple", &self->ui_details->widget,
915           NULL);
916
917       empathy_account_widget_handle_params (self,
918           "entry_id_simple", "account",
919           "entry_password_simple", "password",
920           NULL);
921
922       self->ui_details->default_focus = g_strdup ("entry_id_simple");
923     }
924   else
925     {
926       self->ui_details->gui = empathy_builder_get_file (filename,
927           "table_common_msn_settings", &priv->table_common_settings,
928           "vbox_msn_settings", &self->ui_details->widget,
929           NULL);
930
931       empathy_account_widget_handle_params (self,
932           "entry_id", "account",
933           "entry_password", "password",
934           "entry_server", "server",
935           "spinbutton_port", "port",
936           NULL);
937
938       self->ui_details->default_focus = g_strdup ("entry_id");
939       self->ui_details->add_forget = TRUE;
940     }
941 }
942
943 static gboolean
944 account_widget_is_gtalk (EmpathyAccountWidget *self)
945 {
946   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
947
948   return !tp_strdiff (empathy_account_settings_get_icon_name (priv->settings),
949       "im-google-talk");
950 }
951
952 static gboolean
953 account_widget_is_facebook (EmpathyAccountWidget *self)
954 {
955   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
956
957   return !tp_strdiff (empathy_account_settings_get_icon_name (priv->settings),
958       "im-facebook");
959 }
960
961 #define FACEBOOK_SUFFIX "@chat.facebook.com"
962
963 static void
964 facebook_id_widget_changed_cb (GtkWidget *entry,
965     EmpathyAccountWidget *self)
966 {
967   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
968   const gchar *account;
969
970   account_widget_entry_changed_common (self, GTK_ENTRY (entry), FALSE);
971
972   account = empathy_account_settings_get_string (priv->settings, "account");
973   if (!EMP_STR_EMPTY (account) &&
974       !g_str_has_suffix (account, FACEBOOK_SUFFIX))
975     {
976       gchar *tmp;
977
978       tmp = g_strdup_printf ("%s%s", account, FACEBOOK_SUFFIX);
979
980       DEBUG ("Change account from '%s' to '%s'", account, tmp);
981
982       empathy_account_settings_set_string (priv->settings, "account", tmp);
983       g_free (tmp);
984     }
985
986   empathy_account_widget_changed (self);
987 }
988
989 static gchar *
990 remove_facebook_suffix (const gchar *str)
991 {
992   if (!g_str_has_suffix (str, FACEBOOK_SUFFIX))
993     return g_strdup (str);
994
995   return g_strndup (str, strlen (str) - strlen (FACEBOOK_SUFFIX));
996 }
997
998 static void
999 setup_facebook_id_widget (EmpathyAccountWidget *self,
1000     GtkWidget *widget)
1001 {
1002   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1003   const gchar *str = NULL;
1004
1005   g_object_set_data_full (G_OBJECT (widget), "param_name",
1006       g_strdup ("account"), g_free);
1007
1008   str = empathy_account_settings_get_string (priv->settings, "account");
1009   if (str != NULL)
1010     {
1011       gchar *tmp;
1012
1013       tmp = remove_facebook_suffix (str);
1014       gtk_entry_set_text (GTK_ENTRY (widget), tmp);
1015       g_free (tmp);
1016     }
1017
1018   priv->param_account_widget = widget;
1019
1020   g_signal_connect (widget, "changed",
1021       G_CALLBACK (facebook_id_widget_changed_cb), self);
1022 }
1023
1024 static void
1025 account_widget_build_jabber (EmpathyAccountWidget *self,
1026     const char *filename)
1027 {
1028   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1029   GtkWidget *spinbutton_port;
1030   GtkWidget *checkbutton_ssl;
1031   GtkWidget *label_id, *label_password;
1032   GtkWidget *label_id_create, *label_password_create;
1033   GtkWidget *label_example_gtalk, *label_example_jabber, *label_example_fb;
1034   gboolean is_gtalk, is_facebook;
1035   GtkWidget *expander_advanced;
1036   GtkWidget *entry_id;
1037
1038   is_gtalk = account_widget_is_gtalk (self);
1039   is_facebook = account_widget_is_facebook (self);
1040
1041   if (priv->simple && !is_gtalk && !is_facebook)
1042     {
1043       /* Simple widget for XMPP */
1044       self->ui_details->gui = empathy_builder_get_file (filename,
1045           "vbox_jabber_simple", &self->ui_details->widget,
1046           "label_id_simple", &label_id,
1047           "label_id_create", &label_id_create,
1048           "label_password_simple", &label_password,
1049           "label_password_create", &label_password_create,
1050           NULL);
1051
1052       if (empathy_account_settings_get_boolean (priv->settings, "register"))
1053         {
1054           gtk_widget_hide (label_id);
1055           gtk_widget_hide (label_password);
1056           gtk_widget_show (label_id_create);
1057           gtk_widget_show (label_password_create);
1058         }
1059
1060       empathy_account_widget_handle_params (self,
1061           "entry_id_simple", "account",
1062           "entry_password_simple", "password",
1063           NULL);
1064
1065       self->ui_details->default_focus = g_strdup ("entry_id_simple");
1066     }
1067   else if (priv->simple && is_gtalk)
1068     {
1069       /* Simple widget for Google Talk */
1070       self->ui_details->gui = empathy_builder_get_file (filename,
1071           "vbox_gtalk_simple", &self->ui_details->widget,
1072           NULL);
1073
1074       empathy_account_widget_handle_params (self,
1075           "entry_id_g_simple", "account",
1076           "entry_password_g_simple", "password",
1077           NULL);
1078
1079       self->ui_details->default_focus = g_strdup ("entry_id_g_simple");
1080     }
1081   else if (priv->simple && is_facebook)
1082     {
1083       /* Simple widget for Facebook */
1084       self->ui_details->gui = empathy_builder_get_file (filename,
1085           "vbox_fb_simple", &self->ui_details->widget,
1086           "entry_id_fb_simple", &entry_id,
1087           NULL);
1088
1089       empathy_account_widget_handle_params (self,
1090           "entry_password_fb_simple", "password",
1091           NULL);
1092
1093       setup_facebook_id_widget (self, entry_id);
1094
1095       self->ui_details->default_focus = g_strdup ("entry_id_fb_simple");
1096     }
1097   else
1098     {
1099       /* Full widget for XMPP, Google Talk and Facebook*/
1100       self->ui_details->gui = empathy_builder_get_file (filename,
1101           "table_common_settings", &priv->table_common_settings,
1102           "vbox_jabber_settings", &self->ui_details->widget,
1103           "spinbutton_port", &spinbutton_port,
1104           "checkbutton_ssl", &checkbutton_ssl,
1105           "label_username_example", &label_example_jabber,
1106           "label_username_g_example", &label_example_gtalk,
1107           "label_username_f_example", &label_example_fb,
1108           "expander_advanced", &expander_advanced,
1109           "entry_id", &entry_id,
1110           "label_id", &label_id,
1111           NULL);
1112
1113       empathy_account_widget_handle_params (self,
1114           "entry_password", "password",
1115           "entry_resource", "resource",
1116           "entry_server", "server",
1117           "spinbutton_port", "port",
1118           "spinbutton_priority", "priority",
1119           "checkbutton_ssl", "old-ssl",
1120           "checkbutton_ignore_ssl_errors", "ignore-ssl-errors",
1121           "checkbutton_encryption", "require-encryption",
1122           NULL);
1123
1124       if (is_facebook)
1125         {
1126           gtk_label_set_label (GTK_LABEL (label_id), _("Username:"));
1127
1128           /* Facebook special case the entry ID widget to hide the
1129            * "@chat.facebook.com" part */
1130           setup_facebook_id_widget (self, entry_id);
1131         }
1132       else
1133         {
1134           empathy_account_widget_setup_widget (self, entry_id, "account");
1135         }
1136
1137       self->ui_details->default_focus = g_strdup ("entry_id");
1138       self->ui_details->add_forget = TRUE;
1139       priv->spinbutton_port = spinbutton_port;
1140
1141       g_signal_connect (checkbutton_ssl, "toggled",
1142           G_CALLBACK (account_widget_jabber_ssl_toggled_cb),
1143           self);
1144
1145       if (is_gtalk)
1146         {
1147           gtk_widget_hide (label_example_jabber);
1148           gtk_widget_show (label_example_gtalk);
1149         }
1150       else if (is_facebook)
1151         {
1152           gtk_widget_hide (label_example_jabber);
1153           gtk_widget_show (label_example_fb);
1154           gtk_widget_hide (expander_advanced);
1155         }
1156     }
1157 }
1158
1159 static void
1160 account_widget_build_icq (EmpathyAccountWidget *self,
1161     const char *filename)
1162 {
1163   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1164   GtkWidget *spinbutton_port;
1165
1166   if (priv->simple)
1167     {
1168       self->ui_details->gui = empathy_builder_get_file (filename,
1169           "vbox_icq_simple", &self->ui_details->widget,
1170           NULL);
1171
1172       empathy_account_widget_handle_params (self,
1173           "entry_uin_simple", "account",
1174           "entry_password_simple", "password",
1175           NULL);
1176
1177       self->ui_details->default_focus = g_strdup ("entry_uin_simple");
1178     }
1179   else
1180     {
1181       self->ui_details->gui = empathy_builder_get_file (filename,
1182           "table_common_settings", &priv->table_common_settings,
1183           "vbox_icq_settings", &self->ui_details->widget,
1184           "spinbutton_port", &spinbutton_port,
1185           NULL);
1186
1187       empathy_account_widget_handle_params (self,
1188           "entry_uin", "account",
1189           "entry_password", "password",
1190           "entry_server", "server",
1191           "spinbutton_port", "port",
1192           "entry_charset", "charset",
1193           NULL);
1194
1195       self->ui_details->default_focus = g_strdup ("entry_uin");
1196       self->ui_details->add_forget = TRUE;
1197     }
1198 }
1199
1200 static void
1201 account_widget_build_aim (EmpathyAccountWidget *self,
1202     const char *filename)
1203 {
1204   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1205   GtkWidget *spinbutton_port;
1206
1207   if (priv->simple)
1208     {
1209       self->ui_details->gui = empathy_builder_get_file (filename,
1210           "vbox_aim_simple", &self->ui_details->widget,
1211           NULL);
1212
1213       empathy_account_widget_handle_params (self,
1214           "entry_screenname_simple", "account",
1215           "entry_password_simple", "password",
1216           NULL);
1217
1218       self->ui_details->default_focus = g_strdup ("entry_screenname_simple");
1219     }
1220   else
1221     {
1222       self->ui_details->gui = empathy_builder_get_file (filename,
1223           "table_common_settings", &priv->table_common_settings,
1224           "vbox_aim_settings", &self->ui_details->widget,
1225           "spinbutton_port", &spinbutton_port,
1226           NULL);
1227
1228       empathy_account_widget_handle_params (self,
1229           "entry_screenname", "account",
1230           "entry_password", "password",
1231           "entry_server", "server",
1232           "spinbutton_port", "port",
1233           NULL);
1234
1235       self->ui_details->default_focus = g_strdup ("entry_screenname");
1236       self->ui_details->add_forget = TRUE;
1237     }
1238 }
1239
1240 static void
1241 account_widget_build_yahoo (EmpathyAccountWidget *self,
1242     const char *filename)
1243 {
1244   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1245
1246   if (priv->simple)
1247     {
1248       self->ui_details->gui = empathy_builder_get_file (filename,
1249           "vbox_yahoo_simple", &self->ui_details->widget,
1250           NULL);
1251
1252       empathy_account_widget_handle_params (self,
1253           "entry_id_simple", "account",
1254           "entry_password_simple", "password",
1255           NULL);
1256
1257       self->ui_details->default_focus = g_strdup ("entry_id_simple");
1258     }
1259   else
1260     {
1261       self->ui_details->gui = empathy_builder_get_file (filename,
1262           "table_common_settings", &priv->table_common_settings,
1263           "vbox_yahoo_settings", &self->ui_details->widget,
1264           NULL);
1265
1266       empathy_account_widget_handle_params (self,
1267           "entry_id", "account",
1268           "entry_password", "password",
1269           "entry_server", "server",
1270           "entry_locale", "room-list-locale",
1271           "entry_charset", "charset",
1272           "spinbutton_port", "port",
1273           "checkbutton_yahoojp", "yahoojp",
1274           "checkbutton_ignore_invites", "ignore-invites",
1275           NULL);
1276
1277       self->ui_details->default_focus = g_strdup ("entry_id");
1278       self->ui_details->add_forget = TRUE;
1279     }
1280 }
1281
1282 static void
1283 account_widget_build_groupwise (EmpathyAccountWidget *self,
1284     const char *filename)
1285 {
1286   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1287
1288   if (priv->simple)
1289     {
1290       self->ui_details->gui = empathy_builder_get_file (filename,
1291           "vbox_groupwise_simple", &self->ui_details->widget,
1292           NULL);
1293
1294       empathy_account_widget_handle_params (self,
1295           "entry_id_simple", "account",
1296           "entry_password_simple", "password",
1297           NULL);
1298
1299       self->ui_details->default_focus = g_strdup ("entry_id_simple");
1300     }
1301   else
1302     {
1303       self->ui_details->gui = empathy_builder_get_file (filename,
1304           "table_common_groupwise_settings", &priv->table_common_settings,
1305           "vbox_groupwise_settings", &self->ui_details->widget,
1306           NULL);
1307
1308       empathy_account_widget_handle_params (self,
1309           "entry_id", "account",
1310           "entry_password", "password",
1311           "entry_server", "server",
1312           "spinbutton_port", "port",
1313           NULL);
1314
1315       self->ui_details->default_focus = g_strdup ("entry_id");
1316       self->ui_details->add_forget = TRUE;
1317     }
1318 }
1319
1320 static void
1321 account_widget_destroy_cb (GtkWidget *widget,
1322     EmpathyAccountWidget *self)
1323 {
1324   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1325   /* set the destroyed flag - workaround */
1326   priv->destroyed = TRUE;
1327
1328   g_object_unref (self);
1329 }
1330
1331 static void
1332 empathy_account_widget_enabled_cb (TpAccount *account,
1333       GParamSpec *spec,
1334       gpointer user_data)
1335 {
1336   EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
1337   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1338   gboolean enabled = tp_account_is_enabled (account);
1339
1340   if (priv->enabled_checkbox != NULL)
1341     {
1342 #ifdef HAVE_MEEGO
1343       mx_gtk_light_switch_set_active (
1344           MX_GTK_LIGHT_SWITCH (priv->enabled_checkbox),
1345           enabled);
1346 #else
1347       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->enabled_checkbox),
1348           enabled);
1349 #endif /* HAVE_MEEGO */
1350     }
1351 }
1352
1353 static void
1354 #ifdef HAVE_MEEGO
1355 account_widget_switch_flipped_cb (MxGtkLightSwitch *sw,
1356     gboolean state,
1357     gpointer user_data)
1358 #else
1359 account_widget_enabled_released_cb (GtkToggleButton *toggle_button,
1360     gpointer user_data)
1361 #endif /* HAVE_MEEGO */
1362 {
1363   EmpathyAccountWidgetPriv *priv = GET_PRIV (user_data);
1364   TpAccount *account;
1365 #ifndef HAVE_MEEGO
1366   gboolean state;
1367
1368   state = gtk_toggle_button_get_active (toggle_button);
1369 #endif /* HAVE_MEEGO */
1370
1371   account = empathy_account_settings_get_account (priv->settings);
1372
1373   /* Enable the account according to the value of the "Enabled" checkbox */
1374   /* workaround to keep widget alive during async call */
1375   g_object_ref (user_data);
1376   tp_account_set_enabled_async (account, state,
1377       account_widget_account_enabled_cb, user_data);
1378 }
1379
1380 void
1381 empathy_account_widget_set_other_accounts_exist (EmpathyAccountWidget *self,
1382     gboolean others_exist)
1383 {
1384   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1385
1386   priv->other_accounts_exist = others_exist;
1387
1388   if (priv->creating_account)
1389     account_widget_handle_control_buttons_sensitivity (self);
1390 }
1391
1392 static void
1393 do_set_property (GObject *object,
1394     guint prop_id,
1395     const GValue *value,
1396     GParamSpec *pspec)
1397 {
1398   EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
1399
1400   switch (prop_id)
1401     {
1402     case PROP_SETTINGS:
1403       priv->settings = g_value_dup_object (value);
1404       break;
1405     case PROP_SIMPLE:
1406       priv->simple = g_value_get_boolean (value);
1407       break;
1408     case PROP_CREATING_ACCOUNT:
1409       priv->creating_account = g_value_get_boolean (value);
1410       break;
1411     case PROP_OTHER_ACCOUNTS_EXIST:
1412       empathy_account_widget_set_other_accounts_exist (
1413           EMPATHY_ACCOUNT_WIDGET (object), g_value_get_boolean (value));
1414       break;
1415     default:
1416       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1417     }
1418 }
1419
1420 static void
1421 do_get_property (GObject *object,
1422     guint prop_id,
1423     GValue *value,
1424     GParamSpec *pspec)
1425 {
1426   EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
1427
1428   switch (prop_id)
1429     {
1430     case PROP_PROTOCOL:
1431       g_value_set_string (value,
1432         empathy_account_settings_get_protocol (priv->settings));
1433       break;
1434     case PROP_SETTINGS:
1435       g_value_set_object (value, priv->settings);
1436       break;
1437     case PROP_SIMPLE:
1438       g_value_set_boolean (value, priv->simple);
1439       break;
1440     case PROP_CREATING_ACCOUNT:
1441       g_value_set_boolean (value, priv->creating_account);
1442       break;
1443     case PROP_OTHER_ACCOUNTS_EXIST:
1444       g_value_set_boolean (value, priv->other_accounts_exist);
1445       break;
1446     default:
1447       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1448     }
1449 }
1450
1451 static void
1452 presence_changed_cb (TpAccountManager *manager,
1453     TpConnectionPresenceType state,
1454     const gchar *status,
1455     const gchar *message,
1456     EmpathyAccountWidget *self)
1457 {
1458   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1459
1460   if (priv->destroyed)
1461     return;
1462
1463   if (priv->apply_button == NULL)
1464     /* This button doesn't exist in 'simple' mode */
1465     return;
1466
1467   if (state > TP_CONNECTION_PRESENCE_TYPE_OFFLINE &&
1468       priv->creating_account)
1469     {
1470       /* We are online and creating a new account, display a Login button */
1471       GtkWidget *image;
1472
1473       gtk_button_set_use_stock (GTK_BUTTON (priv->apply_button), FALSE);
1474       gtk_button_set_label (GTK_BUTTON (priv->apply_button), _("L_og in"));
1475
1476       image = gtk_image_new_from_stock (GTK_STOCK_CONNECT,
1477           GTK_ICON_SIZE_BUTTON);
1478       gtk_button_set_image (GTK_BUTTON (priv->apply_button), image);
1479     }
1480   else
1481     {
1482       /* We are offline or modifying an existing account, display
1483        * a Save button */
1484       gtk_button_set_image (GTK_BUTTON (priv->apply_button), NULL);
1485       gtk_button_set_use_stock (GTK_BUTTON (priv->apply_button), TRUE);
1486       gtk_button_set_label (GTK_BUTTON (priv->apply_button), GTK_STOCK_APPLY);
1487     }
1488 }
1489
1490 static void
1491 account_manager_ready_cb (GObject *source_object,
1492     GAsyncResult *result,
1493     gpointer user_data)
1494 {
1495   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (user_data);
1496   TpAccountManager *account_manager = TP_ACCOUNT_MANAGER (source_object);
1497   GError *error = NULL;
1498   TpConnectionPresenceType state;
1499
1500   if (!tp_account_manager_prepare_finish (account_manager, result, &error))
1501     {
1502       DEBUG ("Failed to prepare account manager: %s", error->message);
1503       g_error_free (error);
1504       goto out;
1505     }
1506
1507   state = tp_account_manager_get_most_available_presence (account_manager, NULL,
1508       NULL);
1509
1510   /* simulate a presence change so the apply button will be changed
1511    * if needed */
1512   presence_changed_cb (account_manager, state, NULL, NULL, self);
1513
1514 out:
1515   g_object_unref (self);
1516 }
1517
1518 #define WIDGET(cm, proto) \
1519   { #cm, #proto, "empathy-account-widget-"#proto".ui", \
1520     account_widget_build_##proto }
1521
1522 static void
1523 add_enable_checkbox (EmpathyAccountWidget *self,
1524     TpAccount *account)
1525 {
1526   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1527 #ifdef HAVE_MEEGO
1528   GtkWidget *w;
1529 #else
1530   GtkWidget *vbox = self->ui_details->widget;
1531 #endif /* HAVE_MEEGO */
1532   guint nb_rows, nb_columns;
1533   gboolean is_enabled;
1534
1535   /* handle the "Enabled" checkbox. We only add it when modifying an account */
1536   if (priv->creating_account || priv->table_common_settings == NULL)
1537     return;
1538
1539   is_enabled = tp_account_is_enabled (account);
1540
1541 #ifdef HAVE_MEEGO
1542   w = gtk_label_new (_("Account:"));
1543   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
1544
1545   priv->enabled_checkbox = mx_gtk_light_switch_new ();
1546
1547   mx_gtk_light_switch_set_active (
1548       MX_GTK_LIGHT_SWITCH (priv->enabled_checkbox), is_enabled);
1549
1550   gtk_widget_show (w);
1551 #else
1552   priv->enabled_checkbox =
1553       gtk_check_button_new_with_label (_("Enabled"));
1554
1555   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->enabled_checkbox),
1556       is_enabled);
1557 #endif /* HAVE_MEEGO */
1558
1559   g_object_get (priv->table_common_settings, "n-rows", &nb_rows,
1560       "n-columns", &nb_columns, NULL);
1561
1562   gtk_table_resize (GTK_TABLE (priv->table_common_settings), ++nb_rows,
1563       nb_columns);
1564
1565 #ifdef HAVE_MEEGO
1566   gtk_table_attach (GTK_TABLE (priv->table_common_settings),
1567       w,
1568       0, 1, nb_rows - 1, nb_rows,
1569       GTK_FILL, 0, 0, 0);
1570   gtk_table_attach (GTK_TABLE (priv->table_common_settings),
1571       priv->enabled_checkbox,
1572       1, nb_columns, nb_rows - 1, nb_rows,
1573       GTK_EXPAND | GTK_FILL, 0, 0, 0);
1574 #else
1575   gtk_box_pack_start (GTK_BOX (vbox), priv->enabled_checkbox, FALSE, FALSE, 0);
1576   gtk_box_reorder_child (GTK_BOX (vbox), priv->enabled_checkbox, 0);
1577 #endif /* HAVE_MEEGO */
1578
1579   gtk_widget_show (priv->enabled_checkbox);
1580
1581 #ifdef HAVE_MEEGO
1582   g_signal_connect (G_OBJECT (priv->enabled_checkbox), "switch-flipped",
1583       G_CALLBACK (account_widget_switch_flipped_cb), self);
1584 #else
1585   g_signal_connect (G_OBJECT (priv->enabled_checkbox), "released",
1586       G_CALLBACK (account_widget_enabled_released_cb), self);
1587 #endif /* HAVE_MEEGO */
1588 }
1589
1590 #ifndef HAVE_MEEGO
1591 /* Meego doesn't support registration */
1592 static void
1593 add_register_buttons (EmpathyAccountWidget *self,
1594     TpAccount *account)
1595 {
1596   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1597   const TpConnectionManagerProtocol *protocol;
1598   GtkWidget *radiobutton_register;
1599   GtkWidget *vbox = self->ui_details->widget;
1600
1601   if (!priv->creating_account)
1602     return;
1603
1604   protocol = empathy_account_settings_get_tp_protocol (priv->settings);
1605   if (protocol == NULL)
1606     return;
1607
1608   if (!tp_connection_manager_protocol_can_register (protocol))
1609     return;
1610
1611   if (account_widget_is_gtalk (self) || account_widget_is_facebook (self))
1612     return;
1613
1614   if (priv->simple)
1615     return;
1616
1617   priv->radiobutton_reuse = gtk_radio_button_new_with_label (NULL,
1618       _("This account already exists on the server"));
1619   radiobutton_register = gtk_radio_button_new_with_label (
1620       gtk_radio_button_get_group (GTK_RADIO_BUTTON (priv->radiobutton_reuse)),
1621       _("Create a new account on the server"));
1622
1623   gtk_box_pack_start (GTK_BOX (vbox), priv->radiobutton_reuse, FALSE, FALSE, 0);
1624   gtk_box_pack_start (GTK_BOX (vbox), radiobutton_register, FALSE, FALSE, 0);
1625   gtk_box_reorder_child (GTK_BOX (vbox), priv->radiobutton_reuse, 0);
1626   gtk_box_reorder_child (GTK_BOX (vbox), radiobutton_register, 1);
1627   gtk_widget_show (priv->radiobutton_reuse);
1628   gtk_widget_show (radiobutton_register);
1629 }
1630 #endif /* HAVE_MEEGO */
1631
1632 static void
1633 do_constructed (GObject *obj)
1634 {
1635   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1636   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1637   TpAccount *account;
1638   const gchar *protocol, *cm_name;
1639   const gchar *display_name, *default_display_name;
1640   guint i = 0;
1641   struct {
1642     const gchar *cm_name;
1643     const gchar *protocol;
1644     const char *file;
1645     void (*func)(EmpathyAccountWidget *self, const gchar *filename);
1646   } widgets [] = {
1647     { "salut", "local-xmpp", "empathy-account-widget-local-xmpp.ui",
1648         account_widget_build_salut },
1649     WIDGET (gabble, jabber),
1650     WIDGET (butterfly, msn),
1651     WIDGET (haze, icq),
1652     WIDGET (haze, aim),
1653     WIDGET (haze, yahoo),
1654     WIDGET (haze, groupwise),
1655     WIDGET (idle, irc),
1656     WIDGET (sofiasip, sip),
1657   };
1658
1659   cm_name = empathy_account_settings_get_cm (priv->settings);
1660   protocol = empathy_account_settings_get_protocol (priv->settings);
1661
1662   for (i = 0 ; i < G_N_ELEMENTS (widgets); i++)
1663     {
1664       if (!tp_strdiff (widgets[i].cm_name, cm_name) &&
1665           !tp_strdiff (widgets[i].protocol, protocol))
1666         {
1667           gchar *filename;
1668
1669           filename = empathy_file_lookup (widgets[i].file,
1670               "libempathy-gtk");
1671           widgets[i].func (self, filename);
1672           g_free (filename);
1673
1674           break;
1675         }
1676     }
1677
1678   if (i == G_N_ELEMENTS (widgets))
1679     {
1680       gchar *filename = empathy_file_lookup (
1681           "empathy-account-widget-generic.ui", "libempathy-gtk");
1682       account_widget_build_generic (self, filename);
1683       g_free (filename);
1684     }
1685
1686   /* handle default focus */
1687   if (self->ui_details->default_focus != NULL)
1688     {
1689       GObject *default_focus_entry;
1690
1691       default_focus_entry = gtk_builder_get_object
1692         (self->ui_details->gui, self->ui_details->default_focus);
1693       g_signal_connect (default_focus_entry, "realize",
1694           G_CALLBACK (gtk_widget_grab_focus),
1695           NULL);
1696     }
1697
1698   /* handle forget button */
1699   if (self->ui_details->add_forget)
1700     {
1701       const gchar *password = NULL;
1702
1703       priv->button_forget = GTK_WIDGET (gtk_builder_get_object
1704           (self->ui_details->gui, "button_forget"));
1705       priv->entry_password = GTK_WIDGET (gtk_builder_get_object
1706           (self->ui_details->gui, "entry_password"));
1707
1708       password = empathy_account_settings_get_string (priv->settings,
1709           "password");
1710       gtk_widget_set_sensitive (priv->button_forget,
1711           !EMP_STR_EMPTY (password));
1712
1713       g_signal_connect (priv->button_forget, "clicked",
1714           G_CALLBACK (account_widget_forget_clicked_cb),
1715           self);
1716       g_signal_connect (priv->entry_password, "changed",
1717           G_CALLBACK (account_widget_password_changed_cb),
1718           self);
1719     }
1720
1721   /* dup and init the account-manager */
1722   priv->account_manager = tp_account_manager_dup ();
1723
1724   g_object_ref (self);
1725   tp_account_manager_prepare_async (priv->account_manager, NULL,
1726       account_manager_ready_cb, self);
1727
1728   /* handle apply and cancel button */
1729   if (!priv->simple)
1730     {
1731       GtkWidget *hbox = gtk_hbox_new (TRUE, 3);
1732
1733       priv->cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
1734
1735       priv->apply_button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
1736
1737       /* We'll change this button to a "Log in" one if we are creating a new
1738        * account and are connected. */
1739       empathy_signal_connect_weak (priv->account_manager,
1740           "most-available-presence-changed",
1741           G_CALLBACK (presence_changed_cb), obj);
1742
1743       gtk_box_pack_end (GTK_BOX (hbox), priv->apply_button, TRUE,
1744           TRUE, 3);
1745       gtk_box_pack_end (GTK_BOX (hbox), priv->cancel_button, TRUE,
1746           TRUE, 3);
1747
1748       gtk_box_pack_end (GTK_BOX (self->ui_details->widget), hbox, FALSE,
1749           FALSE, 3);
1750
1751       g_signal_connect (priv->cancel_button, "clicked",
1752           G_CALLBACK (account_widget_cancel_clicked_cb),
1753           self);
1754       g_signal_connect (priv->apply_button, "clicked",
1755           G_CALLBACK (account_widget_apply_clicked_cb),
1756           self);
1757       gtk_widget_show_all (hbox);
1758
1759       if (priv->creating_account)
1760         /* When creating an account, the user might have nothing to enter.
1761          * That means that no control interaction might occur,
1762          * so we update the control button sensitivity manually.
1763          */
1764         account_widget_handle_control_buttons_sensitivity (self);
1765       else
1766         account_widget_set_control_buttons_sensitivity (self, FALSE);
1767     }
1768
1769   account = empathy_account_settings_get_account (priv->settings);
1770
1771   if (account != NULL)
1772     {
1773       g_signal_connect (account, "notify::enabled",
1774           G_CALLBACK (empathy_account_widget_enabled_cb), self);
1775     }
1776
1777 #ifndef HAVE_MEEGO
1778   add_register_buttons (self, account);
1779 #endif /* HAVE_MEEGO */
1780   add_enable_checkbox (self, account);
1781
1782   /* hook up to widget destruction to unref ourselves */
1783   g_signal_connect (self->ui_details->widget, "destroy",
1784       G_CALLBACK (account_widget_destroy_cb), self);
1785
1786   empathy_builder_unref_and_keep_widget (self->ui_details->gui,
1787       self->ui_details->widget);
1788   self->ui_details->gui = NULL;
1789
1790   display_name = empathy_account_settings_get_display_name (priv->settings);
1791   default_display_name = empathy_account_widget_get_default_display_name (self);
1792
1793   if (tp_strdiff (display_name, default_display_name))
1794     {
1795       /* The display name of the account is not the one that we'd assign by
1796        * default; assume that the user changed it manually */
1797       g_object_set (priv->settings, "display-name-overridden", TRUE, NULL);
1798     }
1799 }
1800
1801 static void
1802 do_dispose (GObject *obj)
1803 {
1804   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1805   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1806
1807   if (priv->dispose_run)
1808     return;
1809
1810   priv->dispose_run = TRUE;
1811
1812   if (priv->settings != NULL)
1813     {
1814       TpAccount *account;
1815       account = empathy_account_settings_get_account (priv->settings);
1816
1817       if (account != NULL)
1818         {
1819           g_signal_handlers_disconnect_by_func (account,
1820               empathy_account_widget_enabled_cb, self);
1821         }
1822
1823       g_object_unref (priv->settings);
1824       priv->settings = NULL;
1825     }
1826
1827   if (priv->account_manager != NULL)
1828     {
1829       g_object_unref (priv->account_manager);
1830       priv->account_manager = NULL;
1831     }
1832
1833   if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose != NULL)
1834     G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose (obj);
1835 }
1836
1837 static void
1838 do_finalize (GObject *obj)
1839 {
1840   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1841
1842   g_free (self->ui_details->default_focus);
1843   g_slice_free (EmpathyAccountWidgetUIDetails, self->ui_details);
1844
1845   if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize != NULL)
1846     G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize (obj);
1847 }
1848
1849 static void
1850 empathy_account_widget_class_init (EmpathyAccountWidgetClass *klass)
1851 {
1852   GObjectClass *oclass = G_OBJECT_CLASS (klass);
1853   GParamSpec *param_spec;
1854
1855   oclass->get_property = do_get_property;
1856   oclass->set_property = do_set_property;
1857   oclass->constructed = do_constructed;
1858   oclass->dispose = do_dispose;
1859   oclass->finalize = do_finalize;
1860
1861   param_spec = g_param_spec_string ("protocol",
1862       "protocol", "The protocol of the account",
1863       NULL,
1864       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
1865   g_object_class_install_property (oclass, PROP_PROTOCOL, param_spec);
1866
1867   param_spec = g_param_spec_object ("settings",
1868       "settings", "The settings of the account",
1869       EMPATHY_TYPE_ACCOUNT_SETTINGS,
1870       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1871   g_object_class_install_property (oclass, PROP_SETTINGS, param_spec);
1872
1873   param_spec = g_param_spec_boolean ("simple",
1874       "simple", "Whether the account widget is a simple or an advanced one",
1875       FALSE,
1876       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1877   g_object_class_install_property (oclass, PROP_SIMPLE, param_spec);
1878
1879   param_spec = g_param_spec_boolean ("creating-account",
1880       "creating-account",
1881       "TRUE if we're creating an account, FALSE if we're modifying it",
1882       FALSE,
1883       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1884   g_object_class_install_property (oclass, PROP_CREATING_ACCOUNT, param_spec);
1885
1886   param_spec = g_param_spec_boolean ("other-accounts-exist",
1887       "other-accounts-exist",
1888       "TRUE if there are any other accounts (even if this isn't yet saved)",
1889       FALSE,
1890       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1891   g_object_class_install_property (oclass, PROP_OTHER_ACCOUNTS_EXIST,
1892                   param_spec);
1893
1894   signals[HANDLE_APPLY] =
1895     g_signal_new ("handle-apply", G_TYPE_FROM_CLASS (klass),
1896         G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1897         g_cclosure_marshal_VOID__BOOLEAN,
1898         G_TYPE_NONE,
1899         1, G_TYPE_BOOLEAN);
1900
1901   /* This signal is emitted when an account has been created and enabled. */
1902   signals[ACCOUNT_CREATED] =
1903       g_signal_new ("account-created", G_TYPE_FROM_CLASS (klass),
1904           G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1905           g_cclosure_marshal_VOID__OBJECT,
1906           G_TYPE_NONE,
1907           1, G_TYPE_OBJECT);
1908
1909   signals[CANCELLED] =
1910       g_signal_new ("cancelled", G_TYPE_FROM_CLASS (klass),
1911           G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1912           g_cclosure_marshal_VOID__VOID,
1913           G_TYPE_NONE,
1914           0);
1915
1916   g_type_class_add_private (klass, sizeof (EmpathyAccountWidgetPriv));
1917 }
1918
1919 static void
1920 empathy_account_widget_init (EmpathyAccountWidget *self)
1921 {
1922   EmpathyAccountWidgetPriv *priv =
1923     G_TYPE_INSTANCE_GET_PRIVATE ((self), EMPATHY_TYPE_ACCOUNT_WIDGET,
1924         EmpathyAccountWidgetPriv);
1925
1926   self->priv = priv;
1927   priv->dispose_run = FALSE;
1928
1929   self->ui_details = g_slice_new0 (EmpathyAccountWidgetUIDetails);
1930 }
1931
1932 /* public methods */
1933
1934 void
1935 empathy_account_widget_discard_pending_changes
1936     (EmpathyAccountWidget *widget)
1937 {
1938   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1939
1940   empathy_account_settings_discard_changes (priv->settings);
1941   priv->contains_pending_changes = FALSE;
1942 }
1943
1944 gboolean
1945 empathy_account_widget_contains_pending_changes (EmpathyAccountWidget *widget)
1946 {
1947   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1948
1949   return priv->contains_pending_changes;
1950 }
1951
1952 void
1953 empathy_account_widget_handle_params (EmpathyAccountWidget *self,
1954     const gchar *first_widget,
1955     ...)
1956 {
1957   va_list args;
1958
1959   va_start (args, first_widget);
1960   account_widget_handle_params_valist (self, first_widget, args);
1961   va_end (args);
1962 }
1963
1964 GtkWidget *
1965 empathy_account_widget_get_widget (EmpathyAccountWidget *widget)
1966 {
1967   return widget->ui_details->widget;
1968 }
1969
1970 EmpathyAccountWidget *
1971 empathy_account_widget_new_for_protocol (EmpathyAccountSettings *settings,
1972     gboolean simple)
1973 {
1974   EmpathyAccountWidget *self;
1975
1976   g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), NULL);
1977
1978   self = g_object_new
1979     (EMPATHY_TYPE_ACCOUNT_WIDGET,
1980         "settings", settings, "simple", simple,
1981         "creating-account",
1982         empathy_account_settings_get_account (settings) == NULL,
1983         NULL);
1984
1985   return self;
1986 }
1987
1988 gchar *
1989 empathy_account_widget_get_default_display_name (EmpathyAccountWidget *self)
1990 {
1991   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1992   const gchar *login_id;
1993   const gchar *protocol, *p;
1994   gchar *default_display_name;
1995
1996   login_id = empathy_account_settings_get_string (priv->settings, "account");
1997   protocol = empathy_account_settings_get_protocol (priv->settings);
1998
1999   if (login_id != NULL)
2000     {
2001       /* TODO: this should be done in empathy-account-widget-irc */
2002       if (!tp_strdiff (protocol, "irc"))
2003         {
2004           const gchar* server;
2005           server = empathy_account_settings_get_string (priv->settings,
2006               "server");
2007
2008           /* To translators: The first parameter is the login id and the
2009            * second one is the server. The resulting string will be something
2010            * like: "MyUserName on chat.freenode.net".
2011            * You should reverse the order of these arguments if the
2012            * server should come before the login id in your locale.*/
2013           default_display_name = g_strdup_printf (_("%1$s on %2$s"),
2014               login_id, server);
2015         }
2016       else if (account_widget_is_facebook (self))
2017         {
2018           gchar *tmp;
2019
2020           tmp = remove_facebook_suffix (login_id);
2021           default_display_name = g_strdup_printf ("Facebook (%s)", tmp);
2022           g_free (tmp);
2023         }
2024       else
2025         {
2026           default_display_name = g_strdup (login_id);
2027         }
2028
2029       return default_display_name;
2030     }
2031
2032   if ((p = empathy_protocol_name_to_display_name (protocol)) != NULL)
2033     protocol = p;
2034
2035   if (protocol != NULL)
2036     {
2037       /* To translators: The parameter is the protocol name. The resulting
2038        * string will be something like: "Jabber Account" */
2039       default_display_name = g_strdup_printf (_("%s Account"), protocol);
2040     }
2041   else
2042     {
2043       default_display_name = g_strdup (_("New account"));
2044     }
2045
2046   return default_display_name;
2047 }
2048
2049 /* Used by subclass to indicate that widget contains pending changes */
2050 void
2051 empathy_account_widget_changed (EmpathyAccountWidget *self)
2052 {
2053   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
2054
2055   account_widget_handle_control_buttons_sensitivity (self);
2056   priv->contains_pending_changes = TRUE;
2057 }
2058
2059 void
2060 empathy_account_widget_set_account_param (EmpathyAccountWidget *self,
2061     const gchar *account)
2062 {
2063   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
2064
2065   if (priv->param_account_widget == NULL)
2066     return;
2067
2068   gtk_entry_set_text (GTK_ENTRY (priv->param_account_widget), account);
2069 }
2070
2071 void
2072 empathy_account_widget_set_password_param (EmpathyAccountWidget *self,
2073     const gchar *account)
2074 {
2075   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
2076
2077   if (priv->param_password_widget == NULL)
2078     return;
2079
2080   gtk_entry_set_text (GTK_ENTRY (priv->param_password_widget), account);
2081 }