From f7120120cdd3c8bdfdc201a2bbcff847fa198d0b Mon Sep 17 00:00:00 2001 From: Christopher James Lahey Date: Fri, 24 Aug 2001 16:33:30 +0000 Subject: Added start_drag signals. 2001-08-24 Christopher James Lahey * e-table-group-container.c, e-table-group-leaf.c, e-table-group-leaf.h, e-table-group.c, e-table-group.h: Added start_drag signals. * e-table-item.c, e-table-item.h (eti_event): Send the start_drag signal. Fixes Ximian bug #807. * e-table.c, e-table.h, e-tree.c, e-tree.h: Added start_drag signal. Made default handler start drag & drop if we're set to automatically handle dnd. Ripped out the code to handle watching events for dnd since start_drag does this now. svn path=/trunk/; revision=12437 --- widgets/table/e-table-group-container.c | 9 ++ widgets/table/e-table-group-leaf.c | 28 +++-- widgets/table/e-table-group-leaf.h | 1 + widgets/table/e-table-group.c | 34 ++++++ widgets/table/e-table-group.h | 5 + widgets/table/e-table-item.c | 117 ++++++++++++++---- widgets/table/e-table-item.h | 21 +++- widgets/table/e-table.c | 159 ++++++++++--------------- widgets/table/e-table.h | 6 +- widgets/table/e-tree.c | 203 ++++++++++++++------------------ widgets/table/e-tree.h | 1 + 11 files changed, 329 insertions(+), 255 deletions(-) (limited to 'widgets') diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c index 034c5625b8..ce10fbf9a8 100644 --- a/widgets/table/e-table-group-container.c +++ b/widgets/table/e-table-group-container.c @@ -393,6 +393,13 @@ child_key_press (ETableGroup *etg, int row, int col, GdkEvent *event, return e_table_group_key_press (E_TABLE_GROUP (etgc), row, col, event); } +static gint +child_start_drag (ETableGroup *etg, int row, int col, GdkEvent *event, + ETableGroupContainer *etgc) +{ + return e_table_group_start_drag (E_TABLE_GROUP (etgc), row, col, event); +} + static ETableGroupContainerChildNode * create_child_node (ETableGroupContainer *etgc, void *val) { @@ -438,6 +445,8 @@ create_child_node (ETableGroupContainer *etgc, void *val) GTK_SIGNAL_FUNC (child_click), etgc); gtk_signal_connect (GTK_OBJECT (child), "key_press", GTK_SIGNAL_FUNC (child_key_press), etgc); + gtk_signal_connect (GTK_OBJECT (child), "start_drag", + GTK_SIGNAL_FUNC (child_start_drag), etgc); child_node->child = child; child_node->key = e_table_model_duplicate_value (etg->model, etgc->ecol->col_idx, val); child_node->string = e_table_model_value_to_string (etg->model, etgc->ecol->col_idx, val); diff --git a/widgets/table/e-table-group-leaf.c b/widgets/table/e-table-group-leaf.c index 440b7562e1..e4c46747dd 100644 --- a/widgets/table/e-table-group-leaf.c +++ b/widgets/table/e-table-group-leaf.c @@ -66,6 +66,9 @@ etgl_destroy (GtkObject *object) if (etgl->etgl_key_press_id != 0) gtk_signal_disconnect (GTK_OBJECT (etgl->item), etgl->etgl_key_press_id); + if (etgl->etgl_start_drag_id != 0) + gtk_signal_disconnect (GTK_OBJECT (etgl->item), + etgl->etgl_start_drag_id); gtk_object_destroy (GTK_OBJECT(etgl->item)); etgl->etgl_cursor_change_id = 0; @@ -74,6 +77,7 @@ etgl_destroy (GtkObject *object) etgl->etgl_right_click_id = 0; etgl->etgl_click_id = 0; etgl->etgl_key_press_id = 0; + etgl->etgl_start_drag_id = 0; etgl->item = NULL; } if (etgl->selection_model) @@ -139,16 +143,16 @@ etgl_cursor_change (GtkObject *object, gint row, ETableGroupLeaf *etgl) } static void -etgl_cursor_activated (GtkObject *object, gint row, ETableGroupLeaf *etgl) +etgl_cursor_activated (GtkObject *object, gint view_row, ETableGroupLeaf *etgl) { - if (row < E_TABLE_SUBSET(etgl->ets)->n_map) - e_table_group_cursor_activated (E_TABLE_GROUP(etgl), E_TABLE_SUBSET(etgl->ets)->map_table[row]); + if (view_row < E_TABLE_SUBSET(etgl->ets)->n_map) + e_table_group_cursor_activated (E_TABLE_GROUP(etgl), E_TABLE_SUBSET(etgl->ets)->map_table[view_row]); } static void -etgl_double_click (GtkObject *object, gint row, gint col, GdkEvent *event, ETableGroupLeaf *etgl) +etgl_double_click (GtkObject *object, gint model_row, gint model_col, GdkEvent *event, ETableGroupLeaf *etgl) { - e_table_group_double_click (E_TABLE_GROUP(etgl), row, col, event); + e_table_group_double_click (E_TABLE_GROUP(etgl), model_row, model_col, event); } static gint @@ -161,10 +165,16 @@ etgl_key_press (GtkObject *object, gint row, gint col, GdkEvent *event, ETableGr } static gint -etgl_right_click (GtkObject *object, gint row, gint col, GdkEvent *event, ETableGroupLeaf *etgl) +etgl_start_drag (GtkObject *object, gint model_row, gint model_col, GdkEvent *event, ETableGroupLeaf *etgl) { - if (row < E_TABLE_SUBSET(etgl->ets)->n_map) - return e_table_group_right_click (E_TABLE_GROUP(etgl), E_TABLE_SUBSET(etgl->ets)->map_table[row], col, event); + return e_table_group_start_drag (E_TABLE_GROUP(etgl), model_row, model_col, event); +} + +static gint +etgl_right_click (GtkObject *object, gint view_row, gint model_col, GdkEvent *event, ETableGroupLeaf *etgl) +{ + if (view_row < E_TABLE_SUBSET(etgl->ets)->n_map) + return e_table_group_right_click (E_TABLE_GROUP(etgl), E_TABLE_SUBSET(etgl->ets)->map_table[view_row], model_col, event); else return 0; } @@ -219,6 +229,7 @@ etgl_realize (GnomeCanvasItem *item) etgl->etgl_right_click_id = gtk_signal_connect (GTK_OBJECT(etgl->item), "right_click", GTK_SIGNAL_FUNC(etgl_right_click), etgl); etgl->etgl_click_id = gtk_signal_connect (GTK_OBJECT(etgl->item), "click", GTK_SIGNAL_FUNC(etgl_click), etgl); etgl->etgl_key_press_id = gtk_signal_connect (GTK_OBJECT(etgl->item), "key_press", GTK_SIGNAL_FUNC(etgl_key_press), etgl); + etgl->etgl_start_drag_id = gtk_signal_connect (GTK_OBJECT(etgl->item), "start_drag", GTK_SIGNAL_FUNC(etgl_start_drag), etgl); e_canvas_item_request_reflow(item); } @@ -511,6 +522,7 @@ etgl_init (GtkObject *object) etgl->etgl_right_click_id = 0; etgl->etgl_click_id = 0; etgl->etgl_key_press_id = 0; + etgl->etgl_start_drag_id = 0; etgl->alternating_row_colors = 1; etgl->horizontal_draw_grid = 1; diff --git a/widgets/table/e-table-group-leaf.h b/widgets/table/e-table-group-leaf.h index d6c0406a60..e7ba841493 100644 --- a/widgets/table/e-table-group-leaf.h +++ b/widgets/table/e-table-group-leaf.h @@ -44,6 +44,7 @@ typedef struct { int etgl_right_click_id; int etgl_click_id; int etgl_key_press_id; + int etgl_start_drag_id; ESelectionModel *selection_model; } ETableGroupLeaf; diff --git a/widgets/table/e-table-group.c b/widgets/table/e-table-group.c index c31be579d4..d9174452be 100644 --- a/widgets/table/e-table-group.c +++ b/widgets/table/e-table-group.c @@ -31,6 +31,7 @@ enum { RIGHT_CLICK, CLICK, KEY_PRESS, + START_DRAG, LAST_SIGNAL }; @@ -524,6 +525,30 @@ e_table_group_key_press (ETableGroup *e_table_group, gint row, gint col, GdkEven return return_val; } +/** + * e_table_group_start_drag + * @eti: %ETableGroup to emit the signal on + * @row: The cursor row (model row) + * @col: The cursor col (model col) + * @event: The event that caused this signal + * + * This routine emits the "start_drag" signal. + */ +gint +e_table_group_start_drag (ETableGroup *e_table_group, gint row, gint col, GdkEvent *event) +{ + gint return_val = 0; + + g_return_val_if_fail (e_table_group != NULL, 0); + g_return_val_if_fail (E_IS_TABLE_GROUP (e_table_group), 0); + + gtk_signal_emit (GTK_OBJECT (e_table_group), + etg_signals [START_DRAG], + row, col, event, &return_val); + + return return_val; +} + /** * e_table_group_get_header * @eti: %ETableGroup to check @@ -586,6 +611,7 @@ etg_class_init (GtkObjectClass *object_class) klass->right_click = NULL; klass->click = NULL; klass->key_press = NULL; + klass->start_drag = NULL; klass->add = NULL; klass->add_array = NULL; @@ -650,6 +676,14 @@ etg_class_init (GtkObjectClass *object_class) e_marshal_INT__INT_INT_POINTER, GTK_TYPE_INT, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); + etg_signals [START_DRAG] = + gtk_signal_new ("start_drag", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableGroupClass, start_drag), + e_marshal_INT__INT_INT_POINTER, + GTK_TYPE_INT, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); + gtk_object_class_add_signals (object_class, etg_signals, LAST_SIGNAL); } diff --git a/widgets/table/e-table-group.h b/widgets/table/e-table-group.h index 18866b7ad5..3e7e842894 100644 --- a/widgets/table/e-table-group.h +++ b/widgets/table/e-table-group.h @@ -53,6 +53,7 @@ typedef struct { gint (*right_click) (ETableGroup *etg, int row, int col, GdkEvent *event); gint (*click) (ETableGroup *etg, int row, int col, GdkEvent *event); gint (*key_press) (ETableGroup *etg, int row, int col, GdkEvent *event); + gint (*start_drag) (ETableGroup *etg, int row, int col, GdkEvent *event); /* Virtual functions. */ void (*add) (ETableGroup *etg, gint row); @@ -139,6 +140,10 @@ gint e_table_group_key_press (ETableGroup *etg, gint row, gint col, GdkEvent *event); +gint e_table_group_start_drag (ETableGroup *etg, + gint row, + gint col, + GdkEvent *event); GtkType e_table_group_get_type (void); typedef void (*ETableGroupLeafFn) (void *e_table_item, void *closure); diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c index bd6863fbbf..4132eaf969 100644 --- a/widgets/table/e-table-item.c +++ b/widgets/table/e-table-item.c @@ -49,6 +49,7 @@ enum { RIGHT_CLICK, CLICK, KEY_PRESS, + START_DRAG, LAST_SIGNAL }; @@ -1173,7 +1174,7 @@ eti_init (GnomeCanvasItem *item) eti->selection_change_id = 0; eti->cursor_change_id = 0; - eti->cursor_activated_id = 0; + eti->cursor_activated_id = 0; eti->selection = NULL; eti->needs_redraw = 0; @@ -1190,6 +1191,10 @@ eti_init (GnomeCanvasItem *item) eti->grabbed_col = -1; eti->grabbed_row = -1; + eti->in_drag = 0; + eti->maybe_in_drag = 0; + eti->grabbed = 0; + e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (eti), eti_reflow); } @@ -1702,9 +1707,11 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) switch (e->type){ case GDK_BUTTON_PRESS: { double x1, y1; + double realx, realy; GdkEventButton button; int col, row; gint cursor_row, cursor_col; + gint new_cursor_row, new_cursor_col; if (eti->tooltip->timer) { gtk_timeout_remove (eti->tooltip->timer); @@ -1717,7 +1724,10 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) e_canvas_item_grab_focus(GNOME_CANVAS_ITEM(eti), TRUE); gnome_canvas_item_w2i (item, &e->button.x, &e->button.y); - if (!find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1)) { + realx = e->button.x; + realy = e->button.y; + + if (!find_cell (eti, realx, realy, &col, &row, &x1, &y1)) { if (eti_editing (eti)) e_table_item_leave_edit (eti); return TRUE; @@ -1746,19 +1756,15 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) "cursor_col", &cursor_col, NULL); - if (cursor_row != view_to_model_row(eti, row) || cursor_col != view_to_model_col(eti, col)) { - eti->click_count = 0; - } - - e_selection_model_do_something(E_SELECTION_MODEL (eti->selection), view_to_model_row(eti, row), view_to_model_col(eti, col), button.state); - + e_selection_model_maybe_do_something(E_SELECTION_MODEL (eti->selection), view_to_model_row(eti, row), view_to_model_col(eti, col), button.state); gtk_object_get(GTK_OBJECT(eti->selection), - "cursor_row", &cursor_row, - "cursor_col", &cursor_col, + "cursor_row", &new_cursor_row, + "cursor_col", &new_cursor_col, NULL); - if (cursor_row == view_to_model_row(eti, row) && cursor_col == view_to_model_col(eti, col)){ - + if (cursor_row != new_cursor_row || cursor_col != new_cursor_col) { + eti->click_count = 1; + } else { eti->click_count ++; eti->row_guess = row; @@ -1770,9 +1776,28 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) * Adjust the event positions */ - return_val = eti_e_cell_event (eti, ecell_view, (GdkEvent *) &button, button.time, - view_to_model_col(eti, col), col, row, E_CELL_EDITING); + if (eti_editing (eti)) { + return_val = eti_e_cell_event (eti, ecell_view, (GdkEvent *) &button, button.time, + view_to_model_col(eti, col), col, row, E_CELL_EDITING); + if (return_val) + return TRUE; + } } + + if (e->button.button == 1) { + eti->maybe_in_drag = TRUE; + eti->drag_row = new_cursor_row; + eti->drag_col = new_cursor_col; + eti->drag_x = realx; + eti->drag_y = realy; + eti->drag_state = e->button.state; + eti->grabbed = TRUE; + if (!gnome_canvas_item_grab(item, + (1 << (4 + e->button.button)) | GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, + NULL, e->button.time)) + gtk_grab_add (GTK_WIDGET (item->canvas)); + } + d(g_print("Single click\n")); break; @@ -1783,7 +1808,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) return TRUE; e_selection_model_maybe_do_something(E_SELECTION_MODEL (eti->selection), view_to_model_row(eti, row), view_to_model_col(eti, col), 0); - + gtk_signal_emit (GTK_OBJECT (eti), eti_signals [RIGHT_CLICK], row, view_to_model_col(eti, col), e, &return_val); break; @@ -1801,6 +1826,21 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) int col, row; gint cursor_row, cursor_col; + if (e->button.button == 1) { + if (eti->maybe_in_drag) { + eti->maybe_in_drag = FALSE; + e_selection_model_do_something(E_SELECTION_MODEL (eti->selection), eti->drag_row, eti->drag_col, eti->drag_state); + } + if (eti->in_drag) { + eti->in_drag = FALSE; + } + if (eti->grabbed) { + gtk_grab_remove (GTK_WIDGET (item->canvas)); + gnome_canvas_item_ungrab(item, e->button.time); + } + eti->grabbed = FALSE; + } + if (eti->tooltip->timer) { gtk_timeout_remove (eti->tooltip->timer); eti->tooltip->timer = 0; @@ -1809,6 +1849,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) switch (e->button.button) { case 1: /* Fall through. */ case 2: + gnome_canvas_item_w2i (item, &e->button.x, &e->button.y); if (!find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1)) @@ -1819,7 +1860,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) "cursor_col", &cursor_col, NULL); - if (cursor_row == view_to_model_row(eti, row) && cursor_col == view_to_model_col(eti, col)){ + if (eti_editing (eti) && cursor_row == view_to_model_row(eti, row) && cursor_col == view_to_model_col(eti, col)){ ecell_view = eti->cell_views [col]; @@ -1845,7 +1886,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) } case GDK_2BUTTON_PRESS: { - int col, row; + int model_col, model_row; #if 0 double x1, y1; #endif @@ -1870,12 +1911,12 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) #endif gtk_object_get(GTK_OBJECT(eti->selection), - "cursor_row", &row, - "cursor_col", &col, + "cursor_row", &model_row, + "cursor_col", &model_col, NULL); - button.x -= e_table_header_col_diff (eti->header, 0, model_to_view_col (eti, col)); - button.y -= e_table_item_row_diff (eti, 0, model_to_view_row (eti, row)); + button.x -= e_table_header_col_diff (eti->header, 0, model_to_view_col (eti, model_col)); + button.y -= e_table_item_row_diff (eti, 0, model_to_view_row (eti, model_row)); #if 0 button = *(GdkEventButton *)e; @@ -1883,9 +1924,9 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) button.y = y1; #endif - if (row != -1 && col != -1) { + if (model_row != -1 && model_col != -1) { gtk_signal_emit (GTK_OBJECT (eti), eti_signals [DOUBLE_CLICK], - row, col, &button); + model_row, model_col, &button); d(g_print("Double click\n")); } } @@ -1898,6 +1939,21 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) gnome_canvas_item_w2i (item, &e->motion.x, &e->motion.y); + if (eti->maybe_in_drag) { + if (abs (e->motion.x - eti->drag_x) >= 3 || + abs (e->motion.y - eti->drag_y) >= 3) { + gint drag_handled; + + eti->maybe_in_drag = 0; + gtk_signal_emit (GTK_OBJECT (eti), eti_signals [START_DRAG], + eti->drag_row, eti->drag_col, e, &drag_handled); + if (drag_handled) + eti->in_drag = 1; + else + eti->in_drag = 0; + } + } + if (!find_cell (eti, e->motion.x, e->motion.y, &col, &row, &x1, &y1)) return TRUE; @@ -1928,13 +1984,13 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) */ e->motion.x = x1; e->motion.y = y1; - + return_val = eti_e_cell_event (eti, ecell_view, e, e->motion.time, view_to_model_col(eti, col), col, row, E_CELL_EDITING); } break; } - + case GDK_KEY_PRESS: { gint cursor_row, cursor_col; gint handled = TRUE; @@ -2153,7 +2209,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e) return_val = FALSE; } return return_val; -} + } static void eti_class_init (GtkObjectClass *object_class) @@ -2180,6 +2236,7 @@ eti_class_init (GtkObjectClass *object_class) eti_class->right_click = NULL; eti_class->click = NULL; eti_class->key_press = NULL; + eti_class->start_drag = NULL; gtk_object_add_arg_type ("ETableItem::ETableHeader", E_TABLE_HEADER_TYPE, GTK_ARG_WRITABLE, ARG_TABLE_HEADER); @@ -2233,6 +2290,14 @@ eti_class_init (GtkObjectClass *object_class) gtk_marshal_NONE__INT_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); + eti_signals [START_DRAG] = + gtk_signal_new ("start_drag", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableItemClass, start_drag), + e_marshal_INT__INT_INT_POINTER, + GTK_TYPE_INT, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); + eti_signals [RIGHT_CLICK] = gtk_signal_new ("right_click", GTK_RUN_LAST, diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h index 87394dc26d..efa55482ac 100644 --- a/widgets/table/e-table-item.h +++ b/widgets/table/e-table-item.h @@ -70,6 +70,16 @@ typedef struct { guint in_key_press : 1; + guint maybe_in_drag : 1; + guint in_drag : 1; + guint grabbed : 1; + + int drag_col; + int drag_row; + int drag_x; + int drag_y; + guint drag_state; + /* * Realized views, per column */ @@ -107,12 +117,13 @@ typedef struct { typedef struct { GnomeCanvasItemClass parent_class; - void (*cursor_change) (ETableItem *eti, int row); + void (*cursor_change) (ETableItem *eti, int row); void (*cursor_activated) (ETableItem *eti, int row); - void (*double_click) (ETableItem *eti, int row, int col, GdkEvent *event); - gint (*right_click) (ETableItem *eti, int row, int col, GdkEvent *event); - gint (*click) (ETableItem *eti, int row, int col, GdkEvent *event); - gint (*key_press) (ETableItem *eti, int row, int col, GdkEvent *event); + void (*double_click) (ETableItem *eti, int row, int col, GdkEvent *event); + gint (*right_click) (ETableItem *eti, int row, int col, GdkEvent *event); + gint (*click) (ETableItem *eti, int row, int col, GdkEvent *event); + gint (*key_press) (ETableItem *eti, int row, int col, GdkEvent *event); + gint (*start_drag) (ETableItem *eti, int row, int col, GdkEvent *event); } ETableItemClass; GtkType e_table_item_get_type (void); diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c index d97936406c..a4e17d9571 100644 --- a/widgets/table/e-table.c +++ b/widgets/table/e-table.c @@ -51,6 +51,7 @@ enum { RIGHT_CLICK, CLICK, KEY_PRESS, + START_DRAG, TABLE_DRAG_BEGIN, TABLE_DRAG_END, @@ -118,9 +119,6 @@ static void et_drag_data_received(GtkWidget *widget, guint info, guint time, ETable *et); -static gint e_table_drag_source_event_cb (GtkWidget *widget, - GdkEvent *event, - ETable *table); static gint et_focus (GtkContainer *container, GtkDirectionType direction); @@ -234,8 +232,8 @@ e_table_init (GtkObject *object) e_table->drop_row = -1; e_table->drop_col = -1; e_table->site = NULL; - e_table->drag_source_button_press_event_id = 0; - e_table->drag_source_motion_notify_event_id = 0; + + e_tasble->do_drag = 0; e_table->sorter = NULL; e_table->selection = e_table_selection_model_new(); @@ -525,6 +523,16 @@ group_key_press (ETableGroup *etg, int row, int col, GdkEvent *event, ETable *et return return_val; } +static gint +group_start_drag (ETableGroup *etg, int row, int col, GdkEvent *event, ETable *et) +{ + int return_val = 0; + gtk_signal_emit (GTK_OBJECT (et), + et_signals [KEY_PRESS], + row, col, event, &return_val); + return return_val; +} + static void et_table_model_changed (ETableModel *model, ETable *et) { @@ -625,6 +633,8 @@ et_build_groups (ETable *et) GTK_SIGNAL_FUNC (group_click), et); gtk_signal_connect (GTK_OBJECT (et->group), "key_press", GTK_SIGNAL_FUNC (group_key_press), et); + gtk_signal_connect (GTK_OBJECT (et->group), "start_drag", + GTK_SIGNAL_FUNC (group_start_drag), et); if (!(et->is_grouped) && was_grouped) @@ -1779,6 +1789,40 @@ e_table_drag_dest_unset (GtkWidget *widget) /* Source side */ +static gint +et_real_start_drag (ETable *table, int row, int col, GdkEvent *event) +{ + GtkDragSourceInfo *info; + GdkDragContext *context; + ETableDragSourceSite *site; + + if (table->do_drag) { + site = table->site; + + site->state = 0; + context = e_table_drag_begin (table, row, col, + site->target_list, + site->actions, + 1, event); + + if (context) { + info = g_dataset_get_data (context, "gtk-info"); + + if (info && !info->icon_window) { + if (site->pixmap) + gtk_drag_set_icon_pixmap (context, + site->colormap, + site->pixmap, + site->mask, -2, -2); + else + gtk_drag_set_icon_default (context); + } + } + return TRUE; + } + return FALSE; +} + void e_table_drag_source_set (ETable *table, GdkModifierType start_button_mask, @@ -1800,21 +1844,13 @@ e_table_drag_source_set (ETable *table, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK | GDK_STRUCTURE_MASK); + table->do_drag = TRUE; + if (site) { if (site->target_list) gtk_target_list_unref (site->target_list); } else { site = g_new0 (ETableDragSourceSite, 1); - - table->drag_source_button_press_event_id = - gtk_signal_connect (GTK_OBJECT (canvas), "button_press_event", - GTK_SIGNAL_FUNC (e_table_drag_source_event_cb), - table); - table->drag_source_motion_notify_event_id = - gtk_signal_connect (GTK_OBJECT (canvas), "motion_notify_event", - GTK_SIGNAL_FUNC (e_table_drag_source_event_cb), - table); - table->site = site; } @@ -1839,15 +1875,10 @@ e_table_drag_source_unset (ETable *table) site = table->site; if (site) { - gtk_signal_disconnect ( - GTK_OBJECT (table->table_canvas), - table->drag_source_button_press_event_id); - gtk_signal_disconnect ( - GTK_OBJECT (table->table_canvas), - table->drag_source_motion_notify_event_id); g_free (site); table->site = NULL; } + table->do_drag = FALSE; } /* There probably should be functions for setting the targets @@ -2157,81 +2188,6 @@ et_drag_data_received(GtkWidget *widget, time); } -static gint -e_table_drag_source_event_cb (GtkWidget *widget, - GdkEvent *event, - ETable *table) -{ - ETableDragSourceSite *site; - site = table->site; - - switch (event->type) { - case GDK_BUTTON_PRESS: - if ((GDK_BUTTON1_MASK << (event->button.button - 1)) & site->start_button_mask) { - int row, col; - e_table_get_cell_at (table, event->button.x, event->button.y, &row, &col); - if (row >= 0 && col >= 0) { - site->state |= (GDK_BUTTON1_MASK << (event->button.button - 1)); - site->x = event->button.x; - site->y = event->button.y; - site->row = row; - site->col = col; - } - } - break; - - case GDK_BUTTON_RELEASE: - if ((GDK_BUTTON1_MASK << (event->button.button - 1)) & site->start_button_mask) { - site->state &= ~(GDK_BUTTON1_MASK << (event->button.button - 1)); - } - break; - - case GDK_MOTION_NOTIFY: - if (site->state & event->motion.state & site->start_button_mask) { - /* FIXME: This is really broken and can leave us - * with a stuck grab - */ - int i; - for (i=1; i<6; i++) { - if (site->state & event->motion.state & - GDK_BUTTON1_MASK << (i - 1)) - break; - } - - if (MAX (abs (site->x - event->motion.x), - abs (site->y - event->motion.y)) > 3) { - GtkDragSourceInfo *info; - GdkDragContext *context; - - site->state = 0; - context = e_table_drag_begin (table, site->row, site->col, - site->target_list, - site->actions, - i, event); - - info = g_dataset_get_data (context, "gtk-info"); - - if (!info->icon_window) { - if (site->pixmap) - gtk_drag_set_icon_pixmap (context, - site->colormap, - site->pixmap, - site->mask, -2, -2); - else - gtk_drag_set_icon_default (context); - } - - return TRUE; - } - } - break; - - default: /* hit for 2/3BUTTON_PRESS */ - break; - } - return FALSE; -} - static void e_table_class_init (ETableClass *class) { @@ -2254,12 +2210,13 @@ e_table_class_init (ETableClass *class) container_class->focus = et_focus; class->cursor_change = NULL; - class->cursor_activated = NULL; + class->cursor_activated = NULL; class->selection_change = NULL; class->double_click = NULL; class->right_click = NULL; class->click = NULL; class->key_press = NULL; + class->start_drag = et_real_start_drag; class->table_drag_begin = NULL; class->table_drag_end = NULL; @@ -2327,6 +2284,14 @@ e_table_class_init (ETableClass *class) e_marshal_INT__INT_INT_POINTER, GTK_TYPE_INT, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); + et_signals [START_DRAG] = + gtk_signal_new ("start_drag", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETableClass, start_drag), + e_marshal_INT__INT_INT_POINTER, + GTK_TYPE_INT, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); + et_signals[TABLE_DRAG_BEGIN] = gtk_signal_new ("table_drag_begin", GTK_RUN_LAST, diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h index b5b9dd5f0a..e2550d1392 100644 --- a/widgets/table/e-table.h +++ b/widgets/table/e-table.h @@ -85,6 +85,8 @@ typedef struct { guint is_grouped : 1; guint scroll_down : 1; + + guint do_drag : 1; char *click_to_add_message; GnomeCanvasItem *click_to_add; @@ -107,9 +109,6 @@ typedef struct { int drag_row; int drag_col; ETableDragSourceSite *site; - - int drag_source_button_press_event_id; - int drag_source_motion_notify_event_id; } ETable; typedef struct { @@ -122,6 +121,7 @@ typedef struct { gint (*right_click) (ETable *et, int row, int col, GdkEvent *event); gint (*click) (ETable *et, int row, int col, GdkEvent *event); gint (*key_press) (ETable *et, int row, int col, GdkEvent *event); + gint (*start_drag) (ETable *et, int row, int col, GdkEvent *event); void (*set_scroll_adjustments) (ETable *table, GtkAdjustment *hadjustment, diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c index 1789b0d90a..568574f98f 100644 --- a/widgets/table/e-tree.c +++ b/widgets/table/e-tree.c @@ -53,6 +53,7 @@ enum { RIGHT_CLICK, CLICK, KEY_PRESS, + START_DRAG, TREE_DRAG_BEGIN, TREE_DRAG_END, @@ -121,6 +122,8 @@ struct ETreePriv { guint scroll_down : 1; + guint do_drag : 1; + ECursorMode cursor_mode; int drop_row; @@ -140,9 +143,6 @@ struct ETreePriv { ETreePath drag_path; int drag_col; ETreeDragSourceSite *site; - - int drag_source_button_press_event_id; - int drag_source_motion_notify_event_id; }; static gint et_signals [LAST_SIGNAL] = { 0, }; @@ -189,9 +189,6 @@ static void et_drag_data_received(GtkWidget *widget, guint info, guint time, ETree *et); -static gint e_tree_drag_source_event_cb (GtkWidget *widget, - GdkEvent *event, - ETree *tree); static gint et_focus (GtkContainer *container, GtkDirectionType direction); @@ -320,8 +317,7 @@ e_tree_init (GtkObject *object) e_tree->priv->drag_col = -1; e_tree->priv->site = NULL; - e_tree->priv->drag_source_button_press_event_id = 0; - e_tree->priv->drag_source_motion_notify_event_id = 0; + e_tree->priv->do_drag = FALSE; #ifdef E_TREE_USE_TREE_SELECTION e_tree->priv->selection = E_SELECTION_MODEL(e_tree_selection_model_new()); @@ -619,6 +615,22 @@ item_key_press (ETableItem *eti, int row, int col, GdkEvent *event, ETree *et) return return_val; } +static gint +item_start_drag (ETableItem *eti, int row, int col, GdkEvent *event, ETree *et) +{ + ETreePath path; + gint return_val = 0; + + path = e_tree_table_adapter_node_at_row(et->priv->etta, row); + path = e_tree_sorted_view_to_model_path(et->priv->sorted, path); + + gtk_signal_emit (GTK_OBJECT (et), + et_signals [START_DRAG], + row, path, col, event, &return_val); + + return return_val; +} + static void et_selection_model_selection_change (ETableSelectionModel *etsm, ETable *et) { @@ -654,6 +666,8 @@ et_build_item (ETree *et) GTK_SIGNAL_FUNC (item_click), et); gtk_signal_connect (GTK_OBJECT (et->priv->item), "key_press", GTK_SIGNAL_FUNC (item_key_press), et); + gtk_signal_connect (GTK_OBJECT (et->priv->item), "start_drag", + GTK_SIGNAL_FUNC (item_start_drag), et); } static void @@ -1610,6 +1624,7 @@ struct _GtkDragSourceInfo /* Drag & drop stuff. */ /* Target */ + void e_tree_drag_get_data (ETree *tree, int row, @@ -1712,6 +1727,8 @@ e_tree_drag_unhighlight (ETree *tree) g_return_if_fail(tree != NULL); g_return_if_fail(E_IS_TREE(tree)); + g_print ("Unhighlight requested\n"); + if (tree->priv->drop_highlight) { gtk_object_destroy (GTK_OBJECT (tree->priv->drop_highlight)); tree->priv->drop_highlight = NULL; @@ -1764,6 +1781,40 @@ e_tree_drag_dest_unset (GtkWidget *widget) /* Source side */ +static gint +et_real_start_drag (ETree *tree, int row, ETreePath path, int col, GdkEvent *event) +{ + GtkDragSourceInfo *info; + GdkDragContext *context; + ETreeDragSourceSite *site; + + if (tree->priv->do_drag) { + site = tree->priv->site; + + site->state = 0; + context = e_tree_drag_begin (tree, row, col, + site->target_list, + site->actions, + 1, event); + + if (context) { + info = g_dataset_get_data (context, "gtk-info"); + + if (info && !info->icon_window) { + if (site->pixmap) + gtk_drag_set_icon_pixmap (context, + site->colormap, + site->pixmap, + site->mask, -2, -2); + else + gtk_drag_set_icon_default (context); + } + } + return TRUE; + } + return FALSE; +} + void e_tree_drag_source_set (ETree *tree, GdkModifierType start_button_mask, @@ -1780,6 +1831,8 @@ e_tree_drag_source_set (ETree *tree, canvas = GTK_WIDGET(tree->priv->table_canvas); site = tree->priv->site; + tree->priv->do_drag = TRUE; + gtk_widget_add_events (canvas, gtk_widget_get_events (canvas) | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -1790,16 +1843,6 @@ e_tree_drag_source_set (ETree *tree, gtk_target_list_unref (site->target_list); } else { site = g_new0 (ETreeDragSourceSite, 1); - - tree->priv->drag_source_button_press_event_id = - gtk_signal_connect (GTK_OBJECT (canvas), "button_press_event", - GTK_SIGNAL_FUNC (e_tree_drag_source_event_cb), - tree); - tree->priv->drag_source_motion_notify_event_id = - gtk_signal_connect (GTK_OBJECT (canvas), "motion_notify_event", - GTK_SIGNAL_FUNC (e_tree_drag_source_event_cb), - tree); - tree->priv->site = site; } @@ -1824,12 +1867,6 @@ e_tree_drag_source_unset (ETree *tree) site = tree->priv->site; if (site) { - gtk_signal_disconnect ( - GTK_OBJECT (tree->priv->table_canvas), - tree->priv->drag_source_button_press_event_id); - gtk_signal_disconnect ( - GTK_OBJECT (tree->priv->table_canvas), - tree->priv->drag_source_motion_notify_event_id); g_free (site); tree->priv->site = NULL; } @@ -1859,7 +1896,7 @@ e_tree_drag_begin (ETree *tree, tree->priv->drag_path = path; tree->priv->drag_col = col; - return gtk_drag_begin(GTK_WIDGET(tree), + return gtk_drag_begin(GTK_WIDGET (tree->priv->table_canvas), targets, actions, button, @@ -2298,81 +2335,6 @@ et_drag_data_received(GtkWidget *widget, time); } -static gint -e_tree_drag_source_event_cb (GtkWidget *widget, - GdkEvent *event, - ETree *tree) -{ - ETreeDragSourceSite *site; - site = tree->priv->site; - - switch (event->type) { - case GDK_BUTTON_PRESS: - if ((GDK_BUTTON1_MASK << (event->button.button - 1)) & site->start_button_mask) { - int row, col; - e_tree_get_cell_at(tree, event->button.x, event->button.y, &row, &col); - if (row >= 0 && col >= 0) { - site->state |= (GDK_BUTTON1_MASK << (event->button.button - 1)); - site->x = event->button.x; - site->y = event->button.y; - site->row = row; - site->col = col; - } - } - break; - - case GDK_BUTTON_RELEASE: - if ((GDK_BUTTON1_MASK << (event->button.button - 1)) & site->start_button_mask) { - site->state &= ~(GDK_BUTTON1_MASK << (event->button.button - 1)); - } - break; - - case GDK_MOTION_NOTIFY: - if (site->state & event->motion.state & site->start_button_mask) { - /* FIXME: This is really broken and can leave us - * with a stuck grab - */ - int i; - for (i=1; i<6; i++) { - if (site->state & event->motion.state & - GDK_BUTTON1_MASK << (i - 1)) - break; - } - - if (MAX (abs (site->x - event->motion.x), - abs (site->y - event->motion.y)) > 3) { - GtkDragSourceInfo *info; - GdkDragContext *context; - - site->state = 0; - context = e_tree_drag_begin (tree, site->row, site->col, - site->target_list, - site->actions, - i, event); - - info = g_dataset_get_data (context, "gtk-info"); - - if (!info->icon_window) { - if (site->pixmap) - gtk_drag_set_icon_pixmap (context, - site->colormap, - site->pixmap, - site->mask, -2, -2); - else - gtk_drag_set_icon_default (context); - } - - return TRUE; - } - } - break; - - default: /* hit for 2/3BUTTON_PRESS */ - break; - } - return FALSE; -} - static void e_tree_class_init (ETreeClass *class) { @@ -2380,27 +2342,28 @@ e_tree_class_init (ETreeClass *class) GtkWidgetClass *widget_class; GtkContainerClass *container_class; - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - container_class = (GtkContainerClass *) class; + object_class = (GtkObjectClass *) class; + widget_class = (GtkWidgetClass *) class; + container_class = (GtkContainerClass *) class; - parent_class = gtk_type_class (PARENT_TYPE); + parent_class = gtk_type_class (PARENT_TYPE); - object_class->destroy = et_destroy; - object_class->set_arg = et_set_arg; - object_class->get_arg = et_get_arg; + object_class->destroy = et_destroy; + object_class->set_arg = et_set_arg; + object_class->get_arg = et_get_arg; - widget_class->grab_focus = et_grab_focus; + widget_class->grab_focus = et_grab_focus; - container_class->focus = et_focus; + container_class->focus = et_focus; - class->cursor_change = NULL; - class->cursor_activated = NULL; - class->selection_change = NULL; - class->double_click = NULL; - class->right_click = NULL; - class->click = NULL; - class->key_press = NULL; + class->cursor_change = NULL; + class->cursor_activated = NULL; + class->selection_change = NULL; + class->double_click = NULL; + class->right_click = NULL; + class->click = NULL; + class->key_press = NULL; + class->start_drag = et_real_start_drag; class->tree_drag_begin = NULL; class->tree_drag_end = NULL; @@ -2468,6 +2431,14 @@ e_tree_class_init (ETreeClass *class) e_marshal_INT__INT_POINTER_INT_POINTER, GTK_TYPE_INT, 4, GTK_TYPE_INT, GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); + et_signals [START_DRAG] = + gtk_signal_new ("start_drag", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETreeClass, start_drag), + e_marshal_NONE__INT_POINTER_INT_POINTER, + GTK_TYPE_NONE, 4, GTK_TYPE_INT, GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); + et_signals[TREE_DRAG_BEGIN] = gtk_signal_new ("tree_drag_begin", GTK_RUN_LAST, diff --git a/widgets/table/e-tree.h b/widgets/table/e-tree.h index 8034d43c95..46481a046a 100644 --- a/widgets/table/e-tree.h +++ b/widgets/table/e-tree.h @@ -45,6 +45,7 @@ typedef struct { gint (*right_click) (ETree *et, int row, ETreePath path, int col, GdkEvent *event); gint (*click) (ETree *et, int row, ETreePath path, int col, GdkEvent *event); gint (*key_press) (ETree *et, int row, ETreePath path, int col, GdkEvent *event); + gint (*start_drag) (ETree *et, int row, ETreePath path, int col, GdkEvent *event); void (*set_scroll_adjustments) (ETree *tree, GtkAdjustment *hadjustment, -- cgit v1.2.3