]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-account-widget.c
Merge commit 'jtellier/confirm-lose-accounts-settings'
[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 #include <libempathy/empathy-utils.h>
34 #include <libempathy/empathy-account.h>
35
36 #include <telepathy-glib/connection-manager.h>
37 #include <telepathy-glib/util.h>
38 #include <dbus/dbus-protocol.h>
39
40 #include "empathy-account-widget.h"
41 #include "empathy-account-widget-private.h"
42 #include "empathy-account-widget-sip.h"
43 #include "empathy-account-widget-irc.h"
44 #include "empathy-ui-utils.h"
45
46 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
47 #include <libempathy/empathy-debug.h>
48
49 G_DEFINE_TYPE (EmpathyAccountWidget, empathy_account_widget, G_TYPE_OBJECT)
50
51 typedef struct {
52   EmpathyAccountSettings *settings;
53
54   GtkWidget *table_common_settings;
55   GtkWidget *apply_button;
56   GtkWidget *cancel_button;
57   GtkWidget *entry_password;
58   GtkWidget *button_forget;
59   GtkWidget *spinbutton_port;
60   GtkWidget *enabled_checkbox;
61
62   gboolean simple;
63
64   gboolean contains_pending_changes;
65   gboolean original_enabled_checkbox_value;
66
67   /* An EmpathyAccountWidget can be used to either create an account or
68    * modify it. When we are creating an account, this member is set to TRUE */
69   gboolean creating_account;
70
71   gboolean dispose_run;
72 } EmpathyAccountWidgetPriv;
73
74 enum {
75   PROP_PROTOCOL = 1,
76   PROP_SETTINGS,
77   PROP_SIMPLE,
78   PROP_CREATING_ACCOUNT
79 };
80
81 enum {
82   HANDLE_APPLY,
83   ACCOUNT_CREATED,
84   CANCELLED,
85   LAST_SIGNAL
86 };
87
88 static guint signals[LAST_SIGNAL] = { 0 };
89
90 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountWidget)
91 #define CHANGED_TIMEOUT 300
92
93 static void
94 account_widget_set_control_buttons_sensitivity (EmpathyAccountWidget *self,
95     gboolean sensitive)
96 {
97   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
98
99   if (!priv->simple)
100     {
101       gtk_widget_set_sensitive (priv->apply_button, sensitive);
102       gtk_widget_set_sensitive (priv->cancel_button, sensitive);
103       priv->contains_pending_changes = sensitive;
104     }
105 }
106
107 static void
108 account_widget_handle_control_buttons_sensitivity (EmpathyAccountWidget *self)
109 {
110   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
111   gboolean is_valid;
112
113   is_valid = empathy_account_settings_is_valid (priv->settings);
114
115   if (!priv->simple)
116       account_widget_set_control_buttons_sensitivity (self, is_valid);
117
118   g_signal_emit (self, signals[HANDLE_APPLY], 0, is_valid);
119 }
120
121 static void
122 account_widget_entry_changed_common (EmpathyAccountWidget *self,
123     GtkEntry *entry, gboolean focus)
124 {
125   const gchar *str;
126   const gchar *param_name;
127   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
128
129   str = gtk_entry_get_text (entry);
130   param_name = g_object_get_data (G_OBJECT (entry), "param_name");
131
132   if (EMP_STR_EMPTY (str))
133     {
134       const gchar *value = NULL;
135
136       empathy_account_settings_unset (priv->settings, param_name);
137
138       if (focus)
139         {
140           value = empathy_account_settings_get_string (priv->settings,
141               param_name);
142           DEBUG ("Unset %s and restore to %s", param_name, value);
143           gtk_entry_set_text (entry, value ? value : "");
144         }
145     }
146   else
147     {
148       DEBUG ("Setting %s to %s", param_name,
149           tp_strdiff (param_name, "password") ? str : "***");
150       empathy_account_settings_set_string (priv->settings, param_name, str);
151     }
152 }
153
154 static void
155 account_widget_entry_changed_cb (GtkEditable *entry,
156     EmpathyAccountWidget *self)
157 {
158   account_widget_entry_changed_common (self, GTK_ENTRY (entry), FALSE);
159   account_widget_handle_control_buttons_sensitivity (self);
160 }
161
162 static void
163 account_widget_int_changed_cb (GtkWidget *widget,
164     EmpathyAccountWidget *self)
165 {
166   const gchar *param_name;
167   gint value;
168   const gchar *signature;
169   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
170
171   value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
172   param_name = g_object_get_data (G_OBJECT (widget), "param_name");
173
174   signature = empathy_account_settings_get_dbus_signature (priv->settings,
175     param_name);
176   g_return_if_fail (signature != NULL);
177
178   DEBUG ("Setting %s to %d", param_name, value);
179
180   switch ((int)*signature)
181     {
182     case DBUS_TYPE_INT16:
183     case DBUS_TYPE_INT32:
184       empathy_account_settings_set_int32 (priv->settings, param_name, value);
185       break;
186     case DBUS_TYPE_INT64:
187       empathy_account_settings_set_int64 (priv->settings, param_name, value);
188       break;
189     case DBUS_TYPE_UINT16:
190     case DBUS_TYPE_UINT32:
191       empathy_account_settings_set_uint32 (priv->settings, param_name, value);
192       break;
193     case DBUS_TYPE_UINT64:
194       empathy_account_settings_set_uint64 (priv->settings, param_name, value);
195       break;
196     default:
197       g_return_if_reached ();
198     }
199
200   account_widget_handle_control_buttons_sensitivity (self);
201 }
202
203 static void
204 account_widget_checkbutton_toggled_cb (GtkWidget *widget,
205     EmpathyAccountWidget *self)
206 {
207   gboolean     value;
208   gboolean     default_value;
209   const gchar *param_name;
210   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
211
212   value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
213   param_name = g_object_get_data (G_OBJECT (widget), "param_name");
214
215   /* FIXME: This is ugly! checkbox don't have a "not-set" value so we
216    * always unset the param and set the value if different from the
217    * default value. */
218   empathy_account_settings_unset (priv->settings, param_name);
219   default_value = empathy_account_settings_get_boolean (priv->settings,
220       param_name);
221
222   if (default_value == value)
223     {
224       DEBUG ("Unset %s and restore to %d", param_name, default_value);
225     }
226   else
227     {
228       DEBUG ("Setting %s to %d", param_name, value);
229       empathy_account_settings_set_boolean (priv->settings, param_name, value);
230     }
231
232   account_widget_handle_control_buttons_sensitivity (self);
233 }
234
235 static void
236 account_widget_forget_clicked_cb (GtkWidget *button,
237     EmpathyAccountWidget *self)
238 {
239   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
240   const gchar *param_name;
241
242   param_name = g_object_get_data (G_OBJECT (priv->entry_password),
243       "param_name");
244
245   DEBUG ("Unset %s", param_name);
246   empathy_account_settings_unset (priv->settings, param_name);
247   gtk_entry_set_text (GTK_ENTRY (priv->entry_password), "");
248
249   account_widget_handle_control_buttons_sensitivity (self);
250 }
251
252 static void
253 account_widget_password_changed_cb (GtkWidget *entry,
254     EmpathyAccountWidget *self)
255 {
256   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
257   const gchar *str;
258
259   str = gtk_entry_get_text (GTK_ENTRY (entry));
260   gtk_widget_set_sensitive (priv->button_forget, !EMP_STR_EMPTY (str));
261 }
262
263 static void
264 account_widget_jabber_ssl_toggled_cb (GtkWidget *checkbutton_ssl,
265     EmpathyAccountWidget *self)
266 {
267   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
268   gboolean   value;
269   gint32       port = 0;
270
271   value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl));
272   port = empathy_account_settings_get_uint32 (priv->settings, "port");
273
274   if (value)
275     {
276       if (port == 5222 || port == 0)
277         port = 5223;
278     }
279   else
280     {
281       if (port == 5223 || port == 0)
282         port = 5222;
283     }
284
285   gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->spinbutton_port), port);
286 }
287
288 static void
289 account_widget_setup_widget (EmpathyAccountWidget *self,
290     GtkWidget *widget,
291     const gchar *param_name)
292 {
293   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
294
295   g_object_set_data_full (G_OBJECT (widget), "param_name",
296       g_strdup (param_name), g_free);
297
298   if (GTK_IS_SPIN_BUTTON (widget))
299     {
300       gint value = 0;
301       const gchar *signature;
302
303       signature = empathy_account_settings_get_dbus_signature (priv->settings,
304           param_name);
305       g_return_if_fail (signature != NULL);
306
307       switch ((int)*signature)
308         {
309           case DBUS_TYPE_INT16:
310           case DBUS_TYPE_INT32:
311             value = empathy_account_settings_get_int32 (priv->settings,
312               param_name);
313             break;
314           case DBUS_TYPE_INT64:
315             value = empathy_account_settings_get_int64 (priv->settings,
316               param_name);
317             break;
318           case DBUS_TYPE_UINT16:
319           case DBUS_TYPE_UINT32:
320             value = empathy_account_settings_get_uint32 (priv->settings,
321               param_name);
322             break;
323           case DBUS_TYPE_UINT64:
324             value = empathy_account_settings_get_uint64 (priv->settings,
325                 param_name);
326             break;
327           default:
328             g_return_if_reached ();
329         }
330
331       gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
332
333       g_signal_connect (widget, "value-changed",
334           G_CALLBACK (account_widget_int_changed_cb),
335           self);
336     }
337   else if (GTK_IS_ENTRY (widget))
338     {
339       const gchar *str = NULL;
340
341       str = empathy_account_settings_get_string (priv->settings, param_name);
342       gtk_entry_set_text (GTK_ENTRY (widget), str ? str : "");
343
344       if (strstr (param_name, "password"))
345         {
346           gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
347         }
348
349       g_signal_connect (widget, "changed",
350           G_CALLBACK (account_widget_entry_changed_cb), self);
351     }
352   else if (GTK_IS_TOGGLE_BUTTON (widget))
353     {
354       gboolean value = FALSE;
355
356       value = empathy_account_settings_get_boolean (priv->settings,
357           param_name);
358       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
359
360       g_signal_connect (widget, "toggled",
361           G_CALLBACK (account_widget_checkbutton_toggled_cb),
362           self);
363     }
364   else
365     {
366       DEBUG ("Unknown type of widget for param %s", param_name);
367     }
368 }
369
370 static gchar *
371 account_widget_generic_format_param_name (const gchar *param_name)
372 {
373   gchar *str;
374   gchar *p;
375
376   str = g_strdup (param_name);
377
378   if (str && g_ascii_isalpha (str[0]))
379     str[0] = g_ascii_toupper (str[0]);
380
381   while ((p = strchr (str, '-')) != NULL)
382     {
383       if (p[1] != '\0' && g_ascii_isalpha (p[1]))
384         {
385           p[0] = ' ';
386           p[1] = g_ascii_toupper (p[1]);
387         }
388
389       p++;
390     }
391
392   return str;
393 }
394
395 static void
396 accounts_widget_generic_setup (EmpathyAccountWidget *self,
397     GtkWidget *table_common_settings,
398     GtkWidget *table_advanced_settings)
399 {
400   TpConnectionManagerParam *params, *param;
401   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
402
403   params = empathy_account_settings_get_tp_params (priv->settings);
404
405   for (param = params; param != NULL && param->name != NULL; param++)
406     {
407       GtkWidget       *table_settings;
408       guint            n_rows = 0;
409       GtkWidget       *widget = NULL;
410       gchar           *param_name_formatted;
411
412       if (param->flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED)
413         table_settings = table_common_settings;
414       else if (priv->simple)
415         return;
416       else
417         table_settings = table_advanced_settings;
418
419       param_name_formatted = account_widget_generic_format_param_name
420         (param->name);
421       g_object_get (table_settings, "n-rows", &n_rows, NULL);
422       gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2);
423
424       if (param->dbus_signature[0] == 's')
425         {
426           gchar *str;
427
428           str = g_strdup_printf (_("%s:"), param_name_formatted);
429           widget = gtk_label_new (str);
430           gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
431           g_free (str);
432
433           gtk_table_attach (GTK_TABLE (table_settings),
434               widget,
435               0, 1,
436               n_rows - 1, n_rows,
437               GTK_FILL, 0,
438               0, 0);
439           gtk_widget_show (widget);
440
441           widget = gtk_entry_new ();
442           if (strcmp (param->name, "account") == 0)
443             {
444               g_signal_connect (widget, "realize",
445                   G_CALLBACK (gtk_widget_grab_focus),
446                   NULL);
447             }
448           gtk_table_attach (GTK_TABLE (table_settings),
449               widget,
450               1, 2,
451               n_rows - 1, n_rows,
452               GTK_FILL | GTK_EXPAND, 0,
453               0, 0);
454           gtk_widget_show (widget);
455         }
456       /* int types: ynqiuxt. double type is 'd' */
457       else if (param->dbus_signature[0] == 'y' ||
458           param->dbus_signature[0] == 'n' ||
459           param->dbus_signature[0] == 'q' ||
460           param->dbus_signature[0] == 'i' ||
461           param->dbus_signature[0] == 'u' ||
462           param->dbus_signature[0] == 'x' ||
463           param->dbus_signature[0] == 't' ||
464           param->dbus_signature[0] == 'd')
465         {
466           gchar   *str = NULL;
467           gdouble  minint = 0;
468           gdouble  maxint = 0;
469           gdouble  step = 1;
470
471           switch (param->dbus_signature[0])
472             {
473             case 'y': minint = G_MININT8;  maxint = G_MAXINT8;   break;
474             case 'n': minint = G_MININT16; maxint = G_MAXINT16;  break;
475             case 'q': minint = 0;          maxint = G_MAXUINT16; break;
476             case 'i': minint = G_MININT32; maxint = G_MAXINT32;  break;
477             case 'u': minint = 0;          maxint = G_MAXUINT32; break;
478             case 'x': minint = G_MININT64; maxint = G_MAXINT64;  break;
479             case 't': minint = 0;          maxint = G_MAXUINT64; break;
480             case 'd': minint = G_MININT32; maxint = G_MAXINT32;
481               step = 0.1; break;
482             }
483
484           str = g_strdup_printf (_("%s:"), param_name_formatted);
485           widget = gtk_label_new (str);
486           gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
487           g_free (str);
488
489           gtk_table_attach (GTK_TABLE (table_settings),
490               widget,
491               0, 1,
492               n_rows - 1, n_rows,
493               GTK_FILL, 0,
494               0, 0);
495           gtk_widget_show (widget);
496
497           widget = gtk_spin_button_new_with_range (minint, maxint, step);
498           gtk_table_attach (GTK_TABLE (table_settings),
499               widget,
500               1, 2,
501               n_rows - 1, n_rows,
502               GTK_FILL | GTK_EXPAND, 0,
503               0, 0);
504           gtk_widget_show (widget);
505         }
506       else if (param->dbus_signature[0] == 'b')
507         {
508           widget = gtk_check_button_new_with_label (param_name_formatted);
509           gtk_table_attach (GTK_TABLE (table_settings),
510               widget,
511               0, 2,
512               n_rows - 1, n_rows,
513               GTK_FILL | GTK_EXPAND, 0,
514               0, 0);
515           gtk_widget_show (widget);
516         }
517       else
518         {
519           DEBUG ("Unknown signature for param %s: %s",
520               param_name_formatted, param->dbus_signature);
521         }
522
523       if (widget)
524         account_widget_setup_widget (self, widget, param->name);
525
526       g_free (param_name_formatted);
527     }
528 }
529
530 static void
531 account_widget_handle_params_valist (EmpathyAccountWidget *self,
532     const gchar *first_widget,
533     va_list args)
534 {
535   GObject *object;
536   const gchar *name;
537
538   for (name = first_widget; name; name = va_arg (args, const gchar *))
539     {
540       const gchar *param_name;
541
542       param_name = va_arg (args, const gchar *);
543       object = gtk_builder_get_object (self->ui_details->gui, name);
544
545       if (!object)
546         {
547           g_warning ("Builder is missing object '%s'.", name);
548           continue;
549         }
550
551       account_widget_setup_widget (self, GTK_WIDGET (object), param_name);
552     }
553 }
554
555 static void
556 account_widget_cancel_clicked_cb (GtkWidget *button,
557     EmpathyAccountWidget *self)
558 {
559   g_signal_emit (self, signals[CANCELLED], 0);
560 }
561
562 static void
563 account_widget_account_enabled_cb (GObject *source_object,
564     GAsyncResult *res,
565     gpointer user_data)
566 {
567   GError *error = NULL;
568   EmpathyAccount *account = EMPATHY_ACCOUNT (source_object);
569   EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
570
571   empathy_account_set_enabled_finish (account, res, &error);
572
573   if (error != NULL)
574     {
575       DEBUG ("Could not automatically enable new account: %s", error->message);
576       g_error_free (error);
577     }
578   else
579     {
580       g_signal_emit (widget, signals[ACCOUNT_CREATED], 0);
581     }
582 }
583
584 static void
585 account_widget_applied_cb (GObject *source_object,
586     GAsyncResult *res,
587     gpointer user_data)
588 {
589   GError *error = NULL;
590   EmpathyAccount *account;
591   EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (source_object);
592   EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
593   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
594
595   empathy_account_settings_apply_finish (settings, res, &error);
596
597   if (error != NULL)
598     {
599       DEBUG ("Could not apply changes to account: %s", error->message);
600       g_error_free (error);
601       return;
602     }
603
604   account = empathy_account_settings_get_account (priv->settings);
605
606   if (account != NULL)
607     {
608       if (priv->creating_account)
609         {
610           /* By default, when an account is created, we enable it. */
611           empathy_account_set_enabled_async (account, TRUE,
612               account_widget_account_enabled_cb, widget);
613         }
614       else if (priv->enabled_checkbox != NULL)
615         {
616           gboolean enabled_checked;
617
618           enabled_checked = gtk_toggle_button_get_active (
619               GTK_TOGGLE_BUTTON (priv->enabled_checkbox));
620
621           if (empathy_account_is_enabled (account) && enabled_checked)
622             {
623               /* After having applied changes to a user account, we
624                * automatically reconnect it. This is done so the new
625                * information entered by the user is validated on the server. */
626               empathy_account_reconnect_async (account, NULL, NULL);
627             }
628           else
629             {
630               /* The account is disabled so we enable it according to the value
631                * of the "Enabled" checkbox */
632               empathy_account_set_enabled_async (account, enabled_checked,
633                   NULL, NULL);
634             }
635         }
636     }
637
638   account_widget_set_control_buttons_sensitivity (widget, FALSE);
639 }
640
641 static void
642 account_widget_apply_clicked_cb (GtkWidget *button,
643     EmpathyAccountWidget *self)
644 {
645   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
646
647   empathy_account_settings_apply_async (priv->settings,
648       account_widget_applied_cb, self);
649 }
650
651 static void
652 account_widget_setup_generic (EmpathyAccountWidget *self)
653 {
654   GtkWidget *table_common_settings;
655   GtkWidget *table_advanced_settings;
656
657   table_common_settings = GTK_WIDGET (gtk_builder_get_object
658       (self->ui_details->gui, "table_common_settings"));
659   table_advanced_settings = GTK_WIDGET (gtk_builder_get_object
660       (self->ui_details->gui, "table_advanced_settings"));
661
662   accounts_widget_generic_setup (self, table_common_settings,
663       table_advanced_settings);
664
665   g_object_unref (self->ui_details->gui);
666 }
667
668 static void
669 account_widget_settings_ready_cb (EmpathyAccountSettings *settings,
670     GParamSpec *pspec,
671     gpointer user_data)
672 {
673   EmpathyAccountWidget *self = user_data;
674   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
675
676   if (empathy_account_settings_is_ready (priv->settings))
677     account_widget_setup_generic (self);
678 }
679
680 static void
681 account_widget_build_generic (EmpathyAccountWidget *self,
682     const char *filename)
683 {
684   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
685   GtkWidget *expander_advanced;
686
687   self->ui_details->gui = empathy_builder_get_file (filename,
688       "table_common_settings", &priv->table_common_settings,
689       "vbox_generic_settings", &self->ui_details->widget,
690       "expander_advanced_settings", &expander_advanced,
691       NULL);
692
693   if (priv->simple)
694     gtk_widget_hide (expander_advanced);
695
696   g_object_ref (self->ui_details->gui);
697
698   if (empathy_account_settings_is_ready (priv->settings))
699     account_widget_setup_generic (self);
700   else
701     g_signal_connect (priv->settings, "notify::ready",
702         G_CALLBACK (account_widget_settings_ready_cb), self);
703 }
704
705 static void
706 account_widget_build_salut (EmpathyAccountWidget *self,
707     const char *filename)
708 {
709   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
710
711   self->ui_details->gui = empathy_builder_get_file (filename,
712       "table_common_settings", &priv->table_common_settings,
713       "vbox_salut_settings", &self->ui_details->widget,
714       NULL);
715
716   empathy_account_widget_handle_params (self,
717       "entry_published", "published-name",
718       "entry_nickname", "nickname",
719       "entry_first_name", "first-name",
720       "entry_last_name", "last-name",
721       "entry_email", "email",
722       "entry_jid", "jid",
723       NULL);
724
725   self->ui_details->default_focus = g_strdup ("entry_nickname");
726 }
727
728 static void
729 account_widget_build_irc (EmpathyAccountWidget *self,
730   const char *filename)
731 {
732   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
733   empathy_account_widget_irc_build (self, filename,
734     &priv->table_common_settings);
735 }
736
737 static void
738 account_widget_build_sip (EmpathyAccountWidget *self,
739   const char *filename)
740 {
741   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
742   empathy_account_widget_sip_build (self, filename,
743     &priv->table_common_settings);
744 }
745
746 static void
747 account_widget_build_msn (EmpathyAccountWidget *self,
748     const char *filename)
749 {
750   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
751
752   if (priv->simple)
753     {
754       self->ui_details->gui = empathy_builder_get_file (filename,
755           "vbox_msn_simple", &self->ui_details->widget,
756           NULL);
757
758       empathy_account_widget_handle_params (self,
759           "entry_id_simple", "account",
760           "entry_password_simple", "password",
761           NULL);
762
763       self->ui_details->default_focus = g_strdup ("entry_id_simple");
764     }
765   else
766     {
767       self->ui_details->gui = empathy_builder_get_file (filename,
768           "table_common_msn_settings", &priv->table_common_settings,
769           "vbox_msn_settings", &self->ui_details->widget,
770           NULL);
771
772       empathy_account_widget_handle_params (self,
773           "entry_id", "account",
774           "entry_password", "password",
775           "entry_server", "server",
776           "spinbutton_port", "port",
777           NULL);
778
779       self->ui_details->default_focus = g_strdup ("entry_id");
780       self->ui_details->add_forget = TRUE;
781     }
782 }
783
784 static void
785 account_widget_build_jabber (EmpathyAccountWidget *self,
786     const char *filename)
787 {
788   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
789   GtkWidget *spinbutton_port;
790   GtkWidget *checkbutton_ssl;
791   GtkWidget *label_id, *label_password;
792   GtkWidget *label_id_create, *label_password_create;
793
794   if (priv->simple)
795     {
796       self->ui_details->gui = empathy_builder_get_file (filename,
797           "vbox_jabber_simple", &self->ui_details->widget,
798           "label_id_simple", &label_id,
799           "label_id_create", &label_id_create,
800           "label_password_simple", &label_password,
801           "label_password_create", &label_password_create,
802           NULL);
803
804       if (empathy_account_settings_get_boolean (priv->settings, "register"))
805         {
806           gtk_widget_hide (label_id);
807           gtk_widget_hide (label_password);
808           gtk_widget_show (label_id_create);
809           gtk_widget_show (label_password_create);
810         }
811
812       empathy_account_widget_handle_params (self,
813           "entry_id_simple", "account",
814           "entry_password_simple", "password",
815           NULL);
816
817       self->ui_details->default_focus = g_strdup ("entry_id_simple");
818     }
819   else
820     {
821       self->ui_details->gui = empathy_builder_get_file (filename,
822           "table_common_settings", &priv->table_common_settings,
823           "vbox_jabber_settings", &self->ui_details->widget,
824           "spinbutton_port", &spinbutton_port,
825           "checkbutton_ssl", &checkbutton_ssl,
826           NULL);
827
828       empathy_account_widget_handle_params (self,
829           "entry_id", "account",
830           "entry_password", "password",
831           "entry_resource", "resource",
832           "entry_server", "server",
833           "spinbutton_port", "port",
834           "spinbutton_priority", "priority",
835           "checkbutton_ssl", "old-ssl",
836           "checkbutton_ignore_ssl_errors", "ignore-ssl-errors",
837           "checkbutton_encryption", "require-encryption",
838           NULL);
839
840       self->ui_details->default_focus = g_strdup ("entry_id");
841       self->ui_details->add_forget = TRUE;
842       priv->spinbutton_port = spinbutton_port;
843
844       g_signal_connect (checkbutton_ssl, "toggled",
845           G_CALLBACK (account_widget_jabber_ssl_toggled_cb),
846           self);
847     }
848 }
849
850 static void
851 account_widget_build_icq (EmpathyAccountWidget *self,
852     const char *filename)
853 {
854   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
855   GtkWidget *spinbutton_port;
856
857   if (priv->simple)
858     {
859       self->ui_details->gui = empathy_builder_get_file (filename,
860           "vbox_icq_simple", &self->ui_details->widget,
861           NULL);
862
863       empathy_account_widget_handle_params (self,
864           "entry_uin_simple", "account",
865           "entry_password_simple", "password",
866           NULL);
867
868       self->ui_details->default_focus = g_strdup ("entry_uin_simple");
869     }
870   else
871     {
872       self->ui_details->gui = empathy_builder_get_file (filename,
873           "table_common_settings", &priv->table_common_settings,
874           "vbox_icq_settings", &self->ui_details->widget,
875           "spinbutton_port", &spinbutton_port,
876           NULL);
877
878       empathy_account_widget_handle_params (self,
879           "entry_uin", "account",
880           "entry_password", "password",
881           "entry_server", "server",
882           "spinbutton_port", "port",
883           "entry_charset", "charset",
884           NULL);
885
886       self->ui_details->default_focus = g_strdup ("entry_uin");
887       self->ui_details->add_forget = TRUE;
888     }
889 }
890
891 static void
892 account_widget_build_aim (EmpathyAccountWidget *self,
893     const char *filename)
894 {
895   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
896   GtkWidget *spinbutton_port;
897
898   if (priv->simple)
899     {
900       self->ui_details->gui = empathy_builder_get_file (filename,
901           "vbox_aim_simple", &self->ui_details->widget,
902           NULL);
903
904       empathy_account_widget_handle_params (self,
905           "entry_screenname_simple", "account",
906           "entry_password_simple", "password",
907           NULL);
908
909       self->ui_details->default_focus = g_strdup ("entry_screenname_simple");
910     }
911   else
912     {
913       self->ui_details->gui = empathy_builder_get_file (filename,
914           "table_common_settings", &priv->table_common_settings,
915           "vbox_aim_settings", &self->ui_details->widget,
916           "spinbutton_port", &spinbutton_port,
917           NULL);
918
919       empathy_account_widget_handle_params (self,
920           "entry_screenname", "account",
921           "entry_password", "password",
922           "entry_server", "server",
923           "spinbutton_port", "port",
924           NULL);
925
926       self->ui_details->default_focus = g_strdup ("entry_screenname");
927       self->ui_details->add_forget = TRUE;
928     }
929 }
930
931 static void
932 account_widget_build_yahoo (EmpathyAccountWidget *self,
933     const char *filename)
934 {
935   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
936
937   if (priv->simple)
938     {
939       self->ui_details->gui = empathy_builder_get_file (filename,
940           "vbox_yahoo_simple", &self->ui_details->widget,
941           NULL);
942
943       empathy_account_widget_handle_params (self,
944           "entry_id_simple", "account",
945           "entry_password_simple", "password",
946           NULL);
947
948       self->ui_details->default_focus = g_strdup ("entry_id_simple");
949     }
950   else
951     {
952       self->ui_details->gui = empathy_builder_get_file (filename,
953           "table_common_settings", &priv->table_common_settings,
954           "vbox_yahoo_settings", &self->ui_details->widget,
955           NULL);
956
957       empathy_account_widget_handle_params (self,
958           "entry_id", "account",
959           "entry_password", "password",
960           "entry_server", "server",
961           "entry_locale", "room-list-locale",
962           "entry_charset", "charset",
963           "spinbutton_port", "port",
964           "checkbutton_yahoojp", "yahoojp",
965           "checkbutton_ignore_invites", "ignore-invites",
966           NULL);
967
968       self->ui_details->default_focus = g_strdup ("entry_id");
969       self->ui_details->add_forget = TRUE;
970     }
971 }
972
973 static void
974 account_widget_build_groupwise (EmpathyAccountWidget *self,
975     const char *filename)
976 {
977   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
978
979   if (priv->simple)
980     {
981       self->ui_details->gui = empathy_builder_get_file (filename,
982           "vbox_groupwise_simple", &self->ui_details->widget,
983           NULL);
984
985       empathy_account_widget_handle_params (self,
986           "entry_id_simple", "account",
987           "entry_password_simple", "password",
988           NULL);
989
990       self->ui_details->default_focus = g_strdup ("entry_id_simple");
991     }
992   else
993     {
994       self->ui_details->gui = empathy_builder_get_file (filename,
995           "table_common_groupwise_settings", &priv->table_common_settings,
996           "vbox_groupwise_settings", &self->ui_details->widget,
997           NULL);
998
999       empathy_account_widget_handle_params (self,
1000           "entry_id", "account",
1001           "entry_password", "password",
1002           "entry_server", "server",
1003           "spinbutton_port", "port",
1004           NULL);
1005
1006       self->ui_details->default_focus = g_strdup ("entry_id");
1007       self->ui_details->add_forget = TRUE;
1008     }
1009 }
1010
1011 static void
1012 account_widget_destroy_cb (GtkWidget *widget,
1013     EmpathyAccountWidget *self)
1014 {
1015   g_object_unref (self);
1016 }
1017
1018 static void
1019 empathy_account_widget_enabled_cb (EmpathyAccount *account,
1020       GParamSpec *spec,
1021       gpointer user_data)
1022 {
1023   EmpathyAccountWidget *widget = EMPATHY_ACCOUNT_WIDGET (user_data);
1024   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1025   gboolean enabled = empathy_account_is_enabled (account);
1026
1027   if (priv->enabled_checkbox != NULL)
1028     {
1029       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->enabled_checkbox),
1030           enabled);
1031     }
1032 }
1033
1034 static void
1035 account_widget_enabled_released_cb (GtkToggleButton *toggle_button,
1036     gpointer user_data)
1037 {
1038   account_widget_handle_control_buttons_sensitivity (
1039       EMPATHY_ACCOUNT_WIDGET (user_data));
1040 }
1041
1042 static void
1043 do_set_property (GObject *object,
1044     guint prop_id,
1045     const GValue *value,
1046     GParamSpec *pspec)
1047 {
1048   EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
1049
1050   switch (prop_id)
1051     {
1052     case PROP_SETTINGS:
1053       priv->settings = g_value_dup_object (value);
1054       break;
1055     case PROP_SIMPLE:
1056       priv->simple = g_value_get_boolean (value);
1057       break;
1058     case PROP_CREATING_ACCOUNT:
1059       priv->creating_account = g_value_get_boolean (value);
1060       break;
1061     default:
1062       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1063     }
1064 }
1065
1066 static void
1067 do_get_property (GObject *object,
1068     guint prop_id,
1069     GValue *value,
1070     GParamSpec *pspec)
1071 {
1072   EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
1073
1074   switch (prop_id)
1075     {
1076     case PROP_PROTOCOL:
1077       g_value_set_string (value,
1078         empathy_account_settings_get_protocol (priv->settings));
1079       break;
1080     case PROP_SETTINGS:
1081       g_value_set_object (value, priv->settings);
1082       break;
1083     case PROP_SIMPLE:
1084       g_value_set_boolean (value, priv->simple);
1085       break;
1086     case PROP_CREATING_ACCOUNT:
1087       g_value_set_boolean (value, priv->creating_account);
1088       break;
1089     default:
1090       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1091     }
1092 }
1093
1094 #define WIDGET(cm, proto) \
1095   { #cm, #proto, "empathy-account-widget-"#proto".ui", \
1096     account_widget_build_##proto }
1097
1098 static void
1099 do_constructed (GObject *obj)
1100 {
1101   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1102   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1103   EmpathyAccount *account;
1104   const gchar *protocol, *cm_name;
1105   int i = 0;
1106   struct {
1107     const gchar *cm_name;
1108     const gchar *protocol;
1109     const char *file;
1110     void (*func)(EmpathyAccountWidget *self, const gchar *filename);
1111   } widgets [] = {
1112     { "salut", "local-xmpp", "empathy-account-widget-local-xmpp.ui",
1113         account_widget_build_salut },
1114     WIDGET (gabble, jabber),
1115     WIDGET (butterfly, msn),
1116     WIDGET (haze, icq),
1117     WIDGET (haze, aim),
1118     WIDGET (haze, yahoo),
1119     WIDGET (haze, groupwise),
1120     WIDGET (idle, irc),
1121     WIDGET (sofiasip, sip),
1122   };
1123
1124   cm_name = empathy_account_settings_get_cm (priv->settings);
1125   protocol = empathy_account_settings_get_protocol (priv->settings);
1126
1127   for (i = 0 ; i < G_N_ELEMENTS (widgets); i++)
1128     {
1129       if (!tp_strdiff (widgets[i].cm_name, cm_name) &&
1130           !tp_strdiff (widgets[i].protocol, protocol))
1131         {
1132           gchar *filename;
1133
1134           filename = empathy_file_lookup (widgets[i].file,
1135               "libempathy-gtk");
1136           widgets[i].func (self, filename);
1137           g_free (filename);
1138
1139           break;
1140         }
1141     }
1142
1143   if (i == G_N_ELEMENTS (widgets))
1144     {
1145       gchar *filename = empathy_file_lookup (
1146           "empathy-account-widget-generic.ui", "libempathy-gtk");
1147       account_widget_build_generic (self, filename);
1148       g_free (filename);
1149     }
1150
1151   /* handle default focus */
1152   if (self->ui_details->default_focus != NULL)
1153     {
1154       GObject *default_focus_entry;
1155
1156       default_focus_entry = gtk_builder_get_object
1157         (self->ui_details->gui, self->ui_details->default_focus);
1158       g_signal_connect (default_focus_entry, "realize",
1159           G_CALLBACK (gtk_widget_grab_focus),
1160           NULL);
1161     }
1162
1163   /* handle forget button */
1164   if (self->ui_details->add_forget)
1165     {
1166       const gchar *password = NULL;
1167
1168       priv->button_forget = GTK_WIDGET (gtk_builder_get_object
1169           (self->ui_details->gui, "button_forget"));
1170       priv->entry_password = GTK_WIDGET (gtk_builder_get_object
1171           (self->ui_details->gui, "entry_password"));
1172
1173       password = empathy_account_settings_get_string (priv->settings,
1174           "password");
1175       gtk_widget_set_sensitive (priv->button_forget,
1176           !EMP_STR_EMPTY (password));
1177
1178       g_signal_connect (priv->button_forget, "clicked",
1179           G_CALLBACK (account_widget_forget_clicked_cb),
1180           self);
1181       g_signal_connect (priv->entry_password, "changed",
1182           G_CALLBACK (account_widget_password_changed_cb),
1183           self);
1184     }
1185
1186   /* handle apply and cancel button */
1187   if (!priv->simple)
1188     {
1189       GtkWidget *hbox = gtk_hbox_new (TRUE, 3);
1190
1191       priv->cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
1192       priv->apply_button = gtk_button_new_from_stock (
1193         priv->creating_account ? GTK_STOCK_CONNECT : GTK_STOCK_APPLY);
1194
1195       gtk_box_pack_end (GTK_BOX (hbox), priv->apply_button, TRUE,
1196           TRUE, 3);
1197       gtk_box_pack_end (GTK_BOX (hbox), priv->cancel_button, TRUE,
1198           TRUE, 3);
1199
1200       gtk_box_pack_end (GTK_BOX (self->ui_details->widget), hbox, FALSE,
1201           FALSE, 3);
1202
1203       g_signal_connect (priv->cancel_button, "clicked",
1204           G_CALLBACK (account_widget_cancel_clicked_cb),
1205           self);
1206       g_signal_connect (priv->apply_button, "clicked",
1207           G_CALLBACK (account_widget_apply_clicked_cb),
1208           self);
1209       gtk_widget_show_all (hbox);
1210       account_widget_set_control_buttons_sensitivity (self, FALSE);
1211     }
1212
1213   account = empathy_account_settings_get_account (priv->settings);
1214
1215   if (account != NULL)
1216     {
1217       g_signal_connect (account, "notify::enabled",
1218           G_CALLBACK (empathy_account_widget_enabled_cb), self);
1219     }
1220
1221   /* handle the "Enabled" checkbox. We only add it when modifying an account */
1222   if (!priv->creating_account && priv->table_common_settings != NULL)
1223     {
1224       guint nb_rows, nb_columns;
1225
1226       priv->enabled_checkbox =
1227           gtk_check_button_new_with_label (_("Enabled"));
1228       priv->original_enabled_checkbox_value =
1229           empathy_account_is_enabled (account);
1230       gtk_toggle_button_set_active (
1231           GTK_TOGGLE_BUTTON (priv->enabled_checkbox),
1232           priv->original_enabled_checkbox_value);
1233
1234       g_object_get (priv->table_common_settings, "n-rows", &nb_rows,
1235           "n-columns", &nb_columns, NULL);
1236
1237       gtk_table_resize (GTK_TABLE (priv->table_common_settings), ++nb_rows,
1238           nb_columns);
1239
1240       gtk_table_attach (GTK_TABLE (priv->table_common_settings),
1241           priv->enabled_checkbox, 0, nb_columns, nb_rows - 1, nb_rows,
1242           GTK_EXPAND | GTK_FILL, 0, 0, 0);
1243
1244       gtk_widget_show (priv->enabled_checkbox);
1245
1246       g_signal_connect (G_OBJECT (priv->enabled_checkbox), "released",
1247           G_CALLBACK (account_widget_enabled_released_cb), self);
1248     }
1249
1250   /* hook up to widget destruction to unref ourselves */
1251   g_signal_connect (self->ui_details->widget, "destroy",
1252       G_CALLBACK (account_widget_destroy_cb), self);
1253
1254   empathy_builder_unref_and_keep_widget (self->ui_details->gui,
1255       self->ui_details->widget);
1256   self->ui_details->gui = NULL;
1257 }
1258
1259 static void
1260 do_dispose (GObject *obj)
1261 {
1262   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1263   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
1264
1265   if (priv->dispose_run)
1266     return;
1267
1268   priv->dispose_run = TRUE;
1269
1270   empathy_account_settings_is_ready (priv->settings);
1271
1272   if (priv->settings != NULL)
1273     {
1274       EmpathyAccount *account;
1275       account = empathy_account_settings_get_account (priv->settings);
1276
1277       if (account != NULL)
1278         {
1279           g_signal_handlers_disconnect_by_func (account,
1280               empathy_account_widget_enabled_cb, self);
1281         }
1282
1283       g_object_unref (priv->settings);
1284       priv->settings = NULL;
1285     }
1286
1287   if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose != NULL)
1288     G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose (obj);
1289 }
1290
1291 static void
1292 do_finalize (GObject *obj)
1293 {
1294   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
1295
1296   g_free (self->ui_details->default_focus);
1297   g_slice_free (EmpathyAccountWidgetUIDetails, self->ui_details);
1298
1299   if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize != NULL)
1300     G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize (obj);
1301 }
1302
1303 static void
1304 empathy_account_widget_class_init (EmpathyAccountWidgetClass *klass)
1305 {
1306   GObjectClass *oclass = G_OBJECT_CLASS (klass);
1307   GParamSpec *param_spec;
1308
1309   oclass->get_property = do_get_property;
1310   oclass->set_property = do_set_property;
1311   oclass->constructed = do_constructed;
1312   oclass->dispose = do_dispose;
1313   oclass->finalize = do_finalize;
1314
1315   param_spec = g_param_spec_string ("protocol",
1316       "protocol", "The protocol of the account",
1317       NULL,
1318       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
1319   g_object_class_install_property (oclass, PROP_PROTOCOL, param_spec);
1320
1321   param_spec = g_param_spec_object ("settings",
1322       "settings", "The settings of the account",
1323       EMPATHY_TYPE_ACCOUNT_SETTINGS,
1324       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1325   g_object_class_install_property (oclass, PROP_SETTINGS, param_spec);
1326
1327   param_spec = g_param_spec_boolean ("simple",
1328       "simple", "Whether the account widget is a simple or an advanced one",
1329       FALSE,
1330       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1331   g_object_class_install_property (oclass, PROP_SIMPLE, param_spec);
1332
1333   param_spec = g_param_spec_boolean ("creating-account",
1334       "creating-account",
1335       "TRUE if we're creating an account, FALSE if we're modifying it",
1336       FALSE,
1337       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1338   g_object_class_install_property (oclass, PROP_CREATING_ACCOUNT, param_spec);
1339
1340   signals[HANDLE_APPLY] =
1341     g_signal_new ("handle-apply", G_TYPE_FROM_CLASS (klass),
1342         G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1343         g_cclosure_marshal_VOID__BOOLEAN,
1344         G_TYPE_NONE,
1345         1, G_TYPE_BOOLEAN);
1346
1347   /* This signal is emitted when an account has been created and enabled. */
1348   signals[ACCOUNT_CREATED] =
1349       g_signal_new ("account-created", G_TYPE_FROM_CLASS (klass),
1350           G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1351           g_cclosure_marshal_VOID__VOID,
1352           G_TYPE_NONE,
1353           0);
1354
1355   signals[CANCELLED] =
1356       g_signal_new ("cancelled", G_TYPE_FROM_CLASS (klass),
1357           G_SIGNAL_RUN_LAST, 0, NULL, NULL,
1358           g_cclosure_marshal_VOID__VOID,
1359           G_TYPE_NONE,
1360           0);
1361
1362   g_type_class_add_private (klass, sizeof (EmpathyAccountWidgetPriv));
1363 }
1364
1365 static void
1366 empathy_account_widget_init (EmpathyAccountWidget *self)
1367 {
1368   EmpathyAccountWidgetPriv *priv =
1369     G_TYPE_INSTANCE_GET_PRIVATE ((self), EMPATHY_TYPE_ACCOUNT_WIDGET,
1370         EmpathyAccountWidgetPriv);
1371
1372   self->priv = priv;
1373   priv->dispose_run = FALSE;
1374
1375   self->ui_details = g_slice_new0 (EmpathyAccountWidgetUIDetails);
1376 }
1377
1378 /* public methods */
1379
1380 void
1381 empathy_account_widget_discard_pending_changes
1382     (EmpathyAccountWidget *widget)
1383 {
1384   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1385
1386   empathy_account_settings_discard_changes (priv->settings);
1387   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->enabled_checkbox),
1388       priv->original_enabled_checkbox_value);
1389   priv->contains_pending_changes = FALSE;
1390 }
1391
1392 gboolean
1393 empathy_account_widget_contains_pending_changes (EmpathyAccountWidget *widget)
1394 {
1395   EmpathyAccountWidgetPriv *priv = GET_PRIV (widget);
1396
1397   return priv->contains_pending_changes;
1398 }
1399
1400 void
1401 empathy_account_widget_handle_params (EmpathyAccountWidget *self,
1402     const gchar *first_widget,
1403     ...)
1404 {
1405   va_list args;
1406
1407   va_start (args, first_widget);
1408   account_widget_handle_params_valist (self, first_widget, args);
1409   va_end (args);
1410 }
1411
1412 GtkWidget *
1413 empathy_account_widget_get_widget (EmpathyAccountWidget *widget)
1414 {
1415   return widget->ui_details->widget;
1416 }
1417
1418 EmpathyAccountWidget *
1419 empathy_account_widget_new_for_protocol (EmpathyAccountSettings *settings,
1420     gboolean simple)
1421 {
1422   EmpathyAccountWidget *self;
1423
1424   g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), NULL);
1425
1426   self = g_object_new
1427     (EMPATHY_TYPE_ACCOUNT_WIDGET,
1428         "settings", settings, "simple", simple,
1429         "creating-account",
1430         empathy_account_settings_get_account (settings) == NULL,
1431         NULL);
1432
1433   return self;
1434 }