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