diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2008-11-29 23:26:50 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2008-11-29 23:26:50 +0800 |
commit | 6375ba9a6cf327e665d98c5820992ab7fb80a6d0 (patch) | |
tree | 3917285854f52e19cc529c6ab56cf0d2b5a414bc /addressbook/gui | |
parent | 4f4615a46d5ba518c1e6a0c2412b1edf1e268d99 (diff) | |
download | gsoc2013-evolution-6375ba9a6cf327e665d98c5820992ab7fb80a6d0.tar.gz gsoc2013-evolution-6375ba9a6cf327e665d98c5820992ab7fb80a6d0.tar.zst gsoc2013-evolution-6375ba9a6cf327e665d98c5820992ab7fb80a6d0.zip |
Get drag-and-drop-to-source-selector working for contacts, memos and tasks.
Utilizes the new ESourceSelector::data-dropped signal.
svn path=/branches/kill-bonobo/; revision=36822
Diffstat (limited to 'addressbook/gui')
6 files changed, 153 insertions, 173 deletions
diff --git a/addressbook/gui/component/e-book-shell-sidebar.c b/addressbook/gui/component/e-book-shell-sidebar.c index 9532745c98..fd9cdbe925 100644 --- a/addressbook/gui/component/e-book-shell-sidebar.c +++ b/addressbook/gui/component/e-book-shell-sidebar.c @@ -21,6 +21,7 @@ #include "e-book-shell-sidebar.h" +#include <string.h> #include <glib/gi18n.h> #include <e-book-shell-view.h> diff --git a/addressbook/gui/component/e-book-shell-view-private.c b/addressbook/gui/component/e-book-shell-view-private.c index 90ebad94f8..521260bdeb 100644 --- a/addressbook/gui/component/e-book-shell-view-private.c +++ b/addressbook/gui/component/e-book-shell-view-private.c @@ -276,6 +276,12 @@ book_shell_view_activate_selected_source (EBookShellView *book_shell_view, e_book_shell_content_set_current_view ( book_shell_content, E_ADDRESSBOOK_VIEW (widget)); + /* XXX We have to keep the addressbook selector informed of the + * current view so it can move contacts via drag-and-drop. */ + e_addressbook_selector_set_current_view ( + E_ADDRESSBOOK_SELECTOR (selector), + E_ADDRESSBOOK_VIEW (widget)); + view_instance = e_addressbook_view_get_view_instance (view); view_id = gal_view_instance_get_current_view_id (view_instance); e_shell_view_set_view_id (shell_view, view_id); diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h index d53ced9440..9bb4f91a22 100644 --- a/addressbook/gui/component/e-book-shell-view-private.h +++ b/addressbook/gui/component/e-book-shell-view-private.h @@ -40,6 +40,7 @@ #include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" #include "addressbook/gui/widgets/eab-gui-util.h" #include "addressbook/gui/widgets/e-addressbook-view.h" +#include "addressbook/gui/widgets/e-addressbook-selector.h" #include <e-book-shell-content.h> #include <e-book-shell-sidebar.h> diff --git a/addressbook/gui/component/eab-composer-util.c b/addressbook/gui/component/eab-composer-util.c index ce3a96cc13..aa994df216 100644 --- a/addressbook/gui/component/eab-composer-util.c +++ b/addressbook/gui/component/eab-composer-util.c @@ -18,6 +18,7 @@ #include "eab-composer-util.h" +#include <string.h> #include <glib/gi18n.h> #include <libebook/e-contact.h> #include <libebook/e-destination.h> diff --git a/addressbook/gui/widgets/e-addressbook-selector.c b/addressbook/gui/widgets/e-addressbook-selector.c index 8e498fa380..e7bec99ba2 100644 --- a/addressbook/gui/widgets/e-addressbook-selector.c +++ b/addressbook/gui/widgets/e-addressbook-selector.c @@ -33,7 +33,7 @@ typedef struct _MergeContext MergeContext; struct _EAddressbookSelectorPrivate { - gint dummy_value; + EAddressbookView *current_view; }; struct _MergeContext { @@ -49,6 +49,11 @@ struct _MergeContext { }; enum { + PROP_0, + PROP_CURRENT_VIEW +}; + +enum { DND_TARGET_TYPE_VCARD, DND_TARGET_TYPE_SOURCE_VCARD }; @@ -192,168 +197,124 @@ addressbook_selector_load_primary_source (ESourceSelector *selector) } static void -addressbook_selector_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time_) +addressbook_selector_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - /* XXX This is exactly the same as in ECalendarSelector. - * Consider merging this callback into ESourceSelector. */ - - GtkTreeView *tree_view; - GtkTreeViewDropPosition pos; - - tree_view = GTK_TREE_VIEW (widget); - pos = GTK_TREE_VIEW_DROP_BEFORE; + switch (property_id) { + case PROP_CURRENT_VIEW: + e_addressbook_selector_set_current_view ( + E_ADDRESSBOOK_SELECTOR (object), + g_value_get_object (value)); + return; + } - gtk_tree_view_set_drag_dest_row (tree_view, NULL, pos); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } -static gboolean -addressbook_selector_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time_) +static void +addressbook_selector_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { - /* XXX This is exactly the same as in ECalendarSelector. - * Consider merging this callback into ESourceSelector. */ - - GtkTreeView *tree_view; - GtkTreeModel *model; - GtkTreePath *path = NULL; - GtkTreeIter iter; - GtkTreeViewDropPosition pos; - GdkDragAction action = 0; - gpointer object; - - tree_view = GTK_TREE_VIEW (widget); - model = gtk_tree_view_get_model (tree_view); - - if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL)) - goto exit; - - if (!gtk_tree_model_get_iter (model, &iter, path)) - goto exit; - - gtk_tree_model_get (model, &iter, 0, &object, -1); - - if (!E_IS_SOURCE (object) || e_source_get_readonly (object)) - goto exit; + switch (property_id) { + case PROP_CURRENT_VIEW: + g_value_set_object ( + value, + e_addressbook_selector_get_current_view ( + E_ADDRESSBOOK_SELECTOR (object))); + return; + } - gtk_tree_view_set_drag_dest_row ( - tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_BEFORE); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} - pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE; - gtk_tree_view_set_drag_dest_row (tree_view, path, pos); +static void +addressbook_selector_dispose (GObject *object) +{ + EAddressbookSelectorPrivate *priv; - if (context->actions & GDK_ACTION_MOVE) - action = GDK_ACTION_MOVE; - else - action = context->suggested_action; + priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (object); -exit: - if (path != NULL) - gtk_tree_path_free (path); + if (priv->current_view != NULL) { + g_object_unref (priv->current_view); + priv->current_view = NULL; + } - if (object != NULL) - g_object_unref (object); + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} - gdk_drag_status (context, action, time_); +static void +addressbook_selector_constructed (GObject *object) +{ + ESourceSelector *selector; - return TRUE; + selector = E_SOURCE_SELECTOR (object); + addressbook_selector_load_primary_source (selector); } -static gboolean -addressbook_selector_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time_) +static void +addressbook_selector_primary_selection_changed (ESourceSelector *selector) { - /* XXX This is exactly the same as in ECalendarSelector. - * Consider merging this callback into ESourceSelector. */ - - GtkTreeView *tree_view; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - gboolean drop_zone; - gboolean valid; - gpointer object; - - tree_view = GTK_TREE_VIEW (widget); - model = gtk_tree_view_get_model (tree_view); - - if (!gtk_tree_view_get_path_at_pos ( - tree_view, x, y, &path, NULL, NULL, NULL)) - return FALSE; + ESource *source; + GConfClient *client; + const gchar *key; + const gchar *string; - valid = gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - g_return_val_if_fail (valid, FALSE); + /* XXX If ESourceSelector had a "primary-uid" property, + * we could just bind the GConf key to it. */ - gtk_tree_model_get (model, &iter, 0, &object, -1); - drop_zone = E_IS_SOURCE (object); - g_object_unref (object); + source = e_source_selector_peek_primary_selection (selector); + if (source == NULL) + return; - return drop_zone; + client = gconf_client_get_default (); + key = PRIMARY_ADDRESSBOOK_KEY; + string = e_source_peek_uid (source); + gconf_client_set_string (client, key, string, NULL); + g_object_unref (client); } -static void -addressbook_selector_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time_) +static gboolean +addressbook_selector_data_dropped (ESourceSelector *selector, + GtkSelectionData *selection_data, + ESource *destination, + GdkDragAction action, + guint info) { - /* XXX This is NEARLY the same as in ECalendarSelector. - * Consider merging this callback into ESourceSelector. - * Use a callback to allow subclasses to handle the - * received selection data. */ - + EAddressbookSelectorPrivate *priv; MergeContext *merge_context; - GtkTreeView *tree_view; - GtkTreeModel *model; - GtkTreePath *path = NULL; - GtkTreeIter iter; + EAddressbookModel *model; EBook *source_book; EBook *target_book; GList *list; const gchar *string; gboolean remove_from_source; - gboolean success = FALSE; - gpointer object; - tree_view = GTK_TREE_VIEW (widget); - model = gtk_tree_view_get_model (tree_view); + priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (selector); + g_return_val_if_fail (priv->current_view != NULL, FALSE); string = (const gchar *) selection_data->data; - remove_from_source = (context->action == GDK_ACTION_MOVE); - - if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL)) - goto exit; - - if (!gtk_tree_model_get_iter (model, &iter, path)) - goto exit; - - gtk_tree_model_get (model, &iter, 0, &object, -1); - - if (!E_IS_SOURCE (object) || e_source_get_readonly (object)) - goto exit; + remove_from_source = (action == GDK_ACTION_MOVE); - target_book = e_book_new (object, NULL); + target_book = e_book_new (destination, NULL); if (target_book == NULL) - goto exit; + return FALSE; e_book_open (target_book, FALSE, NULL); + /* XXX Function assumes both out arguments are provided. All we + * care about is the contact list; source_book will be NULL. */ eab_book_and_contact_list_from_string (string, &source_book, &list); if (list == NULL) - goto exit; + return FALSE; - /* XXX Get the currently selected EBook. */ + model = e_addressbook_view_get_model (priv->current_view); + source_book = e_addressbook_model_get_book (model); + g_return_val_if_fail (E_IS_BOOK (source_book), FALSE); merge_context = merge_context_new (source_book, target_book, list); merge_context->remove_from_source = remove_from_source; @@ -363,71 +324,38 @@ addressbook_selector_drag_data_received (GtkWidget *widget, (EBookIdCallback) addressbook_selector_merge_next_cb, merge_context); - success = TRUE; - -exit: - if (path != NULL) - gtk_tree_path_free (path); - - if (object != NULL) - g_object_unref (object); - - gtk_drag_finish (context, success, remove_from_source, time_); -} - -static void -addressbook_selector_primary_selection_changed (ESourceSelector *selector) -{ - ESource *source; - GConfClient *client; - const gchar *key; - const gchar *string; - - /* XXX If ESourceSelector had a "primary-uid" property, - * we could just bind the GConf key to it. */ - - source = e_source_selector_peek_primary_selection (selector); - if (source == NULL) - return; - - client = gconf_client_get_default (); - key = PRIMARY_ADDRESSBOOK_KEY; - string = e_source_peek_uid (source); - gconf_client_set_string (client, key, string, NULL); - g_object_unref (client); -} - -static void -addressbook_selector_constructed (GObject *object) -{ - ESourceSelector *selector; - - selector = E_SOURCE_SELECTOR (object); - addressbook_selector_load_primary_source (selector); + return TRUE; } static void addressbook_selector_class_init (EAddressbookSelectorClass *class) { GObjectClass *object_class; - GtkWidgetClass *widget_class; ESourceSelectorClass *selector_class; parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (EAddressbookSelectorPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->set_property = addressbook_selector_set_property; + object_class->get_property = addressbook_selector_get_property; + object_class->dispose = addressbook_selector_dispose; object_class->constructed = addressbook_selector_constructed; - widget_class = GTK_WIDGET_CLASS (class); - widget_class->drag_leave = addressbook_selector_drag_leave; - widget_class->drag_motion = addressbook_selector_drag_motion; - widget_class->drag_drop = addressbook_selector_drag_drop; - widget_class->drag_data_received = addressbook_selector_drag_data_received; - selector_class = E_SOURCE_SELECTOR_CLASS (class); selector_class->primary_selection_changed = addressbook_selector_primary_selection_changed; + selector_class->data_dropped = addressbook_selector_data_dropped; + + g_object_class_install_property ( + object_class, + PROP_CURRENT_VIEW, + g_param_spec_object ( + "current-view", + NULL, + NULL, + E_TYPE_ADDRESSBOOK_VIEW, + G_PARAM_READWRITE)); } static void @@ -477,3 +405,39 @@ e_addressbook_selector_new (ESourceList *source_list) E_TYPE_ADDRESSBOOK_SELECTOR, "source-list", source_list, NULL); } + +EAddressbookView * +e_addressbook_selector_get_current_view (EAddressbookSelector *selector) +{ + g_return_val_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector), NULL); + + return selector->priv->current_view; +} + +void +e_addressbook_selector_set_current_view (EAddressbookSelector *selector, + EAddressbookView *current_view) +{ + /* XXX This is only needed for moving contacts via drag-and-drop. + * The selection data doesn't include the source of the data + * (the model for the currently selected address book view), + * so we have to rely on it being provided to us. I would + * be happy to see this function go away. */ + + g_return_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector)); + + if (current_view != NULL) + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (current_view)); + + if (selector->priv->current_view != NULL) { + g_object_unref (selector->priv->current_view); + selector->priv->current_view = NULL; + } + + if (current_view != NULL) + g_object_ref (current_view); + + selector->priv->current_view = current_view; + + g_object_notify (G_OBJECT (selector), "current-view"); +} diff --git a/addressbook/gui/widgets/e-addressbook-selector.h b/addressbook/gui/widgets/e-addressbook-selector.h index 67a2c8f6e5..c0102cb3b8 100644 --- a/addressbook/gui/widgets/e-addressbook-selector.h +++ b/addressbook/gui/widgets/e-addressbook-selector.h @@ -23,6 +23,7 @@ #include <libedataserver/e-source-list.h> #include <libedataserverui/e-source-selector.h> +#include "e-addressbook-view.h" /* Standard GObject macros */ #define E_TYPE_ADDRESSBOOK_SELECTOR \ @@ -60,6 +61,12 @@ struct _EAddressbookSelectorClass { GType e_addressbook_selector_get_type (void); GtkWidget * e_addressbook_selector_new (ESourceList *source_list); +EAddressbookView * + e_addressbook_selector_get_current_view + (EAddressbookSelector *selector); +void e_addressbook_selector_set_current_view + (EAddressbookSelector *selector, + EAddressbookView *current_view); G_END_DECLS |