]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-account-widget.c
3cb5e00ea7958f1e4aa46364f2506463e883aeff
[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 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., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, 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.h>
31
32 #include <libmissioncontrol/mc-account.h>
33 #include <libmissioncontrol/mc-protocol.h>
34
35 #include <libempathy/empathy-debug.h>
36
37 #include "empathy-account-widget.h"
38 #include "empathy-ui-utils.h"
39
40 #define DEBUG_DOMAIN "AccountWidget"
41
42 static gboolean 
43 account_widget_entry_focus_cb (GtkWidget     *widget,
44                                GdkEventFocus *event,
45                                McAccount     *account)
46 {
47         const gchar *str;
48         const gchar *param_name;
49
50         str = gtk_entry_get_text (GTK_ENTRY (widget));
51         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
52
53         if (G_STR_EMPTY (str)) {
54                 gchar *value = NULL;
55
56                 mc_account_unset_param (account, param_name);
57                 mc_account_get_param_string (account, param_name, &value);
58                 empathy_debug (DEBUG_DOMAIN, "Unset %s and restore to %s", param_name, value);
59                 gtk_entry_set_text (GTK_ENTRY (widget), value ? value : "");
60                 g_free (value);
61         } else {
62                 empathy_debug (DEBUG_DOMAIN, "Setting %s to %s", param_name, str);
63                 mc_account_set_param_string (account, param_name, str);
64         }
65
66         return FALSE;
67 }
68
69 static void
70 account_widget_int_changed_cb (GtkWidget *widget,
71                                McAccount *account)
72 {
73         const gchar *param_name;
74         gint         value;
75
76         value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
77         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
78
79         if (value == 0) {
80                 gint val;
81
82                 mc_account_unset_param (account, param_name);
83                 mc_account_get_param_int (account, param_name, &val);
84                 empathy_debug (DEBUG_DOMAIN, "Unset %s and restore to %d", param_name, val);
85                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), val);
86         } else {
87                 empathy_debug (DEBUG_DOMAIN, "Setting %s to %d", param_name, value);
88                 mc_account_set_param_int (account, param_name, (gint) value);
89         }
90 }
91
92 static void  
93 account_widget_checkbutton_toggled_cb (GtkWidget *widget,
94                                        McAccount *account)
95 {
96         gboolean     value;
97         gboolean     default_value;
98         const gchar *param_name;
99
100         value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
101         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
102
103         /* FIXME: This is ugly! checkbox don't have a "not-set" value so we
104          * always unset the param and set the value if different from the
105          * default value. */
106         mc_account_unset_param (account, param_name);
107         mc_account_get_param_boolean (account, param_name, &default_value);
108
109         if (default_value == value) {
110                 empathy_debug (DEBUG_DOMAIN, "Unset %s and restore to %d", param_name, default_value);
111         } else {
112                 empathy_debug (DEBUG_DOMAIN, "Setting %s to %d", param_name, value);
113                 mc_account_set_param_boolean (account, param_name, value);
114         }
115 }
116
117 static void
118 account_widget_forget_clicked_cb (GtkWidget *button,
119                                   GtkWidget *entry)
120 {
121         McAccount   *account;
122         const gchar *param_name;
123
124         param_name = g_object_get_data (G_OBJECT (entry), "param_name");
125         account = g_object_get_data (G_OBJECT (entry), "account");
126
127         empathy_debug (DEBUG_DOMAIN, "Unset %s", param_name);
128         mc_account_unset_param (account, param_name);
129         gtk_entry_set_text (GTK_ENTRY (entry), "");
130 }
131
132 static void
133 account_widget_password_changed_cb (GtkWidget *entry,
134                                     GtkWidget *button)
135 {
136         const gchar *str;
137
138         str = gtk_entry_get_text (GTK_ENTRY (entry));
139         gtk_widget_set_sensitive (button, !G_STR_EMPTY (str));
140 }
141
142 static void  
143 account_widget_jabber_ssl_toggled_cb (GtkWidget *checkbutton_ssl,
144                                       GtkWidget *spinbutton_port)
145 {
146         McAccount *account;
147         gboolean   value;
148         gint       port = 0;
149
150         value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl));
151         account = g_object_get_data (G_OBJECT (spinbutton_port), "account");
152         mc_account_get_param_int (account, "port", &port);
153
154         if (value) {
155                 if (port == 5222 || port == 0) {
156                         port = 5223;
157                 }
158         } else {
159                 if (port == 5223 || port == 0) {
160                         port = 5222;
161                 }
162         }
163
164         gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton_port), port);
165 }
166
167 static void
168 account_widget_setup_widget (GtkWidget   *widget,
169                              McAccount   *account,
170                              const gchar *param_name)
171 {
172         g_object_set_data_full (G_OBJECT (widget), "param_name", 
173                                 g_strdup (param_name), g_free);
174         g_object_set_data_full (G_OBJECT (widget), "account", 
175                                 g_object_ref (account), g_object_unref);
176
177         if (GTK_IS_SPIN_BUTTON (widget)) {
178                 gint value = 0;
179
180                 mc_account_get_param_int (account, param_name, &value);
181                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
182
183                 g_signal_connect (widget, "value-changed",
184                                   G_CALLBACK (account_widget_int_changed_cb),
185                                   account);
186         }
187         else if (GTK_IS_ENTRY (widget)) {
188                 gchar *str = NULL;
189
190                 mc_account_get_param_string (account, param_name, &str);
191                 gtk_entry_set_text (GTK_ENTRY (widget), str ? str : "");
192                 g_free (str);
193
194                 if (strstr (param_name, "password")) {
195                         gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
196                 }
197
198                 g_signal_connect (widget, "focus-out-event",
199                                   G_CALLBACK (account_widget_entry_focus_cb),
200                                   account);
201         }
202         else if (GTK_IS_TOGGLE_BUTTON (widget)) {
203                 gboolean value = FALSE;
204
205                 mc_account_get_param_boolean (account, param_name, &value);
206                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
207
208                 g_signal_connect (widget, "toggled",
209                                   G_CALLBACK (account_widget_checkbutton_toggled_cb),
210                                   account);
211         } else {
212                 empathy_debug (DEBUG_DOMAIN,
213                                "Unknown type of widget for param %s",
214                                param_name);
215         }
216 }
217
218 static gchar *
219 account_widget_generic_format_param_name (const gchar *param_name)
220 {
221         gchar *str;
222         gchar *p;
223
224         str = g_strdup (param_name);
225         
226         if (str && g_ascii_isalpha (str[0])) {
227                 str[0] = g_ascii_toupper (str[0]);
228         }
229         
230         while ((p = strchr (str, '-')) != NULL) {
231                 if (p[1] != '\0' && g_ascii_isalpha (p[1])) {
232                         p[0] = ' ';
233                         p[1] = g_ascii_toupper (p[1]);
234                 }
235
236                 p++;
237         }
238         
239         return str;
240 }
241
242 static void
243 accounts_widget_generic_setup (McAccount *account,
244                                GtkWidget *table_settings)
245 {
246         McProtocol *protocol;
247         McProfile  *profile;
248         GSList     *params, *l;
249         guint       n_rows = 0;
250
251         profile = mc_account_get_profile (account);
252         protocol = mc_profile_get_protocol (profile);
253
254         if (!protocol) {
255                 /* The CM is not installed, MC shouldn't list them
256                  * see SF bug #1688779
257                  * FIXME: We should display something asking the user to 
258                  * install the CM
259                  */
260                 g_object_unref (profile);
261                 return;
262         }
263
264         params = mc_protocol_get_params (protocol);
265
266         for (l = params; l; l = l->next) {
267                 McProtocolParam *param;
268                 GtkWidget       *widget = NULL;
269                 gchar           *param_name_formatted;
270
271                 param = l->data;
272                 param_name_formatted = account_widget_generic_format_param_name (param->name);
273                 gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2);
274
275                 if (param->signature[0] == 's') {
276                         gchar *str;
277
278                         str = g_strdup_printf (_("%s:"), param_name_formatted);
279                         widget = gtk_label_new (str);
280                         gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
281                         g_free (str);
282
283                         gtk_table_attach (GTK_TABLE (table_settings),
284                                           widget,
285                                           0, 1,
286                                           n_rows - 1, n_rows,
287                                           GTK_FILL, 0,
288                                           0, 0);
289
290                         widget = gtk_entry_new ();
291                         gtk_table_attach (GTK_TABLE (table_settings),
292                                           widget,
293                                           1, 2,
294                                           n_rows - 1, n_rows,
295                                           GTK_FILL | GTK_EXPAND, 0,
296                                           0, 0);
297                 }
298                 /* int types: ynqiuxt. double type is 'd' */
299                 else if (param->signature[0] == 'y' ||
300                          param->signature[0] == 'n' ||
301                          param->signature[0] == 'q' ||
302                          param->signature[0] == 'i' ||
303                          param->signature[0] == 'u' ||
304                          param->signature[0] == 'x' ||
305                          param->signature[0] == 't' ||
306                          param->signature[0] == 'd') {
307                         gchar   *str = NULL;
308                         gdouble  minint = 0;
309                         gdouble  maxint = 0;
310                         gdouble  step = 1;
311
312                         switch (param->signature[0]) {
313                         case 'y': minint = G_MININT8;  maxint = G_MAXINT8;   break;
314                         case 'n': minint = G_MININT16; maxint = G_MAXINT16;  break;
315                         case 'q': minint = 0;          maxint = G_MAXUINT16; break;
316                         case 'i': minint = G_MININT32; maxint = G_MAXINT32;  break;
317                         case 'u': minint = 0;          maxint = G_MAXUINT32; break;
318                         case 'x': minint = G_MININT64; maxint = G_MAXINT64;  break;
319                         case 't': minint = 0;          maxint = G_MAXUINT64; break;
320                         case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break;
321                         }
322
323                         str = g_strdup_printf (_("%s:"), param_name_formatted);
324                         widget = gtk_label_new (str);
325                         gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
326                         g_free (str);
327
328                         gtk_table_attach (GTK_TABLE (table_settings),
329                                           widget,
330                                           0, 1,
331                                           n_rows - 1, n_rows,
332                                           GTK_FILL, 0,
333                                           0, 0);
334
335                         widget = gtk_spin_button_new_with_range (minint, maxint, step);
336                         gtk_table_attach (GTK_TABLE (table_settings),
337                                           widget,
338                                           1, 2,
339                                           n_rows - 1, n_rows,
340                                           GTK_FILL | GTK_EXPAND, 0,
341                                           0, 0);
342                 }
343                 else if (param->signature[0] == 'b') {
344                         widget = gtk_check_button_new_with_label (param_name_formatted);
345                         gtk_table_attach (GTK_TABLE (table_settings),
346                                           widget,
347                                           0, 2,
348                                           n_rows - 1, n_rows,
349                                           GTK_FILL | GTK_EXPAND, 0,
350                                           0, 0);
351                 } else {
352                         empathy_debug (DEBUG_DOMAIN,
353                                        "Unknown signature for param %s: %s",
354                                        param_name_formatted, param->signature);
355                 }
356
357                 if (widget) {
358                         account_widget_setup_widget (widget, account, param->name);
359                 }
360
361                 g_free (param_name_formatted);
362         }
363
364         g_slist_free (params);
365         g_object_unref (profile);
366         g_object_unref (protocol);
367 }
368
369 static void
370 account_widget_handle_params_valist (McAccount   *account,
371                                      GladeXML    *gui,
372                                      const gchar *first_widget_name,
373                                      va_list      args)
374 {
375         GtkWidget   *widget;
376         const gchar *widget_name;
377
378         for (widget_name = first_widget_name; widget_name; widget_name = va_arg (args, gchar*)) {
379                 const gchar *param_name;
380
381                 param_name = va_arg (args, gchar*);
382
383                 widget = glade_xml_get_widget (gui, widget_name);
384
385                 if (!widget) {
386                         g_warning ("Glade is missing widget '%s'.", widget_name);
387                         continue;
388                 }
389
390                 account_widget_setup_widget (widget, account, param_name);
391         }
392 }
393
394 void
395 empathy_account_widget_handle_params (McAccount   *account,
396                                       GladeXML    *gui,
397                                       const gchar *first_widget_name,
398                                       ...)
399 {
400         va_list args;
401
402         g_return_if_fail (MC_IS_ACCOUNT (account));
403
404         va_start (args, first_widget_name);
405         account_widget_handle_params_valist (account, gui,
406                                              first_widget_name,
407                                              args);
408         va_end (args);
409 }
410
411 void
412 emapthy_account_widget_add_forget_button (McAccount   *account,
413                                           GladeXML    *glade,
414                                           const gchar *button,
415                                           const gchar *entry)
416 {
417         GtkWidget *button_forget;
418         GtkWidget *entry_password;
419         gchar     *password = NULL;
420         
421         button_forget = glade_xml_get_widget (glade, button);
422         entry_password = glade_xml_get_widget (glade, entry);
423
424         mc_account_get_param_string (account, "password", &password);
425         gtk_widget_set_sensitive (button_forget, !G_STR_EMPTY (password));
426         g_free (password);
427
428         g_signal_connect (button_forget, "clicked",
429                           G_CALLBACK (account_widget_forget_clicked_cb),
430                           entry_password);
431         g_signal_connect (entry_password, "changed",
432                           G_CALLBACK (account_widget_password_changed_cb),
433                           button_forget);
434 }
435
436 GtkWidget *
437 empathy_account_widget_generic_new (McAccount *account)
438 {
439         GtkWidget *table_settings;
440         GtkWidget *sw;
441
442         g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
443
444         table_settings = gtk_table_new (0, 2, FALSE);
445         gtk_table_set_row_spacings (GTK_TABLE (table_settings), 6);
446         gtk_table_set_col_spacings (GTK_TABLE (table_settings), 6);
447         sw = gtk_scrolled_window_new (NULL, NULL);
448         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
449                                         GTK_POLICY_AUTOMATIC,
450                                         GTK_POLICY_AUTOMATIC);
451         gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
452                                                table_settings);
453         
454         accounts_widget_generic_setup (account, table_settings);
455
456         gtk_widget_show_all (sw);
457
458         return sw;
459 }
460
461 GtkWidget *
462 empathy_account_widget_salut_new (McAccount *account)
463 {
464         GladeXML  *glade;
465         GtkWidget *widget;
466
467         glade = empathy_glade_get_file ("empathy-account-widget-salut.glade",
468                                         "vbox_salut_settings",
469                                         NULL,
470                                         "vbox_salut_settings", &widget,
471                                         NULL);
472
473         empathy_account_widget_handle_params (account, glade,
474                         "entry_published", "published-name",
475                         "entry_nickname", "nickname",
476                         "entry_first_name", "first-name",
477                         "entry_last_name", "last-name",
478                         "entry_email", "email",
479                         "entry_jid", "jid",
480                         NULL);
481
482         g_object_unref (glade);
483
484         gtk_widget_show (widget);
485
486         return widget;
487 }
488
489 GtkWidget *
490 empathy_account_widget_msn_new (McAccount *account)
491 {
492         GladeXML  *glade;
493         GtkWidget *widget;
494
495         glade = empathy_glade_get_file ("empathy-account-widget-msn.glade",
496                                         "vbox_msn_settings",
497                                         NULL,
498                                         "vbox_msn_settings", &widget,
499                                         NULL);
500
501         empathy_account_widget_handle_params (account, glade,
502                         "entry_id", "account",
503                         "entry_password", "password",
504                         "entry_server", "server",
505                         "spinbutton_port", "port",
506                         NULL);
507
508         emapthy_account_widget_add_forget_button (account, glade,
509                                                   "button_forget",
510                                                   "entry_password");
511
512         g_object_unref (glade);
513
514         gtk_widget_show (widget);
515
516         return widget;
517 }
518
519 GtkWidget *
520 empathy_account_widget_jabber_new (McAccount *account)
521 {
522         GladeXML  *glade;
523         GtkWidget *widget;
524         GtkWidget *spinbutton_port;
525         GtkWidget *checkbutton_ssl;
526
527         glade = empathy_glade_get_file ("empathy-account-widget-jabber.glade",
528                                         "vbox_jabber_settings",
529                                         NULL,
530                                         "vbox_jabber_settings", &widget,
531                                         "spinbutton_port", &spinbutton_port,
532                                         "checkbutton_ssl", &checkbutton_ssl,
533                                         NULL);
534
535         empathy_account_widget_handle_params (account, glade,
536                         "entry_id", "account",
537                         "entry_password", "password",
538                         "entry_resource", "resource",
539                         "entry_server", "server",
540                         "spinbutton_port", "port",
541                         "spinbutton_priority", "priority",
542                         "checkbutton_ssl", "old-ssl",
543                         "checkbutton_ignore_ssl_errors", "ignore-ssl-errors",
544                         "checkbutton_encryption", "require-encryption",
545                         NULL);
546
547         emapthy_account_widget_add_forget_button (account, glade,
548                                                   "button_forget",
549                                                   "entry_password");
550
551         g_signal_connect (checkbutton_ssl, "toggled",
552                           G_CALLBACK (account_widget_jabber_ssl_toggled_cb),
553                           spinbutton_port);
554
555         g_object_unref (glade);
556
557         gtk_widget_show (widget);
558
559         return widget;
560 }
561