aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/table/e-table-item.c264
-rw-r--r--widgets/table/e-table-item.h12
2 files changed, 208 insertions, 68 deletions
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index a69db6f84d..473901bf67 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -83,11 +83,7 @@ static void e_table_item_focus (ETableItem *eti, int col, int row, GdkModifierTy
static void eti_cursor_change (ESelectionModel *selection, int row, int col, ETableItem *eti);
static void eti_cursor_activated (ESelectionModel *selection, int row, int col, ETableItem *eti);
static void eti_selection_change (ESelectionModel *selection, ETableItem *eti);
-#ifdef SHOW_ON_CHANGED
-static void eti_request_region_show (ETableItem *eti,
- int start_col, int start_row,
- int end_col, int end_row);
-#endif
+
#define ETI_ROW_HEIGHT(eti,row) ((eti)->height_cache && (eti)->height_cache[(row)] != -1 ? (eti)->height_cache[(row)] : eti_row_height((eti),(row)))
inline static gint
@@ -648,44 +644,6 @@ eti_item_region_redraw (ETableItem *eti, int x0, int y0, int x1, int y1)
}
/*
- * Callback routine: invoked before the ETableModel has suffers a change
- */
-static void
-eti_table_model_pre_change (ETableModel *table_model, ETableItem *eti)
-{
- if (eti_editing (eti))
- e_table_item_leave_edit (eti);
-}
-
-/*
- * Callback routine: invoked when the ETableModel has suffered a change
- */
-static void
-eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
-{
- if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
- return;
-#ifdef SHOW_ON_CHANGED
- int view_row;
-#endif
-
- eti->rows = e_table_model_row_count (eti->table_model);
-
- free_height_cache(eti);
-
- eti->needs_compute_height = 1;
- e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
- eti->needs_redraw = 1;
- gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
-
-#ifdef SHOW_ON_CHANGED
- view_row = model_to_view_row(eti, eti->cursor_row);
- if (view_row >= 0 && eti->cursor_col >= 0)
- eti_request_region_show (eti, eti->cursor_col, view_row, eti->cursor_col, view_row);
-#endif
-}
-
-/*
* Computes the distance between @start_row and @end_row in pixels
*/
int
@@ -706,6 +664,29 @@ e_table_item_row_diff (ETableItem *eti, int start_row, int end_row)
return total;
}
+static void
+eti_get_region (ETableItem *eti,
+ int start_col, int start_row,
+ int end_col, int end_row,
+ int *x1p, int *y1p,
+ int *x2p, int *y2p)
+{
+ int x1, y1, x2, y2;
+
+ x1 = e_table_header_col_diff (eti->header, 0, start_col);
+ y1 = e_table_item_row_diff (eti, 0, start_row);
+ x2 = x1 + e_table_header_col_diff (eti->header, start_col, end_col + 1);
+ y2 = y1 + e_table_item_row_diff (eti, start_row, end_row + 1);
+ if (x1p)
+ *x1p = x1;
+ if (y1p)
+ *y1p = y1;
+ if (x2p)
+ *x2p = x2;
+ if (y2p)
+ *y2p = y2;
+}
+
/*
* eti_request_region_redraw:
*
@@ -721,19 +702,19 @@ eti_request_region_redraw (ETableItem *eti,
int start_col, int start_row,
int end_col, int end_row, int border)
{
- int x1, y1, width, height;
+ int x1, y1, x2, y2;
if (eti->rows > 0) {
-
- x1 = e_table_header_col_diff (eti->header, 0, start_col);
- y1 = e_table_item_row_diff (eti, 0, start_row);
- width = e_table_header_col_diff (eti->header, start_col, end_col + 1);
- height = e_table_item_row_diff (eti, start_row, end_row + 1);
+
+ eti_get_region (eti,
+ start_col, start_row,
+ end_col, end_row,
+ &x1, &y1, &x2, &y2);
eti_item_region_redraw (eti, eti->x1 + x1 - border,
eti->y1 + y1 - border,
- eti->x1 + x1 + width + 1 + border,
- eti->y1 + y1 + height + 1 + border);
+ eti->x1 + x2 + 1 + border,
+ eti->y1 + y2 + 1 + border);
}
}
@@ -749,11 +730,11 @@ eti_request_region_show (ETableItem *eti,
int end_col, int end_row, int delay)
{
int x1, y1, x2, y2;
-
- x1 = e_table_header_col_diff (eti->header, 0, start_col);
- y1 = e_table_item_row_diff (eti, 0, start_row);
- x2 = x1 + e_table_header_col_diff (eti->header, start_col, end_col + 1);
- y2 = y1 + e_table_item_row_diff (eti, start_row, end_row + 1);
+
+ eti_get_region (eti,
+ start_col, start_row,
+ end_col, end_row,
+ &x1, &y1, &x2, &y2);
if (delay)
e_canvas_item_show_area_delayed(GNOME_CANVAS_ITEM(eti), x1, y1, x2, y2, delay);
@@ -762,6 +743,112 @@ eti_request_region_show (ETableItem *eti,
}
static void
+eti_show_cursor (ETableItem *eti, int delay)
+{
+ int cursor_row;
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ NULL);
+
+ if (cursor_row != -1) {
+ cursor_row = model_to_view_row (eti, cursor_row);
+ d(g_print ("%s: cursor row: %d\n", __FUNCTION__, cursor_row));
+ eti_request_region_show (eti,
+ 0, cursor_row, eti->cols + 1, cursor_row + 1,
+ delay);
+ }
+}
+
+static void
+eti_check_cursor_on_screen (ETableItem *eti)
+{
+ eti->cursor_on_screen = e_canvas_item_area_shown (GNOME_CANVAS_ITEM(eti),
+ eti->cursor_x1,
+ eti->cursor_y1,
+ eti->cursor_x2,
+ eti->cursor_y2);
+
+ d(g_print ("%s: cursor on screen: %s\n", __FUNCTION__, eti->cursor_on_screen ? "TRUE" : "FALSE"));
+}
+
+static void
+eti_check_cursor_bounds (ETableItem *eti)
+{
+ int x1, y1, x2, y2;
+ int cursor_row;
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ NULL);
+
+ if (cursor_row == -1) {
+ eti->cursor_x1 = -1;
+ eti->cursor_y1 = -1;
+ eti->cursor_x2 = -1;
+ eti->cursor_y2 = -1;
+ eti->cursor_on_screen = FALSE;
+ return;
+ }
+
+ cursor_row = model_to_view_row (eti, cursor_row);
+
+ d(g_print ("%s: cursor row: %d\n", __FUNCTION__, cursor_row));
+
+ eti_get_region (eti,
+ 0, cursor_row, eti->cols + 1, cursor_row + 1,
+ &x1, &y1, &x2, &y2);
+ eti->cursor_x1 = x1;
+ eti->cursor_y1 = y1;
+ eti->cursor_x2 = x2;
+ eti->cursor_y2 = y2;
+ eti->cursor_on_screen = e_canvas_item_area_shown (GNOME_CANVAS_ITEM(eti), x1, y1, x2, y2);
+
+ d(g_print ("%s: cursor on screen: %s\n", __FUNCTION__, eti->cursor_on_screen ? "TRUE" : "FALSE"));
+}
+
+static void
+eti_maybe_show_cursor(ETableItem *eti, int delay)
+{
+ d(g_print ("%s: cursor on screen: %s\n", __FUNCTION__, eti->cursor_on_screen ? "TRUE" : "FALSE"));
+ if (eti->cursor_on_screen)
+ eti_show_cursor (eti, delay);
+ eti_check_cursor_bounds (eti);
+}
+
+/*
+ * Callback routine: invoked before the ETableModel has suffers a change
+ */
+static void
+eti_table_model_pre_change (ETableModel *table_model, ETableItem *eti)
+{
+ eti_check_cursor_bounds (eti);
+ if (eti_editing (eti))
+ e_table_item_leave_edit (eti);
+}
+
+/*
+ * Callback routine: invoked when the ETableModel has suffered a change
+ */
+static void
+eti_table_model_changed (ETableModel *table_model, ETableItem *eti)
+{
+ if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
+ return;
+
+ eti->rows = e_table_model_row_count (eti->table_model);
+
+ free_height_cache(eti);
+
+ eti->needs_compute_height = 1;
+ e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
+ eti->needs_redraw = 1;
+ gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (eti));
+
+ eti_maybe_show_cursor(eti, 0);
+}
+
+static void
eti_table_model_row_changed (ETableModel *table_model, int row, ETableItem *eti)
{
if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
@@ -1203,6 +1290,12 @@ eti_init (GnomeCanvasItem *item)
eti->maybe_in_drag = 0;
eti->grabbed = 0;
+ eti->cursor_on_screen = FALSE;
+ eti->cursor_x1 = -1;
+ eti->cursor_y1 = -1;
+ eti->cursor_x2 = -1;
+ eti->cursor_y2 = -1;
+
eti->rows = -1;
e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (eti), eti_reflow);
@@ -1214,6 +1307,12 @@ static const char gray50_bits[] = {
0x02, 0x01, };
static void
+adjustment_changed (GtkAdjustment *adjustment, ETableItem *eti)
+{
+ eti_check_cursor_on_screen (eti);
+}
+
+static void
eti_realize (GnomeCanvasItem *item)
{
ETableItem *eti = E_TABLE_ITEM (item);
@@ -1243,6 +1342,18 @@ eti_realize (GnomeCanvasItem *item)
gdk_gc_set_stipple (eti->focus_gc, eti->stipple);
gdk_gc_set_fill (eti->focus_gc, GDK_OPAQUE_STIPPLED);
+ eti->hadjustment_change_id =
+ gtk_signal_connect(GTK_OBJECT(gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))), "changed",
+ GTK_SIGNAL_FUNC (adjustment_changed), eti);
+ eti->hadjustment_value_change_id =
+ gtk_signal_connect(GTK_OBJECT(gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))), "value_changed",
+ GTK_SIGNAL_FUNC (adjustment_changed), eti);
+ eti->vadjustment_change_id =
+ gtk_signal_connect(GTK_OBJECT(gtk_layout_get_vadjustment(GTK_LAYOUT(item->canvas))), "changed",
+ GTK_SIGNAL_FUNC (adjustment_changed), eti);
+ eti->vadjustment_value_change_id =
+ gtk_signal_connect(GTK_OBJECT(gtk_layout_get_vadjustment(GTK_LAYOUT(item->canvas))), "value_changed",
+ GTK_SIGNAL_FUNC (adjustment_changed), eti);
if (eti->cell_views == NULL)
eti_attach_cell_views (eti);
@@ -1262,9 +1373,9 @@ static void
eti_unrealize (GnomeCanvasItem *item)
{
ETableItem *eti = E_TABLE_ITEM (item);
-
+
if (eti->grabbed) {
- gtk_grab_remove (GTK_WIDGET (GNOME_CANVAS_ITEM (eti)->canvas));
+ gtk_grab_remove (GTK_WIDGET (item->canvas));
eti->grabbed = FALSE;
}
@@ -1279,11 +1390,20 @@ eti_unrealize (GnomeCanvasItem *item)
eti->focus_gc = NULL;
gdk_bitmap_unref (eti->stipple);
eti->stipple = NULL;
-
+
eti_unrealize_cell_views (eti);
eti->height = 0;
-
+
+ gtk_signal_disconnect(GTK_OBJECT(gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))),
+ eti->hadjustment_change_id);
+ gtk_signal_disconnect(GTK_OBJECT(gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))),
+ eti->hadjustment_value_change_id);
+ gtk_signal_disconnect(GTK_OBJECT(gtk_layout_get_vadjustment(GTK_LAYOUT(item->canvas))),
+ eti->vadjustment_change_id);
+ gtk_signal_disconnect(GTK_OBJECT(gtk_layout_get_vadjustment(GTK_LAYOUT(item->canvas))),
+ eti->vadjustment_value_change_id);
+
if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->unrealize)(item);
}
@@ -1329,7 +1449,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
ETableCol *ecol = e_table_header_get_column (eti->header, col);
x2 = x1 + ecol->width;
-
+
if (x1 > (x + width))
break;
if (x2 < x)
@@ -1845,6 +1965,11 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
gint cursor_row, cursor_col;
if (e->button.button == 1) {
+ if (eti->grabbed) {
+ gtk_grab_remove (GTK_WIDGET (item->canvas));
+ gnome_canvas_item_ungrab(item, e->button.time);
+ }
+ eti->grabbed = FALSE;
if (eti->maybe_in_drag) {
eti->maybe_in_drag = FALSE;
if (!eti->maybe_did_something)
@@ -1853,11 +1978,6 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
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) {
@@ -2448,9 +2568,9 @@ eti_cursor_change (ESelectionModel *selection, int row, int col, ETableItem *eti
if (! e_table_model_has_change_pending (eti->table_model)) {
if (!eti->in_key_press) {
- eti_request_region_show (eti, view_col, view_row, view_col, view_row, DOUBLE_CLICK_TIME + 10);
+ eti_maybe_show_cursor(eti, DOUBLE_CLICK_TIME + 10);
} else {
- eti_request_region_show (eti, view_col, view_row, view_col, view_row, 0);
+ eti_maybe_show_cursor(eti, 0);
}
}
@@ -2480,6 +2600,14 @@ eti_cursor_activated (ESelectionModel *selection, int row, int col, ETableItem *
return;
}
+ if (! e_table_model_has_change_pending (eti->table_model)) {
+ if (!eti->in_key_press) {
+ eti_show_cursor(eti, DOUBLE_CLICK_TIME + 10);
+ } else {
+ eti_show_cursor(eti, 0);
+ }
+ }
+
if (eti_editing(eti))
e_table_item_leave_edit (eti);
gtk_signal_emit (GTK_OBJECT (eti), eti_signals [CURSOR_ACTIVATED],
diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h
index 7cd9729833..2e91473947 100644
--- a/widgets/table/e-table-item.h
+++ b/widgets/table/e-table-item.h
@@ -49,6 +49,11 @@ typedef struct {
int selection_change_id;
int cursor_change_id;
int cursor_activated_id;
+
+ int hadjustment_change_id;
+ int hadjustment_value_change_id;
+ int vadjustment_change_id;
+ int vadjustment_value_change_id;
GdkGC *fill_gc;
GdkGC *grid_gc;
@@ -76,6 +81,13 @@ typedef struct {
guint maybe_did_something : 1;
+ guint cursor_on_screen : 1;
+
+ int cursor_x1;
+ int cursor_y1;
+ int cursor_x2;
+ int cursor_y2;
+
int drag_col;
int drag_row;
int drag_x;