]> git.0d.be Git - empathy.git/blob - src/empathy-import-widget.c
Reorder header inclusions accordingly to the Telepathy coding style
[empathy.git] / src / empathy-import-widget.c
1 /*
2  * Copyright (C) 2008-2009 Collabora Ltd.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA  02110-1301  USA
18  *
19  * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
20  *          Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
21  */
22
23 /* empathy-import-widget.c */
24
25 #include "config.h"
26 #include "empathy-import-widget.h"
27
28 #include <glib/gi18n-lib.h>
29
30 #include "empathy-import-dialog.h"
31 #include "empathy-ui-utils.h"
32 #include "empathy-utils.h"
33
34 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
35 #include "empathy-debug.h"
36
37 G_DEFINE_TYPE (EmpathyImportWidget, empathy_import_widget, G_TYPE_OBJECT)
38
39 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyImportWidget)
40
41 enum
42 {
43   COL_IMPORT = 0,
44   COL_PROTOCOL,
45   COL_NAME,
46   COL_SOURCE,
47   COL_ACCOUNT_DATA,
48   COL_COUNT
49 };
50
51 enum {
52   PROP_APPLICATION_ID = 1,
53   PROP_CMS
54 };
55
56 typedef struct {
57   GtkWidget *vbox;
58   GtkWidget *treeview;
59   GtkWidget *scrolledwindow;
60
61   GList *accounts;
62   EmpathyImportApplication app_id;
63
64   EmpathyConnectionManagers *cms;
65
66   gboolean dispose_run;
67 } EmpathyImportWidgetPriv;
68
69 static gboolean
70 import_widget_account_id_in_list (GList *accounts,
71     const gchar *account_id)
72 {
73   GList *l;
74
75   for (l = accounts; l; l = l->next)
76     {
77       TpAccount *account = l->data;
78       const GHashTable *parameters;
79
80       parameters = tp_account_get_parameters (account);
81
82       if (!tp_strdiff (tp_asv_get_string (parameters, "account"), account_id))
83         return TRUE;
84     }
85
86   return FALSE;
87 }
88
89 #define MAX_TREEVIEW_HEIGHT 300
90
91 static void
92 import_widget_add_accounts_to_model (EmpathyImportWidget *self)
93 {
94   TpAccountManager *manager;
95   GtkTreeModel *model;
96   GList *l;
97   EmpathyImportWidgetPriv *priv = GET_PRIV (self);
98   gint min, natural;
99
100   manager = tp_account_manager_dup ();
101
102   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
103
104   for (l = priv->accounts; l; l = l->next)
105     {
106       GValue *value;
107       EmpathyImportAccountData *data = l->data;
108       gboolean import;
109       GList *accounts;
110       TpConnectionManager *cm = NULL;
111
112       if (!empathy_import_protocol_is_supported (data->protocol, &cm))
113         continue;
114
115       data->connection_manager = g_strdup (
116           tp_connection_manager_get_name (cm));
117
118       value = g_hash_table_lookup (data->settings, "account");
119
120       accounts = tp_account_manager_dup_valid_accounts (manager);
121
122       /* Only set the "Import" cell to be active if there isn't already an
123        * account set up with the same account id. */
124       import = !import_widget_account_id_in_list (accounts,
125           g_value_get_string (value));
126
127       g_list_free_full (accounts, g_object_unref);
128
129       gtk_list_store_insert_with_values (GTK_LIST_STORE (model), NULL, -1,
130           COL_IMPORT, import,
131           COL_PROTOCOL, data->protocol,
132           COL_NAME, g_value_get_string (value),
133           COL_SOURCE, data->source,
134           COL_ACCOUNT_DATA, data,
135           -1);
136
137     }
138
139   /* Display as much rows as possible */
140   gtk_widget_get_preferred_height (priv->treeview, &min, &natural);
141   gtk_widget_set_size_request (priv->scrolledwindow, -1,
142       MIN (natural, MAX_TREEVIEW_HEIGHT));
143
144   g_object_unref (manager);
145 }
146
147 static void
148 import_widget_create_account_cb (GObject *source,
149   GAsyncResult *result,
150   gpointer user_data)
151 {
152   TpAccountManager *account_manager;
153   TpAccount *account;
154   GError *error = NULL;
155   EmpathyImportWidget *self = user_data;
156
157   account = tp_account_manager_create_account_finish (
158     TP_ACCOUNT_MANAGER (source), result, &error);
159
160   if (account == NULL)
161     {
162       DEBUG ("Failed to create account: %s",
163           error ? error->message : "No error given");
164       g_clear_error (&error);
165       return;
166     }
167
168   DEBUG ("account created\n");
169
170   if (tp_account_is_enabled (account))
171     {
172       account_manager = tp_account_manager_dup ();
173       empathy_connect_new_account (account, account_manager);
174       g_object_unref (account_manager);
175     }
176
177   g_object_unref (self);
178 }
179
180 static void
181 import_widget_add_account (EmpathyImportWidget *self,
182     EmpathyImportAccountData *data)
183 {
184   TpAccountManager *account_manager;
185   gchar *display_name = NULL;
186   GHashTable *properties;
187   GValue *username;
188
189   account_manager = tp_account_manager_dup ();
190
191   DEBUG ("connection_manager: %s\n", data->connection_manager);
192
193   /* Set the display name of the account */
194   username = g_hash_table_lookup (data->settings, "account");
195
196   if (!tp_strdiff (data->protocol, "irc"))
197     {
198       const gchar *server;
199
200       server = tp_asv_get_string (data->settings, "server");
201
202       if (server != NULL)
203         display_name = g_strdup_printf ("%s on %s",
204             g_value_get_string (username), server);
205     }
206
207   if (display_name == NULL)
208     {
209       display_name = g_strdup_printf ("%s (%s)",
210           data->protocol, g_value_get_string (username));
211     }
212
213   DEBUG ("display name: %s\n", display_name);
214
215   properties = tp_asv_new (NULL, NULL);
216   tp_asv_set_boolean (properties, TP_IFACE_ACCOUNT ".Enabled", data->enabled);
217
218   tp_account_manager_create_account_async (account_manager,
219       (const gchar*) data->connection_manager, data->protocol, display_name,
220       data->settings, properties, import_widget_create_account_cb,
221       g_object_ref (self));
222
223   g_hash_table_unref (properties);
224   g_free (display_name);
225   g_object_unref (account_manager);
226 }
227
228 static gboolean
229 import_widget_tree_model_foreach (GtkTreeModel *model,
230     GtkTreePath *path,
231     GtkTreeIter *iter,
232     gpointer user_data)
233 {
234   gboolean to_import;
235   EmpathyImportAccountData *data;
236   EmpathyImportWidget *self = user_data;
237
238   gtk_tree_model_get (model, iter,
239       COL_IMPORT, &to_import,
240       COL_ACCOUNT_DATA, &data,
241       -1);
242
243   if (to_import)
244     import_widget_add_account (self, data);
245
246   return FALSE;
247 }
248
249 static void
250 import_widget_cell_toggled_cb (GtkCellRendererToggle *cell_renderer,
251     const gchar *path_str,
252     EmpathyImportWidget *self)
253 {
254   GtkTreeModel *model;
255   GtkTreeIter iter;
256   GtkTreePath *path;
257   EmpathyImportWidgetPriv *priv = GET_PRIV (self);
258
259   path = gtk_tree_path_new_from_string (path_str);
260   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
261
262   gtk_tree_model_get_iter (model, &iter, path);
263
264   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
265       COL_IMPORT, !gtk_cell_renderer_toggle_get_active (cell_renderer),
266       -1);
267
268   gtk_tree_path_free (path);
269 }
270
271 static void
272 import_widget_set_up_account_list (EmpathyImportWidget *self)
273 {
274   EmpathyImportWidgetPriv *priv = GET_PRIV (self);
275   GtkListStore *store;
276   GtkTreeView *view;
277   GtkTreeViewColumn *column;
278   GtkCellRenderer *cell;
279
280   priv->accounts = empathy_import_accounts_load (priv->app_id);
281
282   store = gtk_list_store_new (COL_COUNT, G_TYPE_BOOLEAN, G_TYPE_STRING,
283       G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
284
285   gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
286       GTK_TREE_MODEL (store));
287
288   g_object_unref (store);
289
290   view = GTK_TREE_VIEW (priv->treeview);
291   gtk_tree_view_set_headers_visible (view, TRUE);
292
293   /* Import column */
294   cell = gtk_cell_renderer_toggle_new ();
295   gtk_tree_view_insert_column_with_attributes (view, -1,
296       /* Translators: this is the header of a treeview column */
297       _("Import"), cell,
298       "active", COL_IMPORT,
299       NULL);
300
301   g_signal_connect (cell, "toggled",
302       G_CALLBACK (import_widget_cell_toggled_cb), self);
303
304   /* Protocol column */
305   column = gtk_tree_view_column_new ();
306   gtk_tree_view_column_set_title (column, _("Protocol"));
307   gtk_tree_view_column_set_expand (column, TRUE);
308   gtk_tree_view_append_column (view, column);
309
310   cell = gtk_cell_renderer_text_new ();
311   g_object_set (cell, "editable", FALSE, NULL);
312   gtk_tree_view_column_pack_start (column, cell, TRUE);
313   gtk_tree_view_column_add_attribute (column, cell, "text", COL_PROTOCOL);
314
315   /* Account column */
316   column = gtk_tree_view_column_new ();
317   gtk_tree_view_column_set_title (column, _("Account"));
318   gtk_tree_view_column_set_expand (column, TRUE);
319   gtk_tree_view_append_column (view, column);
320
321   cell = gtk_cell_renderer_text_new ();
322   g_object_set (cell, "editable", FALSE, NULL);
323   gtk_tree_view_column_pack_start (column, cell, TRUE);
324   gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME);
325
326   if (priv->app_id == EMPATHY_IMPORT_APPLICATION_ALL)
327     {
328       /* Source column */
329       column = gtk_tree_view_column_new ();
330       gtk_tree_view_column_set_title (column, _("Source"));
331       gtk_tree_view_column_set_expand (column, TRUE);
332       gtk_tree_view_append_column (view, column);
333
334       cell = gtk_cell_renderer_text_new ();
335       g_object_set (cell, "editable", FALSE, NULL);
336       gtk_tree_view_column_pack_start (column, cell, TRUE);
337       gtk_tree_view_column_add_attribute (column, cell, "text", COL_SOURCE);
338     }
339
340   import_widget_add_accounts_to_model (self);
341 }
342
343 static void
344 import_widget_destroy_cb (GtkWidget *w,
345     EmpathyImportWidget *self)
346 {
347   g_object_unref (self);
348 }
349
350 static void
351 do_get_property (GObject *object,
352     guint property_id,
353     GValue *value,
354     GParamSpec *pspec)
355 {
356   EmpathyImportWidgetPriv *priv = GET_PRIV (object);
357
358   switch (property_id)
359     {
360     case PROP_APPLICATION_ID:
361       g_value_set_int (value, priv->app_id);
362       break;
363     case PROP_CMS:
364       g_value_set_object (value, priv->cms);
365       break;
366     default:
367       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
368     }
369 }
370
371 static void
372 do_set_property (GObject *object,
373     guint property_id,
374     const GValue *value,
375     GParamSpec *pspec)
376 {
377   EmpathyImportWidgetPriv *priv = GET_PRIV (object);
378
379   switch (property_id)
380     {
381     case PROP_APPLICATION_ID:
382       priv->app_id = g_value_get_int (value);
383       break;
384     case PROP_CMS:
385       priv->cms = g_value_dup_object (value);
386       break;
387     default:
388       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
389     }
390 }
391
392 static void
393 do_finalize (GObject *obj)
394 {
395   EmpathyImportWidgetPriv *priv = GET_PRIV (obj);
396
397   g_list_foreach (priv->accounts, (GFunc) empathy_import_account_data_free,
398       NULL);
399   g_list_free (priv->accounts);
400
401   if (G_OBJECT_CLASS (empathy_import_widget_parent_class)->finalize != NULL)
402     G_OBJECT_CLASS (empathy_import_widget_parent_class)->finalize (obj);
403 }
404
405 static void
406 do_dispose (GObject *obj)
407 {
408   EmpathyImportWidgetPriv *priv = GET_PRIV (obj);
409
410   if (priv->dispose_run)
411     return;
412
413   priv->dispose_run = TRUE;
414
415   if (priv->cms != NULL)
416     {
417       g_object_unref (priv->cms);
418       priv->cms = NULL;
419     }
420
421   if (G_OBJECT_CLASS (empathy_import_widget_parent_class)->dispose != NULL)
422     G_OBJECT_CLASS (empathy_import_widget_parent_class)->dispose (obj);
423 }
424
425 static void
426 do_constructed (GObject *obj)
427 {
428   EmpathyImportWidget *self = EMPATHY_IMPORT_WIDGET (obj);
429   EmpathyImportWidgetPriv *priv = GET_PRIV (self);
430   GtkBuilder *gui;
431   gchar *filename;
432
433   filename = empathy_file_lookup ("empathy-import-dialog.ui", "src");
434   gui = empathy_builder_get_file (filename,
435       "widget_vbox", &priv->vbox,
436       "treeview", &priv->treeview,
437       "scrolledwindow", &priv->scrolledwindow,
438       NULL);
439
440   g_free (filename);
441   empathy_builder_unref_and_keep_widget (gui, priv->vbox);
442
443   g_signal_connect (priv->vbox, "destroy",
444       G_CALLBACK (import_widget_destroy_cb), self);
445
446   import_widget_set_up_account_list (self);
447 }
448
449 static void
450 empathy_import_widget_class_init (EmpathyImportWidgetClass *klass)
451 {
452   GObjectClass *oclass = G_OBJECT_CLASS (klass);
453   GParamSpec *param_spec;
454
455   oclass->constructed = do_constructed;
456   oclass->finalize = do_finalize;
457   oclass->dispose = do_dispose;
458   oclass->set_property = do_set_property;
459   oclass->get_property = do_get_property;
460
461   param_spec = g_param_spec_int ("application-id",
462       "application-id", "The application id to import from",
463       0, EMPATHY_IMPORT_APPLICATION_INVALID, EMPATHY_IMPORT_APPLICATION_ALL,
464       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
465   g_object_class_install_property (oclass, PROP_APPLICATION_ID, param_spec);
466
467   param_spec = g_param_spec_object ("cms",
468       "EmpathyConnectionManagers", "EmpathyConnectionManager",
469       EMPATHY_TYPE_CONNECTION_MANAGERS,
470       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
471   g_object_class_install_property (oclass, PROP_CMS, param_spec);
472
473   g_type_class_add_private (klass, sizeof (EmpathyImportWidgetPriv));
474 }
475
476 static void
477 empathy_import_widget_init (EmpathyImportWidget *self)
478 {
479   EmpathyImportWidgetPriv *priv =
480     G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_IMPORT_WIDGET,
481         EmpathyImportWidgetPriv);
482
483   self->priv = priv;
484 }
485
486 EmpathyImportWidget *
487 empathy_import_widget_new (EmpathyImportApplication id,
488     EmpathyConnectionManagers *cms)
489 {
490   g_return_val_if_fail (EMPATHY_IS_CONNECTION_MANAGERS (cms), NULL);
491
492   return g_object_new (EMPATHY_TYPE_IMPORT_WIDGET,
493       "application-id", id,
494       "cms", cms,
495       NULL);
496 }
497
498 GtkWidget *
499 empathy_import_widget_get_widget (EmpathyImportWidget *self)
500 {
501   EmpathyImportWidgetPriv *priv = GET_PRIV (self);
502
503   return priv->vbox;
504 }
505
506 void
507 empathy_import_widget_add_selected_accounts (EmpathyImportWidget *self)
508 {
509   GtkTreeModel *model;
510   EmpathyImportWidgetPriv *priv = GET_PRIV (self);
511
512   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
513   gtk_tree_model_foreach (model, import_widget_tree_model_foreach, self);
514 }