]> git.0d.be Git - empathy.git/commitdiff
Added an account importer dialog. Fixes bug #541060 (Jonny Lamb)
authorJonny Lamb <jonny.lamb@collabora.co.uk>
Fri, 17 Oct 2008 12:45:44 +0000 (12:45 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Fri, 17 Oct 2008 12:45:44 +0000 (12:45 +0000)
Signed-off-by: Jonny Lamb <jonny.lamb@collabora.co.uk>
svn path=/trunk/; revision=1593

src/Makefile.am
src/empathy-import-dialog.c [new file with mode: 0644]
src/empathy-import-dialog.h [new file with mode: 0644]
src/empathy-main-window.c
src/empathy-main-window.glade

index 4d0caba6348438f8d94effb2b190e784b1687339..eee9510bf625cf3e59d53b656124d27fcbe53a53 100644 (file)
@@ -28,6 +28,7 @@ empathy_SOURCES =                                                     \
        empathy-chatrooms-window.c empathy-chatrooms-window.h           \
        empathy-chat-window.c empathy-chat-window.h                     \
        empathy-event-manager.c empathy-event-manager.h                 \
+       empathy-import-dialog.c empathy-import-dialog.h                 \
        empathy-main-window.c empathy-main-window.h                     \
        empathy-new-chatroom-dialog.c empathy-new-chatroom-dialog.h     \
        empathy-preferences.c empathy-preferences.h                     \
diff --git a/src/empathy-import-dialog.c b/src/empathy-import-dialog.c
new file mode 100644 (file)
index 0000000..31a6c01
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
+ * */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <libmissioncontrol/mc-account.h>
+
+#include "empathy-import-dialog.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
+#include <libempathy/empathy-debug.h>
+
+typedef enum {
+        EMPATHY_IMPORT_SETTING_TYPE_STRING,
+        EMPATHY_IMPORT_SETTING_TYPE_BOOL,
+        EMPATHY_IMPORT_SETTING_TYPE_INT,
+} EmpathyImportSettingType;
+
+typedef struct {
+        gpointer     value;
+        EmpathyImportSettingType  type;
+} EmpathyImportSetting;
+
+
+/* Pidgin to MC map */
+const struct {
+        gchar *protocol;
+        gchar *pidgin_name;
+        gchar *mc_name;
+} pidgin_mc_map[] = {
+        { "msn", "server", "server" },
+        { "msn", "port", "port" },
+
+        { "jabber", "connect_server", "server" },
+        { "jabber", "port", "port" },
+        { "jabber", "require_tls", "require-encryption" },
+        { "jabber", "old_ssl", "old-ssl" },
+
+        { "aim", "server", "server" },
+        { "aim", "port", "port" },
+
+        { "salut", "first", "first-name" },
+        { "salut", "last", "last-name" },
+        { "salut", "jid", "jid" },
+        { "salut", "email", "email" },
+
+        { "groupwise", "server", "server" },
+        { "groupwise", "port", "port" },
+
+        { "icq", "server", "server" },
+        { "icq", "port", "port" },
+
+        { "irc", "realname", "fullname" },
+        { "irc", "ssl", "use-ssl" },
+        { "irc", "port", "port" },
+
+        { "yahoo", "server", "server" },
+        { "yahoo", "port", "port" },
+        { "yahoo", "xfer_port", "xfer-port" },
+        { "yahoo", "ignore_invites", "ignore-invites" },
+        { "yahoo", "yahoojp", "yahoojp" },
+        { "yahoo", "xferjp_host", "xferjp-host" },
+        { "yahoo", "serverjp", "serverjp" },
+        { "yahoo", "xfer_host", "xfer-host" },
+};
+
+#define PIDGIN_MC_MAP_ITEMS 27
+
+typedef struct {
+        GtkWidget       *window;
+        GtkWidget       *label_select;
+        GtkWidget       *combo;
+} EmpathyImportDialog;
+
+static void     empathy_import_dialog_add_setting               (GHashTable               *settings,
+                                                                 gchar                    *key,
+                                                                 gpointer                  value,
+                                                                 EmpathyImportSettingType  type);
+static gboolean empathy_import_dialog_add_account               (gchar                    *protocol_name,
+                                                                 GHashTable               *settings);
+static void     empathy_import_dialog_pidgin_parse_setting      (gchar                    *protocol,
+                                                                 xmlNodePtr                setting,
+                                                                 GHashTable               *settings);
+static void     empathy_import_dialog_pidgin_import_accounts    ();
+static void     empathy_import_dialog_response_cb               (GtkDialog                *dialog_window,
+                                                                 gint                      response,
+                                                                 EmpathyImportDialog      *dialog);
+
+static EmpathyImportDialog *dialog_p = NULL;
+
+static void
+empathy_import_dialog_add_setting (GHashTable              *settings,
+                                   gchar                   *key,
+                                   gpointer                 value,
+                                   EmpathyImportSettingType type)
+{
+        EmpathyImportSetting *set = g_new0 (EmpathyImportSetting, 1);
+
+        set->value = value;
+        set->type = type;
+
+        g_hash_table_insert (settings, key, set);
+}
+
+static gboolean
+empathy_import_dialog_add_account (gchar      *protocol_name,
+                                   GHashTable *settings)
+{
+        McProfile *profile;
+        McAccount *account;
+
+        DEBUG ("Looking up profile with protocol '%s'", protocol_name);
+        profile = mc_profile_lookup (protocol_name);
+
+        if (profile != NULL) {
+                account = mc_account_create (profile);
+
+                if (account != NULL) {
+                        const gchar *unique_name;
+                        GHashTableIter iter;
+                        gpointer key, value;
+                        EmpathyImportSetting *set;
+
+                        unique_name = mc_account_get_unique_name (account);
+                        mc_account_set_display_name (account, unique_name);
+
+                        g_hash_table_iter_init (&iter, settings);
+                        while (g_hash_table_iter_next (&iter, &key, &value)) {
+                                set = (EmpathyImportSetting *) value;
+                                switch (((EmpathyImportSetting *) value)->type) {
+                                        case EMPATHY_IMPORT_SETTING_TYPE_STRING:
+                                                DEBUG ("Setting %s to (string) %s",
+                                                        (gchar *) key, (gchar *) set->value);
+                                                mc_account_set_param_string (account,
+                                                        (gchar *) key, (gchar *) set->value);
+                                                break;
+
+                                        case EMPATHY_IMPORT_SETTING_TYPE_BOOL:
+                                                DEBUG ("Setting %s to (bool) %i",
+                                                        (gchar *) key, (gboolean) set->value);
+                                                mc_account_set_param_boolean (account,
+                                                        (gchar *) key, (gboolean) set->value);
+                                                break;
+
+                                        case EMPATHY_IMPORT_SETTING_TYPE_INT:
+                                                DEBUG ("Setting %s to (int) %i",
+                                                        (gchar *) key, (gint) set->value);
+                                                mc_account_set_param_int (account,
+                                                        (gchar *) key, (gint) set->value);
+                                                break;
+                                }
+                        }
+                        g_object_unref (account);
+                }
+
+                g_object_unref (profile);
+                return TRUE;
+        }
+        return FALSE;
+}
+
+static void
+empathy_import_dialog_pidgin_parse_setting (gchar *protocol,
+                                            xmlNodePtr setting,
+                                            GHashTable *settings)
+{
+        int i;
+
+        if (!xmlHasProp (setting, (xmlChar *) "name"))
+                return;
+
+        for (i = 0; i < PIDGIN_MC_MAP_ITEMS; i++) {
+                if (strcmp(protocol, pidgin_mc_map[i].protocol) != 0) {
+                        continue;
+                }
+
+                if (strcmp ((gchar *) xmlGetProp (setting, (xmlChar *) "name"),
+                        pidgin_mc_map[i].pidgin_name) == 0) {
+
+                        int arg;
+                        gchar *type = NULL;
+
+                        type = (gchar *) xmlGetProp (setting, (xmlChar *) "type");
+
+                        if (strcmp (type, "bool") == 0) {
+                                sscanf ((gchar *) xmlNodeGetContent (setting),"%i", &arg);
+                                empathy_import_dialog_add_setting (settings, pidgin_mc_map[i].mc_name,
+                                        (gpointer) arg,
+                                        EMPATHY_IMPORT_SETTING_TYPE_BOOL);
+                        } else if (strcmp (type, "int") == 0) {
+                                sscanf ((gchar *) xmlNodeGetContent (setting),
+                                        "%i", &arg);
+                                empathy_import_dialog_add_setting (settings, pidgin_mc_map[i].mc_name,
+                                        (gpointer) arg,
+                                        EMPATHY_IMPORT_SETTING_TYPE_INT);
+                        } else if (strcmp (type, "string") == 0) {
+                                empathy_import_dialog_add_setting (settings, pidgin_mc_map[i].mc_name,
+                                        (gpointer) xmlNodeGetContent (setting),
+                                        EMPATHY_IMPORT_SETTING_TYPE_STRING);
+                        }
+                }
+        }
+
+}
+
+static void
+empathy_import_dialog_pidgin_import_accounts ()
+{
+        xmlNodePtr rootnode, node, child, setting;
+        xmlParserCtxtPtr ctxt;
+        xmlDocPtr doc;
+        gchar *filename;
+        gchar *protocol = NULL;
+        gchar *name = NULL;
+        gchar *username = NULL;
+        GHashTable *settings;
+
+        ctxt = xmlNewParserCtxt ();
+
+        filename = g_build_filename (g_get_home_dir (), ".purple", "accounts.xml", NULL);
+
+        doc = xmlCtxtReadFile (ctxt, filename, NULL, 0);
+
+        g_free (filename);
+
+        rootnode = xmlDocGetRootElement (doc);
+
+        if (rootnode == NULL) {
+                return;
+        }
+
+        node = rootnode->children;
+
+        while (node) {
+                if (strcmp ((gchar *) node->name, "account") == 0) {
+                        child = node->children;
+
+                        settings = g_hash_table_new (g_str_hash, g_str_equal);
+
+                        while (child) {
+
+                                if (strcmp ((gchar *) child->name, "protocol") == 0) {
+                                        protocol = (gchar *) xmlNodeGetContent (child);
+
+                                        if (g_str_has_prefix (protocol, "prpl-")) {
+                                                protocol = strchr (protocol, '-') + 1;
+                                        }
+
+                                        if (strcmp (protocol, "bonjour") == 0) {
+                                                protocol = "salut";
+                                        } else if (strcmp (protocol, "novell") == 0) {
+                                                protocol = "groupwise";
+                                        }
+
+                                        empathy_import_dialog_add_setting (settings, "protocol",
+                                                (gpointer) protocol,
+                                                EMPATHY_IMPORT_SETTING_TYPE_STRING);
+
+                                } else if (strcmp ((gchar *) child->name, "name") == 0) {
+                                        name = (gchar *) xmlNodeGetContent (child);
+
+                                        if (g_strrstr (name, "/") != NULL) {
+                                                gchar **name_resource;
+                                                name_resource = g_strsplit (name, "/", 2);
+                                                username = name_resource[0];
+                                        } else {
+                                                username = name;
+                                        }
+
+                                        if (strstr (name, "@") && strcmp (protocol, "irc") == 0) {
+                                                gchar **nick_server;
+                                                nick_server = g_strsplit (name, "@", 2);
+                                                username = nick_server[0];
+                                                empathy_import_dialog_add_setting (settings,
+                                                        "server", (gpointer) nick_server[1],
+                                                        EMPATHY_IMPORT_SETTING_TYPE_STRING);
+                                        }
+
+                                        empathy_import_dialog_add_setting (settings, "account",
+                                                (gpointer) username, EMPATHY_IMPORT_SETTING_TYPE_STRING);
+
+                                } else if (strcmp ((gchar *) child->name, "password") == 0) {
+                                        empathy_import_dialog_add_setting (settings, "password",
+                                                (gpointer) xmlNodeGetContent (child),
+                                                EMPATHY_IMPORT_SETTING_TYPE_STRING);
+
+                                } else if (strcmp ((gchar *) child->name, "settings") == 0) {
+
+                                        setting = child->children;
+
+                                        while (setting) {
+                                                empathy_import_dialog_pidgin_parse_setting (protocol,
+                                                        setting, settings);
+                                                setting = setting->next;
+                                        }
+
+                                }
+                                child = child->next;
+                        }
+
+                        if (g_hash_table_size (settings) > 0) {
+                                empathy_import_dialog_add_account (protocol, settings);
+                        }
+                        g_free (username);
+                        g_hash_table_unref (settings);
+
+                }
+                node = node->next;
+        }
+
+        xmlFreeDoc(doc);
+        xmlFreeParserCtxt (ctxt);
+
+}
+
+static void
+empathy_import_dialog_response_cb (GtkDialog           *dialog_window,
+                                   gint                 response,
+                                   EmpathyImportDialog *dialog)
+{
+        gchar *from = NULL;
+        if (response == GTK_RESPONSE_OK) {
+
+                from = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->combo));
+
+                if (strcmp (from, "Pidgin") == 0) {
+                        empathy_import_dialog_pidgin_import_accounts ();
+                }
+        }
+
+        gtk_widget_destroy (GTK_WIDGET (dialog_window));
+        dialog_p = NULL;
+        g_free (dialog);
+}
+
+void
+empathy_import_dialog_show (GtkWindow *parent)
+{
+        EmpathyImportDialog *dialog;
+
+        if (dialog_p) {
+                gtk_window_present (GTK_WINDOW (dialog_p->window));
+                return;
+        }
+
+        dialog_p = dialog = g_new0 (EmpathyImportDialog, 1);
+
+        dialog->window = gtk_dialog_new_with_buttons (_("Import accounts"),
+                                                      NULL,
+                                                      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                                      GTK_STOCK_OK, GTK_RESPONSE_OK,
+                                                      NULL);
+
+        g_signal_connect (G_OBJECT (dialog->window), "response",
+                          G_CALLBACK (empathy_import_dialog_response_cb),
+                          dialog);
+
+        dialog->label_select = gtk_label_new (_("Select the program to import accounts from:"));
+
+        dialog->combo = gtk_combo_box_new_text ();
+
+        gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->combo), "Pidgin");
+        gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combo), 0);
+
+        gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dialog->window)->vbox),
+                dialog->label_select);
+
+        gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dialog->window)->vbox),
+                dialog->combo);
+
+
+        if (parent) {
+                gtk_window_set_transient_for (GTK_WINDOW (dialog->window),
+                                              parent);
+        }
+
+        gtk_widget_show_all (dialog->window);
+}
diff --git a/src/empathy-import-dialog.h b/src/empathy-import-dialog.h
new file mode 100644 (file)
index 0000000..d3ac30a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
+ */
+
+#include <gtk/gtk.h>
+
+#ifndef __EMPATHY_IMPORT_DIALOG_H__
+#define __EMPATHY_IMPORT_DIALOG_H__
+
+G_BEGIN_DECLS
+
+void empathy_import_dialog_show (GtkWindow *parent);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IMPORT_DIALOG_H__ */
index c5437385ff0c4de8252da7f301436d9dac74ae72..ee4358687419f5f4cfa3c8e7bc86dca23fc41c6e 100644 (file)
@@ -56,6 +56,7 @@
 #include "empathy-new-chatroom-dialog.h"
 #include "empathy-chatrooms-window.h"
 #include "empathy-event-manager.h"
+#include "empathy-import-dialog.h"
 
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
 #include <libempathy/empathy-debug.h>
@@ -133,6 +134,8 @@ static void     main_window_room_manage_favorites_cb           (GtkWidget
                                                                EmpathyMainWindow        *window);
 static void     main_window_chat_add_contact_cb                (GtkWidget                *widget,
                                                                EmpathyMainWindow        *window);
+static void     main_window_chat_import_cb                     (GtkWidget                *widget,
+                                                               EmpathyMainWindow        *window);
 static void     main_window_chat_show_offline_cb               (GtkCheckMenuItem         *item,
                                                                EmpathyMainWindow        *window);
 static gboolean main_window_edit_button_press_event_cb         (GtkWidget                *widget,
@@ -421,6 +424,7 @@ empathy_main_window_show (void)
                              "room_join_favorites", "activate", main_window_room_join_favorites_cb,
                              "room_manage_favorites", "activate", main_window_room_manage_favorites_cb,
                              "chat_add_contact", "activate", main_window_chat_add_contact_cb,
+                             "chat_import", "activate", main_window_chat_import_cb,
                              "chat_show_offline", "toggled", main_window_chat_show_offline_cb,
                              "edit", "button-press-event", main_window_edit_button_press_event_cb,
                              "edit_accounts", "activate", main_window_edit_accounts_cb,
@@ -799,6 +803,13 @@ main_window_chat_add_contact_cb (GtkWidget         *widget,
        empathy_new_contact_dialog_show (GTK_WINDOW (window->window));
 }
 
+static void
+main_window_chat_import_cb (GtkWidget         *widget,
+                           EmpathyMainWindow *window)
+{
+       empathy_import_dialog_show (GTK_WINDOW (window->window));
+}
+
 static void
 main_window_chat_show_offline_cb (GtkCheckMenuItem  *item,
                                  EmpathyMainWindow *window)
index 737105d2391dfe39288ff66573cc450629266f5e..2868b19c74a94fbd0879b6a1ab4ea81915b0af9f 100644 (file)
                         </child>
                       </widget>
                     </child>
+                    <child>
+                      <widget class="GtkImageMenuItem" id="chat_import">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">_Import contacts...</property>
+                        <property name="use_underline">True</property>
+                        <accelerator key="N" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+                        <child internal-child="image">
+                          <widget class="GtkImage" id="menu-item-image9">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-add</property>
+                            <property name="icon_size">1</property>
+                          </widget>
+                        </child>
+                      </widget>
+                    </child>
                     <child>
                       <widget class="GtkSeparatorMenuItem" id="separator3">
                         <property name="visible">True</property>