]> git.0d.be Git - empathy.git/blob - src/empathy-import-dialog.c
Revert "Don't use deprecated g_mapped_file_free()"
[empathy.git] / src / empathy-import-dialog.c
1 /*
2  * Copyright (C) 2008 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  * */
21
22 #include <config.h>
23
24 #include <string.h>
25
26 #include <glib.h>
27 #include <gtk/gtk.h>
28 #include <glib/gi18n.h>
29
30 #include <telepathy-glib/util.h>
31
32 #include "empathy-import-dialog.h"
33 #include "empathy-import-pidgin.h"
34
35 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
36 #include <libempathy/empathy-debug.h>
37 #include <libempathy/empathy-utils.h>
38 #include <libempathy/empathy-account-manager.h>
39
40 #include <libempathy-gtk/empathy-ui-utils.h>
41
42 typedef struct
43 {
44   GtkWidget *window;
45   GtkWidget *treeview;
46   GtkWidget *button_ok;
47   GtkWidget *button_cancel;
48   GList *accounts;
49 } EmpathyImportDialog;
50
51 enum
52 {
53   COL_IMPORT = 0,
54   COL_PROTOCOL,
55   COL_NAME,
56   COL_SOURCE,
57   COL_ACCOUNT_DATA,
58   COL_COUNT
59 };
60
61 EmpathyImportAccountData *
62 empathy_import_account_data_new (const gchar *source)
63 {
64   EmpathyImportAccountData *data;
65
66   g_return_val_if_fail (!EMP_STR_EMPTY (source), NULL);
67
68   data = g_slice_new0 (EmpathyImportAccountData);
69   data->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
70     (GDestroyNotify) tp_g_value_slice_free);
71   data->source = g_strdup (source);
72
73   return data;
74 }
75
76 void
77 empathy_import_account_data_free (EmpathyImportAccountData *data)
78 {
79   if (data == NULL)
80     return;
81   if (data->profile != NULL)
82     g_object_unref (data->profile);
83   if (data->settings != NULL)
84     g_hash_table_destroy (data->settings);
85   if (data->source != NULL)
86     g_free (data->source);
87
88   g_slice_free (EmpathyImportAccountData, data);
89 }
90
91 static void
92 import_dialog_add_account (EmpathyImportAccountData *data)
93 {
94   EmpathyAccountManager *account_manager;
95   EmpathyAccount *account;
96   GHashTableIter iter;
97   gpointer key, value;
98   gchar *display_name;
99   GValue *username;
100
101   account_manager = empathy_account_manager_dup_singleton ();
102   account = empathy_account_manager_create (account_manager, data->profile);
103   g_object_unref (account_manager);
104   if (account == NULL)
105     {
106       DEBUG ("Failed to create account");
107       return;
108     }
109
110   g_hash_table_iter_init (&iter, data->settings);
111   while (g_hash_table_iter_next (&iter, &key, &value))
112     {
113       const gchar *param = key;
114       GValue *gvalue = value;
115
116       switch (G_VALUE_TYPE (gvalue))
117         {
118           case G_TYPE_STRING:
119             DEBUG ("Set param '%s' to '%s' (string)",
120                 param, g_value_get_string (gvalue));
121             empathy_account_set_param_string (account,
122                 param, g_value_get_string (gvalue));
123             break;
124
125           case G_TYPE_BOOLEAN:
126             DEBUG ("Set param '%s' to %s (boolean)",
127                 param, g_value_get_boolean (gvalue) ? "TRUE" : "FALSE");
128             empathy_account_set_param_boolean (account,
129                 param, g_value_get_boolean (gvalue));
130             break;
131
132           case G_TYPE_INT:
133             DEBUG ("Set param '%s' to '%i' (integer)",
134                 param, g_value_get_int (gvalue));
135             empathy_account_set_param_int (account,
136                 param, g_value_get_int (gvalue));
137             break;
138         }
139     }
140
141   /* Set the display name of the account */
142   username = g_hash_table_lookup (data->settings, "account");
143   display_name = g_strdup_printf ("%s (%s)",
144       mc_profile_get_display_name (data->profile),
145       g_value_get_string (username));
146   empathy_account_set_display_name (account, display_name);
147
148   g_free (display_name);
149   g_object_unref (account);
150 }
151
152 static gboolean
153 import_dialog_account_id_in_list (GList *accounts,
154                                   const gchar *account_id)
155 {
156   GList *l;
157
158   for (l = accounts; l; l = l->next)
159     {
160       McAccount *account = l->data;
161       gchar *value = NULL;
162       gboolean result;
163
164       mc_account_get_param_string (account, "account", &value);
165
166       if (value == NULL)
167         continue;
168
169       result = tp_strdiff (value, account_id);
170
171       g_free (value);
172
173       if (!result)
174         return TRUE;
175     }
176
177   return FALSE;
178 }
179
180 static void
181 import_dialog_add_accounts_to_model (EmpathyImportDialog *dialog)
182 {
183   GtkTreeModel *model;
184   GtkTreeIter iter;
185   GList *l;
186
187   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview));
188
189   for (l = dialog->accounts; l; l = l->next)
190     {
191       GValue *value;
192       EmpathyImportAccountData *data = l->data;
193       gboolean import;
194       GList *accounts;
195
196       value = g_hash_table_lookup (data->settings, "account");
197
198       accounts = mc_accounts_list_by_profile (data->profile);
199
200       /* Only set the "Import" cell to be active if there isn't already an
201        * account set up with the same account id. */
202       import = !import_dialog_account_id_in_list (accounts,
203           g_value_get_string (value));
204
205       mc_accounts_list_free (accounts);
206
207       gtk_list_store_append (GTK_LIST_STORE (model), &iter);
208
209       gtk_list_store_set (GTK_LIST_STORE (model), &iter,
210           COL_IMPORT, import,
211           COL_PROTOCOL, mc_profile_get_display_name (data->profile),
212           COL_NAME, g_value_get_string (value),
213           COL_SOURCE, data->source,
214           COL_ACCOUNT_DATA, data,
215           -1);
216     }
217 }
218
219 static void
220 import_dialog_cell_toggled_cb (GtkCellRendererToggle *cell_renderer,
221                                const gchar *path_str,
222                                EmpathyImportDialog *dialog)
223 {
224   GtkTreeModel *model;
225   GtkTreeIter iter;
226   GtkTreePath *path;
227
228   path = gtk_tree_path_new_from_string (path_str);
229   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview));
230
231   gtk_tree_model_get_iter (model, &iter, path);
232
233   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
234       COL_IMPORT, !gtk_cell_renderer_toggle_get_active (cell_renderer),
235       -1);
236
237   gtk_tree_path_free (path);
238 }
239
240 static void
241 import_dialog_set_up_account_list (EmpathyImportDialog *dialog)
242 {
243   GtkListStore *store;
244   GtkTreeView *view;
245   GtkTreeViewColumn *column;
246   GtkCellRenderer *cell;
247
248   store = gtk_list_store_new (COL_COUNT, G_TYPE_BOOLEAN, G_TYPE_STRING,
249       G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
250
251   gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview),
252       GTK_TREE_MODEL (store));
253
254   g_object_unref (store);
255
256   view = GTK_TREE_VIEW (dialog->treeview);
257   gtk_tree_view_set_headers_visible (view, TRUE);
258
259   /* Import column */
260   cell = gtk_cell_renderer_toggle_new ();
261   gtk_tree_view_insert_column_with_attributes (view, -1,
262       /* Translators: this is the header of a treeview column */
263       _("Import"), cell,
264       "active", COL_IMPORT,
265       NULL);
266
267   g_signal_connect (cell, "toggled",
268       G_CALLBACK (import_dialog_cell_toggled_cb), dialog);
269
270   /* Protocol column */
271   column = gtk_tree_view_column_new ();
272   gtk_tree_view_column_set_title (column, _("Protocol"));
273   gtk_tree_view_column_set_expand (column, TRUE);
274   gtk_tree_view_append_column (view, column);
275
276   cell = gtk_cell_renderer_text_new ();
277   g_object_set (cell,
278       "editable", FALSE,
279       NULL);
280   gtk_tree_view_column_pack_start (column, cell, TRUE);
281   gtk_tree_view_column_add_attribute (column, cell, "text", COL_PROTOCOL);
282
283   /* Account column */
284   column = gtk_tree_view_column_new ();
285   gtk_tree_view_column_set_title (column, _("Account"));
286   gtk_tree_view_column_set_expand (column, TRUE);
287   gtk_tree_view_append_column (view, column);
288
289   cell = gtk_cell_renderer_text_new ();
290   g_object_set (cell,
291       "editable", FALSE,
292       NULL);
293   gtk_tree_view_column_pack_start (column, cell, TRUE);
294   gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME);
295
296   /* Source column */
297   column = gtk_tree_view_column_new ();
298   gtk_tree_view_column_set_title (column, _("Source"));
299   gtk_tree_view_column_set_expand (column, TRUE);
300   gtk_tree_view_append_column (view, column);
301
302   cell = gtk_cell_renderer_text_new ();
303   g_object_set (cell,
304       "editable", FALSE,
305       NULL);
306   gtk_tree_view_column_pack_start (column, cell, TRUE);
307   gtk_tree_view_column_add_attribute (column, cell, "text", COL_SOURCE);
308
309   import_dialog_add_accounts_to_model (dialog);
310 }
311
312 static gboolean
313 import_dialog_tree_model_foreach (GtkTreeModel *model,
314                                   GtkTreePath *path,
315                                   GtkTreeIter *iter,
316                                   gpointer user_data)
317 {
318   gboolean to_import;
319   EmpathyImportAccountData *data;
320
321   gtk_tree_model_get (model, iter,
322       COL_IMPORT, &to_import,
323       COL_ACCOUNT_DATA, &data,
324       -1);
325
326   if (to_import)
327     import_dialog_add_account (data);
328
329   return FALSE;
330 }
331
332 static void
333 import_dialog_response_cb (GtkWidget *widget,
334                            gint response,
335                            EmpathyImportDialog *dialog)
336 {
337   if (response == GTK_RESPONSE_OK)
338     {
339       GtkTreeModel *model;
340
341       model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview));
342       gtk_tree_model_foreach (model, import_dialog_tree_model_foreach, dialog);
343     }
344
345   gtk_widget_destroy (dialog->window);
346 }
347
348 static void
349 import_dialog_destroy_cb (GtkWidget *widget,
350                           EmpathyImportDialog *dialog)
351 {
352   g_list_foreach (dialog->accounts, (GFunc) empathy_import_account_data_free,
353     NULL);
354   g_list_free (dialog->accounts);
355   g_slice_free (EmpathyImportDialog, dialog);
356 }
357
358 gboolean
359 empathy_import_dialog_accounts_to_import (void)
360 {
361   return empathy_import_pidgin_accounts_to_import ();
362 }
363
364 void
365 empathy_import_dialog_show (GtkWindow *parent,
366                             gboolean warning)
367 {
368   static EmpathyImportDialog *dialog = NULL;
369   GtkBuilder *gui;
370   gchar *filename;
371   GList *accounts = NULL;
372
373   /* This window is a singleton. If it already exist, present it */
374   if (dialog)
375     {
376       gtk_window_present (GTK_WINDOW (dialog->window));
377       return;
378     }
379
380   /* Load all accounts from all supported applications */
381   accounts = g_list_concat (accounts, empathy_import_pidgin_load ());
382
383   /* Check if we have accounts to import before creating the window */
384   if (!accounts)
385     {
386       GtkWidget *message;
387
388       if (warning)
389         {
390           message = gtk_message_dialog_new (parent,
391               GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
392               _("No accounts to import could be found. Empathy currently only "
393                 "supports importing accounts from Pidgin."));
394
395           gtk_dialog_run (GTK_DIALOG (message));
396           gtk_widget_destroy (message);
397         }
398       else
399         DEBUG ("No accounts to import; closing dialog silently.");
400
401       return;
402     }
403
404   /* We have accounts, let's display the window with them */
405   dialog = g_slice_new0 (EmpathyImportDialog);
406   dialog->accounts = accounts;
407
408   filename = empathy_file_lookup ("empathy-import-dialog.ui", "src");
409   gui = empathy_builder_get_file (filename,
410       "import_dialog", &dialog->window,
411       "treeview", &dialog->treeview,
412       NULL);
413
414   empathy_builder_connect (gui, dialog,
415       "import_dialog", "destroy", import_dialog_destroy_cb,
416       "import_dialog", "response", import_dialog_response_cb,
417       NULL);
418
419   g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog);
420
421   g_free (filename);
422   g_object_unref (gui);
423
424   if (parent)
425     gtk_window_set_transient_for (GTK_WINDOW (dialog->window), parent);
426
427   import_dialog_set_up_account_list (dialog);
428
429   gtk_widget_show (dialog->window);
430 }
431