diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2009-08-07 23:21:56 +0800 |
---|---|---|
committer | Sjoerd Simons <sjoerd.simons@collabora.co.uk> | 2009-08-22 21:23:51 +0800 |
commit | 2f019885754917e5130b35d167cadb4c5ca966d5 (patch) | |
tree | 4ec0e849d58c7e2ed5945f7de1bed0bb23a82fb6 | |
parent | 1ca4a9ee58260df26a03bc6565867b7958333f4c (diff) | |
download | gsoc2013-empathy-2f019885754917e5130b35d167cadb4c5ca966d5.tar gsoc2013-empathy-2f019885754917e5130b35d167cadb4c5ca966d5.tar.gz gsoc2013-empathy-2f019885754917e5130b35d167cadb4c5ca966d5.tar.bz2 gsoc2013-empathy-2f019885754917e5130b35d167cadb4c5ca966d5.tar.lz gsoc2013-empathy-2f019885754917e5130b35d167cadb4c5ca966d5.tar.xz gsoc2013-empathy-2f019885754917e5130b35d167cadb4c5ca966d5.tar.zst gsoc2013-empathy-2f019885754917e5130b35d167cadb4c5ca966d5.zip |
Split EmpathyImportDialog and EmpathyImportWidget
Also, take this as a chance to GObject-ify everything.
-rw-r--r-- | src/empathy-import-dialog.c | 493 | ||||
-rw-r--r-- | src/empathy-import-dialog.h | 39 | ||||
-rw-r--r-- | src/empathy-import-dialog.ui | 78 | ||||
-rw-r--r-- | src/empathy-import-widget.c | 464 | ||||
-rw-r--r-- | src/empathy-import-widget.h | 68 |
5 files changed, 739 insertions, 403 deletions
diff --git a/src/empathy-import-dialog.c b/src/empathy-import-dialog.c index a70a6eedd..4866b81c5 100644 --- a/src/empathy-import-dialog.c +++ b/src/empathy-import-dialog.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2008-2009 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 @@ -17,7 +17,8 @@ * Boston, MA 02110-1301 USA * * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> - * */ + * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> + */ #include <config.h> @@ -31,6 +32,7 @@ #include "empathy-import-dialog.h" #include "empathy-import-pidgin.h" +#include "empathy-import-widget.h" #define DEBUG_FLAG EMPATHY_DEBUG_OTHER #include <libempathy/empathy-debug.h> @@ -39,25 +41,22 @@ #include <libempathy/empathy-connection-managers.h> #include <libempathy-gtk/empathy-ui-utils.h> -typedef struct -{ - GtkWidget *window; - GtkWidget *treeview; - GtkWidget *button_ok; - GtkWidget *button_cancel; - GList *accounts; -} EmpathyImportDialog; - -enum -{ - COL_IMPORT = 0, - COL_PROTOCOL, - COL_NAME, - COL_SOURCE, - COL_ACCOUNT_DATA, - COL_COUNT +enum { + PROP_PARENT = 1, + PROP_SHOW_WARNING }; +typedef struct { + GtkWindow *parent_window; + + EmpathyImportWidget *iw; + + gboolean show_warning; +} EmpathyImportDialogPriv; + +G_DEFINE_TYPE (EmpathyImportDialog, empathy_import_dialog, GTK_TYPE_DIALOG) +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyImportDialog) + EmpathyImportAccountData * empathy_import_account_data_new (const gchar *source) { @@ -92,377 +91,193 @@ empathy_import_account_data_free (EmpathyImportAccountData *data) g_slice_free (EmpathyImportAccountData, data); } -static void -import_dialog_create_account_cb (GObject *source, - GAsyncResult *result, - gpointer user_data) +gboolean +empathy_import_dialog_accounts_to_import (void) { - EmpathyImportAccountData *data = (EmpathyImportAccountData *) user_data; - EmpathyAccount *account; - GError *error = NULL; - - account = empathy_account_manager_create_account_finish ( - EMPATHY_ACCOUNT_MANAGER (source), result, &error); - - if (account == NULL) - { - DEBUG ("Failed to create account: %s", - error ? error->message : "No error given"); - g_clear_error (&error); - empathy_import_account_data_free (data); - return; - } - - DEBUG ("account created\n"); - - g_object_unref (account); + return empathy_import_pidgin_accounts_to_import (); } static void -import_dialog_add_account (EmpathyImportAccountData *data) +import_dialog_add_import_widget (EmpathyImportDialog *self) { - EmpathyAccountManager *account_manager; - gchar *display_name; - GHashTable *properties; - GValue *username; - - account_manager = empathy_account_manager_dup_singleton (); - - DEBUG ("connection_manager: %s\n", data->connection_manager); - - /* Set the display name of the account */ - username = g_hash_table_lookup (data->settings, "account"); - display_name = g_strdup_printf ("%s (%s)", - data->protocol, - g_value_get_string (username)); - - DEBUG ("display name: %s\n", display_name); - - properties = g_hash_table_new (NULL, NULL); - - empathy_account_manager_create_account_async (account_manager, - (const gchar*) data->connection_manager, data->protocol, display_name, - data->settings, properties, import_dialog_create_account_cb, NULL); - - g_hash_table_unref (properties); - g_free (display_name); - g_object_unref (account_manager); + EmpathyImportWidget *iw; + EmpathyImportDialogPriv *priv = GET_PRIV (self); + GtkWidget *widget, *area; + + area = gtk_dialog_get_content_area (GTK_DIALOG (self)); + + iw = empathy_import_widget_new (); + widget = empathy_import_widget_get_widget (iw); + gtk_box_pack_start (GTK_BOX (area), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + priv->iw = iw; + + gtk_dialog_add_buttons (GTK_DIALOG (self), GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); } -static gboolean -import_dialog_account_id_in_list (GList *accounts, - const gchar *account_id) +static void +import_dialog_show_warning_message (EmpathyImportDialog *self) { - GList *l; + GtkWidget *hbox, *vbox, *w; - for (l = accounts; l; l = l->next) - { - EmpathyAccount *account = l->data; - const gchar *account_string; - GValue *value; - gboolean result; - const GHashTable *parameters; + vbox = gtk_vbox_new (FALSE, 12); + hbox = gtk_hbox_new (FALSE, 12); - parameters = empathy_account_get_parameters (account); + w = gtk_label_new (_("No accounts to import could be found. Empathy " + "currently only supports importing accounts from Pidgin.")); + gtk_label_set_line_wrap (GTK_LABEL (w), TRUE); + gtk_label_set_selectable (GTK_LABEL (w), TRUE); + gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0); + gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0); - value = g_hash_table_lookup ((GHashTable *) parameters, "account"); + w = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, + GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (w), 0.5, 0.0); + gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0); - if (value == NULL) - continue; + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - account_string = g_value_get_string (value); + w = gtk_dialog_get_content_area (GTK_DIALOG (self)); + gtk_box_pack_start (GTK_BOX (w), hbox, FALSE, FALSE, 0); - result = tp_strdiff (account_string, account_id); + gtk_box_set_spacing (GTK_BOX (w), 14); /* 14 + 2 * 5 = 24 */ - if (!result) - return TRUE; - } + gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE); - return FALSE; + gtk_widget_show_all (w); } -static gboolean protocol_is_supported (EmpathyImportAccountData *data) +static void +impl_signal_response (GtkDialog *dialog, + gint response_id) { - EmpathyConnectionManagers *cm = - empathy_connection_managers_dup_singleton (); - GList *cms = empathy_connection_managers_get_cms (cm); - GList *l; - gboolean proto_is_supported = FALSE; + EmpathyImportDialogPriv *priv = GET_PRIV (dialog); - for (l = cms; l; l = l->next) - { - TpConnectionManager *tp_cm = l->data; - const gchar *cm_name = tp_connection_manager_get_name (tp_cm); - if (tp_connection_manager_has_protocol (tp_cm, - (const gchar*)data->protocol)) - { - data->connection_manager = g_strdup (cm_name); - proto_is_supported = TRUE; - break; - } - } - - g_object_unref (cm); + if (response_id == GTK_RESPONSE_OK) + empathy_import_widget_add_selected_accounts (priv->iw); - return proto_is_supported; + gtk_widget_destroy (GTK_WIDGET (dialog)); } static void -import_dialog_add_accounts_to_model (EmpathyImportDialog *dialog) +do_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { - GtkTreeModel *model; - GtkTreeIter iter; - GList *l; - EmpathyAccountManager *manager = empathy_account_manager_dup_singleton (); + EmpathyImportDialogPriv *priv = GET_PRIV (object); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - - for (l = dialog->accounts; l; l = l->next) + switch (property_id) { - GValue *value; - EmpathyImportAccountData *data = l->data; - gboolean import; - GList *accounts; - - if (!protocol_is_supported (data)) - continue; - - value = g_hash_table_lookup (data->settings, "account"); - - accounts = empathy_account_manager_dup_accounts (manager); - - /* Only set the "Import" cell to be active if there isn't already an - * account set up with the same account id. */ - import = !import_dialog_account_id_in_list (accounts, - g_value_get_string (value)); - - g_list_foreach (accounts, (GFunc) g_object_unref, NULL); - g_list_free (accounts); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_IMPORT, import, - COL_PROTOCOL, data->protocol, - COL_NAME, g_value_get_string (value), - COL_SOURCE, data->source, - COL_ACCOUNT_DATA, data, - -1); + case PROP_PARENT: + g_value_set_object (value, priv->parent_window); + break; + case PROP_SHOW_WARNING: + g_value_set_boolean (value, priv->show_warning); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } - - g_object_unref (manager); -} - -static void -import_dialog_cell_toggled_cb (GtkCellRendererToggle *cell_renderer, - const gchar *path_str, - EmpathyImportDialog *dialog) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreePath *path; - - path = gtk_tree_path_new_from_string (path_str); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - - gtk_tree_model_get_iter (model, &iter, path); - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_IMPORT, !gtk_cell_renderer_toggle_get_active (cell_renderer), - -1); - - gtk_tree_path_free (path); } static void -import_dialog_set_up_account_list (EmpathyImportDialog *dialog) -{ - GtkListStore *store; - GtkTreeView *view; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - - store = gtk_list_store_new (COL_COUNT, G_TYPE_BOOLEAN, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); - - gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview), - GTK_TREE_MODEL (store)); - - g_object_unref (store); - - view = GTK_TREE_VIEW (dialog->treeview); - gtk_tree_view_set_headers_visible (view, TRUE); - - /* Import column */ - cell = gtk_cell_renderer_toggle_new (); - gtk_tree_view_insert_column_with_attributes (view, -1, - /* Translators: this is the header of a treeview column */ - _("Import"), cell, - "active", COL_IMPORT, - NULL); - - g_signal_connect (cell, "toggled", - G_CALLBACK (import_dialog_cell_toggled_cb), dialog); - - /* Protocol column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Protocol")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "editable", FALSE, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_PROTOCOL); - - /* Account column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Account")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "editable", FALSE, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME); - - /* Source column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Source")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "editable", FALSE, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_SOURCE); - - import_dialog_add_accounts_to_model (dialog); -} - -static gboolean -import_dialog_tree_model_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data) +do_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - gboolean to_import; - EmpathyImportAccountData *data; - - gtk_tree_model_get (model, iter, - COL_IMPORT, &to_import, - COL_ACCOUNT_DATA, &data, - -1); - - if (to_import) - import_dialog_add_account (data); - - return FALSE; -} + EmpathyImportDialogPriv *priv = GET_PRIV (object); -static void -import_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyImportDialog *dialog) -{ - if (response == GTK_RESPONSE_OK) + switch (property_id) { - GtkTreeModel *model; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - gtk_tree_model_foreach (model, import_dialog_tree_model_foreach, dialog); + case PROP_PARENT: + priv->parent_window = g_value_get_object (value); + break; + case PROP_SHOW_WARNING: + priv->show_warning = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } - - gtk_widget_destroy (dialog->window); } static void -import_dialog_destroy_cb (GtkWidget *widget, - EmpathyImportDialog *dialog) +do_constructed (GObject *obj) { - g_list_foreach (dialog->accounts, (GFunc) empathy_import_account_data_free, - NULL); - g_list_free (dialog->accounts); - g_slice_free (EmpathyImportDialog, dialog); -} + EmpathyImportDialog *self = EMPATHY_IMPORT_DIALOG (obj); + EmpathyImportDialogPriv *priv = GET_PRIV (self); + gboolean have_accounts; -gboolean -empathy_import_dialog_accounts_to_import (void) -{ - return empathy_import_pidgin_accounts_to_import (); -} + have_accounts = empathy_import_dialog_accounts_to_import (); -void -empathy_import_dialog_show (GtkWindow *parent, - gboolean warning) -{ - static EmpathyImportDialog *dialog = NULL; - GtkBuilder *gui; - gchar *filename; - GList *accounts = NULL; - - /* This window is a singleton. If it already exist, present it */ - if (dialog) - { - gtk_window_present (GTK_WINDOW (dialog->window)); - return; - } - - /* Load all accounts from all supported applications */ - accounts = g_list_concat (accounts, empathy_import_pidgin_load ()); - - /* Check if we have accounts to import before creating the window */ - if (!accounts) + if (!have_accounts) { - GtkWidget *message; - - if (warning) + if (priv->show_warning) { - message = gtk_message_dialog_new (parent, - GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, - _("No accounts to import could be found. Empathy currently only " - "supports importing accounts from Pidgin.")); - - gtk_dialog_run (GTK_DIALOG (message)); - gtk_widget_destroy (message); + import_dialog_show_warning_message (self); } else DEBUG ("No accounts to import; closing dialog silently."); - - return; + } + else + { + import_dialog_add_import_widget (self); } - /* We have accounts, let's display the window with them */ - dialog = g_slice_new0 (EmpathyImportDialog); - dialog->accounts = accounts; - - filename = empathy_file_lookup ("empathy-import-dialog.ui", "src"); - gui = empathy_builder_get_file (filename, - "import_dialog", &dialog->window, - "treeview", &dialog->treeview, - NULL); - - empathy_builder_connect (gui, dialog, - "import_dialog", "destroy", import_dialog_destroy_cb, - "import_dialog", "response", import_dialog_response_cb, - NULL); - - g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog); + if (priv->parent_window) + gtk_window_set_transient_for (GTK_WINDOW (self), priv->parent_window); +} - g_free (filename); - g_object_unref (gui); +static void +empathy_import_dialog_init (EmpathyImportDialog *self) +{ + EmpathyImportDialogPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + EMPATHY_TYPE_IMPORT_DIALOG, EmpathyImportDialogPriv); - if (parent) - gtk_window_set_transient_for (GTK_WINDOW (dialog->window), parent); + self->priv = priv; - import_dialog_set_up_account_list (dialog); + gtk_container_set_border_width (GTK_CONTAINER (self), 5); + gtk_window_set_title (GTK_WINDOW (self), _("Import Accounts")); + gtk_window_set_modal (GTK_WINDOW (self), TRUE); + gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE); +} - gtk_widget_show (dialog->window); +static void +empathy_import_dialog_class_init (EmpathyImportDialogClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GtkDialogClass *gtkclass = GTK_DIALOG_CLASS (klass); + GParamSpec *param_spec; + + oclass->constructed = do_constructed; + oclass->get_property = do_get_property; + oclass->set_property = do_set_property; + + gtkclass->response = impl_signal_response; + + param_spec = g_param_spec_object ("parent-window", + "parent-window", "The parent window", + GTK_TYPE_WINDOW, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (oclass, PROP_PARENT, param_spec); + + param_spec = g_param_spec_boolean ("show-warning", + "show-warning", "Whether a warning should be shown when there are no " + "sources for importing accounts.", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (oclass, PROP_SHOW_WARNING, param_spec); + + g_type_class_add_private (klass, sizeof (EmpathyImportDialogPriv)); } +GtkWidget * +empathy_import_dialog_new (GtkWindow *parent, + gboolean warning) +{ + return g_object_new (EMPATHY_TYPE_IMPORT_DIALOG, "parent-window", + parent, "show-warning", warning, NULL); +} diff --git a/src/empathy-import-dialog.h b/src/empathy-import-dialog.h index bdd0de732..14ab33b47 100644 --- a/src/empathy-import-dialog.h +++ b/src/empathy-import-dialog.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2008-2009 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 @@ -17,6 +17,7 @@ * Boston, MA 02110-1301 USA * * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> + * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> */ #include <gtk/gtk.h> @@ -26,6 +27,21 @@ G_BEGIN_DECLS +#define EMPATHY_TYPE_IMPORT_DIALOG empathy_import_dialog_get_type() +#define EMPATHY_IMPORT_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_IMPORT_DIALOG,\ + EmpathyImportDialog)) +#define EMPATHY_IMPORT_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), EMPATHY_TYPE_IMPORT_DIALOG,\ + EmpathyImportDialogClass)) +#define EMPATHY_IS_IMPORT_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_IMPORT_DIALOG)) +#define EMPATHY_IS_IMPORT_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), EMPATHY_TYPE_IMPORT_DIALOG)) +#define EMPATHY_IMPORT_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_IMPORT_DIALOG,\ + EmpathyImportDialogClass)) + typedef struct { /* Table mapping CM param string to a GValue */ @@ -38,10 +54,27 @@ typedef struct gchar *source; } EmpathyImportAccountData; -EmpathyImportAccountData *empathy_import_account_data_new (const gchar *source); +typedef struct { + GtkDialog parent; + + /* private */ + gpointer priv; +} EmpathyImportDialog; + +typedef struct { + GtkDialogClass parent_class; +} EmpathyImportDialogClass; + +GType empathy_import_dialog_get_type (void); + +GtkWidget* empathy_import_dialog_new (GtkWindow *parent_window, + gboolean show_warning); + +EmpathyImportAccountData *empathy_import_account_data_new ( + const gchar *source); void empathy_import_account_data_free (EmpathyImportAccountData *data); + gboolean empathy_import_dialog_accounts_to_import (void); -void empathy_import_dialog_show (GtkWindow *parent, gboolean warning); G_END_DECLS diff --git a/src/empathy-import-dialog.ui b/src/empathy-import-dialog.ui index 38ba434e4..ce7a56a74 100644 --- a/src/empathy-import-dialog.ui +++ b/src/empathy-import-dialog.ui @@ -1,73 +1,29 @@ <?xml version="1.0"?> -<!--Generated with glade3 3.4.5 on Fri Oct 17 11:01:30 2008 --> <interface> - <object class="GtkDialog" id="import_dialog"> - <property name="border_width">5</property> - <property name="title" translatable="yes">Import Accounts</property> - <property name="modal">True</property> - <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> - <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <object class="GtkVBox" id="dialog-vbox1"> + <!-- interface-requires gtk+ 2.12 --> + <!-- interface-naming-policy toplevel-contextual --> + <object class="GtkVBox" id="widget_vbox"> + <property name="visible">True</property> + <property name="spacing">2</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow17"> <property name="visible">True</property> - <property name="spacing">2</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">never</property> + <property name="vscrollbar_policy">automatic</property> + <property name="shadow_type">in</property> <child> - <object class="GtkScrolledWindow" id="scrolledwindow17"> + <object class="GtkTreeView" id="treeview"> + <property name="height_request">200</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <child> - <object class="GtkTreeView" id="treeview"> - <property name="height_request">200</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="enable_search">False</property> - </object> - </child> + <property name="enable_search">False</property> </object> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <object class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - <child> - <object class="GtkButton" id="button_cancel"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - </object> - </child> - <child> - <object class="GtkButton" id="button_ok"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> </child> </object> + <packing> + <property name="position">1</property> + </packing> </child> - <action-widgets> - <action-widget response="0">button_cancel</action-widget> - <action-widget response="-5">button_ok</action-widget> - </action-widgets> </object> </interface> diff --git a/src/empathy-import-widget.c b/src/empathy-import-widget.c new file mode 100644 index 000000000..d276c03e5 --- /dev/null +++ b/src/empathy-import-widget.c @@ -0,0 +1,464 @@ +/* + * Copyright (C) 2008-2009 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> + * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> + */ + +/* empathy-import-widget.c */ + +#include "empathy-import-dialog.h" +#include "empathy-import-widget.h" +#include "empathy-import-pidgin.h" + +#define DEBUG_FLAG EMPATHY_DEBUG_OTHER +#include <libempathy/empathy-debug.h> +#include <libempathy/empathy-account.h> +#include <libempathy/empathy-account-manager.h> +#include <libempathy/empathy-connection-managers.h> +#include <libempathy/empathy-utils.h> + +#include <libempathy-gtk/empathy-ui-utils.h> + +#include <telepathy-glib/util.h> + +#include <glib/gi18n.h> + +G_DEFINE_TYPE (EmpathyImportWidget, empathy_import_widget, G_TYPE_OBJECT) + +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyImportWidget) + +enum +{ + COL_IMPORT = 0, + COL_PROTOCOL, + COL_NAME, + COL_SOURCE, + COL_ACCOUNT_DATA, + COL_COUNT +}; + +typedef struct { + GtkWidget *vbox; + GtkWidget *treeview; + + GList *accounts; + + EmpathyConnectionManagers *cms; + + gboolean dispose_run; +} EmpathyImportWidgetPriv; + +static gboolean +import_widget_account_id_in_list (GList *accounts, + const gchar *account_id) +{ + GList *l; + + for (l = accounts; l; l = l->next) + { + EmpathyAccount *account = l->data; + const gchar *account_string; + GValue *value; + gboolean result; + const GHashTable *parameters; + + parameters = empathy_account_get_parameters (account); + + value = g_hash_table_lookup ((GHashTable *)parameters, "account"); + + if (value == NULL) + continue; + + account_string = g_value_get_string (value); + + result = tp_strdiff (account_string, account_id); + + if (!result) + return TRUE; + } + + return FALSE; +} + +static gboolean +protocol_is_supported (EmpathyImportWidget *self, + EmpathyImportAccountData *data) +{ + EmpathyImportWidgetPriv *priv = GET_PRIV (self); + GList *cms = empathy_connection_managers_get_cms (priv->cms); + GList *l; + gboolean proto_is_supported = FALSE; + + for (l = cms; l; l = l->next) + { + TpConnectionManager *tp_cm = l->data; + const gchar *cm_name = tp_connection_manager_get_name (tp_cm); + if (tp_connection_manager_has_protocol (tp_cm, + (const gchar*) data->protocol)) + { + data->connection_manager = g_strdup (cm_name); + proto_is_supported = TRUE; + break; + } + } + + return proto_is_supported; +} + +static void +import_widget_add_accounts_to_model (EmpathyImportWidget *self) +{ + GtkTreeModel *model; + GtkTreeIter iter; + GList *l; + EmpathyImportWidgetPriv *priv = GET_PRIV (self); + EmpathyAccountManager *manager = empathy_account_manager_dup_singleton (); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + + for (l = priv->accounts; l; l = l->next) + { + GValue *value; + EmpathyImportAccountData *data = l->data; + gboolean import; + GList *accounts; + + if (!protocol_is_supported (self, data)) + continue; + + value = g_hash_table_lookup (data->settings, "account"); + + accounts = empathy_account_manager_dup_accounts (manager); + + /* Only set the "Import" cell to be active if there isn't already an + * account set up with the same account id. */ + import = !import_widget_account_id_in_list (accounts, + g_value_get_string (value)); + + g_list_foreach (accounts, (GFunc) g_object_unref, NULL); + g_list_free (accounts); + + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_IMPORT, import, + COL_PROTOCOL, data->protocol, + COL_NAME, g_value_get_string (value), + COL_SOURCE, data->source, + COL_ACCOUNT_DATA, data, + -1); + } + + g_object_unref (manager); +} + +static void +import_widget_create_account_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyAccount *account; + GError *error = NULL; + EmpathyImportWidget *self = user_data; + + account = empathy_account_manager_create_account_finish ( + EMPATHY_ACCOUNT_MANAGER (source), result, &error); + + if (account == NULL) + { + DEBUG ("Failed to create account: %s", + error ? error->message : "No error given"); + g_clear_error (&error); + return; + } + + DEBUG ("account created\n"); + + g_object_unref (self); +} + +static void +import_widget_add_account (EmpathyImportWidget *self, + EmpathyImportAccountData *data) +{ + EmpathyAccountManager *account_manager; + gchar *display_name; + GHashTable *properties; + GValue *username; + + account_manager = empathy_account_manager_dup_singleton (); + + DEBUG ("connection_manager: %s\n", data->connection_manager); + + /* Set the display name of the account */ + username = g_hash_table_lookup (data->settings, "account"); + display_name = g_strdup_printf ("%s (%s)", + data->protocol, + g_value_get_string (username)); + + DEBUG ("display name: %s\n", display_name); + + properties = g_hash_table_new (NULL, NULL); + + empathy_account_manager_create_account_async (account_manager, + (const gchar*) data->connection_manager, data->protocol, display_name, + data->settings, properties, import_widget_create_account_cb, + g_object_ref (self)); + + g_hash_table_unref (properties); + g_free (display_name); + g_object_unref (account_manager); +} + +static gboolean +import_widget_tree_model_foreach (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer user_data) +{ + gboolean to_import; + EmpathyImportAccountData *data; + EmpathyImportWidget *self = user_data; + + gtk_tree_model_get (model, iter, + COL_IMPORT, &to_import, + COL_ACCOUNT_DATA, &data, + -1); + + if (to_import) + import_widget_add_account (self, data); + + return FALSE; +} + +static void +import_widget_cell_toggled_cb (GtkCellRendererToggle *cell_renderer, + const gchar *path_str, + EmpathyImportWidget *self) +{ + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreePath *path; + EmpathyImportWidgetPriv *priv = GET_PRIV (self); + + path = gtk_tree_path_new_from_string (path_str); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + + gtk_tree_model_get_iter (model, &iter, path); + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_IMPORT, !gtk_cell_renderer_toggle_get_active (cell_renderer), + -1); + + gtk_tree_path_free (path); +} + +static void +import_widget_set_up_account_list (EmpathyImportWidget *self) +{ + EmpathyImportWidgetPriv *priv = GET_PRIV (self); + GtkListStore *store; + GtkTreeView *view; + GtkTreeViewColumn *column; + GtkCellRenderer *cell; + + store = gtk_list_store_new (COL_COUNT, G_TYPE_BOOLEAN, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); + + gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview), + GTK_TREE_MODEL (store)); + + g_object_unref (store); + + view = GTK_TREE_VIEW (priv->treeview); + gtk_tree_view_set_headers_visible (view, TRUE); + + /* Import column */ + cell = gtk_cell_renderer_toggle_new (); + gtk_tree_view_insert_column_with_attributes (view, -1, + /* Translators: this is the header of a treeview column */ + _("Import"), cell, + "active", COL_IMPORT, + NULL); + + g_signal_connect (cell, "toggled", + G_CALLBACK (import_widget_cell_toggled_cb), self); + + /* Protocol column */ + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Protocol")); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_append_column (view, column); + + cell = gtk_cell_renderer_text_new (); + g_object_set (cell, "editable", FALSE, NULL); + gtk_tree_view_column_pack_start (column, cell, TRUE); + gtk_tree_view_column_add_attribute (column, cell, "text", COL_PROTOCOL); + + /* Account column */ + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Account")); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_append_column (view, column); + + cell = gtk_cell_renderer_text_new (); + g_object_set (cell, "editable", FALSE, NULL); + gtk_tree_view_column_pack_start (column, cell, TRUE); + gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME); + + /* Source column */ + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Source")); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_append_column (view, column); + + cell = gtk_cell_renderer_text_new (); + g_object_set (cell, "editable", FALSE, NULL); + gtk_tree_view_column_pack_start (column, cell, TRUE); + gtk_tree_view_column_add_attribute (column, cell, "text", COL_SOURCE); + + import_widget_add_accounts_to_model (self); +} + +static void +import_widget_cms_ready_cb (EmpathyConnectionManagers *cms, + GParamSpec *pspec, + EmpathyImportWidget *self) +{ + if (empathy_connection_managers_is_ready (cms)) + import_widget_set_up_account_list (self); +} + +static void +import_widget_destroy_cb (GtkWidget *w, + EmpathyImportWidget *self) +{ + g_object_unref (self); +} + +static void +do_finalize (GObject *obj) +{ + EmpathyImportWidgetPriv *priv = GET_PRIV (obj); + + g_list_foreach (priv->accounts, (GFunc) empathy_import_account_data_free, + NULL); + g_list_free (priv->accounts); + + if (G_OBJECT_CLASS (empathy_import_widget_parent_class)->finalize != NULL) + G_OBJECT_CLASS (empathy_import_widget_parent_class)->finalize (obj); +} + +static void +do_dispose (GObject *obj) +{ + EmpathyImportWidgetPriv *priv = GET_PRIV (obj); + + if (priv->dispose_run) + return; + + priv->dispose_run = TRUE; + + if (priv->cms != NULL) + { + g_object_unref (priv->cms); + priv->cms = NULL; + } + + if (G_OBJECT_CLASS (empathy_import_widget_parent_class)->dispose != NULL) + G_OBJECT_CLASS (empathy_import_widget_parent_class)->dispose (obj); +} + +static void +do_constructed (GObject *obj) +{ + EmpathyImportWidget *self = EMPATHY_IMPORT_WIDGET (obj); + EmpathyImportWidgetPriv *priv = GET_PRIV (self); + GtkBuilder *gui; + gchar *filename; + + filename = empathy_file_lookup ("empathy-import-dialog.ui", "src"); + gui = empathy_builder_get_file (filename, + "widget_vbox", &priv->vbox, + "treeview", &priv->treeview, + NULL); + + g_free (filename); + empathy_builder_unref_and_keep_widget (gui, priv->vbox); + + g_signal_connect (priv->vbox, "destroy", + G_CALLBACK (import_widget_destroy_cb), self); + + if (empathy_connection_managers_is_ready (priv->cms)) + import_widget_set_up_account_list (self); + else + g_signal_connect (priv->cms, "notify::ready", + G_CALLBACK (import_widget_cms_ready_cb), self); +} + +static void +empathy_import_widget_class_init (EmpathyImportWidgetClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + + oclass->constructed = do_constructed; + oclass->finalize = do_finalize; + oclass->dispose = do_dispose; + + g_type_class_add_private (klass, sizeof (EmpathyImportWidgetPriv)); +} + +static void +empathy_import_widget_init (EmpathyImportWidget *self) +{ + EmpathyImportWidgetPriv *priv = + G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_IMPORT_WIDGET, + EmpathyImportWidgetPriv); + + self->priv = priv; + + /* Load all accounts from all supported applications */ + priv->accounts = empathy_import_pidgin_load (); + + priv->cms = empathy_connection_managers_dup_singleton (); +} + +EmpathyImportWidget * +empathy_import_widget_new (void) +{ + return g_object_new (EMPATHY_TYPE_IMPORT_WIDGET, NULL); +} + +GtkWidget * +empathy_import_widget_get_widget (EmpathyImportWidget *self) +{ + EmpathyImportWidgetPriv *priv = GET_PRIV (self); + + return priv->vbox; +} + +void +empathy_import_widget_add_selected_accounts (EmpathyImportWidget *self) +{ + GtkTreeModel *model; + EmpathyImportWidgetPriv *priv = GET_PRIV (self); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + gtk_tree_model_foreach (model, import_widget_tree_model_foreach, self); +} diff --git a/src/empathy-import-widget.h b/src/empathy-import-widget.h new file mode 100644 index 000000000..8af953d79 --- /dev/null +++ b/src/empathy-import-widget.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008-2009 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> + * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> + */ + +/* empathy-import-widget.h */ + +#ifndef __EMPATHY_IMPORT_WIDGET_H__ +#define __EMPATHY_IMPORT_WIDGET_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define EMPATHY_TYPE_IMPORT_WIDGET empathy_import_widget_get_type() +#define EMPATHY_IMPORT_WIDGET(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_IMPORT_WIDGET,\ + EmpathyImportWidget)) +#define EMPATHY_IMPORT_WIDGET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), EMPATHY_TYPE_IMPORT_WIDGET,\ + EmpathyImportWidgetClass)) +#define EMPATHY_IS_IMPORT_WIDGET(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_IMPORT_WIDGET)) +#define EMPATHY_IS_IMPORT_WIDGET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), EMPATHY_TYPE_IMPORT_WIDGET)) +#define EMPATHY_IMPORT_WIDGET_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_IMPORT_WIDGET,\ + EmpathyImportWidgetClass)) + +typedef struct { + GObject parent; + + /* private */ + gpointer priv; +} EmpathyImportWidget; + +typedef struct { + GObjectClass parent_class; +} EmpathyImportWidgetClass; + +GType empathy_import_widget_get_type (void); + +EmpathyImportWidget* empathy_import_widget_new (void); + +GtkWidget * empathy_import_widget_get_widget (EmpathyImportWidget *self); + +void empathy_import_widget_add_selected_accounts (EmpathyImportWidget *self); + +G_END_DECLS + +#endif /* __EMPATHY_IMPORT_WIDGET_H__ */ |