]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-account-widget-generic.c
Initial room list support. It does not works yet.
[empathy.git] / libempathy-gtk / empathy-account-widget-generic.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-generic.h"
38 #include "empathy-ui-utils.h"
39
40 #define DEBUG_DOMAIN "AccountWidgetGeneric"
41
42 typedef struct {
43         McAccount     *account;
44
45         GtkWidget     *sw;
46         GtkWidget     *table_settings;
47         GtkSizeGroup  *size_group;
48
49         guint          n_rows;
50 } EmpathyAccountWidgetGeneric;
51
52 static gboolean account_widget_generic_entry_focus_cb         (GtkWidget                  *widget,
53                                                                GdkEventFocus              *event,
54                                                                EmpathyAccountWidgetGeneric *settings);
55 static void     account_widget_generic_int_changed_cb         (GtkWidget                  *widget,
56                                                                EmpathyAccountWidgetGeneric *settings);
57 static void     account_widget_generic_checkbutton_toggled_cb (GtkWidget                  *widget,
58                                                                EmpathyAccountWidgetGeneric *settings);
59 static gchar *  account_widget_generic_format_param_name      (const gchar                *param_name);
60 static void     account_widget_generic_setup_foreach          (McProtocolParam            *param,
61                                                                EmpathyAccountWidgetGeneric *settings);
62 static void     account_widget_generic_destroy_cb             (GtkWidget                  *widget,
63                                                                EmpathyAccountWidgetGeneric *settings);
64
65 static gboolean 
66 account_widget_generic_entry_focus_cb (GtkWidget                  *widget,
67                                        GdkEventFocus              *event,
68                                        EmpathyAccountWidgetGeneric *settings)
69 {
70         const gchar *str;
71         const gchar *param_name;
72
73         str = gtk_entry_get_text (GTK_ENTRY (widget));
74         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
75
76         mc_account_set_param_string (settings->account, param_name, str);
77
78         return FALSE;
79 }
80
81 static void
82 account_widget_generic_int_changed_cb (GtkWidget                  *widget,
83                                        EmpathyAccountWidgetGeneric *settings)
84 {
85         const gchar *param_name;
86         gint         value;
87
88         value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
89         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
90
91         mc_account_set_param_int (settings->account, param_name, value);
92 }
93
94 static void  
95 account_widget_generic_checkbutton_toggled_cb (GtkWidget                  *widget,
96                                                EmpathyAccountWidgetGeneric *settings)
97 {
98         gboolean     active;
99         const gchar *param_name;
100
101         active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
102         param_name = g_object_get_data (G_OBJECT (widget), "param_name");
103
104         mc_account_set_param_boolean (settings->account, param_name, active);
105 }
106
107 static gchar *
108 account_widget_generic_format_param_name (const gchar *param_name)
109 {
110         gchar *str;
111         gchar *p;
112
113         str = g_strdup (param_name);
114         
115         if (str && g_ascii_isalpha (str[0])) {
116                 str[0] = g_ascii_toupper (str[0]);
117         }
118         
119         while ((p = strchr (str, '-')) != NULL) {
120                 if (p[1] != '\0' && g_ascii_isalpha (p[1])) {
121                         p[0] = ' ';
122                         p[1] = g_ascii_toupper (p[1]);
123                 }
124
125                 p++;
126         }
127         
128         return str;
129 }
130
131 static void
132 account_widget_generic_setup_foreach (McProtocolParam            *param,
133                                       EmpathyAccountWidgetGeneric *settings)
134 {
135         GtkWidget *widget;
136         gchar     *param_name_formatted;
137
138         param_name_formatted = account_widget_generic_format_param_name (param->name);
139
140         gtk_table_resize (GTK_TABLE (settings->table_settings),
141                           ++settings->n_rows,
142                           2);
143
144         if (param->signature[0] == 's') {
145                 gchar *str = NULL;
146
147                 str = g_strdup_printf (_("%s:"), param_name_formatted);
148                 widget = gtk_label_new (str);
149                 g_free (str);
150
151                 gtk_size_group_add_widget (settings->size_group, widget);
152                 gtk_table_attach (GTK_TABLE (settings->table_settings),
153                                   widget,
154                                   0, 1,
155                                   settings->n_rows - 1, settings->n_rows,
156                                   GTK_FILL, 0,
157                                   0, 0);
158
159                 str = NULL;
160                 widget = gtk_entry_new ();
161                 mc_account_get_param_string (settings->account,
162                                              param->name,
163                                              &str);
164                 if (str) {
165                         gtk_entry_set_text (GTK_ENTRY (widget), str);
166                         g_free (str);
167                 }
168
169                 if (strstr (param->name, "password")) {
170                         gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
171                 }
172
173                 g_signal_connect (widget, "focus-out-event",
174                                   G_CALLBACK (account_widget_generic_entry_focus_cb),
175                                   settings);
176
177                 gtk_table_attach (GTK_TABLE (settings->table_settings),
178                                   widget,
179                                   1, 2,
180                                   settings->n_rows - 1, settings->n_rows,
181                                   GTK_FILL | GTK_EXPAND, 0,
182                                   0, 0);
183         }
184         /* int types: ynqiuxt. double type is 'd' */
185         else if (param->signature[0] == 'y' ||
186                  param->signature[0] == 'n' ||
187                  param->signature[0] == 'q' ||
188                  param->signature[0] == 'i' ||
189                  param->signature[0] == 'u' ||
190                  param->signature[0] == 'x' ||
191                  param->signature[0] == 't' ||
192                  param->signature[0] == 'd') {
193                 gchar   *str = NULL;
194                 gint     value = 0;
195                 gdouble  minint = 0;
196                 gdouble  maxint = 0;
197                 gdouble  step = 1;
198                 switch (param->signature[0]) {
199                 case 'y': minint = G_MININT8;  maxint = G_MAXINT8;   break;
200                 case 'n': minint = G_MININT16; maxint = G_MAXINT16;  break;
201                 case 'q': minint = 0;          maxint = G_MAXUINT16; break;
202                 case 'i': minint = G_MININT32; maxint = G_MAXINT32;  break;
203                 case 'u': minint = 0;          maxint = G_MAXUINT32; break;
204                 case 'x': minint = G_MININT64; maxint = G_MAXINT64;  break;
205                 case 't': minint = 0;          maxint = G_MAXUINT64; break;
206                 case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break;
207                 }
208
209                 str = g_strdup_printf (_("%s:"), param_name_formatted);
210                 widget = gtk_label_new (str);
211                 g_free (str);
212
213                 gtk_size_group_add_widget (settings->size_group, widget);
214                 gtk_table_attach (GTK_TABLE (settings->table_settings),
215                                   widget,
216                                   0, 1,
217                                   settings->n_rows - 1, settings->n_rows,
218                                   GTK_FILL, 0,
219                                   0, 0);
220
221                 widget = gtk_spin_button_new_with_range (minint, maxint, step);
222                 mc_account_get_param_int (settings->account,
223                                           param->name,
224                                           &value);
225                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
226
227                 g_signal_connect (widget, "value-changed",
228                                   G_CALLBACK (account_widget_generic_int_changed_cb),
229                                   settings);
230
231                 gtk_table_attach (GTK_TABLE (settings->table_settings),
232                                   widget,
233                                   1, 2,
234                                   settings->n_rows - 1, settings->n_rows,
235                                   GTK_FILL | GTK_EXPAND, 0,
236                                   0, 0);
237         }
238         else if (param->signature[0] == 'b') {
239                 gboolean value = FALSE;
240
241                 mc_account_get_param_boolean (settings->account,
242                                               param->name,
243                                               &value);
244
245                 widget = gtk_check_button_new_with_label (param_name_formatted);
246                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);
247
248                 g_signal_connect (widget, "toggled",
249                                   G_CALLBACK (account_widget_generic_checkbutton_toggled_cb),
250                                   settings);
251
252                 gtk_table_attach (GTK_TABLE (settings->table_settings),
253                                   widget,
254                                   0, 2,
255                                   settings->n_rows - 1, settings->n_rows,
256                                   GTK_FILL | GTK_EXPAND, 0,
257                                   0, 0);
258         } else {
259                 empathy_debug (DEBUG_DOMAIN,
260                                "Unknown signature for param %s: %s\n",
261                                param_name_formatted, param->signature);
262                 g_assert_not_reached ();
263         }
264
265         g_free (param_name_formatted);
266
267         g_object_set_data_full (G_OBJECT (widget), "param_name", 
268                                 g_strdup (param->name), g_free);
269 }
270
271 static void
272 accounts_widget_generic_setup (EmpathyAccountWidgetGeneric *settings)
273 {
274         McProtocol *protocol;
275         McProfile  *profile;
276         GSList     *params;
277
278         profile = mc_account_get_profile (settings->account);
279         protocol = mc_profile_get_protocol (profile);
280
281         if (!protocol) {
282                 /* The CM is not installed, MC shouldn't list them
283                  * see SF bug #1688779
284                  * FIXME: We should display something asking the user to 
285                  * install the CM
286                  */
287                 g_object_unref (profile);
288                 return;
289         }
290
291         params = mc_protocol_get_params (protocol);
292
293         g_slist_foreach (params,
294                          (GFunc) account_widget_generic_setup_foreach,
295                          settings);
296
297         g_slist_free (params);
298         g_object_unref (profile);
299         g_object_unref (protocol);
300 }
301
302 static void
303 account_widget_generic_destroy_cb (GtkWidget                  *widget,
304                                    EmpathyAccountWidgetGeneric *settings)
305 {
306         g_object_unref (settings->account);
307         g_object_unref (settings->size_group);
308
309         g_free (settings);
310 }
311
312 GtkWidget *
313 empathy_account_widget_generic_new (McAccount *account,
314                                    GtkWidget *label_name)
315 {
316         EmpathyAccountWidgetGeneric *settings;
317
318         g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
319         g_return_val_if_fail (GTK_IS_WIDGET (label_name), NULL);
320
321         settings = g_new0 (EmpathyAccountWidgetGeneric, 1);
322
323         settings->account = g_object_ref (account);
324
325         settings->table_settings = gtk_table_new (0, 2, FALSE);
326         gtk_table_set_row_spacings (GTK_TABLE (settings->table_settings), 6);
327         gtk_table_set_col_spacings (GTK_TABLE (settings->table_settings), 6);
328         settings->sw = gtk_scrolled_window_new (NULL, NULL);
329         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (settings->sw),
330                                         GTK_POLICY_AUTOMATIC,
331                                         GTK_POLICY_AUTOMATIC);
332         gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (settings->sw),
333                                                settings->table_settings);
334
335         settings->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
336         if (label_name) {
337                 gtk_size_group_add_widget (settings->size_group, label_name);
338         }
339         
340         accounts_widget_generic_setup (settings);
341
342         g_signal_connect (settings->sw, "destroy",
343                           G_CALLBACK (account_widget_generic_destroy_cb),
344                           settings);
345
346         gtk_widget_show_all (settings->sw);
347
348         return settings->sw;
349 }