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