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