diff options
Diffstat (limited to 'addressbook/gui/widgets')
-rw-r--r-- | addressbook/gui/widgets/e-addressbook-view.c | 50 | ||||
-rw-r--r-- | addressbook/gui/widgets/e-minicard-view.c | 74 | ||||
-rw-r--r-- | addressbook/gui/widgets/e-minicard-view.h | 4 | ||||
-rw-r--r-- | addressbook/gui/widgets/e-minicard.c | 43 | ||||
-rw-r--r-- | addressbook/gui/widgets/e-minicard.h | 6 |
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); }; |