aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/gui
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/gui')
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c50
-rw-r--r--addressbook/gui/widgets/e-minicard-view.c74
-rw-r--r--addressbook/gui/widgets/e-minicard-view.h4
-rw-r--r--addressbook/gui/widgets/e-minicard.c43
-rw-r--r--addressbook/gui/widgets/e-minicard.h6
5 files changed, 177 insertions, 0 deletions
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index 685ee0b79d..60ec90b7f9 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -74,6 +74,15 @@ enum {
LAST_SIGNAL
};
+enum DndTargetType {
+ DND_TARGET_TYPE_VCARD,
+};
+#define VCARD_TYPE "text/x-vcard"
+static GtkTargetEntry drag_types[] = {
+ { VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD },
+};
+static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
+
static guint e_addressbook_view_signals [LAST_SIGNAL] = {0, };
GtkType
@@ -588,6 +597,38 @@ table_right_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EA
}
static void
+table_drag_data_get (ETable *table,
+ int row,
+ int col,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer user_data)
+{
+ EAddressbookView *view = user_data;
+
+ printf ("table_drag_data_get (row %d, col %d)\n", row, col);
+
+ if (!E_IS_ADDRESSBOOK_MODEL(view->object))
+ return;
+
+ switch (info) {
+ case DND_TARGET_TYPE_VCARD: {
+ char *value;
+
+ value = e_card_simple_get_vcard(E_ADDRESSBOOK_MODEL(view->object)->data[row]);
+
+ gtk_selection_data_set (selection_data,
+ selection_data->target,
+ 8,
+ value, strlen (value));
+ break;
+ }
+ }
+}
+
+static void
status_message (GtkObject *object, const gchar *status, EAddressbookView *eav)
{
gtk_signal_emit (GTK_OBJECT (eav),
@@ -707,6 +748,15 @@ create_table_view (EAddressbookView *view)
gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "right_click",
GTK_SIGNAL_FUNC(table_right_click), view);
+ /* drag & drop signals */
+ e_table_drag_source_set (E_TABLE(E_TABLE_SCROLLED(table)->table), GDK_BUTTON1_MASK,
+ drag_types, num_drag_types, GDK_ACTION_MOVE);
+
+ gtk_signal_connect (GTK_OBJECT (E_TABLE_SCROLLED(table)->table),
+ "table_drag_data_get",
+ GTK_SIGNAL_FUNC (table_drag_data_get),
+ view);
+
gtk_table_attach(GTK_TABLE(view), table,
0, 1,
0, 1,
diff --git a/addressbook/gui/widgets/e-minicard-view.c b/addressbook/gui/widgets/e-minicard-view.c
index 639e41c2c7..115aac6128 100644
--- a/addressbook/gui/widgets/e-minicard-view.c
+++ b/addressbook/gui/widgets/e-minicard-view.c
@@ -22,6 +22,8 @@
#include <config.h>
+#include <gtk/gtkselection.h>
+#include <gtk/gtkdnd.h>
#include <gal/widgets/e-canvas.h>
#include <libgnome/gnome-i18n.h>
@@ -38,6 +40,12 @@ static gboolean e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event);
static void canvas_destroy (GtkObject *object, EMinicardView *view);
static void disconnect_signals (EMinicardView *view);
static void e_minicard_view_update_selection (EMinicardView *view);
+static void e_minicard_view_drag_data_get(GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ EMinicardView *view);
static EReflowSortedClass *parent_class = NULL;
@@ -54,6 +62,15 @@ enum {
LAST_SIGNAL
};
+enum DndTargetType {
+ DND_TARGET_TYPE_VCARD,
+};
+#define VCARD_TYPE "text/x-vcard"
+static GtkTargetEntry drag_types[] = {
+ { VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD }
+};
+static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
+
static guint e_minicard_view_signals [LAST_SIGNAL] = {0, };
GtkType
@@ -153,6 +170,53 @@ e_minicard_view_init (EMinicardView *view)
E_REFLOW_SORTED(view)->string_func = (EReflowStringFunc) e_minicard_get_card_id;
}
+static void
+e_minicard_view_drag_data_get(GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ EMinicardView *view)
+{
+ printf ("e_minicard_view_drag_data_get (e_minicard = %p)\n", view->drag_card);
+
+ if (!E_IS_MINICARD_VIEW(view))
+ return;
+
+ switch (info) {
+ case DND_TARGET_TYPE_VCARD: {
+ char *value;
+
+ value = e_card_simple_get_vcard(view->drag_card->simple);
+
+ gtk_selection_data_set (selection_data,
+ selection_data->target,
+ 8,
+ value, strlen (value));
+ break;
+ }
+ }
+}
+
+static int
+e_minicard_view_drag_begin (EMinicard *card, GdkEvent *event, EMinicardView *view)
+{
+ GdkDragContext *context;
+ GtkTargetList *target_list;
+ GdkDragAction actions = GDK_ACTION_MOVE;
+
+ view->drag_card = card;
+
+ target_list = gtk_target_list_new (drag_types, num_drag_types);
+
+ context = gtk_drag_begin (GTK_WIDGET (GNOME_CANVAS_ITEM (view)->canvas),
+ target_list, actions, 1/*XXX*/, event);
+
+ gtk_drag_set_icon_default (context);
+
+ return TRUE;
+}
+
static gint
card_selected (EMinicard *card, GdkEvent *event, EMinicardView *view)
{
@@ -185,6 +249,9 @@ create_card(EBookView *book_view, const GList *cards, EMinicardView *view)
gtk_signal_connect(GTK_OBJECT(item), "selected",
GTK_SIGNAL_FUNC(card_selected), view);
+ gtk_signal_connect(GTK_OBJECT(item), "drag_begin",
+ GTK_SIGNAL_FUNC(e_minicard_view_drag_begin), view);
+
e_reflow_add_item(E_REFLOW(view), item, &position);
e_selection_model_simple_insert_rows(view->selection, position, 1);
@@ -245,6 +312,13 @@ book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, gpointe
"destroy", GTK_SIGNAL_FUNC(canvas_destroy),
view);
+ if (!view->canvas_drag_data_get_id)
+ view->canvas_drag_data_get_id =
+ gtk_signal_connect (GTK_OBJECT (GNOME_CANVAS_ITEM (view)->canvas),
+ "drag_data_get",
+ GTK_SIGNAL_FUNC (e_minicard_view_drag_data_get),
+ view);
+
view->book_view = book_view;
if (view->book_view)
gtk_object_ref(GTK_OBJECT(view->book_view));
diff --git a/addressbook/gui/widgets/e-minicard-view.h b/addressbook/gui/widgets/e-minicard-view.h
index a82dea3f6a..50a2fa00a7 100644
--- a/addressbook/gui/widgets/e-minicard-view.h
+++ b/addressbook/gui/widgets/e-minicard-view.h
@@ -21,6 +21,7 @@
#ifndef __E_MINICARD_VIEW_H__
#define __E_MINICARD_VIEW_H__
+#include "e-minicard.h"
#include <gal/widgets/e-reflow-sorted.h>
#include <gal/widgets/e-selection-model-simple.h>
#include "addressbook/backend/ebook/e-book.h"
@@ -71,9 +72,12 @@ struct _EMinicardView
ESelectionModelSimple *selection;
+ EMinicard *drag_card;
+
int get_view_idle;
int canvas_destroy_id;
+ int canvas_drag_data_get_id;
int create_card_id, remove_card_id, modify_card_id, status_message_id;
diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c
index 0a05185288..1ca1d12aad 100644
--- a/addressbook/gui/widgets/e-minicard.c
+++ b/addressbook/gui/widgets/e-minicard.c
@@ -22,6 +22,7 @@
#include <config.h>
#include <glib.h>
+#include <gtk/gtkdnd.h>
#include <gdk/gdkkeysyms.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
@@ -54,6 +55,8 @@ static void e_minicard_reflow ( GnomeCanvasItem *item, int flags );
static void e_minicard_resize_children( EMinicard *e_minicard );
static void remodel( EMinicard *e_minicard );
+static gint e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event);
+
static GnomeCanvasGroupClass *parent_class = NULL;
typedef struct _EMinicardField EMinicardField;
@@ -85,6 +88,7 @@ enum {
enum {
SELECTED,
+ DRAG_BEGIN,
LAST_SIGNAL
};
@@ -147,6 +151,14 @@ e_minicard_class_init (EMinicardClass *klass)
gtk_marshal_INT__POINTER,
GTK_TYPE_INT, 1, GTK_TYPE_POINTER);
+ e_minicard_signals [DRAG_BEGIN] =
+ gtk_signal_new ("drag_begin",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (EMinicardClass, drag_begin),
+ gtk_marshal_INT__POINTER,
+ GTK_TYPE_INT, 1, GTK_TYPE_POINTER);
+
gtk_object_class_add_signals (object_class, e_minicard_signals, LAST_SIGNAL);
object_class->set_arg = e_minicard_set_arg;
@@ -647,6 +659,9 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
if (event->button.button == 1) {
int ret_val = e_minicard_selected(e_minicard, event);
e_canvas_item_grab_focus(item, TRUE);
+ e_minicard->button_x = event->button.x;
+ e_minicard->button_y = event->button.y;
+ e_minicard->drag_button_down = TRUE;
return ret_val;
} else if (event->button.button == 3) {
MinicardAndParent *mnp = g_new(MinicardAndParent, 1);
@@ -666,7 +681,25 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
e_popup_menu_run (menu, event, 0, E_IS_MINICARD_VIEW(mnp->parent) ? 0 : 1, mnp);
}
break;
+ case GDK_BUTTON_RELEASE:
+ e_minicard->drag_button_down = FALSE;
+ break;
+ case GDK_MOTION_NOTIFY:
+ /* shamelessly ripped from e-table.c, complete with
+ broken stuck-grab behavior */
+ if (e_minicard->drag_button_down && event->motion.state & GDK_BUTTON1_MASK) {
+ if (MAX (abs (e_minicard->button_x - event->motion.x),
+ abs (e_minicard->button_y - event->motion.y)) > 3) {
+ gint ret_val = e_minicard_drag_begin(e_minicard, event);
+
+ printf ("signalled drag begin\n");
+
+ e_minicard->drag_button_down = FALSE;
+ return ret_val;
+ }
+ }
+ break;
case GDK_2BUTTON_PRESS:
if (event->button.button == 1 && E_IS_MINICARD_VIEW(item->parent)) {
if (e_minicard->editor) {
@@ -989,3 +1022,13 @@ e_minicard_selected (EMinicard *minicard, GdkEvent *event)
event, &ret_val);
return ret_val;
}
+
+static gint
+e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event)
+{
+ gint ret_val = 0;
+ gtk_signal_emit (GTK_OBJECT(minicard),
+ e_minicard_signals[DRAG_BEGIN],
+ event, &ret_val);
+ return ret_val;
+}
diff --git a/addressbook/gui/widgets/e-minicard.h b/addressbook/gui/widgets/e-minicard.h
index 3ebbe22505..3480d9d071 100644
--- a/addressbook/gui/widgets/e-minicard.h
+++ b/addressbook/gui/widgets/e-minicard.h
@@ -83,6 +83,11 @@ struct _EMinicard
guint editable : 1;
+ guint drag_button_down : 1;
+
+ gint button_x;
+ gint button_y;
+
double width;
double height;
};
@@ -92,6 +97,7 @@ struct _EMinicardClass
GnomeCanvasGroupClass parent_class;
gint (* selected) (EMinicard *minicard, GdkEvent *event);
+ gint (* drag_begin) (EMinicard *minicard, GdkEvent *event);
};