aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2008-11-29 23:26:50 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2008-11-29 23:26:50 +0800
commit6375ba9a6cf327e665d98c5820992ab7fb80a6d0 (patch)
tree3917285854f52e19cc529c6ab56cf0d2b5a414bc /addressbook
parent4f4615a46d5ba518c1e6a0c2412b1edf1e268d99 (diff)
downloadgsoc2013-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')
-rw-r--r--addressbook/gui/component/e-book-shell-sidebar.c1
-rw-r--r--addressbook/gui/component/e-book-shell-view-private.c6
-rw-r--r--addressbook/gui/component/e-book-shell-view-private.h1
-rw-r--r--addressbook/gui/component/eab-composer-util.c1
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.c310
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.h7
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