]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-account-widget.c
Fix indentation
[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-2009 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  *          Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
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   char *protocol;
53   EmpathyAccountSettings *settings;
54
55   GtkWidget *apply_button;
56   GtkWidget *entry_password;
57   GtkWidget *button_forget;
58   GtkWidget *spinbutton_port;
59
60   gboolean dispose_run;
61 } EmpathyAccountWidgetPriv;
62
63 enum {
64   PROP_PROTOCOL = 1,
65   PROP_SETTINGS
66 };
67
68 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountWidget)
69
70 static void
71 account_widget_handle_apply_sensitivity (EmpathyAccountWidget *self)
72 {
73   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
74
75   gtk_widget_set_sensitive (priv->apply_button,
76       empathy_account_settings_is_valid (priv->settings));
77 }
78
79 static gboolean
80 account_widget_entry_focus_cb (GtkWidget *widget,
81     GdkEventFocus *event,
82     EmpathyAccountWidget *self)
83 {
84   const gchar *str;
85   const gchar *param_name;
86   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
87
88   str = gtk_entry_get_text (GTK_ENTRY (widget));
89   param_name = g_object_get_data (G_OBJECT (widget), "param_name");
90
91   if (EMP_STR_EMPTY (str))
92     {
93       const gchar *value = NULL;
94
95       empathy_account_settings_unset (priv->settings, param_name);
96       value = empathy_account_settings_get_string (priv->settings, param_name);
97       DEBUG ("Unset %s and restore to %s", param_name, value);
98       gtk_entry_set_text (GTK_ENTRY (widget), value ? value : "");
99     }
100   else
101     {
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_account_settings_get_dbus_signature (priv->settings,
125     param_name);
126   g_return_if_fail (signature != NULL);
127
128   DEBUG ("Setting %s to %d", param_name, value);
129
130   switch ((int)*signature)
131     {
132     case DBUS_TYPE_INT16:
133     case DBUS_TYPE_INT32:
134       empathy_account_settings_set_int32 (priv->settings, param_name, value);
135       break;
136     case DBUS_TYPE_INT64:
137       empathy_account_settings_set_int64 (priv->settings, param_name, value);
138       break;
139     case DBUS_TYPE_UINT16:
140     case DBUS_TYPE_UINT32:
141       empathy_account_settings_set_uint32 (priv->settings, param_name, value);
142       break;
143     case DBUS_TYPE_UINT64:
144       empathy_account_settings_set_uint64 (priv->settings, param_name, value);
145       break;
146     default:
147       g_return_if_reached ();
148     }
149
150   account_widget_handle_apply_sensitivity (self);
151 }
152
153 static void
154 account_widget_checkbutton_toggled_cb (GtkWidget *widget,
155     EmpathyAccountWidget *self)
156 {
157   gboolean     value;
158   gboolean     default_value;
159   const gchar *param_name;
160   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
161
162   value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
163   param_name = g_object_get_data (G_OBJECT (widget), "param_name");
164
165   /* FIXME: This is ugly! checkbox don't have a "not-set" value so we
166    * always unset the param and set the value if different from the
167    * default value. */
168   empathy_account_settings_unset (priv->settings, param_name);
169   default_value = empathy_account_settings_get_boolean (priv->settings, param_name);
170
171   if (default_value == value)
172     {
173       DEBUG ("Unset %s and restore to %d", param_name, default_value);
174     }
175   else
176     {
177       DEBUG ("Setting %s to %d", param_name, value);
178       empathy_account_settings_set_boolean (priv->settings, param_name, value);
179     }
180
181   account_widget_handle_apply_sensitivity (self);
182 }
183
184 static void
185 account_widget_forget_clicked_cb (GtkWidget *button,
186     EmpathyAccountWidget *self)
187 {
188   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
189   const gchar *param_name;
190
191   param_name = g_object_get_data (G_OBJECT (priv->entry_password), "param_name");
192
193   DEBUG ("Unset %s", param_name);
194   empathy_account_settings_unset (priv->settings, param_name);
195   gtk_entry_set_text (GTK_ENTRY (priv->entry_password), "");
196
197   account_widget_handle_apply_sensitivity (self);
198 }
199
200 static void
201 account_widget_password_changed_cb (GtkWidget *entry,
202     EmpathyAccountWidget *self)
203 {
204   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
205   const gchar *str;
206
207   str = gtk_entry_get_text (GTK_ENTRY (entry));
208   gtk_widget_set_sensitive (priv->button_forget, !EMP_STR_EMPTY (str));
209 }
210
211 static void
212 account_widget_jabber_ssl_toggled_cb (GtkWidget *checkbutton_ssl,
213     EmpathyAccountWidget *self)
214 {
215   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
216   gboolean   value;
217   gint32       port = 0;
218
219   value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl));
220   port = empathy_account_settings_get_uint32 (priv->settings, "port");
221
222   if (value)
223     {
224       if (port == 5222 || port == 0)
225         port = 5223;
226     }
227   else
228     {
229       if (port == 5223 || port == 0)
230         port = 5222;
231     }
232
233   gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->spinbutton_port), port);
234 }
235
236 static void
237 account_widget_setup_widget (EmpathyAccountWidget *self,
238     GtkWidget *widget,
239     const gchar *param_name)
240 {
241   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
242
243   g_object_set_data_full (G_OBJECT (widget), "param_name",
244       g_strdup (param_name), g_free);
245
246   if (GTK_IS_SPIN_BUTTON (widget))
247     {
248       gint value = 0;
249       const gchar *signature;
250
251       signature = empathy_account_settings_get_dbus_signature (priv->settings,
252           param_name);
253       g_return_if_fail (signature != NULL);
254
255       switch ((int)*signature)
256         {
257           case DBUS_TYPE_INT16:
258           case DBUS_TYPE_INT32:
259             value = empathy_account_settings_get_int32 (priv->settings,
260               param_name);
261             break;
262           case DBUS_TYPE_INT64:
263             value = empathy_account_settings_get_int64 (priv->settings,
264               param_name);
265             break;
266           case DBUS_TYPE_UINT16:
267           case DBUS_TYPE_UINT32:
268             value = empathy_account_settings_get_uint32 (priv->settings,
269               param_name);
270             break;
271           case DBUS_TYPE_UINT64:
272             value = empathy_account_settings_get_uint64 (priv->settings,
273                 param_name);
274             break;
275           default:
276             g_return_if_reached ();
277         }
278
279       gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
280
281       g_signal_connect (widget, "value-changed",
282           G_CALLBACK (account_widget_int_changed_cb),
283           self);
284     }
285   else if (GTK_IS_ENTRY (widget))
286     {
287       const gchar *str = NULL;
288
289       str = empathy_account_settings_get_string (priv->settings, param_name);
290       gtk_entry_set_text (GTK_ENTRY (widget), str ? str : "");
291
292       if (strstr (param_name, "password"))
293         {
294           gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
295         }
296
297       g_signal_connect (widget, "focus-out-event",
298           G_CALLBACK (account_widget_entry_focus_cb),
299           self);
300     }
301   else if (GTK_IS_TOGGLE_BUTTON (widget))
302     {
303       gboolean value = FALSE;
304
305       value = empathy_account_settings_get_boolean (priv->settings, param_name);
306       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
307
308       g_signal_connect (widget, "toggled",
309           G_CALLBACK (account_widget_checkbutton_toggled_cb),
310           self);
311     }
312   else
313     {
314       DEBUG ("Unknown type of widget for param %s", param_name);
315     }
316 }
317
318 static gchar *
319 account_widget_generic_format_param_name (const gchar *param_name)
320 {
321   gchar *str;
322   gchar *p;
323
324   str = g_strdup (param_name);
325
326   if (str && g_ascii_isalpha (str[0]))
327     str[0] = g_ascii_toupper (str[0]);
328
329   while ((p = strchr (str, '-')) != NULL)
330     {
331       if (p[1] != '\0' && g_ascii_isalpha (p[1]))
332         {
333           p[0] = ' ';
334           p[1] = g_ascii_toupper (p[1]);
335         }
336
337       p++;
338     }
339
340   return str;
341 }
342
343 static void
344 accounts_widget_generic_setup (EmpathyAccountWidget *self,
345     GtkWidget *table_common_settings,
346     GtkWidget *table_advanced_settings)
347 {
348   TpConnectionManagerParam *params, *param;
349   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
350
351   params = empathy_account_settings_get_tp_params (priv->settings);
352
353   for (param = params; param != NULL && param->name != NULL; param++)
354     {
355       GtkWidget       *table_settings;
356       guint            n_rows = 0;
357       GtkWidget       *widget = NULL;
358       gchar           *param_name_formatted;
359
360       if (param->flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED)
361         table_settings = table_common_settings;
362       else
363         table_settings = table_advanced_settings;
364
365       param_name_formatted = account_widget_generic_format_param_name (param->name);
366       g_object_get (table_settings, "n-rows", &n_rows, NULL);
367       gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2);
368
369       if (param->dbus_signature[0] == 's')
370         {
371           gchar *str;
372
373           str = g_strdup_printf (_("%s:"), param_name_formatted);
374           widget = gtk_label_new (str);
375           gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
376           g_free (str);
377
378           gtk_table_attach (GTK_TABLE (table_settings),
379               widget,
380               0, 1,
381               n_rows - 1, n_rows,
382               GTK_FILL, 0,
383               0, 0);
384           gtk_widget_show (widget);
385
386           widget = gtk_entry_new ();
387           if (strcmp (param->name, "account") == 0)
388             {
389               g_signal_connect (widget, "realize",
390                   G_CALLBACK (gtk_widget_grab_focus),
391                   NULL);
392             }
393           gtk_table_attach (GTK_TABLE (table_settings),
394               widget,
395               1, 2,
396               n_rows - 1, n_rows,
397               GTK_FILL | GTK_EXPAND, 0,
398               0, 0);
399           gtk_widget_show (widget);
400         }
401       /* int types: ynqiuxt. double type is 'd' */
402       else if (param->dbus_signature[0] == 'y' ||
403           param->dbus_signature[0] == 'n' ||
404           param->dbus_signature[0] == 'q' ||
405           param->dbus_signature[0] == 'i' ||
406           param->dbus_signature[0] == 'u' ||
407           param->dbus_signature[0] == 'x' ||
408           param->dbus_signature[0] == 't' ||
409           param->dbus_signature[0] == 'd')
410         {
411           gchar   *str = NULL;
412           gdouble  minint = 0;
413           gdouble  maxint = 0;
414           gdouble  step = 1;
415
416           switch (param->dbus_signature[0])
417             {
418             case 'y': minint = G_MININT8;  maxint = G_MAXINT8;   break;
419             case 'n': minint = G_MININT16; maxint = G_MAXINT16;  break;
420             case 'q': minint = 0;          maxint = G_MAXUINT16; break;
421             case 'i': minint = G_MININT32; maxint = G_MAXINT32;  break;
422             case 'u': minint = 0;          maxint = G_MAXUINT32; break;
423             case 'x': minint = G_MININT64; maxint = G_MAXINT64;  break;
424             case 't': minint = 0;          maxint = G_MAXUINT64; break;
425             case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break;
426             }
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_spin_button_new_with_range (minint, maxint, step);
442           gtk_table_attach (GTK_TABLE (table_settings),
443               widget,
444               1, 2,
445               n_rows - 1, n_rows,
446               GTK_FILL | GTK_EXPAND, 0,
447               0, 0);
448           gtk_widget_show (widget);
449         }
450       else if (param->dbus_signature[0] == 'b')
451         {
452           widget = gtk_check_button_new_with_label (param_name_formatted);
453           gtk_table_attach (GTK_TABLE (table_settings),
454               widget,
455               0, 2,
456               n_rows - 1, n_rows,
457               GTK_FILL | GTK_EXPAND, 0,
458               0, 0);
459           gtk_widget_show (widget);
460         }
461       else
462         {
463           DEBUG ("Unknown signature for param %s: %s",
464               param_name_formatted, param->dbus_signature);
465         }
466
467       if (widget)
468         account_widget_setup_widget (self, widget, param->name);
469
470       g_free (param_name_formatted);
471     }
472 }
473
474 static void
475 account_widget_handle_params_valist (EmpathyAccountWidget *self,
476     const gchar *first_widget,
477     va_list args)
478 {
479   GObject *object;
480   const gchar *name;
481
482   for (name = first_widget; name; name = va_arg (args, const gchar *))
483     {
484       const gchar *param_name;
485
486       param_name = va_arg (args, const gchar *);
487       object = gtk_builder_get_object (self->ui_details->gui, name);
488
489       if (!object)
490         {
491           g_warning ("Builder is missing object '%s'.", name);
492           continue;
493         }
494
495       account_widget_setup_widget (self, GTK_WIDGET (object), param_name);
496     }
497 }
498
499 static void
500 account_widget_apply_clicked_cb (GtkWidget *button,
501     EmpathyAccountWidget *self)
502 {
503   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
504
505   empathy_account_settings_apply_async (priv->settings, NULL, NULL);
506 }
507
508 static void
509 account_widget_setup_generic (EmpathyAccountWidget *self)
510 {
511   GtkWidget *table_common_settings;
512   GtkWidget *table_advanced_settings;
513
514   table_common_settings = GTK_WIDGET (gtk_builder_get_object (self->ui_details->gui,
515           "table_common_settings"));
516   table_advanced_settings = GTK_WIDGET (gtk_builder_get_object (self->ui_details->gui,
517           "table_advanced_settings"));
518
519   accounts_widget_generic_setup (self, table_common_settings,
520       table_advanced_settings);
521
522   g_object_unref (self->ui_details->gui);
523 }
524
525 static void
526 account_widget_settings_ready_cb (EmpathyAccountSettings *settings,
527     GParamSpec *pspec,
528     gpointer user_data)
529 {
530   EmpathyAccountWidget *self = user_data;
531   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
532
533   if (empathy_account_settings_is_ready (priv->settings))
534     account_widget_setup_generic (self);
535 }
536
537 static void
538 account_widget_build_generic (EmpathyAccountWidget *self,
539     const char *filename)
540 {
541   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
542   self->ui_details->gui = empathy_builder_get_file (filename,
543       "vbox_generic_settings", &self->ui_details->widget,
544       NULL);
545
546   g_object_ref (self->ui_details->gui);
547
548   if (empathy_account_settings_is_ready (priv->settings))
549     account_widget_setup_generic (self);
550   else
551     g_signal_connect (priv->settings, "notify::ready",
552         G_CALLBACK (account_widget_settings_ready_cb), self);
553 }
554
555 static void
556 account_widget_build_salut (EmpathyAccountWidget *self,
557     const char *filename)
558 {
559   self->ui_details->gui = empathy_builder_get_file (filename,
560       "vbox_salut_settings", &self->ui_details->widget,
561       NULL);
562
563   empathy_account_widget_handle_params (self,
564       "entry_published", "published-name",
565       "entry_nickname", "nickname",
566       "entry_first_name", "first-name",
567       "entry_last_name", "last-name",
568       "entry_email", "email",
569       "entry_jid", "jid",
570       NULL);
571
572   self->ui_details->default_focus = g_strdup ("entry_nickname");
573 }
574
575 static void
576 account_widget_build_msn (EmpathyAccountWidget *self,
577     const char *filename)
578 {
579   self->ui_details->gui = empathy_builder_get_file (filename,
580       "vbox_msn_settings", &self->ui_details->widget,
581       NULL);
582
583   empathy_account_widget_handle_params (self,
584       "entry_id", "account",
585       "entry_password", "password",
586       "entry_server", "server",
587       "spinbutton_port", "port",
588       NULL);
589
590   self->ui_details->default_focus = g_strdup ("entry_id");
591   self->ui_details->add_forget = TRUE;
592 }
593
594 static void
595 account_widget_build_jabber (EmpathyAccountWidget *self,
596     const char *filename)
597 {
598   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
599   GtkWidget *spinbutton_port;
600   GtkWidget *checkbutton_ssl;
601
602   self->ui_details->gui = empathy_builder_get_file (filename,
603       "vbox_jabber_settings", &self->ui_details->widget,
604       "spinbutton_port", &spinbutton_port,
605       "checkbutton_ssl", &checkbutton_ssl,
606       NULL);
607
608   empathy_account_widget_handle_params (self,
609       "entry_id", "account",
610       "entry_password", "password",
611       "entry_resource", "resource",
612       "entry_server", "server",
613       "spinbutton_port", "port",
614       "spinbutton_priority", "priority",
615       "checkbutton_ssl", "old-ssl",
616       "checkbutton_ignore_ssl_errors", "ignore-ssl-errors",
617       "checkbutton_encryption", "require-encryption",
618       NULL);
619
620   self->ui_details->default_focus = g_strdup ("entry_id");
621   self->ui_details->add_forget = TRUE;
622   priv->spinbutton_port = spinbutton_port;
623
624   g_signal_connect (checkbutton_ssl, "toggled",
625       G_CALLBACK (account_widget_jabber_ssl_toggled_cb),
626       self);
627 }
628
629 static void
630 account_widget_build_icq (EmpathyAccountWidget *self,
631     const char *filename)
632 {
633   GtkWidget *spinbutton_port;
634
635   self->ui_details->gui = empathy_builder_get_file (filename,
636       "vbox_icq_settings", &self->ui_details->widget,
637       "spinbutton_port", &spinbutton_port,
638       NULL);
639
640   empathy_account_widget_handle_params (self,
641       "entry_uin", "account",
642       "entry_password", "password",
643       "entry_server", "server",
644       "spinbutton_port", "port",
645       "entry_charset", "charset",
646       NULL);
647
648   self->ui_details->default_focus = g_strdup ("entry_uin");
649   self->ui_details->add_forget = TRUE;
650 }
651
652 static void
653 account_widget_build_aim (EmpathyAccountWidget *self,
654     const char *filename)
655 {
656   GtkWidget *spinbutton_port;
657
658   self->ui_details->gui = empathy_builder_get_file (filename,
659       "vbox_aim_settings", &self->ui_details->widget,
660       "spinbutton_port", &spinbutton_port,
661       NULL);
662
663   empathy_account_widget_handle_params (self,
664       "entry_screenname", "account",
665       "entry_password", "password",
666       "entry_server", "server",
667       "spinbutton_port", "port",
668       NULL);
669
670   self->ui_details->default_focus = g_strdup ("entry_screenname");
671   self->ui_details->add_forget = TRUE;
672 }
673
674 static void
675 account_widget_build_yahoo (EmpathyAccountWidget *self,
676     const char *filename)
677 {
678   self->ui_details->gui = empathy_builder_get_file (filename,
679       "vbox_yahoo_settings", &self->ui_details->widget,
680       NULL);
681
682   empathy_account_widget_handle_params (self,
683       "entry_id", "account",
684       "entry_password", "password",
685       "entry_server", "server",
686       "entry_locale", "room-list-locale",
687       "entry_charset", "charset",
688       "spinbutton_port", "port",
689       "checkbutton_yahoojp", "yahoojp",
690       "checkbutton_ignore_invites", "ignore-invites",
691       NULL);
692
693   self->ui_details->default_focus = g_strdup ("entry_id");
694   self->ui_details->add_forget = TRUE;
695 }
696
697 static void
698 account_widget_build_groupwise (EmpathyAccountWidget *self,
699     const char *filename)
700 {
701   self->ui_details->gui = empathy_builder_get_file (filename,
702       "vbox_groupwise_settings", &self->ui_details->widget,
703       NULL);
704
705   empathy_account_widget_handle_params (self,
706       "entry_id", "account",
707       "entry_password", "password",
708       "entry_server", "server",
709       "spinbutton_port", "port",
710       NULL);
711
712   self->ui_details->default_focus = g_strdup ("entry_id");
713   self->ui_details->add_forget = TRUE;
714 }
715
716 static void
717 account_widget_destroy_cb (GtkWidget *widget,
718     EmpathyAccountWidget *self)
719 {
720   g_object_unref (self);
721 }
722
723 static void
724 do_set_property (GObject *object,
725     guint prop_id,
726     const GValue *value,
727     GParamSpec *pspec)
728 {
729   EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
730
731   switch (prop_id)
732     {
733     case PROP_PROTOCOL:
734       priv->protocol = g_value_dup_string (value);
735       break;
736     case PROP_SETTINGS:
737       priv->settings = g_value_dup_object (value);
738       break;
739     default:
740       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
741     }
742 }
743
744 static void
745 do_get_property (GObject *object,
746     guint prop_id,
747     GValue *value,
748     GParamSpec *pspec)
749 {
750   EmpathyAccountWidgetPriv *priv = GET_PRIV (object);
751
752   switch (prop_id)
753     {
754     case PROP_PROTOCOL:
755       g_value_set_string (value, priv->protocol);
756       break;
757     case PROP_SETTINGS:
758       g_value_set_object (value, priv->settings);
759       break;
760     default:
761       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
762     }
763 }
764
765 static void
766 do_constructed (GObject *obj)
767 {
768   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
769   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
770   char *uiname, *filename;
771
772   uiname = g_strconcat ("empathy-account-widget-", priv->protocol,
773       ".ui", NULL);
774   filename = empathy_file_lookup (uiname, "libempathy-gtk");
775
776   if (!tp_strdiff (priv->protocol, "local-xmpp"))
777     account_widget_build_salut (self, filename);
778   else if (!tp_strdiff (priv->protocol, "msn"))
779     account_widget_build_msn (self, filename);
780   else if (!tp_strdiff (priv->protocol, "jabber"))
781     account_widget_build_jabber (self, filename);
782   else if (!tp_strdiff (priv->protocol, "icq"))
783     account_widget_build_icq (self, filename);
784   else if (!tp_strdiff (priv->protocol, "aim"))
785     account_widget_build_aim (self, filename);
786   else if (!tp_strdiff (priv->protocol, "yahoo"))
787     account_widget_build_yahoo (self, filename);
788   else if (!tp_strdiff (priv->protocol, "groupwise"))
789     account_widget_build_groupwise (self, filename);
790   else if (!tp_strdiff (priv->protocol, "irc"))
791     empathy_account_widget_irc_build (self, filename);
792   else if (!tp_strdiff (priv->protocol, "sip"))
793     empathy_account_widget_sip_build (self, filename);
794   else
795     account_widget_build_generic (self, filename);
796
797   g_free (uiname);
798   g_free (filename);
799
800   /* handle default focus */
801   if (self->ui_details->default_focus != NULL)
802     {
803       GObject *default_focus_entry;
804
805       default_focus_entry = gtk_builder_get_object
806         (self->ui_details->gui, self->ui_details->default_focus);
807       g_signal_connect (default_focus_entry, "realize",
808           G_CALLBACK (gtk_widget_grab_focus),
809           NULL);
810     }
811
812   /* handle forget button */
813   if (self->ui_details->add_forget)
814     {
815       const gchar *password = NULL;
816
817       priv->button_forget = GTK_WIDGET (gtk_builder_get_object (self->ui_details->gui, "button_forget"));
818       priv->entry_password = GTK_WIDGET (gtk_builder_get_object (self->ui_details->gui, "entry_password"));
819
820       password = empathy_account_settings_get_string (priv->settings, "password");
821       gtk_widget_set_sensitive (priv->button_forget, !EMP_STR_EMPTY (password));
822
823       g_signal_connect (priv->button_forget, "clicked",
824           G_CALLBACK (account_widget_forget_clicked_cb),
825           self);
826       g_signal_connect (priv->entry_password, "changed",
827           G_CALLBACK (account_widget_password_changed_cb),
828           self);
829     }
830
831   /* handle apply button */
832   priv->apply_button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
833   gtk_box_pack_end (GTK_BOX (self->ui_details->widget), priv->apply_button, FALSE, FALSE, 3);
834
835   g_signal_connect (priv->apply_button, "clicked",
836       G_CALLBACK (account_widget_apply_clicked_cb),
837       self);
838   account_widget_handle_apply_sensitivity (self);
839   gtk_widget_show (priv->apply_button);
840
841   /* hook up to widget destruction to unref ourselves */
842   g_signal_connect (self->ui_details->widget, "destroy",
843       G_CALLBACK (account_widget_destroy_cb), self);
844
845   empathy_builder_unref_and_keep_widget (self->ui_details->gui, self->ui_details->widget);
846   self->ui_details->gui = NULL;
847 }
848
849 static void
850 do_dispose (GObject *obj)
851 {
852   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
853   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
854
855   if (priv->dispose_run)
856     return;
857
858   priv->dispose_run = TRUE;
859
860   if (priv->settings != NULL)
861     {
862       g_object_unref (priv->settings);
863       priv->settings = NULL;
864     }
865
866   if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose != NULL)
867     G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose (obj);
868 }
869
870 static void
871 do_finalize (GObject *obj)
872 {
873   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
874   EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
875
876   g_free (self->ui_details->default_focus);
877   g_slice_free (EmpathyAccountWidgetUIDetails, self->ui_details);
878
879   g_free (priv->protocol);
880
881   if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize != NULL)
882     G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize (obj);
883 }
884
885 static void
886 empathy_account_widget_class_init (EmpathyAccountWidgetClass *klass)
887 {
888   GObjectClass *oclass = G_OBJECT_CLASS (klass);
889   GParamSpec *param_spec;
890
891   oclass->get_property = do_get_property;
892   oclass->set_property = do_set_property;
893   oclass->constructed = do_constructed;
894   oclass->dispose = do_dispose;
895   oclass->finalize = do_finalize;
896
897   param_spec = g_param_spec_string ("protocol",
898       "protocol", "The protocol of the account",
899       NULL,
900       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
901   g_object_class_install_property (oclass, PROP_PROTOCOL, param_spec);
902
903   param_spec = g_param_spec_object ("settings",
904       "settings", "The settings of the account",
905       EMPATHY_TYPE_ACCOUNT_SETTINGS,
906       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
907   g_object_class_install_property (oclass, PROP_SETTINGS, param_spec);
908
909   g_type_class_add_private (klass, sizeof (EmpathyAccountWidgetPriv));
910 }
911
912 static void
913 empathy_account_widget_init (EmpathyAccountWidget *self)
914 {
915   EmpathyAccountWidgetPriv *priv =
916     G_TYPE_INSTANCE_GET_PRIVATE ((self), EMPATHY_TYPE_ACCOUNT_WIDGET,
917         EmpathyAccountWidgetPriv);
918
919   self->priv = priv;
920   priv->dispose_run = FALSE;
921
922   self->ui_details = g_slice_new0 (EmpathyAccountWidgetUIDetails);
923 }
924
925 /* public methods */
926
927 void
928 empathy_account_widget_handle_params (EmpathyAccountWidget *self,
929     const gchar *first_widget,
930     ...)
931 {
932   va_list args;
933
934   va_start (args, first_widget);
935   account_widget_handle_params_valist (self, first_widget, args);
936   va_end (args);
937 }
938
939 GtkWidget *
940 empathy_account_widget_new_for_protocol (const char *protocol,
941     EmpathyAccountSettings *settings)
942 {
943   EmpathyAccountWidget *self;
944   EmpathyAccountWidgetPriv *priv;
945
946   g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), NULL);
947   g_return_val_if_fail (settings != NULL, NULL);
948
949   self = g_object_new
950     (EMPATHY_TYPE_ACCOUNT_WIDGET, "protocol", protocol,
951         "settings", settings, NULL);
952   priv = GET_PRIV (self);
953
954   return self->ui_details->widget;
955 }