]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-account-widget.c
76145c4833d3b8045d541e1889207f334290a65e
[empathy.git] / libempathy-gtk / empathy-account-widget.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2006-2007 Imendio AB
4  * Copyright (C) 2007-2008 Collabora Ltd.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA  02110-1301  USA
20  *
21  * Authors: Xavier Claessens <xclaesse@gmail.com>
22  *          Martyn Russell <martyn@imendio.com>
23  */
24
25 #include <config.h>
26
27 #include <string.h>
28
29 #include <gtk/gtk.h>
30 #include <glib/gi18n-lib.h>
31
32 #include <libempathy/empathy-utils.h>
33 #include <libempathy/empathy-account.h>
34
35 #include <telepathy-glib/connection-manager.h>
36 #include <telepathy-glib/util.h>
37 #include <dbus/dbus-protocol.h>
38
39 #include "empathy-account-widget.h"
40 #include "empathy-account-widget-private.h"
41 #include "empathy-account-widget-sip.h"
42 #include "empathy-account-widget-irc.h"
43 #include "empathy-ui-utils.h"
44
45 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
46 #include <libempathy/empathy-debug.h>
47
48 G_DEFINE_TYPE (EmpathyAccountWidget, empathy_account_widget, G_TYPE_OBJECT)
49
50 typedef struct {
51         GtkWidget *widget;
52
53         char *protocol;
54         EmpathyAccountSettings *settings;
55         
56         GtkWidget *apply_button;
57         GtkWidget *entry_password;
58         GtkWidget *button_forget;
59         GtkWidget *spinbutton_port;
60
61         GtkBuilder *gui;
62         char *default_focus;
63         gboolean add_forget;
64 } EmpathyAccountWidgetPriv;
65
66 enum {
67         PROP_PROTOCOL = 1,
68         PROP_SETTINGS
69 };
70
71 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountWidget)
72
73 static void
74 account_widget_handle_apply_sensitivity (EmpathyAccountWidget *self)
75 {
76         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
77
78         gtk_widget_set_sensitive (priv->apply_button,
79                                   empathy_account_settings_is_valid (priv->settings));
80 }
81
82 static gboolean
83 account_widget_entry_focus_cb (GtkWidget     *widget,
84                                GdkEventFocus *event,
85                                EmpathyAccountWidget *self)
86 {
87         const gchar *str;
88         const gchar *param_name;
89         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
90
91         str = gtk_entry_get_text (GTK_ENTRY (widget));
92         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
93
94         if (EMP_STR_EMPTY (str)) {
95                 const gchar *value = NULL;
96
97                 empathy_account_settings_unset (priv->settings, param_name);
98                 value = empathy_account_settings_get_string (priv->settings, param_name);
99                 DEBUG ("Unset %s and restore to %s", param_name, value);
100                 gtk_entry_set_text (GTK_ENTRY (widget), value ? value : "");
101         } else {
102                 DEBUG ("Setting %s to %s", param_name,
103                         strstr (param_name, "password") ? "***" : str);
104                 empathy_account_settings_set_string (priv->settings, param_name, str);
105         }
106
107         account_widget_handle_apply_sensitivity (self);
108
109         return FALSE;
110 }
111
112 static void
113 account_widget_int_changed_cb (GtkWidget *widget,
114                                EmpathyAccountWidget *self)
115 {
116         const gchar *param_name;
117         gint value;
118         const gchar *signature;
119                 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
120
121         value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
122         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
123
124         signature = empathy_settings_get_dbus_signature (priv->settings, param_name);
125         g_return_if_fail (signature != NULL);
126
127         DEBUG ("Setting %s to %d", param_name, value);
128
129         switch ((int)*signature)
130                 {
131                         case DBUS_TYPE_INT16:
132                         case DBUS_TYPE_INT32:
133                                 empathy_account_settings_set_int32 (priv->settings, param_name, value);
134                                 break;
135                         case DBUS_TYPE_INT64:
136                                 empathy_account_settings_set_int64 (priv->settings, param_name, value);
137                                 break;
138                         case DBUS_TYPE_UINT16:
139                         case DBUS_TYPE_UINT32:
140                                 empathy_account_settings_set_uint32 (priv->settings, param_name, value);
141                                 break;
142                         case DBUS_TYPE_UINT64:
143                                 empathy_account_settings_set_uint64 (priv->settings, param_name, value);
144                                 break;
145                         default:
146                                 g_return_if_reached ();
147         }
148         
149                 account_widget_handle_apply_sensitivity (self);
150 }
151
152 static void
153 account_widget_checkbutton_toggled_cb (GtkWidget *widget,
154                                        EmpathyAccountWidget *self)
155 {
156         gboolean     value;
157         gboolean     default_value;
158         const gchar *param_name;
159                 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
160
161         value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
162         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
163
164         /* FIXME: This is ugly! checkbox don't have a "not-set" value so we
165          * always unset the param and set the value if different from the
166          * default value. */
167         empathy_account_settings_unset (priv->settings, param_name);
168         default_value = empathy_account_settings_get_boolean (priv->settings, param_name);
169
170         if (default_value == value) {
171                 DEBUG ("Unset %s and restore to %d", param_name, default_value);
172         } else {
173                 DEBUG ("Setting %s to %d", param_name, value);
174                 empathy_account_settings_set_boolean (priv->settings, param_name, value);
175         }
176         
177                 account_widget_handle_apply_sensitivity (self);
178 }
179
180 static void
181 account_widget_forget_clicked_cb (GtkWidget *button,
182                                   EmpathyAccountWidget *self)
183 {
184         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
185         const gchar *param_name;
186
187         param_name = g_object_get_data (G_OBJECT (priv->entry_password), "param_name");
188
189         DEBUG ("Unset %s", param_name);
190         empathy_account_settings_unset (priv->settings, param_name);
191         gtk_entry_set_text (GTK_ENTRY (priv->entry_password), "");
192
193         account_widget_handle_apply_sensitivity (self);
194 }
195
196 static void
197 account_widget_password_changed_cb (GtkWidget *entry,
198                                     GtkWidget *button)
199 {
200         const gchar *str;
201
202         str = gtk_entry_get_text (GTK_ENTRY (entry));
203         gtk_widget_set_sensitive (button, !EMP_STR_EMPTY (str));
204 }
205
206 static void
207 account_widget_jabber_ssl_toggled_cb (GtkWidget *checkbutton_ssl,
208                                       EmpathyAccountWidget *self)
209 {
210         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
211         gboolean   value;
212         gint32       port = 0;
213
214         value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl));
215         port = empathy_account_settings_get_uint32 (priv->settings, "port");
216
217         if (value) {
218                 if (port == 5222 || port == 0) {
219                         port = 5223;
220                 }
221         } else {
222                 if (port == 5223 || port == 0) {
223                         port = 5222;
224                 }
225         }
226
227         gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->spinbutton_port), port);
228 }
229
230 static void
231 account_widget_setup_widget (EmpathyAccountWidget *self,
232                              GtkWidget *widget,
233                              const gchar *param_name)
234 {
235                 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
236         
237         g_object_set_data_full (G_OBJECT (widget), "param_name",
238                                 g_strdup (param_name), g_free);
239
240         if (GTK_IS_SPIN_BUTTON (widget)) {
241                 gint value = 0;
242                 const gchar *signature;
243
244                 signature = empathy_settings_get_dbus_signature (priv->settings, param_name);
245                 g_return_if_fail (signature != NULL);
246
247                 switch ((int)*signature)
248                         {
249                                 case DBUS_TYPE_INT16:
250                                 case DBUS_TYPE_INT32:
251                                         value = empathy_account_settings_get_int32 (priv->settings, param_name);
252                                         break;
253                                 case DBUS_TYPE_INT64:
254                                         value = empathy_account_settings_get_int64 (priv->settings, param_name);
255                                         break;
256                                 case DBUS_TYPE_UINT16:
257                                 case DBUS_TYPE_UINT32:
258                                         value = empathy_account_settings_get_uint32 (priv->settings, param_name);
259                                         break;
260                                 case DBUS_TYPE_UINT64:
261                                         value = empathy_account_settings_get_uint64 (priv->settings, param_name);
262                                         break;
263                                 default:
264                                         g_return_if_reached ();
265                         }
266
267                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
268
269                 g_signal_connect (widget, "value-changed",
270                                   G_CALLBACK (account_widget_int_changed_cb),
271                                   self);
272         }
273         else if (GTK_IS_ENTRY (widget)) {
274                 const gchar *str = NULL;
275
276                 str = empathy_account_settings_get_string (priv->settings, param_name);
277                 gtk_entry_set_text (GTK_ENTRY (widget), str ? str : "");
278
279                 if (strstr (param_name, "password")) {
280                         gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
281                 }
282
283                 g_signal_connect (widget, "focus-out-event",
284                                   G_CALLBACK (account_widget_entry_focus_cb),
285                                   self);
286         }
287         else if (GTK_IS_TOGGLE_BUTTON (widget)) {
288                 gboolean value = FALSE;
289
290                 value = empathy_account_settings_get_boolean (priv->settings, param_name);
291                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
292
293                 g_signal_connect (widget, "toggled",
294                                   G_CALLBACK (account_widget_checkbutton_toggled_cb),
295                                   self);
296         } else {
297                 DEBUG ("Unknown type of widget for param %s", param_name);
298         }
299 }
300
301 static gchar *
302 account_widget_generic_format_param_name (const gchar *param_name)
303 {
304         gchar *str;
305         gchar *p;
306
307         str = g_strdup (param_name);
308
309         if (str && g_ascii_isalpha (str[0])) {
310                 str[0] = g_ascii_toupper (str[0]);
311         }
312
313         while ((p = strchr (str, '-')) != NULL) {
314                 if (p[1] != '\0' && g_ascii_isalpha (p[1])) {
315                         p[0] = ' ';
316                         p[1] = g_ascii_toupper (p[1]);
317                 }
318
319                 p++;
320         }
321
322         return str;
323 }
324
325 static void
326 accounts_widget_generic_setup (EmpathyAccountWidget *self,
327                                GtkWidget *table_common_settings,
328                                GtkWidget *table_advanced_settings)
329 {
330         TpConnectionManagerParam *params, *param;
331         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
332
333         params = empathy_account_settings_get_tp_params (priv->settings);
334
335         for (param = params; param != NULL && param->name != NULL; param++) {
336                 GtkWidget       *table_settings;
337                 guint            n_rows = 0;
338                 GtkWidget       *widget = NULL;
339                 gchar           *param_name_formatted;
340
341                 if (param->flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED) {
342                         table_settings = table_common_settings;
343                 } else {
344                         table_settings = table_advanced_settings;
345                 }
346                 param_name_formatted = account_widget_generic_format_param_name (param->name);
347                 g_object_get (table_settings, "n-rows", &n_rows, NULL);
348                 gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2);
349
350                 if (param->dbus_signature[0] == 's') {
351                         gchar *str;
352
353                         str = g_strdup_printf (_("%s:"), param_name_formatted);
354                         widget = gtk_label_new (str);
355                         gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
356                         g_free (str);
357
358                         gtk_table_attach (GTK_TABLE (table_settings),
359                                           widget,
360                                           0, 1,
361                                           n_rows - 1, n_rows,
362                                           GTK_FILL, 0,
363                                           0, 0);
364                         gtk_widget_show (widget);
365
366                         widget = gtk_entry_new ();
367                         if (strcmp (param->name, "account") == 0) {
368                                 g_signal_connect (widget, "realize",
369                                         G_CALLBACK (gtk_widget_grab_focus),
370                                         NULL);
371                         }
372                         gtk_table_attach (GTK_TABLE (table_settings),
373                                           widget,
374                                           1, 2,
375                                           n_rows - 1, n_rows,
376                                           GTK_FILL | GTK_EXPAND, 0,
377                                           0, 0);
378                         gtk_widget_show (widget);
379                 }
380                 /* int types: ynqiuxt. double type is 'd' */
381                 else if (param->dbus_signature[0] == 'y' ||
382                          param->dbus_signature[0] == 'n' ||
383                          param->dbus_signature[0] == 'q' ||
384                          param->dbus_signature[0] == 'i' ||
385                          param->dbus_signature[0] == 'u' ||
386                          param->dbus_signature[0] == 'x' ||
387                          param->dbus_signature[0] == 't' ||
388                          param->dbus_signature[0] == 'd') {
389                         gchar   *str = NULL;
390                         gdouble  minint = 0;
391                         gdouble  maxint = 0;
392                         gdouble  step = 1;
393
394                         switch (param->dbus_signature[0]) {
395                         case 'y': minint = G_MININT8;  maxint = G_MAXINT8;   break;
396                         case 'n': minint = G_MININT16; maxint = G_MAXINT16;  break;
397                         case 'q': minint = 0;          maxint = G_MAXUINT16; break;
398                         case 'i': minint = G_MININT32; maxint = G_MAXINT32;  break;
399                         case 'u': minint = 0;          maxint = G_MAXUINT32; break;
400                         case 'x': minint = G_MININT64; maxint = G_MAXINT64;  break;
401                         case 't': minint = 0;          maxint = G_MAXUINT64; break;
402                         case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break;
403                         }
404
405                         str = g_strdup_printf (_("%s:"), param_name_formatted);
406                         widget = gtk_label_new (str);
407                         gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
408                         g_free (str);
409
410                         gtk_table_attach (GTK_TABLE (table_settings),
411                                           widget,
412                                           0, 1,
413                                           n_rows - 1, n_rows,
414                                           GTK_FILL, 0,
415                                           0, 0);
416                         gtk_widget_show (widget);
417
418                         widget = gtk_spin_button_new_with_range (minint, maxint, step);
419                         gtk_table_attach (GTK_TABLE (table_settings),
420                                           widget,
421                                           1, 2,
422                                           n_rows - 1, n_rows,
423                                           GTK_FILL | GTK_EXPAND, 0,
424                                           0, 0);
425                         gtk_widget_show (widget);
426                 }
427                 else if (param->dbus_signature[0] == 'b') {
428                         widget = gtk_check_button_new_with_label (param_name_formatted);
429                         gtk_table_attach (GTK_TABLE (table_settings),
430                                           widget,
431                                           0, 2,
432                                           n_rows - 1, n_rows,
433                                           GTK_FILL | GTK_EXPAND, 0,
434                                           0, 0);
435                         gtk_widget_show (widget);
436                 } else {
437                         DEBUG ("Unknown signature for param %s: %s",
438                                 param_name_formatted, param->dbus_signature);
439                 }
440
441                 if (widget) {
442                         account_widget_setup_widget (self, widget, param->name);
443                 }
444
445                 g_free (param_name_formatted);
446         }
447 }
448
449 static void
450 account_widget_handle_params_valist (EmpathyAccountWidget *self,
451                                      const gchar *first_widget,
452                                      va_list      args)
453 {
454         GObject *object;
455         const gchar *name;
456         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
457
458         for (name = first_widget; name; name = va_arg (args, const gchar *)) {
459                 const gchar *param_name;
460
461                 param_name = va_arg (args, const gchar *);
462                 object = gtk_builder_get_object (priv->gui, name);
463
464                 if (!object) {
465                         g_warning ("Builder is missing object '%s'.", name);
466                         continue;
467                 }
468
469                 account_widget_setup_widget (self, GTK_WIDGET (object), param_name);
470         }
471 }
472
473 static void
474 account_widget_apply_clicked_cb (GtkWidget *button,
475                                  EmpathyAccountWidget *self)
476 {
477         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
478         
479   empathy_account_settings_apply_async (priv->settings, NULL, NULL);
480 }
481
482 static void
483 account_widget_setup_generic (EmpathyAccountWidget *self)
484 {
485         GtkWidget *table_common_settings;
486         GtkWidget *table_advanced_settings;
487         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
488
489         table_common_settings = GTK_WIDGET (gtk_builder_get_object (priv->gui,
490                 "table_common_settings"));
491         table_advanced_settings = GTK_WIDGET (gtk_builder_get_object (priv->gui,
492                 "table_advanced_settings"));
493
494         accounts_widget_generic_setup (self, table_common_settings,
495                 table_advanced_settings);
496 }
497
498 static void
499 account_widget_settings_ready_cb (EmpathyAccountSettings *settings,
500   GParamSpec *pspec,
501   gpointer user_data)
502 {
503         EmpathyAccountWidget *self = user_data;
504         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
505
506         if (empathy_account_settings_is_ready (priv->settings))
507                 account_widget_setup_generic (self);
508 }
509
510 static void
511 account_widget_build_generic (EmpathyAccountWidget *self,
512                              const char *filename)
513 {
514                 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
515         priv->gui = empathy_builder_get_file (filename,
516                                         "vbox_generic_settings", &self->ui_details->widget,
517                                         NULL);
518
519         if (empathy_account_settings_is_ready (priv->settings))
520                 account_widget_setup_generic (self);
521         else
522                 g_signal_connect (priv->settings, "notify::ready",
523                         G_CALLBACK (account_widget_settings_ready_cb), self);
524 }
525
526 static void
527 account_widget_build_salut (EmpathyAccountWidget *self,
528                              const char *filename)
529 {
530         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
531         
532         priv->gui = empathy_builder_get_file (filename,
533                                         "vbox_salut_settings", &self->ui_details->widget,
534                                         NULL);
535
536         empathy_account_widget_handle_params (self,
537                         "entry_published", "published-name",
538                         "entry_nickname", "nickname",
539                         "entry_first_name", "first-name",
540                         "entry_last_name", "last-name",
541                         "entry_email", "email",
542                         "entry_jid", "jid",
543                         NULL);
544
545         self->ui_details->default_focus = g_strdup ("entry_nickname");
546 }
547
548 static void
549 account_widget_build_msn (EmpathyAccountWidget *self,
550                              const char *filename)
551 {
552                 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
553         priv->gui = empathy_builder_get_file (filename,
554                                         "vbox_msn_settings", &self->ui_details->widget,
555                                         NULL);
556
557         empathy_account_widget_handle_params (self,
558                         "entry_id", "account",
559                         "entry_password", "password",
560                         "entry_server", "server",
561                         "spinbutton_port", "port",
562                         NULL);
563
564         self->ui_details->default_focus = g_strdup ("entry_id");
565         self->ui_details->add_forget = TRUE;
566 }
567
568 static void
569 account_widget_build_jabber (EmpathyAccountWidget *self,
570                              const char *filename)
571 {
572                 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
573         GtkWidget *spinbutton_port;
574         GtkWidget *checkbutton_ssl;
575
576         priv->gui = empathy_builder_get_file (filename,
577                                         "vbox_jabber_settings", &self->ui_details->widget,
578                                         "spinbutton_port", &spinbutton_port,
579                                         "checkbutton_ssl", &checkbutton_ssl,
580                                         NULL);
581
582         empathy_account_widget_handle_params (self,
583                         "entry_id", "account",
584                         "entry_password", "password",
585                         "entry_resource", "resource",
586                         "entry_server", "server",
587                         "spinbutton_port", "port",
588                         "spinbutton_priority", "priority",
589                         "checkbutton_ssl", "old-ssl",
590                         "checkbutton_ignore_ssl_errors", "ignore-ssl-errors",
591                         "checkbutton_encryption", "require-encryption",
592                         NULL);
593
594         self->ui_details->default_focus = g_strdup ("entry_id");
595         self->ui_details->add_forget = TRUE;
596         priv->spinbutton_port = spinbutton_port;
597
598         g_signal_connect (checkbutton_ssl, "toggled",
599                           G_CALLBACK (account_widget_jabber_ssl_toggled_cb),
600                           self);
601 }
602
603 static void
604 account_widget_build_icq (EmpathyAccountWidget *self,
605                           const char *filename)
606 {
607                 EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
608         GtkWidget *spinbutton_port;
609
610         priv->gui = empathy_builder_get_file (filename,
611                                         "vbox_icq_settings", &self->ui_details->widget,
612                                         "spinbutton_port", &spinbutton_port,
613                                         NULL);
614
615         empathy_account_widget_handle_params (self,
616                         "entry_uin", "account",
617                         "entry_password", "password",
618                         "entry_server", "server",
619                         "spinbutton_port", "port",
620                         "entry_charset", "charset",
621                         NULL);
622
623         self->ui_details->default_focus = g_strdup ("entry_uin");
624         self->ui_details->add_forget = TRUE;
625 }
626
627 static void
628 account_widget_build_aim (EmpathyAccountWidget *self,
629                                 const char *filename)
630 {
631         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
632         GtkWidget *spinbutton_port;
633
634         priv->gui = empathy_builder_get_file (filename,
635                                         "vbox_aim_settings", &self->ui_details->widget,
636                                         "spinbutton_port", &spinbutton_port,
637                                         NULL);
638
639         empathy_account_widget_handle_params (self,
640                         "entry_screenname", "account",
641                         "entry_password", "password",
642                         "entry_server", "server",
643                         "spinbutton_port", "port",
644                         NULL);
645
646         self->ui_details->default_focus = g_strdup ("entry_screenname");
647         self->ui_details->add_forget = TRUE;
648 }
649
650 static void
651 account_widget_build_yahoo (EmpathyAccountWidget *self,
652                                 const char *filename)
653 {
654         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
655
656         priv->gui = empathy_builder_get_file (filename,
657                                         "vbox_yahoo_settings", &self->ui_details->widget,
658                                         NULL);
659
660         empathy_account_widget_handle_params (self,
661                         "entry_id", "account",
662                         "entry_password", "password",
663                         "entry_server", "server",
664                         "entry_locale", "room-list-locale",
665                         "entry_charset", "charset",
666                         "spinbutton_port", "port",
667                         "checkbutton_yahoojp", "yahoojp",
668                         "checkbutton_ignore_invites", "ignore-invites",
669                         NULL);
670
671         self->ui_details->default_focus = g_strdup ("entry_id");
672         self->ui_details->add_forget = TRUE;
673 }
674
675 static void
676 account_widget_build_groupwise (EmpathyAccountWidget *self,
677                                 const char *filename)
678 {
679         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
680
681         priv->gui = empathy_builder_get_file (filename,
682                                               "vbox_groupwise_settings", &self->ui_details->widget,
683                                               NULL);
684
685         empathy_account_widget_handle_params (self,
686                         "entry_id", "account",
687                         "entry_password", "password",
688                         "entry_server", "server",
689                         "spinbutton_port", "port",
690                         NULL);
691
692         self->ui_details->default_focus = g_strdup ("entry_id");
693         self->ui_details->add_forget = TRUE;
694 }
695
696 static void
697 do_set_property (GObject *object,
698                  guint prop_id,
699                  const GValue *value,
700                  GParamSpec *pspec)
701 {
702         EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
703
704         switch (prop_id) {
705                 case PROP_PROTOCOL:
706                         priv->protocol = g_value_dup_string (value);
707                         break;
708                 case PROP_SETTINGS:
709                         priv->settings = g_value_dup_object (value);
710                         break;
711                 default:
712                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
713         }
714 }
715
716 static void
717 do_get_property (GObject *object,
718                  guint prop_id,
719                  GValue *value,
720                  GParamSpec *pspec)
721 {
722         EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
723
724         switch (prop_id) {
725                 case PROP_PROTOCOL:
726                         g_value_set_string (value, priv->protocol);
727                         break;
728                 case PROP_SETTINGS:
729                         g_value_set_object (value, priv->settings);
730                         break;
731                 default:
732                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
733         }
734 }
735
736 static void
737 do_constructed (GObject *obj)
738 {      
739         EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
740         EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
741         char *uiname, *filename;
742
743         uiname = g_strconcat ("empathy-account-widget-", priv->protocol,
744                               ".ui", NULL);
745         filename = empathy_file_lookup (uiname, "libempathy-gtk");
746
747         if (!tp_strdiff (priv->protocol, "local-xmpp"))
748                 account_widget_build_salut (self, filename);
749         else if (!tp_strdiff (priv->protocol, "msn"))
750                 account_widget_build_msn (self, filename);
751         else if (!tp_strdiff (priv->protocol, "jabber"))
752                 account_widget_build_jabber (self, filename);
753         else if (!tp_strdiff (priv->protocol, "icq"))
754                 account_widget_build_icq (self, filename);
755         else if (!tp_strdiff (priv->protocol, "aim"))
756                 account_widget_build_aim (self, filename);
757         else if (!tp_strdiff (priv->protocol, "yahoo"))
758                 account_widget_build_yahoo (self, filename);
759         else if (!tp_strdiff (priv->protocol, "groupwise"))
760                 account_widget_build_groupwise (self, filename);
761         else if (!tp_strdiff (priv->protocol, "irc"))
762                 empathy_account_widget_irc_build (self, filename);
763         else if (!tp_strdiff (priv->protocol, "sip"))
764                 empathy_account_widget_sip_build (self, filename);
765         else
766                 account_widget_build_generic (self, filename);
767
768         g_free (uiname);
769         g_free (filename);
770
771         /* handle default focus */
772         if (self->ui_details->default_focus != NULL)
773           {
774                   GObject *default_focus_entry;
775
776                   default_focus_entry = gtk_builder_get_object
777                           (priv->gui, self->ui_details->default_focus);
778                   g_signal_connect (default_focus_entry, "realize",
779                                     G_CALLBACK (gtk_widget_grab_focus),
780                                     NULL);
781           }
782
783         /* handle forget button */
784         if (self->ui_details->add_forget)
785           {
786                   const gchar *password = NULL;
787
788                   priv->button_forget = GTK_WIDGET (gtk_builder_get_object (priv->gui, "button_forget"));
789                   priv->entry_password = GTK_WIDGET (gtk_builder_get_object (priv->gui, "entry_password"));
790
791                   password = empathy_account_settings_get_string (priv->settings, "password");
792                   gtk_widget_set_sensitive (priv->button_forget, !EMP_STR_EMPTY (password));
793
794                   g_signal_connect (priv->button_forget, "clicked",
795                                     G_CALLBACK (account_widget_forget_clicked_cb),
796                                     self);
797                   g_signal_connect (priv->entry_password, "changed",
798                                     G_CALLBACK (account_widget_password_changed_cb),
799                                     self);  
800           }
801
802         /* handle apply button */
803         priv->apply_button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
804         gtk_box_pack_end (GTK_BOX (self->ui_details->widget), priv->apply_button, FALSE, FALSE, 3);
805
806         g_signal_connect (priv->apply_button, "clicked",
807                           G_CALLBACK (account_widget_apply_clicked_cb),
808                           self);
809         gtk_widget_show (priv->apply_button);
810 }
811
812 static void
813 empathy_account_widget_class_init (EmpathyAccountWidgetClass *klass)
814 {
815         GObjectClass *oclass = G_OBJECT_CLASS (klass);
816         GParamSpec *param_spec;
817
818         oclass->get_property = do_get_property;
819         oclass->set_property = do_set_property;
820         oclass->constructed = do_constructed;
821
822         param_spec = g_param_spec_string ("protocol",
823       "protocol", "The protocol of the account",
824       NULL,
825       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
826   g_object_class_install_property (oclass, PROP_PROTOCOL, param_spec);
827
828         param_spec = g_param_spec_object ("settings",
829       "settings", "The settings of the account",
830       EMPATHY_TYPE_ACCOUNT_SETTINGS,
831       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
832   g_object_class_install_property (oclass, PROP_SETTINGS, param_spec);  
833
834         g_type_class_add_private (klass, sizeof (EmpathyAccountWidgetPriv));
835 }
836
837 static void
838 empathy_account_widget_init (EmpathyAccountWidget *self)
839 {
840         EmpathyAccountWidgetPriv *priv = 
841                 G_TYPE_INSTANCE_GET_PRIVATE ((self), EMPATHY_TYPE_ACCOUNT_WIDGET,
842                                              EmpathyAccountWidgetPriv);
843
844         self->priv = priv;
845         self->ui_details = g_slice_new0 (EmpathyAccountWidgetUIDetails);
846 }
847
848 void
849 empathy_account_widget_handle_params (EmpathyAccountWidget *self,
850                                       const gchar *first_widget,
851                                       ...)
852 {
853         va_list args;
854
855         va_start (args, first_widget);
856         account_widget_handle_params_valist (self, first_widget, args);
857         va_end (args);
858 }
859
860 GtkWidget *
861 empathy_account_widget_new_for_protocol (const char *protocol,
862                                          EmpathyAccountSettings *settings)
863 {
864         EmpathyAccountWidget *self;
865         EmpathyAccountWidgetPriv *priv;
866
867         g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), NULL);
868         g_return_val_if_fail (settings != NULL, NULL);
869
870         self = g_object_new
871                 (EMPATHY_TYPE_ACCOUNT_WIDGET, "protocol", protocol,
872                  "settings", settings, NULL);
873         priv = GET_PRIV (self);
874
875         return self->ui_details->widget;
876 }