aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher James Lahey <clahey@helixcode.com>2000-07-27 04:33:39 +0800
committerChris Lahey <clahey@src.gnome.org>2000-07-27 04:33:39 +0800
commit32c3d29bbc14cc1d4c054eb9d6538b0199e90c61 (patch)
tree021834696ac26eae0b65be3e695f05a2afc030ad
parent580e879674ea981023756e1bdaa8d7309223c86b (diff)
downloadgsoc2013-evolution-32c3d29bbc14cc1d4c054eb9d6538b0199e90c61.tar
gsoc2013-evolution-32c3d29bbc14cc1d4c054eb9d6538b0199e90c61.tar.gz
gsoc2013-evolution-32c3d29bbc14cc1d4c054eb9d6538b0199e90c61.tar.bz2
gsoc2013-evolution-32c3d29bbc14cc1d4c054eb9d6538b0199e90c61.tar.lz
gsoc2013-evolution-32c3d29bbc14cc1d4c054eb9d6538b0199e90c61.tar.xz
gsoc2013-evolution-32c3d29bbc14cc1d4c054eb9d6538b0199e90c61.tar.zst
gsoc2013-evolution-32c3d29bbc14cc1d4c054eb9d6538b0199e90c61.zip
Added "table_selection_model" argument. Removed foreach function and
2000-07-26 Christopher James Lahey <clahey@helixcode.com> * e-table-group-container.c, e-table-group-container.h, e-table-group-leaf.c, e-table-group-leaf.h: Added "table_selection_model" argument. Removed foreach function and selection notification. * e-table-group.c, e-table-group.h: Removed foreach function and selection notification. * e-table-header.c: Fixed header width calculation to include the last column. * e-table-item.c, e-table-item.h: Fixed this to use the new selection model. * e-table-scrolled.c, e-table-scrolled.h: Removed selection notification. * e-table-selection-model.c, e-table-selection-model.h: Finished notification signals and fixed a bunch of bit manipulations. Implemented do_something method. * e-table.c, e-table.h: Create an ETableSelectionModel and use it properly. svn path=/trunk/; revision=4363
-rw-r--r--widgets/e-table/ChangeLog25
-rw-r--r--widgets/e-table/e-table-group-container.c55
-rw-r--r--widgets/e-table/e-table-group-container.h2
-rw-r--r--widgets/e-table/e-table-group-leaf.c38
-rw-r--r--widgets/e-table/e-table-group-leaf.h2
-rw-r--r--widgets/e-table/e-table-group.c36
-rw-r--r--widgets/e-table/e-table-group.h8
-rw-r--r--widgets/e-table/e-table-header.c2
-rw-r--r--widgets/e-table/e-table-item.c447
-rw-r--r--widgets/e-table/e-table-item.h11
-rw-r--r--widgets/e-table/e-table-scrolled.c20
-rw-r--r--widgets/e-table/e-table-scrolled.h1
-rw-r--r--widgets/e-table/e-table-selection-model.c238
-rw-r--r--widgets/e-table/e-table-selection-model.h31
-rw-r--r--widgets/e-table/e-table.c50
-rw-r--r--widgets/e-table/e-table.h1
-rw-r--r--widgets/table/e-table-group-container.c55
-rw-r--r--widgets/table/e-table-group-container.h2
-rw-r--r--widgets/table/e-table-group-leaf.c38
-rw-r--r--widgets/table/e-table-group-leaf.h2
-rw-r--r--widgets/table/e-table-group.c36
-rw-r--r--widgets/table/e-table-group.h8
-rw-r--r--widgets/table/e-table-header.c2
-rw-r--r--widgets/table/e-table-item.c447
-rw-r--r--widgets/table/e-table-item.h11
-rw-r--r--widgets/table/e-table-scrolled.c20
-rw-r--r--widgets/table/e-table-scrolled.h1
-rw-r--r--widgets/table/e-table-selection-model.c238
-rw-r--r--widgets/table/e-table-selection-model.h31
-rw-r--r--widgets/table/e-table.c50
-rw-r--r--widgets/table/e-table.h1
31 files changed, 1041 insertions, 868 deletions
diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog
index 39e7449fd9..6f8633c08c 100644
--- a/widgets/e-table/ChangeLog
+++ b/widgets/e-table/ChangeLog
@@ -1,3 +1,28 @@
+2000-07-26 Christopher James Lahey <clahey@helixcode.com>
+
+ * e-table-group-container.c, e-table-group-container.h,
+ e-table-group-leaf.c, e-table-group-leaf.h: Added "table_selection_model"
+ argument. Removed foreach function and selection notification.
+
+ * e-table-group.c, e-table-group.h: Removed foreach function and
+ selection notification.
+
+ * e-table-header.c: Fixed header width calculation to include the
+ last column.
+
+ * e-table-item.c, e-table-item.h: Fixed this to use the new
+ selection model.
+
+ * e-table-scrolled.c, e-table-scrolled.h: Removed selection
+ notification.
+
+ * e-table-selection-model.c, e-table-selection-model.h: Finished
+ notification signals and fixed a bunch of bit manipulations.
+ Implemented do_something method.
+
+ * e-table.c, e-table.h: Create an ETableSelectionModel and use it
+ properly.
+
2000-07-25 Christopher James Lahey <clahey@helixcode.com>
* e-table-selection-model.c: Made foreach call the callback in top
diff --git a/widgets/e-table/e-table-group-container.c b/widgets/e-table/e-table-group-container.c
index f4e10917fb..f3788f154f 100644
--- a/widgets/e-table/e-table-group-container.c
+++ b/widgets/e-table/e-table-group-container.c
@@ -37,6 +37,7 @@ enum {
ARG_TABLE_DRAW_GRID,
ARG_TABLE_DRAW_FOCUS,
ARG_CURSOR_MODE,
+ ARG_TABLE_SELECTION_MODEL,
ARG_LENGTH_THRESHOLD,
};
@@ -97,6 +98,9 @@ etgc_destroy (GtkObject *object)
if (etgc->sort_info)
gtk_object_unref (GTK_OBJECT(etgc->sort_info));
+ if (etgc->table_selection_model)
+ gtk_object_unref (GTK_OBJECT(etgc->table_selection_model));
+
if (etgc->rect)
gtk_object_destroy (GTK_OBJECT(etgc->rect));
@@ -316,13 +320,6 @@ compute_text (ETableGroupContainer *etgc, ETableGroupContainerChildNode *child_n
}
static void
-child_row_selection (ETableGroup *etg, int row, gboolean selected,
- ETableGroupContainer *etgc)
-{
- e_table_group_row_selection (E_TABLE_GROUP (etgc), row, selected);
-}
-
-static void
child_cursor_change (ETableGroup *etg, int row,
ETableGroupContainer *etgc)
{
@@ -395,10 +392,9 @@ etgc_add (ETableGroup *etg, gint row)
"drawgrid", etgc->draw_grid,
"drawfocus", etgc->draw_focus,
"cursor_mode", etgc->cursor_mode,
+ "table_selection_model", etgc->table_selection_model,
"length_threshold", etgc->length_threshold,
NULL);
- gtk_signal_connect (GTK_OBJECT (child), "row_selection",
- GTK_SIGNAL_FUNC (child_row_selection), etgc);
gtk_signal_connect (GTK_OBJECT (child), "cursor_change",
GTK_SIGNAL_FUNC (child_cursor_change), etgc);
gtk_signal_connect (GTK_OBJECT (child), "double_click",
@@ -546,29 +542,6 @@ etgc_get_focus_column (ETableGroup *etg)
return 0;
}
-static void
-etgc_selected_row_foreach (ETableGroup *etg,
- ETableForeachFunc func,
- gpointer closure)
-{
- ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
- if (etgc->children) {
- GList *list;
- for (list = etgc->children; list; list = list->next) {
- ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data;
- ETableGroup *child = child_node->child;
- e_table_group_selected_row_foreach (child, func, closure);
- }
- }
-}
-
-
-
-
-
-
-
-
static void etgc_thaw (ETableGroup *etg)
{
@@ -612,6 +585,20 @@ etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
break;
+ case ARG_TABLE_SELECTION_MODEL:
+ if (etgc->table_selection_model)
+ gtk_object_unref(GTK_OBJECT(etgc->table_selection_model));
+ etgc->table_selection_model = E_TABLE_SELECTION_MODEL(GTK_VALUE_OBJECT (*arg));
+ if (etgc->table_selection_model)
+ gtk_object_ref(GTK_OBJECT(etgc->table_selection_model));
+ for (list = etgc->children; list; list = g_list_next (list)) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data;
+ gtk_object_set (GTK_OBJECT(child_node->child),
+ "table_selection_model", etgc->table_selection_model,
+ NULL);
+ }
+ break;
+
case ARG_TABLE_DRAW_GRID:
etgc->draw_grid = GTK_VALUE_BOOL (*arg);
for (list = etgc->children; list; list = g_list_next (list)) {
@@ -697,7 +684,6 @@ etgc_class_init (GtkObjectClass *object_class)
e_group_class->get_cursor_row = etgc_get_cursor_row;
e_group_class->get_focus_column = etgc_get_focus_column;
e_group_class->get_printable = etgc_get_printable;
- e_group_class->selected_row_foreach = etgc_selected_row_foreach;
gtk_object_add_arg_type ("ETableGroupContainer::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
@@ -705,6 +691,8 @@ etgc_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_FOCUS);
gtk_object_add_arg_type ("ETableGroupContainer::cursor_mode", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_CURSOR_MODE);
+ gtk_object_add_arg_type ("ETableGroupContainer::table_selection_model", GTK_TYPE_OBJECT,
+ GTK_ARG_WRITABLE, ARG_TABLE_SELECTION_MODEL);
gtk_object_add_arg_type ("ETableGroupContainer::length_threshold", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_LENGTH_THRESHOLD);
@@ -811,6 +799,7 @@ etgc_init (GtkObject *object)
container->draw_focus = 1;
container->cursor_mode = E_TABLE_CURSOR_SIMPLE;
container->length_threshold = -1;
+ container->table_selection_model = NULL;
}
E_MAKE_TYPE (e_table_group_container, "ETableGroupContainer", ETableGroupContainer, etgc_class_init, etgc_init, PARENT_TYPE);
diff --git a/widgets/e-table/e-table-group-container.h b/widgets/e-table/e-table-group-container.h
index 1157768ea4..bdb717b92d 100644
--- a/widgets/e-table/e-table-group-container.h
+++ b/widgets/e-table/e-table-group-container.h
@@ -41,6 +41,8 @@ typedef struct {
int n;
int length_threshold;
+ ETableSelectionModel *table_selection_model;
+
guint draw_grid : 1;
guint draw_focus : 1;
ETableCursorMode cursor_mode;
diff --git a/widgets/e-table/e-table-group-leaf.c b/widgets/e-table/e-table-group-leaf.c
index 08c4c4a475..f6b540cdae 100644
--- a/widgets/e-table/e-table-group-leaf.c
+++ b/widgets/e-table/e-table-group-leaf.c
@@ -31,6 +31,7 @@ enum {
ARG_TABLE_DRAW_FOCUS,
ARG_CURSOR_MODE,
ARG_LENGTH_THRESHOLD,
+ ARG_TABLE_SELECTION_MODEL,
};
static void etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
@@ -44,6 +45,8 @@ etgl_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT(etgl->subset));
if (etgl->item)
gtk_object_destroy (GTK_OBJECT(etgl->item));
+ if (etgl->table_selection_model)
+ gtk_object_unref (GTK_OBJECT(etgl->table_selection_model));
if (GTK_OBJECT_CLASS (etgl_parent_class)->destroy)
GTK_OBJECT_CLASS (etgl_parent_class)->destroy (object);
}
@@ -81,13 +84,6 @@ e_table_group_leaf_new (GnomeCanvasGroup *parent,
}
static void
-etgl_row_selection (GtkObject *object, gint row, gboolean selected, ETableGroupLeaf *etgl)
-{
- if (row < E_TABLE_SUBSET(etgl->subset)->n_map)
- e_table_group_row_selection (E_TABLE_GROUP(etgl), E_TABLE_SUBSET(etgl->subset)->map_table[row], selected);
-}
-
-static void
etgl_cursor_change (GtkObject *object, gint row, ETableGroupLeaf *etgl)
{
if (row < E_TABLE_SUBSET(etgl->subset)->n_map)
@@ -149,10 +145,9 @@ etgl_realize (GnomeCanvasItem *item)
"cursor_mode", etgl->cursor_mode,
"minimum_width", etgl->minimum_width,
"length_threshold", etgl->length_threshold,
+ "table_selection_model", etgl->table_selection_model,
NULL));
- gtk_signal_connect (GTK_OBJECT(etgl->item), "row_selection",
- GTK_SIGNAL_FUNC(etgl_row_selection), etgl);
gtk_signal_connect (GTK_OBJECT(etgl->item), "cursor_change",
GTK_SIGNAL_FUNC(etgl_cursor_change), etgl);
gtk_signal_connect (GTK_OBJECT(etgl->item), "double_click",
@@ -245,15 +240,6 @@ etgl_get_printable (ETableGroup *etg)
}
static void
-etgl_selected_row_foreach(ETableGroup *etg,
- ETableForeachFunc func,
- gpointer closure)
-{
- ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
- e_table_item_selected_row_foreach (etgl->item, func, closure);
-}
-
-static void
etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
ETableGroup *etg = E_TABLE_GROUP (object);
@@ -284,6 +270,17 @@ etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
NULL);
}
break;
+ case ARG_TABLE_SELECTION_MODEL:
+ if (etgl->table_selection_model)
+ gtk_object_unref(GTK_OBJECT(etgl->table_selection_model));
+ etgl->table_selection_model = E_TABLE_SELECTION_MODEL(GTK_VALUE_OBJECT (*arg));
+ if (etgl->table_selection_model)
+ gtk_object_ref(GTK_OBJECT(etgl->table_selection_model));
+ if (etgl->item) {
+ gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+ "table_selection_model", etgl->table_selection_model,
+ NULL);
+ }
case ARG_TABLE_DRAW_GRID:
etgl->draw_grid = GTK_VALUE_BOOL (*arg);
@@ -365,7 +362,6 @@ etgl_class_init (GtkObjectClass *object_class)
e_group_class->get_cursor_row = etgl_get_cursor_row;
e_group_class->get_focus_column = etgl_get_focus_column;
e_group_class->get_printable = etgl_get_printable;
- e_group_class->selected_row_foreach = etgl_selected_row_foreach;
gtk_object_add_arg_type ("ETableGroupLeaf::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
@@ -375,6 +371,8 @@ etgl_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_CURSOR_MODE);
gtk_object_add_arg_type ("ETableGroupLeaf::length_threshold", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_LENGTH_THRESHOLD);
+ gtk_object_add_arg_type ("ETableGroupLeaf::table_selection_model", GTK_TYPE_OBJECT,
+ GTK_ARG_WRITABLE, ARG_TABLE_SELECTION_MODEL);
gtk_object_add_arg_type ("ETableGroupLeaf::height", GTK_TYPE_DOUBLE,
GTK_ARG_READABLE, ARG_HEIGHT);
@@ -403,6 +401,8 @@ etgl_init (GtkObject *object)
etgl->cursor_mode = E_TABLE_CURSOR_SIMPLE;
etgl->length_threshold = -1;
+ etgl->table_selection_model = NULL;
+
e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM(object), etgl_reflow);
}
diff --git a/widgets/e-table/e-table-group-leaf.h b/widgets/e-table/e-table-group-leaf.h
index 365f268307..1cc041206b 100644
--- a/widgets/e-table/e-table-group-leaf.h
+++ b/widgets/e-table/e-table-group-leaf.h
@@ -32,6 +32,8 @@ typedef struct {
guint draw_grid : 1;
guint draw_focus : 1;
ETableCursorMode cursor_mode;
+
+ ETableSelectionModel *table_selection_model;
} ETableGroupLeaf;
typedef struct {
diff --git a/widgets/e-table/e-table-group.c b/widgets/e-table/e-table-group.c
index 18f8084b2c..d3c6e2e08d 100644
--- a/widgets/e-table/e-table-group.c
+++ b/widgets/e-table/e-table-group.c
@@ -25,7 +25,6 @@
static GnomeCanvasGroupClass *etg_parent_class;
enum {
- ROW_SELECTION,
CURSOR_CHANGE,
DOUBLE_CLICK,
RIGHT_CLICK,
@@ -240,31 +239,6 @@ e_table_group_get_printable (ETableGroup *etg)
}
void
-e_table_group_selected_row_foreach (ETableGroup *etg,
- ETableForeachFunc func,
- gpointer closure)
-{
- g_return_if_fail (etg != NULL);
- g_return_if_fail (E_IS_TABLE_GROUP (etg));
-
- if (ETG_CLASS (etg)->selected_row_foreach)
- ETG_CLASS (etg)->selected_row_foreach (etg, func, closure);
-}
-
-
-
-void
-e_table_group_row_selection (ETableGroup *e_table_group, gint row, gboolean selected)
-{
- g_return_if_fail (e_table_group != NULL);
- g_return_if_fail (E_IS_TABLE_GROUP (e_table_group));
-
- gtk_signal_emit (GTK_OBJECT (e_table_group),
- etg_signals [ROW_SELECTION],
- row, selected);
-}
-
-void
e_table_group_cursor_change (ETableGroup *e_table_group, gint row)
{
g_return_if_fail (e_table_group != NULL);
@@ -364,7 +338,6 @@ etg_class_init (GtkObjectClass *object_class)
item_class->event = etg_event;
- klass->row_selection = NULL;
klass->cursor_change = NULL;
klass->double_click = NULL;
klass->right_click = NULL;
@@ -382,18 +355,9 @@ etg_class_init (GtkObjectClass *object_class)
klass->get_focus = etg_get_focus;
klass->get_ecol = NULL;
klass->get_printable = NULL;
- klass->selected_row_foreach = NULL;
etg_parent_class = gtk_type_class (PARENT_TYPE);
- etg_signals [ROW_SELECTION] =
- gtk_signal_new ("row_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETableGroupClass, row_selection),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
etg_signals [CURSOR_CHANGE] =
gtk_signal_new ("cursor_change",
GTK_RUN_LAST,
diff --git a/widgets/e-table/e-table-group.h b/widgets/e-table/e-table-group.h
index ef6be1d35f..f4fd25a779 100644
--- a/widgets/e-table/e-table-group.h
+++ b/widgets/e-table/e-table-group.h
@@ -45,7 +45,6 @@ typedef struct {
GnomeCanvasGroupClass parent_class;
/* Signals */
- void (*row_selection) (ETableGroup *etg, int row, gboolean selected);
void (*cursor_change) (ETableGroup *etg, int row);
void (*double_click) (ETableGroup *etg, int row);
gint (*right_click) (ETableGroup *etg, int row, int col, GdkEvent *event);
@@ -65,7 +64,6 @@ typedef struct {
gint (*get_focus_column) (ETableGroup *etg);
ETableCol *(*get_ecol) (ETableGroup *etg);
EPrintable *(*get_printable) (ETableGroup *etg);
- void (*selected_row_foreach) (ETableGroup *etg, ETableForeachFunc func, gpointer closure);
} ETableGroupClass;
@@ -91,9 +89,6 @@ gint e_table_group_get_focus_column (ETableGroup *etg);
ETableHeader *e_table_group_get_header (ETableGroup *etg);
ETableCol *e_table_group_get_ecol (ETableGroup *etg);
EPrintable *e_table_group_get_printable (ETableGroup *etg);
-void e_table_group_selected_row_foreach (ETableGroup *etg,
- ETableForeachFunc func,
- gpointer closure);
ETableGroup *e_table_group_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
@@ -108,9 +103,6 @@ void e_table_group_construct (GnomeCanvasGroup *parent,
ETableModel *model);
/* For emitting the signals */
-void e_table_group_row_selection (ETableGroup *etg,
- gint row,
- gboolean selected);
void e_table_group_cursor_change (ETableGroup *etg,
gint row);
void e_table_group_double_click (ETableGroup *etg,
diff --git a/widgets/e-table/e-table-header.c b/widgets/e-table/e-table-header.c
index 06aeb50b3f..f95797e5c4 100644
--- a/widgets/e-table/e-table-header.c
+++ b/widgets/e-table/e-table-header.c
@@ -616,7 +616,7 @@ e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col)
if (start_col < 0)
start_col = 0;
if (end_col > eth->col_count)
- end_col = eth->col_count - 1;
+ end_col = eth->col_count;
total = 0;
for (col = start_col; col < end_col; col++){
diff --git a/widgets/e-table/e-table-item.c b/widgets/e-table/e-table-item.c
index 947b28107e..9e66a487be 100644
--- a/widgets/e-table/e-table-item.c
+++ b/widgets/e-table/e-table-item.c
@@ -30,7 +30,6 @@
static GnomeCanvasItemClass *eti_parent_class;
enum {
- ROW_SELECTION,
CURSOR_CHANGE,
DOUBLE_CLICK,
RIGHT_CLICK,
@@ -44,11 +43,11 @@ enum {
ARG_0,
ARG_TABLE_HEADER,
ARG_TABLE_MODEL,
+ ARG_TABLE_SELECTION_MODEL,
ARG_TABLE_DRAW_GRID,
ARG_TABLE_DRAW_FOCUS,
ARG_CURSOR_MODE,
ARG_LENGTH_THRESHOLD,
- ARG_HAS_CURSOR,
ARG_CURSOR_ROW,
ARG_MINIMUM_WIDTH,
@@ -59,18 +58,17 @@ enum {
static int eti_get_height (ETableItem *eti);
static int eti_get_minimum_width (ETableItem *eti);
static int eti_row_height (ETableItem *eti, int row);
-static void e_table_item_unselect_row (ETableItem *eti, int row);
-static void e_table_item_select_row (ETableItem *eti, int row);
-static void eti_selection (GnomeCanvasItem *item, int flags, gpointer user_data);
-static int eti_selection_compare (GnomeCanvasItem *item, gpointer data1, gpointer data2, int flags);
-static void e_table_item_focus (ETableItem *eti, int col, int row, gboolean add_selection);
-static void
-eti_request_region_show (ETableItem *eti,
- int start_col, int start_row,
- int end_col, int end_row);
+static void e_table_item_focus (ETableItem *eti, int col, int row, gboolean shift_p, gboolean ctrl_p);
+static void eti_cursor_change (ETableSelectionModel *selection, int row, int col, ETableItem *eti);
+static void eti_selection_change (ETableSelectionModel *selection, ETableItem *eti);
+#if 0
+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)))
-static gint
+inline static gint
model_to_view_row(ETableItem *eti, int row)
{
int i;
@@ -90,7 +88,7 @@ model_to_view_row(ETableItem *eti, int row)
return row;
}
-static gint
+inline static gint
view_to_model_row(ETableItem *eti, int row)
{
if (eti->uses_source_model) {
@@ -310,6 +308,28 @@ eti_remove_table_model (ETableItem *eti)
}
/*
+ * eti_remove_table_model:
+ *
+ * Invoked to release the table model associated with this ETableItem
+ */
+static void
+eti_remove_table_selection_model (ETableItem *eti)
+{
+ if (!eti->selection)
+ return;
+
+ gtk_signal_disconnect (GTK_OBJECT (eti->selection),
+ eti->selection_change_id);
+ gtk_signal_disconnect (GTK_OBJECT (eti->selection),
+ eti->cursor_change_id);
+ gtk_object_unref (GTK_OBJECT (eti->selection));
+
+ eti->selection_change_id = 0;
+ eti->cursor_change_id = 0;
+ eti->selection = NULL;
+}
+
+/*
* eti_remove_header_model:
*
* Invoked to release the header model associated with this ETableItem
@@ -579,16 +599,19 @@ eti_request_region_redraw (ETableItem *eti,
int end_col, int end_row, int border)
{
int x1, y1, width, height;
-
- x1 = e_table_header_col_diff (eti->header, 0, start_col);
- y1 = eti_row_diff (eti, 0, start_row);
- width = e_table_header_col_diff (eti->header, start_col, end_col + 1);
- height = eti_row_diff (eti, start_row, end_row + 1);
-
- 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);
+
+ if (eti->rows > 0) {
+
+ x1 = e_table_header_col_diff (eti->header, 0, start_col);
+ y1 = eti_row_diff (eti, 0, start_row);
+ width = e_table_header_col_diff (eti->header, start_col, end_col + 1);
+ height = eti_row_diff (eti, start_row, end_row + 1);
+
+ 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);
+ }
}
/*
@@ -619,7 +642,7 @@ eti_table_model_row_changed (ETableModel *table_model, int row, ETableItem *eti)
eti_table_model_changed (table_model, eti);
return;
}
-
+
eti_request_region_redraw (eti, 0, row, eti->cols, row, 0);
}
@@ -630,7 +653,7 @@ eti_table_model_cell_changed (ETableModel *table_model, int col, int row, ETable
eti_table_model_changed (table_model, eti);
return;
}
-
+
eti_request_region_redraw (eti, 0, row, eti->cols -1, row, 0);
}
@@ -652,14 +675,20 @@ e_table_item_redraw_range (ETableItem *eti,
int end_col, int end_row)
{
int border;
+ int cursor_col, cursor_row;
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
-
- if ((start_col == eti->cursor_col) ||
- (end_col == eti->cursor_col) ||
- (view_to_model_row(eti, start_row) == eti->cursor_row) ||
- (view_to_model_row(eti, end_row) == eti->cursor_row))
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ if ((start_col == cursor_col) ||
+ (end_col == cursor_col) ||
+ (view_to_model_row(eti, start_row) == cursor_row) ||
+ (view_to_model_row(eti, end_row) == cursor_row))
border = 2;
else
border = 0;
@@ -711,6 +740,25 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
}
static void
+eti_add_table_selection_model (ETableItem *eti, ETableSelectionModel *selection)
+{
+ g_assert (eti->selection == NULL);
+
+ eti->selection = selection;
+ gtk_object_ref (GTK_OBJECT (eti->selection));
+
+ eti->selection_change_id = gtk_signal_connect (
+ GTK_OBJECT (selection), "selection_changed",
+ GTK_SIGNAL_FUNC (eti_selection_change), eti);
+
+ eti->cursor_change_id = gtk_signal_connect (
+ GTK_OBJECT (selection), "cursor_changed",
+ GTK_SIGNAL_FUNC (eti_cursor_change), eti);
+
+ eti_selection_change(selection, eti);
+}
+
+static void
eti_header_dim_changed (ETableHeader *eth, int col, ETableItem *eti)
{
eti->needs_compute_width = 1;
@@ -727,7 +775,7 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
* There should be at least one column
*/
g_assert (eti->cols != 0);
-
+
if (eti->cell_views){
eti_unrealize_cell_views (eti);
eti_detach_cell_views (eti);
@@ -772,10 +820,10 @@ eti_destroy (GtkObject *object)
eti_remove_header_model (eti);
eti_remove_table_model (eti);
+ eti_remove_table_selection_model (eti);
-#if 0
- g_slist_free (eti->selection);
-#endif
+ if (eti->selection)
+ gtk_object_unref(GTK_OBJECT(eti->selection));
if (eti->height_cache_idle_id)
g_source_remove(eti->height_cache_idle_id);
@@ -791,6 +839,7 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
{
GnomeCanvasItem *item;
ETableItem *eti;
+ int cursor_col;
item = GNOME_CANVAS_ITEM (o);
eti = E_TABLE_ITEM (o);
@@ -806,6 +855,12 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
eti_add_table_model (eti, E_TABLE_MODEL(GTK_VALUE_OBJECT (*arg)));
break;
+ case ARG_TABLE_SELECTION_MODEL:
+ eti_remove_table_selection_model (eti);
+ if (GTK_VALUE_OBJECT (*arg))
+ eti_add_table_selection_model (eti, E_TABLE_SELECTION_MODEL(GTK_VALUE_OBJECT (*arg)));
+ break;
+
case ARG_LENGTH_THRESHOLD:
eti->length_threshold = GTK_VALUE_INT (*arg);
break;
@@ -831,7 +886,11 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
break;
case ARG_CURSOR_ROW:
- e_table_item_focus (eti, eti->cursor_col != -1 ? eti->cursor_col : 0, view_to_model_row(eti, GTK_VALUE_INT (*arg)), FALSE);
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ NULL);
+
+ e_table_item_focus (eti, cursor_col != -1 ? cursor_col : 0, view_to_model_row(eti, GTK_VALUE_INT (*arg)), FALSE, FALSE);
break;
}
eti->needs_redraw = 1;
@@ -843,6 +902,7 @@ eti_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
{
GnomeCanvasItem *item;
ETableItem *eti;
+ int row;
item = GNOME_CANVAS_ITEM (o);
eti = E_TABLE_ITEM (o);
@@ -857,11 +917,11 @@ eti_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
case ARG_MINIMUM_WIDTH:
GTK_VALUE_DOUBLE (*arg) = eti->minimum_width;
break;
- case ARG_HAS_CURSOR:
- GTK_VALUE_BOOL (*arg) = (eti->cursor_row != -1);
- break;
case ARG_CURSOR_ROW:
- GTK_VALUE_INT (*arg) = model_to_view_row(eti, eti->cursor_row);
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &row,
+ NULL);
+ GTK_VALUE_INT (*arg) = model_to_view_row(eti, row);
break;
default:
arg->type = GTK_TYPE_INVALID;
@@ -890,18 +950,16 @@ eti_init (GnomeCanvasItem *item)
eti->source_model = NULL;
eti->row_guess = -1;
- eti->cursor_row = -1;
- eti->cursor_col = 0;
eti->cursor_mode = E_TABLE_CURSOR_SIMPLE;
+ eti->selection_change_id = 0;
+ eti->cursor_change_id = 0;
eti->selection = NULL;
eti->needs_redraw = 0;
eti->needs_compute_height = 0;
e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (eti), eti_reflow);
- e_canvas_item_set_selection_callback (GNOME_CANVAS_ITEM (eti), eti_selection);
- e_canvas_item_set_selection_compare_callback (GNOME_CANVAS_ITEM (eti), eti_selection_compare);
}
#define gray50_width 2
@@ -1078,13 +1136,19 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
for (row = first_row; row < last_row; row++){
int xd, height;
gboolean selected;
+ gint cursor_col, cursor_row;
height = ETI_ROW_HEIGHT (eti, row);
xd = x_offset;
/* printf ("paint: %d %d\n", yd, yd + height); */
- selected = g_slist_find (eti->selection, GINT_TO_POINTER (view_to_model_row(eti, row))) != NULL;
+ selected = e_table_selection_model_is_row_selected(eti->selection, row);
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
for (col = first_col; col < last_col; col++){
ETableCol *ecol = e_table_header_get_column (eti->header, col);
@@ -1092,7 +1156,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
gboolean col_selected = selected;
switch (eti->cursor_mode) {
case E_TABLE_CURSOR_SIMPLE:
- if (eti->cursor_col == col && eti->cursor_row == view_to_model_row(eti, row))
+ if (cursor_col == col && cursor_row == view_to_model_row(eti, row))
col_selected = !col_selected;
break;
case E_TABLE_CURSOR_LINE:
@@ -1103,7 +1167,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
e_cell_draw (ecell_view, drawable, ecol->col_idx, col, row, col_selected,
xd, yd, xd + ecol->width, yd + height);
- if (col == eti->cursor_col && view_to_model_row(eti, row) == eti->cursor_row){
+ if (col == cursor_col && view_to_model_row(eti, row) == cursor_row){
f_x1 = xd;
f_x2 = xd + ecol->width;
f_y1 = yd;
@@ -1213,31 +1277,55 @@ static void
eti_cursor_move (ETableItem *eti, gint row, gint column)
{
e_table_item_leave_edit (eti);
- e_table_item_focus (eti, column, view_to_model_row(eti, row), FALSE);
+ e_table_item_focus (eti, column, view_to_model_row(eti, row), FALSE, FALSE);
}
static void
eti_cursor_move_left (ETableItem *eti)
{
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row), eti->cursor_col - 1);
+ int cursor_col, cursor_row;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row), cursor_col - 1);
}
static void
eti_cursor_move_right (ETableItem *eti)
{
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row), eti->cursor_col + 1);
+ int cursor_col, cursor_row;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row), cursor_col + 1);
}
static void
eti_cursor_move_up (ETableItem *eti)
{
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row) - 1, eti->cursor_col);
+ int cursor_col, cursor_row;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row) - 1, cursor_col);
}
static void
eti_cursor_move_down (ETableItem *eti)
{
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row) + 1, eti->cursor_col);
+ int cursor_col, cursor_row;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row) + 1, cursor_col);
}
/* FIXME: cursor */
@@ -1254,36 +1342,26 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
double x1, y1;
int col, row;
gint shifted = e->button.state & GDK_SHIFT_MASK;
+ gint ctrled = e->button.state & GDK_CONTROL_MASK;
+ gint cursor_row, cursor_col;
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))
return TRUE;
-
- if (eti->cursor_row != view_to_model_row(eti, row) || eti->cursor_col != col){
- /*
- * Focus the cell, and select the row
- */
- if (e_table_item_is_row_selected(eti, view_to_model_row(eti, row))) {
- int nums[2];
- e_table_item_leave_edit (eti);
- nums[0] = view_to_model_row(eti, row);
- nums[1] = 0;
- e_canvas_item_remove_selection(GNOME_CANVAS_ITEM(eti), nums);
- } else {
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, col, view_to_model_row(eti, row), shifted);
- }
- }
- if (eti->cursor_row == view_to_model_row(eti, row) && eti->cursor_col == col){
+ e_table_selection_model_do_something(eti->selection, row, col, shifted, ctrled);
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_row == view_to_model_row(eti, row) && cursor_col == col){
- e_table_item_focus (eti, col, view_to_model_row(eti, row), shifted);
-
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
@@ -1316,6 +1394,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
case GDK_BUTTON_RELEASE: {
double x1, y1;
int col, row;
+ gint cursor_row, cursor_col;
switch (e->button.button) {
case 1: /* Fall through. */
@@ -1326,7 +1405,12 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (!find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1))
return TRUE;
- if (eti->cursor_row == view_to_model_row(eti, row) && eti->cursor_col == col){
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_row == view_to_model_row(eti, row) && cursor_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
@@ -1370,13 +1454,19 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
case GDK_MOTION_NOTIFY: {
int col, row;
double x1, y1;
+ gint cursor_col, cursor_row;
gnome_canvas_item_w2i (item, &e->motion.x, &e->motion.y);
if (!find_cell (eti, e->motion.x, e->motion.y, &col, &row, &x1, &y1))
return TRUE;
- if (eti->cursor_row == view_to_model_row(eti, row) && eti->cursor_col == col){
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_row == view_to_model_row(eti, row) && cursor_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
@@ -1391,40 +1481,42 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
break;
}
- case GDK_KEY_PRESS:
- if (eti->cursor_col == -1)
+ case GDK_KEY_PRESS: {
+ gint cursor_row, cursor_col;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_col == -1)
return FALSE;
switch (e->key.keyval){
case GDK_Left:
-#if 0
- if (!eti->mode_spreadsheet && eti_editing (eti))
+ if (eti_editing (eti))
break;
-#endif
- if (eti->cursor_col > 0)
+ if (cursor_col > 0)
eti_cursor_move_left (eti);
break;
case GDK_Right:
-#if 0
- if (!eti->mode_spreadsheet && eti_editing (eti))
+ if (eti_editing (eti))
break;
-#endif
- if (eti->cursor_col < eti->cols - 1)
+ if (cursor_col < eti->cols - 1)
eti_cursor_move_right (eti);
break;
case GDK_Up:
- if (eti->cursor_row != view_to_model_row(eti, 0))
+ if (cursor_row != view_to_model_row(eti, 0))
eti_cursor_move_up (eti);
else
return_val = FALSE;
break;
case GDK_Down:
- if (eti->cursor_row != view_to_model_row(eti, eti->rows - 1))
+ if (cursor_row != view_to_model_row(eti, eti->rows - 1))
eti_cursor_move_down (eti);
else
return_val = FALSE;
@@ -1435,17 +1527,17 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
case GDK_ISO_Left_Tab:
if ((e->key.state & GDK_SHIFT_MASK) != 0){
/* shift tab */
- if (eti->cursor_col > 0)
+ if (cursor_col > 0)
eti_cursor_move_left (eti);
- else if (eti->cursor_row != view_to_model_row(eti, 0))
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row) - 1, eti->cols - 1);
+ else if (cursor_row != view_to_model_row(eti, 0))
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row) - 1, eti->cols - 1);
else
return_val = FALSE;
} else {
- if (eti->cursor_col < eti->cols - 1)
+ if (cursor_col < eti->cols - 1)
eti_cursor_move_right (eti);
- else if (eti->cursor_row != view_to_model_row(eti, eti->rows - 1))
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row) + 1, 0);
+ else if (cursor_row != view_to_model_row(eti, eti->rows - 1))
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row) + 1, 0);
else
return_val = FALSE;
}
@@ -1454,17 +1546,25 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
default:
if (!eti_editing (eti)){
gtk_signal_emit (GTK_OBJECT (eti), eti_signals [KEY_PRESS],
- model_to_view_row(eti, eti->cursor_row), eti->cursor_col, e, &return_val);
+ model_to_view_row(eti, cursor_row), cursor_col, e, &return_val);
} else {
- ecol = e_table_header_get_column (eti->header, eti->cursor_col);
- ecell_view = eti->cell_views [eti->cursor_col];
- e_cell_event (ecell_view, e, ecol->col_idx, eti->cursor_col, model_to_view_row(eti, eti->cursor_row));
+ ecol = e_table_header_get_column (eti->header, cursor_col);
+ ecell_view = eti->cell_views [cursor_col];
+ e_cell_event (ecell_view, e, ecol->col_idx, cursor_col, model_to_view_row(eti, cursor_row));
}
}
break;
+ }
- case GDK_KEY_RELEASE:
- if (eti->cursor_col == -1)
+ case GDK_KEY_RELEASE: {
+ gint cursor_row, cursor_col;
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_col == -1)
return FALSE;
if (eti_editing (eti)){
@@ -1473,6 +1573,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e_cell_event (ecell_view, e, ecol->col_idx, eti->editing_col, eti->editing_row);
}
break;
+ }
default:
return_val = FALSE;
@@ -1480,21 +1581,6 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
return return_val;
}
-/*
- * ETableItem::row_selection method
- */
-static void
-eti_row_selection (ETableItem *eti, int row, gboolean selected)
-{
- int view_row = model_to_view_row(eti, row);
- eti_request_region_redraw (eti, 0, view_row, eti->cols - 1, view_row, 0);
-
- if (selected)
- eti->selection = g_slist_prepend (eti->selection, GINT_TO_POINTER (row));
- else
- eti->selection = g_slist_remove (eti->selection, GINT_TO_POINTER (row));
-}
-
static void
eti_class_init (GtkObjectClass *object_class)
{
@@ -1514,7 +1600,6 @@ eti_class_init (GtkObjectClass *object_class)
item_class->point = eti_point;
item_class->event = eti_event;
- eti_class->row_selection = eti_row_selection;
eti_class->cursor_change = NULL;
eti_class->double_click = NULL;
eti_class->right_click = NULL;
@@ -1524,6 +1609,8 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
gtk_object_add_arg_type ("ETableItem::ETableModel", GTK_TYPE_OBJECT,
GTK_ARG_WRITABLE, ARG_TABLE_MODEL);
+ gtk_object_add_arg_type ("ETableItem::table_selection_model", GTK_TYPE_OBJECT,
+ GTK_ARG_WRITABLE, ARG_TABLE_SELECTION_MODEL);
gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
gtk_object_add_arg_type ("ETableItem::drawfocus", GTK_TYPE_BOOL,
@@ -1539,19 +1626,9 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_READWRITE, ARG_WIDTH);
gtk_object_add_arg_type ("ETableItem::height", GTK_TYPE_DOUBLE,
GTK_ARG_READABLE, ARG_HEIGHT);
- gtk_object_add_arg_type ("ETableItem::has_cursor", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_HAS_CURSOR);
gtk_object_add_arg_type ("ETableItem::cursor_row", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_CURSOR_ROW);
- eti_signals [ROW_SELECTION] =
- gtk_signal_new ("row_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETableItemClass, row_selection),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
eti_signals [CURSOR_CHANGE] =
gtk_signal_new ("cursor_change",
GTK_RUN_LAST,
@@ -1614,11 +1691,11 @@ e_table_item_get_type (void)
void
e_table_item_set_cursor (ETableItem *eti, int col, int row)
{
- e_table_item_focus(eti, col, view_to_model_row(eti, row), FALSE);
+ e_table_item_focus(eti, col, view_to_model_row(eti, row), FALSE, FALSE);
}
static void
-e_table_item_focus (ETableItem *eti, int col, int row, gboolean add_selection)
+e_table_item_focus (ETableItem *eti, int col, int row, gboolean shift_p, gboolean ctrl_p)
{
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
@@ -1632,34 +1709,26 @@ e_table_item_focus (ETableItem *eti, int col, int row, gboolean add_selection)
}
if (row != -1) {
- int *nums;
- nums = g_new(int, 2);
- nums[0] = row;
- nums[1] = col;
- if (add_selection)
- e_canvas_item_add_selection(GNOME_CANVAS_ITEM(eti), nums);
- else
- e_canvas_item_set_cursor(GNOME_CANVAS_ITEM(eti), nums);
+ e_table_selection_model_do_something(eti->selection,
+ row, col,
+ shift_p,
+ ctrl_p);
}
}
gint
e_table_item_get_focused_column (ETableItem *eti)
{
+ int cursor_col;
+
g_return_val_if_fail (eti != NULL, -1);
g_return_val_if_fail (E_IS_TABLE_ITEM (eti), -1);
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ NULL);
- return eti->cursor_col;
-}
-
-
-const GSList *
-e_table_item_get_selection (ETableItem *eti)
-{
- g_return_val_if_fail (eti != NULL, NULL);
- g_return_val_if_fail (E_IS_TABLE_ITEM (eti), NULL);
-
- return eti->selection;
+ return cursor_col;
}
gboolean
@@ -1668,91 +1737,28 @@ e_table_item_is_row_selected (ETableItem *eti, int row)
g_return_val_if_fail (eti != NULL, FALSE);
g_return_val_if_fail (E_IS_TABLE_ITEM (eti), FALSE);
- if (g_slist_find (eti->selection, GINT_TO_POINTER (row)))
- return TRUE;
- else
- return FALSE;
-}
-
-void e_table_item_selected_row_foreach (ETableItem *eti,
- ETableForeachFunc func,
- gpointer closure)
-{
- GSList *list = eti->selection;
- for (; list; list = g_slist_next(list)) {
- (func) (GPOINTER_TO_INT(list->data), closure);
- }
-}
-
-static void
-e_table_item_unselect_row (ETableItem *eti, int row)
-{
- g_return_if_fail (eti != NULL);
- g_return_if_fail (E_IS_TABLE_ITEM (eti));
-
- gtk_signal_emit (GTK_OBJECT (eti), eti_signals [ROW_SELECTION],
- row, 0);
+ return e_table_selection_model_is_row_selected(eti->selection, row);
}
static void
-e_table_item_select_row (ETableItem *eti, int row)
+eti_cursor_change (ETableSelectionModel *selection, int row, int col, ETableItem *eti)
{
- g_return_if_fail (eti != NULL);
- g_return_if_fail (E_IS_TABLE_ITEM (eti));
-
- gtk_signal_emit (GTK_OBJECT (eti), eti_signals [ROW_SELECTION],
- GINT_TO_POINTER (row), 1);
-}
-
-static void
-eti_selection (GnomeCanvasItem *item, int flags, gpointer data)
-{
- int *nums = data;
- int row = nums[0];
- int col = nums[1];
- ETableItem *eti = E_TABLE_ITEM(item);
- int selected = e_table_item_is_row_selected(eti, row);
- int cursored = (row == eti->cursor_row);
+ int view_row = model_to_view_row(eti, row);
- if (selected && (flags & E_CANVAS_ITEM_SELECTION_SELECT) == 0) {
- e_table_item_unselect_row (eti, row);
- }
- if ((!selected) && (flags & E_CANVAS_ITEM_SELECTION_SELECT) != 0) {
- e_table_item_select_row (eti, row);
- }
- if ((!cursored) && (flags & E_CANVAS_ITEM_SELECTION_CURSOR) != 0) {
- int view_row = model_to_view_row(eti, row);
-
- eti->cursor_col = col;
- eti->cursor_row = row;
- gtk_signal_emit (GTK_OBJECT (eti), eti_signals [CURSOR_CHANGE],
- view_row);
- eti_request_region_show (eti, col, view_row, col, view_row);
- }
- if ((cursored) && (flags & E_CANVAS_ITEM_SELECTION_CURSOR) == 0) {
- e_table_item_leave_edit(eti);
- eti->cursor_row = -1;
- eti->cursor_col = -1;
- }
- if (flags & E_CANVAS_ITEM_SELECTION_DELETE_DATA) {
- g_free(data);
- }
+ gtk_signal_emit (GTK_OBJECT (eti), eti_signals [CURSOR_CHANGE],
+ view_row);
+ eti_request_region_show (eti, col, view_row, col, view_row);
+ if (e_table_model_is_cell_editable(selection->model, col, row))
+ e_table_item_enter_edit (eti, col, view_row);
}
-static gint
-eti_selection_compare (GnomeCanvasItem *item, gpointer data1, gpointer data2, int flags)
+static void
+eti_selection_change (ETableSelectionModel *selection, ETableItem *eti)
{
- int *val1 = (int *) data1;
- int *val2 = (int *) data2;
- if (*val1 < *val2)
- return -1;
- else if (*val1 == *val2)
- return 0;
- else
- return 1;
+ eti->needs_redraw = TRUE;
+ gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(eti));
}
-
void
e_table_item_enter_edit (ETableItem *eti, int col, int row)
{
@@ -1760,6 +1766,9 @@ e_table_item_enter_edit (ETableItem *eti, int col, int row)
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ if (eti_editing (eti))
+ e_table_item_leave_edit(eti);
eti->editing_col = col;
eti->editing_row = row;
diff --git a/widgets/e-table/e-table-item.h b/widgets/e-table/e-table-item.h
index 619db68803..7102ef3ef7 100644
--- a/widgets/e-table/e-table-item.h
+++ b/widgets/e-table/e-table-item.h
@@ -5,6 +5,7 @@
#include <libgnomeui/gnome-canvas.h>
#include "e-table-model.h"
#include "e-table-header.h"
+#include "e-table-selection-model.h"
#include "e-table-defines.h"
#include <e-util/e-printable.h>
@@ -27,6 +28,7 @@ typedef struct {
ETableHeader *header;
ETableModel *source_model;
+ ETableSelectionModel *selection;
int x1, y1;
int minimum_width, width, height;
@@ -43,6 +45,9 @@ typedef struct {
int table_model_cell_change_id;
int table_model_row_inserted_id;
int table_model_row_deleted_id;
+
+ int selection_change_id;
+ int cursor_change_id;
GdkGC *fill_gc;
GdkGC *grid_gc;
@@ -77,12 +82,8 @@ typedef struct {
int length_threshold;
gint row_guess;
- gint cursor_row;
- gint cursor_col;
ETableCursorMode cursor_mode;
- GSList *selection;
-
/*
* During editing
*/
@@ -94,7 +95,6 @@ typedef struct {
typedef struct {
GnomeCanvasItemClass parent_class;
- void (*row_selection) (ETableItem *eti, int row, gboolean selected);
void (*cursor_change) (ETableItem *eti, int row);
void (*double_click) (ETableItem *eti, int row);
gint (*right_click) (ETableItem *eti, int row, int col, GdkEvent *event);
@@ -114,7 +114,6 @@ gint e_table_item_get_focused_column (ETableItem *eti);
/*
* Handling the selection
*/
-const GSList *e_table_item_get_selection (ETableItem *e_table_Item);
gboolean e_table_item_is_row_selected (ETableItem *e_table_Item,
int row);
diff --git a/widgets/e-table/e-table-scrolled.c b/widgets/e-table/e-table-scrolled.c
index b8260b6407..1a7b5251ad 100644
--- a/widgets/e-table/e-table-scrolled.c
+++ b/widgets/e-table/e-table-scrolled.c
@@ -28,7 +28,6 @@
static GtkObjectClass *parent_class;
enum {
- ROW_SELECTION,
CURSOR_CHANGE,
DOUBLE_CLICK,
RIGHT_CLICK,
@@ -48,14 +47,6 @@ enum {
static gint ets_signals [LAST_SIGNAL] = { 0, };
static void
-row_selection_proxy (ETable *et, int row, gboolean selected, ETableScrolled *ets)
-{
- gtk_signal_emit (GTK_OBJECT (ets),
- ets_signals [ROW_SELECTION],
- row, selected);
-}
-
-static void
cursor_change_proxy (ETable *et, int row, ETableScrolled *ets)
{
gtk_signal_emit (GTK_OBJECT (ets),
@@ -117,8 +108,6 @@ e_table_scrolled_real_construct (ETableScrolled *ets)
gtk_container_add(GTK_CONTAINER(ets), GTK_WIDGET(ets->table));
- gtk_signal_connect(GTK_OBJECT(ets->table), "row_selection",
- GTK_SIGNAL_FUNC(row_selection_proxy), ets);
gtk_signal_connect(GTK_OBJECT(ets->table), "cursor_change",
GTK_SIGNAL_FUNC(cursor_change_proxy), ets);
gtk_signal_connect(GTK_OBJECT(ets->table), "double_click",
@@ -297,20 +286,11 @@ e_table_scrolled_class_init (GtkObjectClass *object_class)
object_class->set_arg = ets_set_arg;
object_class->get_arg = ets_get_arg;
- klass->row_selection = NULL;
klass->cursor_change = NULL;
klass->double_click = NULL;
klass->right_click = NULL;
klass->key_press = NULL;
- ets_signals [ROW_SELECTION] =
- gtk_signal_new ("row_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETableScrolledClass, row_selection),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
ets_signals [CURSOR_CHANGE] =
gtk_signal_new ("cursor_change",
GTK_RUN_LAST,
diff --git a/widgets/e-table/e-table-scrolled.h b/widgets/e-table/e-table-scrolled.h
index daaf4429a0..d5a0c06a58 100644
--- a/widgets/e-table/e-table-scrolled.h
+++ b/widgets/e-table/e-table-scrolled.h
@@ -25,7 +25,6 @@ typedef struct {
typedef struct {
EScrollFrameClass parent_class;
- void (*row_selection) (ETableScrolled *est, int row, gboolean selected);
void (*cursor_change) (ETableScrolled *est, int row);
void (*double_click) (ETableScrolled *est, int row);
gint (*right_click) (ETableScrolled *est, int row, int col, GdkEvent *event);
diff --git a/widgets/e-table/e-table-selection-model.c b/widgets/e-table/e-table-selection-model.c
index 9c631ca603..35e0cb13aa 100644
--- a/widgets/e-table/e-table-selection-model.c
+++ b/widgets/e-table/e-table-selection-model.c
@@ -15,36 +15,49 @@
#define ETSM_CLASS(e) ((ETableSelectionModelClass *)((GtkObject *)e)->klass)
#define PARENT_TYPE gtk_object_get_type ()
-
+
+#define ONES ((guint32) 0xffffffff)
+
+#define BOX(n) ((n) / 32)
+#define OFFSET(n) (31 - ((n) % 32))
+#define BITMASK(n) (((guint32) 0x1) << OFFSET(n))
+#define BITMASK_LEFT(n) (((guint32) ONES) << (32 - ((n) % 32)))
+#define BITMASK_RIGHT(n) (((guint32) ONES) >> ((n) % 32))
static GtkObjectClass *e_table_selection_model_parent_class;
enum {
- SELECTION_MODEL_CHANGED,
- GROUP_SELECTION_CHANGED,
+ CURSOR_CHANGED,
+ SELECTION_CHANGED,
LAST_SIGNAL
};
static guint e_table_selection_model_signals [LAST_SIGNAL] = { 0, };
+enum {
+ ARG_0,
+ ARG_MODEL,
+ ARG_CURSOR_ROW,
+ ARG_CURSOR_COL,
+};
+
static void
model_changed(ETableModel *etm, ETableSelectionModel *etsm)
{
g_free(etsm->selection);
etsm->selection = NULL;
etsm->row_count = -1;
+ gtk_signal_emit(GTK_OBJECT(etsm),
+ e_table_selection_model_signals [SELECTION_CHANGED]);
}
+#if 1
static void
model_row_inserted(ETableModel *etm, int row, ETableSelectionModel *etsm)
{
int box;
int i;
- int offset;
if(etsm->row_count >= 0) {
- guint32 bitmask1 = 0xffff;
- guint32 bitmask2;
-
/* Add another word if needed. */
if ((etsm->row_count & 0x1f) == 0) {
etsm->selection = g_realloc(etsm->selection, (etsm->row_count >> 5) + 1);
@@ -58,12 +71,8 @@ model_row_inserted(ETableModel *etm, int row, ETableSelectionModel *etsm)
etsm->selection[i] = (etsm->selection[i] >> 1) | (etsm->selection[i - 1] << 31);
}
- /* Build bitmasks for the left and right half of the box */
- offset = row & 0x1f;
- bitmask1 = bitmask1 << (32 - offset);
- bitmask2 = ~bitmask1;
/* Shift right half of box one bit to the right. */
- etsm->selection[box] = (etsm->selection[box] & bitmask1) | ((etsm->selection[box] & bitmask2) >> 1);
+ etsm->selection[box] = (etsm->selection[box] & BITMASK_LEFT(row)) | ((etsm->selection[box] & BITMASK_RIGHT(row)) >> 1);
etsm->row_count ++;
}
}
@@ -74,19 +83,15 @@ model_row_deleted(ETableModel *etm, int row, ETableSelectionModel *etsm)
int box;
int i;
int last;
- int offset;
if(etsm->row_count >= 0) {
- guint32 bitmask1 = 0xffff;
- guint32 bitmask2;
+ guint32 bitmask;
box = row >> 5;
last = etsm->row_count >> 5;
/* Build bitmasks for the left and right half of the box */
- offset = row & 0x1f;
- bitmask1 = bitmask1 << (32 - offset);
- bitmask2 = (~bitmask1) >> 1;
+ bitmask = BITMASK_RIGHT(row) >> 1;
/* Shift right half of box one bit to the left. */
- etsm->selection[box] = (etsm->selection[box] & bitmask1) | ((etsm->selection[box] & bitmask2) << 1);
+ etsm->selection[box] = (etsm->selection[box] & BITMASK_LEFT(row))| ((etsm->selection[box] & bitmask) << 1);
/* Shift all words to the right of our box left one bit. */
if (box < last) {
@@ -105,6 +110,21 @@ model_row_deleted(ETableModel *etm, int row, ETableSelectionModel *etsm)
}
}
+#else
+
+static void
+model_row_inserted(ETableModel *etm, int row, ETableSelectionModel *etsm)
+{
+ model_changed(etm, etsm);
+}
+
+static void
+model_row_deleted(ETableModel *etm, int row, ETableSelectionModel *etsm)
+{
+ model_changed(etm, etsm);
+}
+#endif
+
inline static void
add_model(ETableSelectionModel *etsm, ETableModel *model)
{
@@ -141,15 +161,59 @@ etsm_destroy (GtkObject *object)
ETableSelectionModel *etsm;
etsm = E_TABLE_SELECTION_MODEL (object);
-
+
+ drop_model(etsm);
+
g_free(etsm->selection);
}
static void
+etsm_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableSelectionModel *etsm = E_TABLE_SELECTION_MODEL (o);
+
+ switch (arg_id){
+ case ARG_MODEL:
+ GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(etsm->model);
+ break;
+
+ case ARG_CURSOR_ROW:
+ GTK_VALUE_INT(*arg) = etsm->cursor_row;
+ break;
+
+ case ARG_CURSOR_COL:
+ GTK_VALUE_INT(*arg) = etsm->cursor_col;
+ break;
+ }
+}
+
+static void
+etsm_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableSelectionModel *etsm = E_TABLE_SELECTION_MODEL (o);
+
+ switch (arg_id){
+ case ARG_MODEL:
+ drop_model(etsm);
+ add_model(etsm, GTK_VALUE_OBJECT (*arg) ? E_TABLE_MODEL(GTK_VALUE_OBJECT (*arg)) : NULL);
+ break;
+
+ case ARG_CURSOR_ROW:
+ e_table_selection_model_do_something(etsm, GTK_VALUE_INT(*arg), etsm->cursor_col, FALSE, FALSE);
+ break;
+
+ case ARG_CURSOR_COL:
+ e_table_selection_model_do_something(etsm, etsm->cursor_row, GTK_VALUE_INT(*arg), FALSE, FALSE);
+ break;
+ }
+}
+
+static void
e_table_selection_model_init (ETableSelectionModel *selection)
{
selection->selection = NULL;
selection->row_count = -1;
+ selection->model = NULL;
}
static void
@@ -160,29 +224,38 @@ e_table_selection_model_class_init (ETableSelectionModelClass *klass)
e_table_selection_model_parent_class = gtk_type_class (gtk_object_get_type ());
object_class = GTK_OBJECT_CLASS(klass);
-
+
object_class->destroy = etsm_destroy;
-#if 0
- e_table_selection_model_signals [SELECTION_MODEL_CHANGED] =
- gtk_signal_new ("selection_model_changed",
+ object_class->get_arg = etsm_get_arg;
+ object_class->set_arg = etsm_set_arg;
+
+ e_table_selection_model_signals [CURSOR_CHANGED] =
+ gtk_signal_new ("cursor_changed",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (ETableSelectionModelClass, selection_model_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
+ GTK_SIGNAL_OFFSET (ETableSelectionModelClass, cursor_changed),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
- e_table_selection_model_signals [GROUP_SELECTION_CHANGED] =
- gtk_signal_new ("group_selection_changed",
+ e_table_selection_model_signals [SELECTION_CHANGED] =
+ gtk_signal_new ("selection_changed",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (ETableSelectionModelClass, group_selection_changed),
+ GTK_SIGNAL_OFFSET (ETableSelectionModelClass, selection_changed),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
- klass->selection_model_changed = NULL;
- klass->group_selection_changed = NULL;
-#endif
+ klass->cursor_changed = NULL;
+ klass->selection_changed = NULL;
+
gtk_object_class_add_signals (object_class, e_table_selection_model_signals, LAST_SIGNAL);
+
+ gtk_object_add_arg_type ("ETableSelectionModel::model", GTK_TYPE_OBJECT,
+ GTK_ARG_READWRITE, ARG_MODEL);
+ gtk_object_add_arg_type ("ETableSelectionModel::cursor_row", GTK_TYPE_INT,
+ GTK_ARG_READWRITE, ARG_CURSOR_ROW);
+ gtk_object_add_arg_type ("ETableSelectionModel::cursor_col", GTK_TYPE_INT,
+ GTK_ARG_READWRITE, ARG_CURSOR_COL);
}
E_MAKE_TYPE(e_table_selection_model, "ETableSelectionModel", ETableSelectionModel,
@@ -196,12 +269,12 @@ e_table_selection_model_new (void)
gboolean
e_table_selection_model_is_row_selected (ETableSelectionModel *selection,
- guint n)
+ gint n)
{
if (selection->row_count < n)
return 0;
else
- return ((selection->selection[n / 32]) >> (31 - (n % 32))) & 0x1;
+ return (selection->selection[BOX(n)] >> OFFSET(n)) & 0x1;
}
void
@@ -211,12 +284,12 @@ e_table_selection_model_foreach (ETableSelectionModel *selection,
{
int i;
int last = (selection->row_count + 31) / 32;
- for (i = 0; i < last; i--) {
+ for (i = 0; i < last; i++) {
if (selection->selection[i]) {
int j;
guint32 value = selection->selection[i];
- for (j = 0; j < 32; j--) {
- if (value & 0x8000) {
+ for (j = 0; j < 32; j++) {
+ if (value & 0x80000000) {
callback(i * 32 + j, closure);
}
value <<= 1;
@@ -224,3 +297,92 @@ e_table_selection_model_foreach (ETableSelectionModel *selection,
}
}
}
+
+#define OPERATE(object, mask, grow) ((grow) ? ((object) |= ~(mask)) : ((object) &= (mask)))
+
+void e_table_selection_model_do_something (ETableSelectionModel *selection,
+ guint row,
+ guint col,
+ gboolean shift_p,
+ gboolean ctrl_p)
+{
+ if (selection->row_count < 0) {
+ if (selection->model) {
+ selection->row_count = e_table_model_row_count(selection->model);
+ g_free(selection->selection);
+ selection->selection = g_new0(gint, (selection->row_count + 31) / 32);
+ }
+ }
+ if (selection->row_count >= 0 && row < selection->row_count) {
+ if (shift_p) {
+ int grow_selection;
+ int i;
+ int last;
+ int first_row;
+ int last_row;
+ if ((selection->selection_start_row < row && row <= selection->cursor_row) ||
+ (selection->selection_start_row >= row && row >= selection->cursor_row)) {
+ /* In this case, the selection is shrinking. */
+ grow_selection = FALSE;
+ } else if ((selection->selection_start_row <= selection->cursor_row && selection->cursor_row <= row) ||
+ (selection->selection_start_row > selection->cursor_row && selection->cursor_row >= row)) {
+ /* In this case, the selection is growing. */
+ grow_selection = TRUE;
+ } else {
+ /* In this case the selection is changing direction. Ick. Screw it. */
+ return;
+ }
+ first_row = MIN(selection->cursor_row, row);
+ last_row = MAX(selection->cursor_row, row) + 1;
+ if (first_row != last_row) {
+ i = BOX(first_row);
+ last = BOX(last_row);
+
+ if (i == last) {
+ OPERATE(selection->selection[i], BITMASK_LEFT(first_row) | BITMASK_RIGHT(last_row), grow_selection);
+ } else {
+ OPERATE(selection->selection[i], BITMASK_LEFT(first_row), grow_selection);
+ for (i ++; i < last; i++)
+ if (grow_selection)
+ selection->selection[i] = ONES;
+ else
+ selection->selection[i] = 0;
+ OPERATE(selection->selection[i], BITMASK_RIGHT(last_row), grow_selection);
+ }
+ gtk_signal_emit(GTK_OBJECT(selection),
+ e_table_selection_model_signals [SELECTION_CHANGED]);
+ }
+ } else {
+ if (ctrl_p) {
+ if (selection->selection[BOX(row)] & BITMASK(row))
+ selection->selection[BOX(row)] &= ~BITMASK(row);
+ else
+ selection->selection[BOX(row)] |= BITMASK(row);
+ gtk_signal_emit(GTK_OBJECT(selection),
+ e_table_selection_model_signals [SELECTION_CHANGED]);
+ } else {
+ int i;
+ for (i = 0; i < ((selection->row_count + 31) / 32); i++) {
+ if (!((i == BOX(row) && selection->selection[i] == BITMASK(row)) ||
+ (i != BOX(row) && selection->selection[i] == 0))) {
+ g_free(selection->selection);
+ selection->selection = g_new0(gint, (selection->row_count + 31) / 32);
+ selection->selection[BOX(row)] = BITMASK(row);
+
+ gtk_signal_emit(GTK_OBJECT(selection),
+ e_table_selection_model_signals [SELECTION_CHANGED]);
+ break;
+ }
+ }
+ }
+ selection->selection_start_row = row;
+ }
+ if (selection->cursor_row != row ||
+ selection->cursor_col != col) {
+ gtk_signal_emit(GTK_OBJECT(selection),
+ e_table_selection_model_signals[CURSOR_CHANGED], row, col);
+ selection->cursor_row = row;
+ selection->cursor_col = col;
+ }
+ }
+}
diff --git a/widgets/e-table/e-table-selection-model.h b/widgets/e-table/e-table-selection-model.h
index 2aaba021f8..251b1ceb00 100644
--- a/widgets/e-table/e-table-selection-model.h
+++ b/widgets/e-table/e-table-selection-model.h
@@ -19,13 +19,14 @@ typedef struct {
gint row_count;
guint32 *selection;
-
+
gint cursor_row;
gint cursor_col;
+ gint selection_start_row;
guint model_changed_id;
guint model_row_inserted_id, model_row_deleted_id;
-
+
guint frozen : 1;
guint selection_model_changed : 1;
guint group_info_changed : 1;
@@ -37,20 +38,26 @@ typedef struct {
/*
* Signals
*/
-#if 0
- void (*selection_model_changed) (ETableSelectionModel *selection);
- void (*group_model_changed) (ETableSelectionModel *selection);
-#endif
+
+ void (*cursor_changed) (ETableSelectionModel *selection, int row, int col);
+ void (*selection_changed) (ETableSelectionModel *selection);
+
} ETableSelectionModelClass;
GtkType e_table_selection_model_get_type (void);
-gboolean e_table_selection_model_is_row_selected (ETableSelectionModel *selection,
- guint n);
-void e_table_selection_model_foreach (ETableSelectionModel *selection,
- ETableForeachFunc callback,
- gpointer closure);
+gboolean e_table_selection_model_is_row_selected (ETableSelectionModel *selection,
+ gint n);
+void e_table_selection_model_foreach (ETableSelectionModel *selection,
+ ETableForeachFunc callback,
+ gpointer closure);
+
+void e_table_selection_model_do_something (ETableSelectionModel *selection,
+ guint row,
+ guint col,
+ gboolean shift_p,
+ gboolean ctrl_p);
-ETableSelectionModel *e_table_selection_model_new (void);
+ETableSelectionModel *e_table_selection_model_new (void);
#endif /* _E_TABLE_SELECTION_MODEL_H_ */
diff --git a/widgets/e-table/e-table.c b/widgets/e-table/e-table.c
index c20c7cd21e..ae258a5c44 100644
--- a/widgets/e-table/e-table.c
+++ b/widgets/e-table/e-table.c
@@ -40,7 +40,6 @@
static GtkObjectClass *e_table_parent_class;
enum {
- ROW_SELECTION,
CURSOR_CHANGE,
DOUBLE_CLICK,
RIGHT_CLICK,
@@ -183,6 +182,8 @@ e_table_init (GtkObject *object)
e_table->drag_col = -1;
e_table->drop_row = -1;
e_table->drop_col = -1;
+
+ e_table->selection = e_table_selection_model_new();
}
static void
@@ -270,18 +271,6 @@ table_canvas_reflow (GnomeCanvas *canvas, ETable *e_table)
}
static void
-group_row_selection (ETableGroup *etg, int row, gboolean selected, ETable *et)
-{
- gtk_signal_emit (GTK_OBJECT (et),
- et_signals [ROW_SELECTION],
- row, selected);
- if (et->row_selection_active && selected) {
- e_table_click_to_add_commit (E_TABLE_CLICK_TO_ADD(et->click_to_add));
- et->row_selection_active = FALSE;
- }
-}
-
-static void
group_cursor_change (ETableGroup *etg, int row, ETable *et)
{
gtk_signal_emit (GTK_OBJECT (et),
@@ -336,9 +325,8 @@ changed_idle (gpointer data)
"drawfocus", et->draw_focus,
"cursor_mode", et->cursor_mode,
"length_threshold", et->length_threshold,
+ "table_selection_model", et->selection,
NULL);
- gtk_signal_connect (GTK_OBJECT (et->group), "row_selection",
- GTK_SIGNAL_FUNC (group_row_selection), et);
gtk_signal_connect (GTK_OBJECT (et->group), "cursor_change",
GTK_SIGNAL_FUNC (group_cursor_change), et);
gtk_signal_connect (GTK_OBJECT (et->group), "double_click",
@@ -400,14 +388,6 @@ et_table_row_deleted (ETableModel *table_model, int row, ETable *et)
}
static void
-click_to_add_row_selection (ETableClickToAdd *etcta, int row, gboolean selected, ETable *et)
-{
- if ((!et->row_selection_active) && selected) {
- et->row_selection_active = TRUE;
- }
-}
-
-static void
e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header,
ETableModel *model)
{
@@ -460,9 +440,6 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
"message", e_table->click_to_add_message,
NULL);
- gtk_signal_connect(GTK_OBJECT(e_table->click_to_add), "row_selection",
- GTK_SIGNAL_FUNC(click_to_add_row_selection), e_table);
-
e_canvas_vbox_add_item(E_CANVAS_VBOX(e_table->canvas_vbox), e_table->click_to_add);
}
@@ -477,10 +454,9 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
"drawfocus", e_table->draw_focus,
"cursor_mode", e_table->cursor_mode,
"length_threshold", e_table->length_threshold,
+ "table_selection_model", e_table->selection,
NULL);
- gtk_signal_connect (GTK_OBJECT (e_table->group), "row_selection",
- GTK_SIGNAL_FUNC(group_row_selection), e_table);
gtk_signal_connect (GTK_OBJECT (e_table->group), "cursor_change",
GTK_SIGNAL_FUNC(group_cursor_change), e_table);
gtk_signal_connect (GTK_OBJECT (e_table->group), "double_click",
@@ -607,6 +583,9 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
e_table->model = etm;
gtk_object_ref (GTK_OBJECT (etm));
+ gtk_object_set (GTK_OBJECT (e_table->selection),
+ "model", etm,
+ NULL);
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
@@ -812,9 +791,9 @@ e_table_selected_row_foreach (ETable *e_table,
ETableForeachFunc callback,
gpointer closure)
{
- e_table_group_selected_row_foreach(e_table->group,
- callback,
- closure);
+ e_table_selection_model_foreach(e_table->selection,
+ callback,
+ closure);
}
@@ -1240,7 +1219,6 @@ e_table_class_init (GtkObjectClass *object_class)
object_class->set_arg = et_set_arg;
object_class->get_arg = et_get_arg;
- klass->row_selection = NULL;
klass->cursor_change = NULL;
klass->double_click = NULL;
klass->right_click = NULL;
@@ -1256,14 +1234,6 @@ e_table_class_init (GtkObjectClass *object_class)
klass->table_drag_drop = NULL;
klass->table_drag_data_received = NULL;
- et_signals [ROW_SELECTION] =
- gtk_signal_new ("row_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETableClass, row_selection),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
et_signals [CURSOR_CHANGE] =
gtk_signal_new ("cursor_change",
GTK_RUN_LAST,
diff --git a/widgets/e-table/e-table.h b/widgets/e-table/e-table.h
index 06905a3711..a2e608b41e 100644
--- a/widgets/e-table/e-table.h
+++ b/widgets/e-table/e-table.h
@@ -80,7 +80,6 @@ typedef struct {
typedef struct {
GtkTableClass parent_class;
- void (*row_selection) (ETable *et, int row, gboolean selected);
void (*cursor_change) (ETable *et, int row);
void (*double_click) (ETable *et, int row);
gint (*right_click) (ETable *et, int row, int col, GdkEvent *event);
diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c
index f4e10917fb..f3788f154f 100644
--- a/widgets/table/e-table-group-container.c
+++ b/widgets/table/e-table-group-container.c
@@ -37,6 +37,7 @@ enum {
ARG_TABLE_DRAW_GRID,
ARG_TABLE_DRAW_FOCUS,
ARG_CURSOR_MODE,
+ ARG_TABLE_SELECTION_MODEL,
ARG_LENGTH_THRESHOLD,
};
@@ -97,6 +98,9 @@ etgc_destroy (GtkObject *object)
if (etgc->sort_info)
gtk_object_unref (GTK_OBJECT(etgc->sort_info));
+ if (etgc->table_selection_model)
+ gtk_object_unref (GTK_OBJECT(etgc->table_selection_model));
+
if (etgc->rect)
gtk_object_destroy (GTK_OBJECT(etgc->rect));
@@ -316,13 +320,6 @@ compute_text (ETableGroupContainer *etgc, ETableGroupContainerChildNode *child_n
}
static void
-child_row_selection (ETableGroup *etg, int row, gboolean selected,
- ETableGroupContainer *etgc)
-{
- e_table_group_row_selection (E_TABLE_GROUP (etgc), row, selected);
-}
-
-static void
child_cursor_change (ETableGroup *etg, int row,
ETableGroupContainer *etgc)
{
@@ -395,10 +392,9 @@ etgc_add (ETableGroup *etg, gint row)
"drawgrid", etgc->draw_grid,
"drawfocus", etgc->draw_focus,
"cursor_mode", etgc->cursor_mode,
+ "table_selection_model", etgc->table_selection_model,
"length_threshold", etgc->length_threshold,
NULL);
- gtk_signal_connect (GTK_OBJECT (child), "row_selection",
- GTK_SIGNAL_FUNC (child_row_selection), etgc);
gtk_signal_connect (GTK_OBJECT (child), "cursor_change",
GTK_SIGNAL_FUNC (child_cursor_change), etgc);
gtk_signal_connect (GTK_OBJECT (child), "double_click",
@@ -546,29 +542,6 @@ etgc_get_focus_column (ETableGroup *etg)
return 0;
}
-static void
-etgc_selected_row_foreach (ETableGroup *etg,
- ETableForeachFunc func,
- gpointer closure)
-{
- ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER(etg);
- if (etgc->children) {
- GList *list;
- for (list = etgc->children; list; list = list->next) {
- ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data;
- ETableGroup *child = child_node->child;
- e_table_group_selected_row_foreach (child, func, closure);
- }
- }
-}
-
-
-
-
-
-
-
-
static void etgc_thaw (ETableGroup *etg)
{
@@ -612,6 +585,20 @@ etgc_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
break;
+ case ARG_TABLE_SELECTION_MODEL:
+ if (etgc->table_selection_model)
+ gtk_object_unref(GTK_OBJECT(etgc->table_selection_model));
+ etgc->table_selection_model = E_TABLE_SELECTION_MODEL(GTK_VALUE_OBJECT (*arg));
+ if (etgc->table_selection_model)
+ gtk_object_ref(GTK_OBJECT(etgc->table_selection_model));
+ for (list = etgc->children; list; list = g_list_next (list)) {
+ ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *)list->data;
+ gtk_object_set (GTK_OBJECT(child_node->child),
+ "table_selection_model", etgc->table_selection_model,
+ NULL);
+ }
+ break;
+
case ARG_TABLE_DRAW_GRID:
etgc->draw_grid = GTK_VALUE_BOOL (*arg);
for (list = etgc->children; list; list = g_list_next (list)) {
@@ -697,7 +684,6 @@ etgc_class_init (GtkObjectClass *object_class)
e_group_class->get_cursor_row = etgc_get_cursor_row;
e_group_class->get_focus_column = etgc_get_focus_column;
e_group_class->get_printable = etgc_get_printable;
- e_group_class->selected_row_foreach = etgc_selected_row_foreach;
gtk_object_add_arg_type ("ETableGroupContainer::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
@@ -705,6 +691,8 @@ etgc_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_FOCUS);
gtk_object_add_arg_type ("ETableGroupContainer::cursor_mode", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_CURSOR_MODE);
+ gtk_object_add_arg_type ("ETableGroupContainer::table_selection_model", GTK_TYPE_OBJECT,
+ GTK_ARG_WRITABLE, ARG_TABLE_SELECTION_MODEL);
gtk_object_add_arg_type ("ETableGroupContainer::length_threshold", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_LENGTH_THRESHOLD);
@@ -811,6 +799,7 @@ etgc_init (GtkObject *object)
container->draw_focus = 1;
container->cursor_mode = E_TABLE_CURSOR_SIMPLE;
container->length_threshold = -1;
+ container->table_selection_model = NULL;
}
E_MAKE_TYPE (e_table_group_container, "ETableGroupContainer", ETableGroupContainer, etgc_class_init, etgc_init, PARENT_TYPE);
diff --git a/widgets/table/e-table-group-container.h b/widgets/table/e-table-group-container.h
index 1157768ea4..bdb717b92d 100644
--- a/widgets/table/e-table-group-container.h
+++ b/widgets/table/e-table-group-container.h
@@ -41,6 +41,8 @@ typedef struct {
int n;
int length_threshold;
+ ETableSelectionModel *table_selection_model;
+
guint draw_grid : 1;
guint draw_focus : 1;
ETableCursorMode cursor_mode;
diff --git a/widgets/table/e-table-group-leaf.c b/widgets/table/e-table-group-leaf.c
index 08c4c4a475..f6b540cdae 100644
--- a/widgets/table/e-table-group-leaf.c
+++ b/widgets/table/e-table-group-leaf.c
@@ -31,6 +31,7 @@ enum {
ARG_TABLE_DRAW_FOCUS,
ARG_CURSOR_MODE,
ARG_LENGTH_THRESHOLD,
+ ARG_TABLE_SELECTION_MODEL,
};
static void etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
@@ -44,6 +45,8 @@ etgl_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT(etgl->subset));
if (etgl->item)
gtk_object_destroy (GTK_OBJECT(etgl->item));
+ if (etgl->table_selection_model)
+ gtk_object_unref (GTK_OBJECT(etgl->table_selection_model));
if (GTK_OBJECT_CLASS (etgl_parent_class)->destroy)
GTK_OBJECT_CLASS (etgl_parent_class)->destroy (object);
}
@@ -81,13 +84,6 @@ e_table_group_leaf_new (GnomeCanvasGroup *parent,
}
static void
-etgl_row_selection (GtkObject *object, gint row, gboolean selected, ETableGroupLeaf *etgl)
-{
- if (row < E_TABLE_SUBSET(etgl->subset)->n_map)
- e_table_group_row_selection (E_TABLE_GROUP(etgl), E_TABLE_SUBSET(etgl->subset)->map_table[row], selected);
-}
-
-static void
etgl_cursor_change (GtkObject *object, gint row, ETableGroupLeaf *etgl)
{
if (row < E_TABLE_SUBSET(etgl->subset)->n_map)
@@ -149,10 +145,9 @@ etgl_realize (GnomeCanvasItem *item)
"cursor_mode", etgl->cursor_mode,
"minimum_width", etgl->minimum_width,
"length_threshold", etgl->length_threshold,
+ "table_selection_model", etgl->table_selection_model,
NULL));
- gtk_signal_connect (GTK_OBJECT(etgl->item), "row_selection",
- GTK_SIGNAL_FUNC(etgl_row_selection), etgl);
gtk_signal_connect (GTK_OBJECT(etgl->item), "cursor_change",
GTK_SIGNAL_FUNC(etgl_cursor_change), etgl);
gtk_signal_connect (GTK_OBJECT(etgl->item), "double_click",
@@ -245,15 +240,6 @@ etgl_get_printable (ETableGroup *etg)
}
static void
-etgl_selected_row_foreach(ETableGroup *etg,
- ETableForeachFunc func,
- gpointer closure)
-{
- ETableGroupLeaf *etgl = E_TABLE_GROUP_LEAF (etg);
- e_table_item_selected_row_foreach (etgl->item, func, closure);
-}
-
-static void
etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
ETableGroup *etg = E_TABLE_GROUP (object);
@@ -284,6 +270,17 @@ etgl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
NULL);
}
break;
+ case ARG_TABLE_SELECTION_MODEL:
+ if (etgl->table_selection_model)
+ gtk_object_unref(GTK_OBJECT(etgl->table_selection_model));
+ etgl->table_selection_model = E_TABLE_SELECTION_MODEL(GTK_VALUE_OBJECT (*arg));
+ if (etgl->table_selection_model)
+ gtk_object_ref(GTK_OBJECT(etgl->table_selection_model));
+ if (etgl->item) {
+ gnome_canvas_item_set (GNOME_CANVAS_ITEM(etgl->item),
+ "table_selection_model", etgl->table_selection_model,
+ NULL);
+ }
case ARG_TABLE_DRAW_GRID:
etgl->draw_grid = GTK_VALUE_BOOL (*arg);
@@ -365,7 +362,6 @@ etgl_class_init (GtkObjectClass *object_class)
e_group_class->get_cursor_row = etgl_get_cursor_row;
e_group_class->get_focus_column = etgl_get_focus_column;
e_group_class->get_printable = etgl_get_printable;
- e_group_class->selected_row_foreach = etgl_selected_row_foreach;
gtk_object_add_arg_type ("ETableGroupLeaf::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
@@ -375,6 +371,8 @@ etgl_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_CURSOR_MODE);
gtk_object_add_arg_type ("ETableGroupLeaf::length_threshold", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_LENGTH_THRESHOLD);
+ gtk_object_add_arg_type ("ETableGroupLeaf::table_selection_model", GTK_TYPE_OBJECT,
+ GTK_ARG_WRITABLE, ARG_TABLE_SELECTION_MODEL);
gtk_object_add_arg_type ("ETableGroupLeaf::height", GTK_TYPE_DOUBLE,
GTK_ARG_READABLE, ARG_HEIGHT);
@@ -403,6 +401,8 @@ etgl_init (GtkObject *object)
etgl->cursor_mode = E_TABLE_CURSOR_SIMPLE;
etgl->length_threshold = -1;
+ etgl->table_selection_model = NULL;
+
e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM(object), etgl_reflow);
}
diff --git a/widgets/table/e-table-group-leaf.h b/widgets/table/e-table-group-leaf.h
index 365f268307..1cc041206b 100644
--- a/widgets/table/e-table-group-leaf.h
+++ b/widgets/table/e-table-group-leaf.h
@@ -32,6 +32,8 @@ typedef struct {
guint draw_grid : 1;
guint draw_focus : 1;
ETableCursorMode cursor_mode;
+
+ ETableSelectionModel *table_selection_model;
} ETableGroupLeaf;
typedef struct {
diff --git a/widgets/table/e-table-group.c b/widgets/table/e-table-group.c
index 18f8084b2c..d3c6e2e08d 100644
--- a/widgets/table/e-table-group.c
+++ b/widgets/table/e-table-group.c
@@ -25,7 +25,6 @@
static GnomeCanvasGroupClass *etg_parent_class;
enum {
- ROW_SELECTION,
CURSOR_CHANGE,
DOUBLE_CLICK,
RIGHT_CLICK,
@@ -240,31 +239,6 @@ e_table_group_get_printable (ETableGroup *etg)
}
void
-e_table_group_selected_row_foreach (ETableGroup *etg,
- ETableForeachFunc func,
- gpointer closure)
-{
- g_return_if_fail (etg != NULL);
- g_return_if_fail (E_IS_TABLE_GROUP (etg));
-
- if (ETG_CLASS (etg)->selected_row_foreach)
- ETG_CLASS (etg)->selected_row_foreach (etg, func, closure);
-}
-
-
-
-void
-e_table_group_row_selection (ETableGroup *e_table_group, gint row, gboolean selected)
-{
- g_return_if_fail (e_table_group != NULL);
- g_return_if_fail (E_IS_TABLE_GROUP (e_table_group));
-
- gtk_signal_emit (GTK_OBJECT (e_table_group),
- etg_signals [ROW_SELECTION],
- row, selected);
-}
-
-void
e_table_group_cursor_change (ETableGroup *e_table_group, gint row)
{
g_return_if_fail (e_table_group != NULL);
@@ -364,7 +338,6 @@ etg_class_init (GtkObjectClass *object_class)
item_class->event = etg_event;
- klass->row_selection = NULL;
klass->cursor_change = NULL;
klass->double_click = NULL;
klass->right_click = NULL;
@@ -382,18 +355,9 @@ etg_class_init (GtkObjectClass *object_class)
klass->get_focus = etg_get_focus;
klass->get_ecol = NULL;
klass->get_printable = NULL;
- klass->selected_row_foreach = NULL;
etg_parent_class = gtk_type_class (PARENT_TYPE);
- etg_signals [ROW_SELECTION] =
- gtk_signal_new ("row_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETableGroupClass, row_selection),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
etg_signals [CURSOR_CHANGE] =
gtk_signal_new ("cursor_change",
GTK_RUN_LAST,
diff --git a/widgets/table/e-table-group.h b/widgets/table/e-table-group.h
index ef6be1d35f..f4fd25a779 100644
--- a/widgets/table/e-table-group.h
+++ b/widgets/table/e-table-group.h
@@ -45,7 +45,6 @@ typedef struct {
GnomeCanvasGroupClass parent_class;
/* Signals */
- void (*row_selection) (ETableGroup *etg, int row, gboolean selected);
void (*cursor_change) (ETableGroup *etg, int row);
void (*double_click) (ETableGroup *etg, int row);
gint (*right_click) (ETableGroup *etg, int row, int col, GdkEvent *event);
@@ -65,7 +64,6 @@ typedef struct {
gint (*get_focus_column) (ETableGroup *etg);
ETableCol *(*get_ecol) (ETableGroup *etg);
EPrintable *(*get_printable) (ETableGroup *etg);
- void (*selected_row_foreach) (ETableGroup *etg, ETableForeachFunc func, gpointer closure);
} ETableGroupClass;
@@ -91,9 +89,6 @@ gint e_table_group_get_focus_column (ETableGroup *etg);
ETableHeader *e_table_group_get_header (ETableGroup *etg);
ETableCol *e_table_group_get_ecol (ETableGroup *etg);
EPrintable *e_table_group_get_printable (ETableGroup *etg);
-void e_table_group_selected_row_foreach (ETableGroup *etg,
- ETableForeachFunc func,
- gpointer closure);
ETableGroup *e_table_group_new (GnomeCanvasGroup *parent,
ETableHeader *full_header,
@@ -108,9 +103,6 @@ void e_table_group_construct (GnomeCanvasGroup *parent,
ETableModel *model);
/* For emitting the signals */
-void e_table_group_row_selection (ETableGroup *etg,
- gint row,
- gboolean selected);
void e_table_group_cursor_change (ETableGroup *etg,
gint row);
void e_table_group_double_click (ETableGroup *etg,
diff --git a/widgets/table/e-table-header.c b/widgets/table/e-table-header.c
index 06aeb50b3f..f95797e5c4 100644
--- a/widgets/table/e-table-header.c
+++ b/widgets/table/e-table-header.c
@@ -616,7 +616,7 @@ e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col)
if (start_col < 0)
start_col = 0;
if (end_col > eth->col_count)
- end_col = eth->col_count - 1;
+ end_col = eth->col_count;
total = 0;
for (col = start_col; col < end_col; col++){
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index 947b28107e..9e66a487be 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -30,7 +30,6 @@
static GnomeCanvasItemClass *eti_parent_class;
enum {
- ROW_SELECTION,
CURSOR_CHANGE,
DOUBLE_CLICK,
RIGHT_CLICK,
@@ -44,11 +43,11 @@ enum {
ARG_0,
ARG_TABLE_HEADER,
ARG_TABLE_MODEL,
+ ARG_TABLE_SELECTION_MODEL,
ARG_TABLE_DRAW_GRID,
ARG_TABLE_DRAW_FOCUS,
ARG_CURSOR_MODE,
ARG_LENGTH_THRESHOLD,
- ARG_HAS_CURSOR,
ARG_CURSOR_ROW,
ARG_MINIMUM_WIDTH,
@@ -59,18 +58,17 @@ enum {
static int eti_get_height (ETableItem *eti);
static int eti_get_minimum_width (ETableItem *eti);
static int eti_row_height (ETableItem *eti, int row);
-static void e_table_item_unselect_row (ETableItem *eti, int row);
-static void e_table_item_select_row (ETableItem *eti, int row);
-static void eti_selection (GnomeCanvasItem *item, int flags, gpointer user_data);
-static int eti_selection_compare (GnomeCanvasItem *item, gpointer data1, gpointer data2, int flags);
-static void e_table_item_focus (ETableItem *eti, int col, int row, gboolean add_selection);
-static void
-eti_request_region_show (ETableItem *eti,
- int start_col, int start_row,
- int end_col, int end_row);
+static void e_table_item_focus (ETableItem *eti, int col, int row, gboolean shift_p, gboolean ctrl_p);
+static void eti_cursor_change (ETableSelectionModel *selection, int row, int col, ETableItem *eti);
+static void eti_selection_change (ETableSelectionModel *selection, ETableItem *eti);
+#if 0
+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)))
-static gint
+inline static gint
model_to_view_row(ETableItem *eti, int row)
{
int i;
@@ -90,7 +88,7 @@ model_to_view_row(ETableItem *eti, int row)
return row;
}
-static gint
+inline static gint
view_to_model_row(ETableItem *eti, int row)
{
if (eti->uses_source_model) {
@@ -310,6 +308,28 @@ eti_remove_table_model (ETableItem *eti)
}
/*
+ * eti_remove_table_model:
+ *
+ * Invoked to release the table model associated with this ETableItem
+ */
+static void
+eti_remove_table_selection_model (ETableItem *eti)
+{
+ if (!eti->selection)
+ return;
+
+ gtk_signal_disconnect (GTK_OBJECT (eti->selection),
+ eti->selection_change_id);
+ gtk_signal_disconnect (GTK_OBJECT (eti->selection),
+ eti->cursor_change_id);
+ gtk_object_unref (GTK_OBJECT (eti->selection));
+
+ eti->selection_change_id = 0;
+ eti->cursor_change_id = 0;
+ eti->selection = NULL;
+}
+
+/*
* eti_remove_header_model:
*
* Invoked to release the header model associated with this ETableItem
@@ -579,16 +599,19 @@ eti_request_region_redraw (ETableItem *eti,
int end_col, int end_row, int border)
{
int x1, y1, width, height;
-
- x1 = e_table_header_col_diff (eti->header, 0, start_col);
- y1 = eti_row_diff (eti, 0, start_row);
- width = e_table_header_col_diff (eti->header, start_col, end_col + 1);
- height = eti_row_diff (eti, start_row, end_row + 1);
-
- 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);
+
+ if (eti->rows > 0) {
+
+ x1 = e_table_header_col_diff (eti->header, 0, start_col);
+ y1 = eti_row_diff (eti, 0, start_row);
+ width = e_table_header_col_diff (eti->header, start_col, end_col + 1);
+ height = eti_row_diff (eti, start_row, end_row + 1);
+
+ 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);
+ }
}
/*
@@ -619,7 +642,7 @@ eti_table_model_row_changed (ETableModel *table_model, int row, ETableItem *eti)
eti_table_model_changed (table_model, eti);
return;
}
-
+
eti_request_region_redraw (eti, 0, row, eti->cols, row, 0);
}
@@ -630,7 +653,7 @@ eti_table_model_cell_changed (ETableModel *table_model, int col, int row, ETable
eti_table_model_changed (table_model, eti);
return;
}
-
+
eti_request_region_redraw (eti, 0, row, eti->cols -1, row, 0);
}
@@ -652,14 +675,20 @@ e_table_item_redraw_range (ETableItem *eti,
int end_col, int end_row)
{
int border;
+ int cursor_col, cursor_row;
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
-
- if ((start_col == eti->cursor_col) ||
- (end_col == eti->cursor_col) ||
- (view_to_model_row(eti, start_row) == eti->cursor_row) ||
- (view_to_model_row(eti, end_row) == eti->cursor_row))
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ if ((start_col == cursor_col) ||
+ (end_col == cursor_col) ||
+ (view_to_model_row(eti, start_row) == cursor_row) ||
+ (view_to_model_row(eti, end_row) == cursor_row))
border = 2;
else
border = 0;
@@ -711,6 +740,25 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model)
}
static void
+eti_add_table_selection_model (ETableItem *eti, ETableSelectionModel *selection)
+{
+ g_assert (eti->selection == NULL);
+
+ eti->selection = selection;
+ gtk_object_ref (GTK_OBJECT (eti->selection));
+
+ eti->selection_change_id = gtk_signal_connect (
+ GTK_OBJECT (selection), "selection_changed",
+ GTK_SIGNAL_FUNC (eti_selection_change), eti);
+
+ eti->cursor_change_id = gtk_signal_connect (
+ GTK_OBJECT (selection), "cursor_changed",
+ GTK_SIGNAL_FUNC (eti_cursor_change), eti);
+
+ eti_selection_change(selection, eti);
+}
+
+static void
eti_header_dim_changed (ETableHeader *eth, int col, ETableItem *eti)
{
eti->needs_compute_width = 1;
@@ -727,7 +775,7 @@ eti_header_structure_changed (ETableHeader *eth, ETableItem *eti)
* There should be at least one column
*/
g_assert (eti->cols != 0);
-
+
if (eti->cell_views){
eti_unrealize_cell_views (eti);
eti_detach_cell_views (eti);
@@ -772,10 +820,10 @@ eti_destroy (GtkObject *object)
eti_remove_header_model (eti);
eti_remove_table_model (eti);
+ eti_remove_table_selection_model (eti);
-#if 0
- g_slist_free (eti->selection);
-#endif
+ if (eti->selection)
+ gtk_object_unref(GTK_OBJECT(eti->selection));
if (eti->height_cache_idle_id)
g_source_remove(eti->height_cache_idle_id);
@@ -791,6 +839,7 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
{
GnomeCanvasItem *item;
ETableItem *eti;
+ int cursor_col;
item = GNOME_CANVAS_ITEM (o);
eti = E_TABLE_ITEM (o);
@@ -806,6 +855,12 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
eti_add_table_model (eti, E_TABLE_MODEL(GTK_VALUE_OBJECT (*arg)));
break;
+ case ARG_TABLE_SELECTION_MODEL:
+ eti_remove_table_selection_model (eti);
+ if (GTK_VALUE_OBJECT (*arg))
+ eti_add_table_selection_model (eti, E_TABLE_SELECTION_MODEL(GTK_VALUE_OBJECT (*arg)));
+ break;
+
case ARG_LENGTH_THRESHOLD:
eti->length_threshold = GTK_VALUE_INT (*arg);
break;
@@ -831,7 +886,11 @@ eti_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti));
break;
case ARG_CURSOR_ROW:
- e_table_item_focus (eti, eti->cursor_col != -1 ? eti->cursor_col : 0, view_to_model_row(eti, GTK_VALUE_INT (*arg)), FALSE);
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ NULL);
+
+ e_table_item_focus (eti, cursor_col != -1 ? cursor_col : 0, view_to_model_row(eti, GTK_VALUE_INT (*arg)), FALSE, FALSE);
break;
}
eti->needs_redraw = 1;
@@ -843,6 +902,7 @@ eti_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
{
GnomeCanvasItem *item;
ETableItem *eti;
+ int row;
item = GNOME_CANVAS_ITEM (o);
eti = E_TABLE_ITEM (o);
@@ -857,11 +917,11 @@ eti_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
case ARG_MINIMUM_WIDTH:
GTK_VALUE_DOUBLE (*arg) = eti->minimum_width;
break;
- case ARG_HAS_CURSOR:
- GTK_VALUE_BOOL (*arg) = (eti->cursor_row != -1);
- break;
case ARG_CURSOR_ROW:
- GTK_VALUE_INT (*arg) = model_to_view_row(eti, eti->cursor_row);
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &row,
+ NULL);
+ GTK_VALUE_INT (*arg) = model_to_view_row(eti, row);
break;
default:
arg->type = GTK_TYPE_INVALID;
@@ -890,18 +950,16 @@ eti_init (GnomeCanvasItem *item)
eti->source_model = NULL;
eti->row_guess = -1;
- eti->cursor_row = -1;
- eti->cursor_col = 0;
eti->cursor_mode = E_TABLE_CURSOR_SIMPLE;
+ eti->selection_change_id = 0;
+ eti->cursor_change_id = 0;
eti->selection = NULL;
eti->needs_redraw = 0;
eti->needs_compute_height = 0;
e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (eti), eti_reflow);
- e_canvas_item_set_selection_callback (GNOME_CANVAS_ITEM (eti), eti_selection);
- e_canvas_item_set_selection_compare_callback (GNOME_CANVAS_ITEM (eti), eti_selection_compare);
}
#define gray50_width 2
@@ -1078,13 +1136,19 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
for (row = first_row; row < last_row; row++){
int xd, height;
gboolean selected;
+ gint cursor_col, cursor_row;
height = ETI_ROW_HEIGHT (eti, row);
xd = x_offset;
/* printf ("paint: %d %d\n", yd, yd + height); */
- selected = g_slist_find (eti->selection, GINT_TO_POINTER (view_to_model_row(eti, row))) != NULL;
+ selected = e_table_selection_model_is_row_selected(eti->selection, row);
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
for (col = first_col; col < last_col; col++){
ETableCol *ecol = e_table_header_get_column (eti->header, col);
@@ -1092,7 +1156,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
gboolean col_selected = selected;
switch (eti->cursor_mode) {
case E_TABLE_CURSOR_SIMPLE:
- if (eti->cursor_col == col && eti->cursor_row == view_to_model_row(eti, row))
+ if (cursor_col == col && cursor_row == view_to_model_row(eti, row))
col_selected = !col_selected;
break;
case E_TABLE_CURSOR_LINE:
@@ -1103,7 +1167,7 @@ eti_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width,
e_cell_draw (ecell_view, drawable, ecol->col_idx, col, row, col_selected,
xd, yd, xd + ecol->width, yd + height);
- if (col == eti->cursor_col && view_to_model_row(eti, row) == eti->cursor_row){
+ if (col == cursor_col && view_to_model_row(eti, row) == cursor_row){
f_x1 = xd;
f_x2 = xd + ecol->width;
f_y1 = yd;
@@ -1213,31 +1277,55 @@ static void
eti_cursor_move (ETableItem *eti, gint row, gint column)
{
e_table_item_leave_edit (eti);
- e_table_item_focus (eti, column, view_to_model_row(eti, row), FALSE);
+ e_table_item_focus (eti, column, view_to_model_row(eti, row), FALSE, FALSE);
}
static void
eti_cursor_move_left (ETableItem *eti)
{
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row), eti->cursor_col - 1);
+ int cursor_col, cursor_row;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row), cursor_col - 1);
}
static void
eti_cursor_move_right (ETableItem *eti)
{
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row), eti->cursor_col + 1);
+ int cursor_col, cursor_row;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row), cursor_col + 1);
}
static void
eti_cursor_move_up (ETableItem *eti)
{
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row) - 1, eti->cursor_col);
+ int cursor_col, cursor_row;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row) - 1, cursor_col);
}
static void
eti_cursor_move_down (ETableItem *eti)
{
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row) + 1, eti->cursor_col);
+ int cursor_col, cursor_row;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ "cursor_row", &cursor_row,
+ NULL);
+
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row) + 1, cursor_col);
}
/* FIXME: cursor */
@@ -1254,36 +1342,26 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
double x1, y1;
int col, row;
gint shifted = e->button.state & GDK_SHIFT_MASK;
+ gint ctrled = e->button.state & GDK_CONTROL_MASK;
+ gint cursor_row, cursor_col;
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))
return TRUE;
-
- if (eti->cursor_row != view_to_model_row(eti, row) || eti->cursor_col != col){
- /*
- * Focus the cell, and select the row
- */
- if (e_table_item_is_row_selected(eti, view_to_model_row(eti, row))) {
- int nums[2];
- e_table_item_leave_edit (eti);
- nums[0] = view_to_model_row(eti, row);
- nums[1] = 0;
- e_canvas_item_remove_selection(GNOME_CANVAS_ITEM(eti), nums);
- } else {
- e_table_item_leave_edit (eti);
- e_table_item_focus (eti, col, view_to_model_row(eti, row), shifted);
- }
- }
- if (eti->cursor_row == view_to_model_row(eti, row) && eti->cursor_col == col){
+ e_table_selection_model_do_something(eti->selection, row, col, shifted, ctrled);
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_row == view_to_model_row(eti, row) && cursor_col == col){
- e_table_item_focus (eti, col, view_to_model_row(eti, row), shifted);
-
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
@@ -1316,6 +1394,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
case GDK_BUTTON_RELEASE: {
double x1, y1;
int col, row;
+ gint cursor_row, cursor_col;
switch (e->button.button) {
case 1: /* Fall through. */
@@ -1326,7 +1405,12 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
if (!find_cell (eti, e->button.x, e->button.y, &col, &row, &x1, &y1))
return TRUE;
- if (eti->cursor_row == view_to_model_row(eti, row) && eti->cursor_col == col){
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_row == view_to_model_row(eti, row) && cursor_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
@@ -1370,13 +1454,19 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
case GDK_MOTION_NOTIFY: {
int col, row;
double x1, y1;
+ gint cursor_col, cursor_row;
gnome_canvas_item_w2i (item, &e->motion.x, &e->motion.y);
if (!find_cell (eti, e->motion.x, e->motion.y, &col, &row, &x1, &y1))
return TRUE;
- if (eti->cursor_row == view_to_model_row(eti, row) && eti->cursor_col == col){
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_row == view_to_model_row(eti, row) && cursor_col == col){
ecol = e_table_header_get_column (eti->header, col);
ecell_view = eti->cell_views [col];
@@ -1391,40 +1481,42 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
break;
}
- case GDK_KEY_PRESS:
- if (eti->cursor_col == -1)
+ case GDK_KEY_PRESS: {
+ gint cursor_row, cursor_col;
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_col == -1)
return FALSE;
switch (e->key.keyval){
case GDK_Left:
-#if 0
- if (!eti->mode_spreadsheet && eti_editing (eti))
+ if (eti_editing (eti))
break;
-#endif
- if (eti->cursor_col > 0)
+ if (cursor_col > 0)
eti_cursor_move_left (eti);
break;
case GDK_Right:
-#if 0
- if (!eti->mode_spreadsheet && eti_editing (eti))
+ if (eti_editing (eti))
break;
-#endif
- if (eti->cursor_col < eti->cols - 1)
+ if (cursor_col < eti->cols - 1)
eti_cursor_move_right (eti);
break;
case GDK_Up:
- if (eti->cursor_row != view_to_model_row(eti, 0))
+ if (cursor_row != view_to_model_row(eti, 0))
eti_cursor_move_up (eti);
else
return_val = FALSE;
break;
case GDK_Down:
- if (eti->cursor_row != view_to_model_row(eti, eti->rows - 1))
+ if (cursor_row != view_to_model_row(eti, eti->rows - 1))
eti_cursor_move_down (eti);
else
return_val = FALSE;
@@ -1435,17 +1527,17 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
case GDK_ISO_Left_Tab:
if ((e->key.state & GDK_SHIFT_MASK) != 0){
/* shift tab */
- if (eti->cursor_col > 0)
+ if (cursor_col > 0)
eti_cursor_move_left (eti);
- else if (eti->cursor_row != view_to_model_row(eti, 0))
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row) - 1, eti->cols - 1);
+ else if (cursor_row != view_to_model_row(eti, 0))
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row) - 1, eti->cols - 1);
else
return_val = FALSE;
} else {
- if (eti->cursor_col < eti->cols - 1)
+ if (cursor_col < eti->cols - 1)
eti_cursor_move_right (eti);
- else if (eti->cursor_row != view_to_model_row(eti, eti->rows - 1))
- eti_cursor_move (eti, model_to_view_row(eti, eti->cursor_row) + 1, 0);
+ else if (cursor_row != view_to_model_row(eti, eti->rows - 1))
+ eti_cursor_move (eti, model_to_view_row(eti, cursor_row) + 1, 0);
else
return_val = FALSE;
}
@@ -1454,17 +1546,25 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
default:
if (!eti_editing (eti)){
gtk_signal_emit (GTK_OBJECT (eti), eti_signals [KEY_PRESS],
- model_to_view_row(eti, eti->cursor_row), eti->cursor_col, e, &return_val);
+ model_to_view_row(eti, cursor_row), cursor_col, e, &return_val);
} else {
- ecol = e_table_header_get_column (eti->header, eti->cursor_col);
- ecell_view = eti->cell_views [eti->cursor_col];
- e_cell_event (ecell_view, e, ecol->col_idx, eti->cursor_col, model_to_view_row(eti, eti->cursor_row));
+ ecol = e_table_header_get_column (eti->header, cursor_col);
+ ecell_view = eti->cell_views [cursor_col];
+ e_cell_event (ecell_view, e, ecol->col_idx, cursor_col, model_to_view_row(eti, cursor_row));
}
}
break;
+ }
- case GDK_KEY_RELEASE:
- if (eti->cursor_col == -1)
+ case GDK_KEY_RELEASE: {
+ gint cursor_row, cursor_col;
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_row", &cursor_row,
+ "cursor_col", &cursor_col,
+ NULL);
+
+ if (cursor_col == -1)
return FALSE;
if (eti_editing (eti)){
@@ -1473,6 +1573,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
e_cell_event (ecell_view, e, ecol->col_idx, eti->editing_col, eti->editing_row);
}
break;
+ }
default:
return_val = FALSE;
@@ -1480,21 +1581,6 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
return return_val;
}
-/*
- * ETableItem::row_selection method
- */
-static void
-eti_row_selection (ETableItem *eti, int row, gboolean selected)
-{
- int view_row = model_to_view_row(eti, row);
- eti_request_region_redraw (eti, 0, view_row, eti->cols - 1, view_row, 0);
-
- if (selected)
- eti->selection = g_slist_prepend (eti->selection, GINT_TO_POINTER (row));
- else
- eti->selection = g_slist_remove (eti->selection, GINT_TO_POINTER (row));
-}
-
static void
eti_class_init (GtkObjectClass *object_class)
{
@@ -1514,7 +1600,6 @@ eti_class_init (GtkObjectClass *object_class)
item_class->point = eti_point;
item_class->event = eti_event;
- eti_class->row_selection = eti_row_selection;
eti_class->cursor_change = NULL;
eti_class->double_click = NULL;
eti_class->right_click = NULL;
@@ -1524,6 +1609,8 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
gtk_object_add_arg_type ("ETableItem::ETableModel", GTK_TYPE_OBJECT,
GTK_ARG_WRITABLE, ARG_TABLE_MODEL);
+ gtk_object_add_arg_type ("ETableItem::table_selection_model", GTK_TYPE_OBJECT,
+ GTK_ARG_WRITABLE, ARG_TABLE_SELECTION_MODEL);
gtk_object_add_arg_type ("ETableItem::drawgrid", GTK_TYPE_BOOL,
GTK_ARG_WRITABLE, ARG_TABLE_DRAW_GRID);
gtk_object_add_arg_type ("ETableItem::drawfocus", GTK_TYPE_BOOL,
@@ -1539,19 +1626,9 @@ eti_class_init (GtkObjectClass *object_class)
GTK_ARG_READWRITE, ARG_WIDTH);
gtk_object_add_arg_type ("ETableItem::height", GTK_TYPE_DOUBLE,
GTK_ARG_READABLE, ARG_HEIGHT);
- gtk_object_add_arg_type ("ETableItem::has_cursor", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_HAS_CURSOR);
gtk_object_add_arg_type ("ETableItem::cursor_row", GTK_TYPE_INT,
GTK_ARG_READWRITE, ARG_CURSOR_ROW);
- eti_signals [ROW_SELECTION] =
- gtk_signal_new ("row_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETableItemClass, row_selection),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
eti_signals [CURSOR_CHANGE] =
gtk_signal_new ("cursor_change",
GTK_RUN_LAST,
@@ -1614,11 +1691,11 @@ e_table_item_get_type (void)
void
e_table_item_set_cursor (ETableItem *eti, int col, int row)
{
- e_table_item_focus(eti, col, view_to_model_row(eti, row), FALSE);
+ e_table_item_focus(eti, col, view_to_model_row(eti, row), FALSE, FALSE);
}
static void
-e_table_item_focus (ETableItem *eti, int col, int row, gboolean add_selection)
+e_table_item_focus (ETableItem *eti, int col, int row, gboolean shift_p, gboolean ctrl_p)
{
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
@@ -1632,34 +1709,26 @@ e_table_item_focus (ETableItem *eti, int col, int row, gboolean add_selection)
}
if (row != -1) {
- int *nums;
- nums = g_new(int, 2);
- nums[0] = row;
- nums[1] = col;
- if (add_selection)
- e_canvas_item_add_selection(GNOME_CANVAS_ITEM(eti), nums);
- else
- e_canvas_item_set_cursor(GNOME_CANVAS_ITEM(eti), nums);
+ e_table_selection_model_do_something(eti->selection,
+ row, col,
+ shift_p,
+ ctrl_p);
}
}
gint
e_table_item_get_focused_column (ETableItem *eti)
{
+ int cursor_col;
+
g_return_val_if_fail (eti != NULL, -1);
g_return_val_if_fail (E_IS_TABLE_ITEM (eti), -1);
+
+ gtk_object_get(GTK_OBJECT(eti->selection),
+ "cursor_col", &cursor_col,
+ NULL);
- return eti->cursor_col;
-}
-
-
-const GSList *
-e_table_item_get_selection (ETableItem *eti)
-{
- g_return_val_if_fail (eti != NULL, NULL);
- g_return_val_if_fail (E_IS_TABLE_ITEM (eti), NULL);
-
- return eti->selection;
+ return cursor_col;
}
gboolean
@@ -1668,91 +1737,28 @@ e_table_item_is_row_selected (ETableItem *eti, int row)
g_return_val_if_fail (eti != NULL, FALSE);
g_return_val_if_fail (E_IS_TABLE_ITEM (eti), FALSE);
- if (g_slist_find (eti->selection, GINT_TO_POINTER (row)))
- return TRUE;
- else
- return FALSE;
-}
-
-void e_table_item_selected_row_foreach (ETableItem *eti,
- ETableForeachFunc func,
- gpointer closure)
-{
- GSList *list = eti->selection;
- for (; list; list = g_slist_next(list)) {
- (func) (GPOINTER_TO_INT(list->data), closure);
- }
-}
-
-static void
-e_table_item_unselect_row (ETableItem *eti, int row)
-{
- g_return_if_fail (eti != NULL);
- g_return_if_fail (E_IS_TABLE_ITEM (eti));
-
- gtk_signal_emit (GTK_OBJECT (eti), eti_signals [ROW_SELECTION],
- row, 0);
+ return e_table_selection_model_is_row_selected(eti->selection, row);
}
static void
-e_table_item_select_row (ETableItem *eti, int row)
+eti_cursor_change (ETableSelectionModel *selection, int row, int col, ETableItem *eti)
{
- g_return_if_fail (eti != NULL);
- g_return_if_fail (E_IS_TABLE_ITEM (eti));
-
- gtk_signal_emit (GTK_OBJECT (eti), eti_signals [ROW_SELECTION],
- GINT_TO_POINTER (row), 1);
-}
-
-static void
-eti_selection (GnomeCanvasItem *item, int flags, gpointer data)
-{
- int *nums = data;
- int row = nums[0];
- int col = nums[1];
- ETableItem *eti = E_TABLE_ITEM(item);
- int selected = e_table_item_is_row_selected(eti, row);
- int cursored = (row == eti->cursor_row);
+ int view_row = model_to_view_row(eti, row);
- if (selected && (flags & E_CANVAS_ITEM_SELECTION_SELECT) == 0) {
- e_table_item_unselect_row (eti, row);
- }
- if ((!selected) && (flags & E_CANVAS_ITEM_SELECTION_SELECT) != 0) {
- e_table_item_select_row (eti, row);
- }
- if ((!cursored) && (flags & E_CANVAS_ITEM_SELECTION_CURSOR) != 0) {
- int view_row = model_to_view_row(eti, row);
-
- eti->cursor_col = col;
- eti->cursor_row = row;
- gtk_signal_emit (GTK_OBJECT (eti), eti_signals [CURSOR_CHANGE],
- view_row);
- eti_request_region_show (eti, col, view_row, col, view_row);
- }
- if ((cursored) && (flags & E_CANVAS_ITEM_SELECTION_CURSOR) == 0) {
- e_table_item_leave_edit(eti);
- eti->cursor_row = -1;
- eti->cursor_col = -1;
- }
- if (flags & E_CANVAS_ITEM_SELECTION_DELETE_DATA) {
- g_free(data);
- }
+ gtk_signal_emit (GTK_OBJECT (eti), eti_signals [CURSOR_CHANGE],
+ view_row);
+ eti_request_region_show (eti, col, view_row, col, view_row);
+ if (e_table_model_is_cell_editable(selection->model, col, row))
+ e_table_item_enter_edit (eti, col, view_row);
}
-static gint
-eti_selection_compare (GnomeCanvasItem *item, gpointer data1, gpointer data2, int flags)
+static void
+eti_selection_change (ETableSelectionModel *selection, ETableItem *eti)
{
- int *val1 = (int *) data1;
- int *val2 = (int *) data2;
- if (*val1 < *val2)
- return -1;
- else if (*val1 == *val2)
- return 0;
- else
- return 1;
+ eti->needs_redraw = TRUE;
+ gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(eti));
}
-
void
e_table_item_enter_edit (ETableItem *eti, int col, int row)
{
@@ -1760,6 +1766,9 @@ e_table_item_enter_edit (ETableItem *eti, int col, int row)
g_return_if_fail (eti != NULL);
g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ if (eti_editing (eti))
+ e_table_item_leave_edit(eti);
eti->editing_col = col;
eti->editing_row = row;
diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h
index 619db68803..7102ef3ef7 100644
--- a/widgets/table/e-table-item.h
+++ b/widgets/table/e-table-item.h
@@ -5,6 +5,7 @@
#include <libgnomeui/gnome-canvas.h>
#include "e-table-model.h"
#include "e-table-header.h"
+#include "e-table-selection-model.h"
#include "e-table-defines.h"
#include <e-util/e-printable.h>
@@ -27,6 +28,7 @@ typedef struct {
ETableHeader *header;
ETableModel *source_model;
+ ETableSelectionModel *selection;
int x1, y1;
int minimum_width, width, height;
@@ -43,6 +45,9 @@ typedef struct {
int table_model_cell_change_id;
int table_model_row_inserted_id;
int table_model_row_deleted_id;
+
+ int selection_change_id;
+ int cursor_change_id;
GdkGC *fill_gc;
GdkGC *grid_gc;
@@ -77,12 +82,8 @@ typedef struct {
int length_threshold;
gint row_guess;
- gint cursor_row;
- gint cursor_col;
ETableCursorMode cursor_mode;
- GSList *selection;
-
/*
* During editing
*/
@@ -94,7 +95,6 @@ typedef struct {
typedef struct {
GnomeCanvasItemClass parent_class;
- void (*row_selection) (ETableItem *eti, int row, gboolean selected);
void (*cursor_change) (ETableItem *eti, int row);
void (*double_click) (ETableItem *eti, int row);
gint (*right_click) (ETableItem *eti, int row, int col, GdkEvent *event);
@@ -114,7 +114,6 @@ gint e_table_item_get_focused_column (ETableItem *eti);
/*
* Handling the selection
*/
-const GSList *e_table_item_get_selection (ETableItem *e_table_Item);
gboolean e_table_item_is_row_selected (ETableItem *e_table_Item,
int row);
diff --git a/widgets/table/e-table-scrolled.c b/widgets/table/e-table-scrolled.c
index b8260b6407..1a7b5251ad 100644
--- a/widgets/table/e-table-scrolled.c
+++ b/widgets/table/e-table-scrolled.c
@@ -28,7 +28,6 @@
static GtkObjectClass *parent_class;
enum {
- ROW_SELECTION,
CURSOR_CHANGE,
DOUBLE_CLICK,
RIGHT_CLICK,
@@ -48,14 +47,6 @@ enum {
static gint ets_signals [LAST_SIGNAL] = { 0, };
static void
-row_selection_proxy (ETable *et, int row, gboolean selected, ETableScrolled *ets)
-{
- gtk_signal_emit (GTK_OBJECT (ets),
- ets_signals [ROW_SELECTION],
- row, selected);
-}
-
-static void
cursor_change_proxy (ETable *et, int row, ETableScrolled *ets)
{
gtk_signal_emit (GTK_OBJECT (ets),
@@ -117,8 +108,6 @@ e_table_scrolled_real_construct (ETableScrolled *ets)
gtk_container_add(GTK_CONTAINER(ets), GTK_WIDGET(ets->table));
- gtk_signal_connect(GTK_OBJECT(ets->table), "row_selection",
- GTK_SIGNAL_FUNC(row_selection_proxy), ets);
gtk_signal_connect(GTK_OBJECT(ets->table), "cursor_change",
GTK_SIGNAL_FUNC(cursor_change_proxy), ets);
gtk_signal_connect(GTK_OBJECT(ets->table), "double_click",
@@ -297,20 +286,11 @@ e_table_scrolled_class_init (GtkObjectClass *object_class)
object_class->set_arg = ets_set_arg;
object_class->get_arg = ets_get_arg;
- klass->row_selection = NULL;
klass->cursor_change = NULL;
klass->double_click = NULL;
klass->right_click = NULL;
klass->key_press = NULL;
- ets_signals [ROW_SELECTION] =
- gtk_signal_new ("row_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETableScrolledClass, row_selection),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
ets_signals [CURSOR_CHANGE] =
gtk_signal_new ("cursor_change",
GTK_RUN_LAST,
diff --git a/widgets/table/e-table-scrolled.h b/widgets/table/e-table-scrolled.h
index daaf4429a0..d5a0c06a58 100644
--- a/widgets/table/e-table-scrolled.h
+++ b/widgets/table/e-table-scrolled.h
@@ -25,7 +25,6 @@ typedef struct {
typedef struct {
EScrollFrameClass parent_class;
- void (*row_selection) (ETableScrolled *est, int row, gboolean selected);
void (*cursor_change) (ETableScrolled *est, int row);
void (*double_click) (ETableScrolled *est, int row);
gint (*right_click) (ETableScrolled *est, int row, int col, GdkEvent *event);
diff --git a/widgets/table/e-table-selection-model.c b/widgets/table/e-table-selection-model.c
index 9c631ca603..35e0cb13aa 100644
--- a/widgets/table/e-table-selection-model.c
+++ b/widgets/table/e-table-selection-model.c
@@ -15,36 +15,49 @@
#define ETSM_CLASS(e) ((ETableSelectionModelClass *)((GtkObject *)e)->klass)
#define PARENT_TYPE gtk_object_get_type ()
-
+
+#define ONES ((guint32) 0xffffffff)
+
+#define BOX(n) ((n) / 32)
+#define OFFSET(n) (31 - ((n) % 32))
+#define BITMASK(n) (((guint32) 0x1) << OFFSET(n))
+#define BITMASK_LEFT(n) (((guint32) ONES) << (32 - ((n) % 32)))
+#define BITMASK_RIGHT(n) (((guint32) ONES) >> ((n) % 32))
static GtkObjectClass *e_table_selection_model_parent_class;
enum {
- SELECTION_MODEL_CHANGED,
- GROUP_SELECTION_CHANGED,
+ CURSOR_CHANGED,
+ SELECTION_CHANGED,
LAST_SIGNAL
};
static guint e_table_selection_model_signals [LAST_SIGNAL] = { 0, };
+enum {
+ ARG_0,
+ ARG_MODEL,
+ ARG_CURSOR_ROW,
+ ARG_CURSOR_COL,
+};
+
static void
model_changed(ETableModel *etm, ETableSelectionModel *etsm)
{
g_free(etsm->selection);
etsm->selection = NULL;
etsm->row_count = -1;
+ gtk_signal_emit(GTK_OBJECT(etsm),
+ e_table_selection_model_signals [SELECTION_CHANGED]);
}
+#if 1
static void
model_row_inserted(ETableModel *etm, int row, ETableSelectionModel *etsm)
{
int box;
int i;
- int offset;
if(etsm->row_count >= 0) {
- guint32 bitmask1 = 0xffff;
- guint32 bitmask2;
-
/* Add another word if needed. */
if ((etsm->row_count & 0x1f) == 0) {
etsm->selection = g_realloc(etsm->selection, (etsm->row_count >> 5) + 1);
@@ -58,12 +71,8 @@ model_row_inserted(ETableModel *etm, int row, ETableSelectionModel *etsm)
etsm->selection[i] = (etsm->selection[i] >> 1) | (etsm->selection[i - 1] << 31);
}
- /* Build bitmasks for the left and right half of the box */
- offset = row & 0x1f;
- bitmask1 = bitmask1 << (32 - offset);
- bitmask2 = ~bitmask1;
/* Shift right half of box one bit to the right. */
- etsm->selection[box] = (etsm->selection[box] & bitmask1) | ((etsm->selection[box] & bitmask2) >> 1);
+ etsm->selection[box] = (etsm->selection[box] & BITMASK_LEFT(row)) | ((etsm->selection[box] & BITMASK_RIGHT(row)) >> 1);
etsm->row_count ++;
}
}
@@ -74,19 +83,15 @@ model_row_deleted(ETableModel *etm, int row, ETableSelectionModel *etsm)
int box;
int i;
int last;
- int offset;
if(etsm->row_count >= 0) {
- guint32 bitmask1 = 0xffff;
- guint32 bitmask2;
+ guint32 bitmask;
box = row >> 5;
last = etsm->row_count >> 5;
/* Build bitmasks for the left and right half of the box */
- offset = row & 0x1f;
- bitmask1 = bitmask1 << (32 - offset);
- bitmask2 = (~bitmask1) >> 1;
+ bitmask = BITMASK_RIGHT(row) >> 1;
/* Shift right half of box one bit to the left. */
- etsm->selection[box] = (etsm->selection[box] & bitmask1) | ((etsm->selection[box] & bitmask2) << 1);
+ etsm->selection[box] = (etsm->selection[box] & BITMASK_LEFT(row))| ((etsm->selection[box] & bitmask) << 1);
/* Shift all words to the right of our box left one bit. */
if (box < last) {
@@ -105,6 +110,21 @@ model_row_deleted(ETableModel *etm, int row, ETableSelectionModel *etsm)
}
}
+#else
+
+static void
+model_row_inserted(ETableModel *etm, int row, ETableSelectionModel *etsm)
+{
+ model_changed(etm, etsm);
+}
+
+static void
+model_row_deleted(ETableModel *etm, int row, ETableSelectionModel *etsm)
+{
+ model_changed(etm, etsm);
+}
+#endif
+
inline static void
add_model(ETableSelectionModel *etsm, ETableModel *model)
{
@@ -141,15 +161,59 @@ etsm_destroy (GtkObject *object)
ETableSelectionModel *etsm;
etsm = E_TABLE_SELECTION_MODEL (object);
-
+
+ drop_model(etsm);
+
g_free(etsm->selection);
}
static void
+etsm_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableSelectionModel *etsm = E_TABLE_SELECTION_MODEL (o);
+
+ switch (arg_id){
+ case ARG_MODEL:
+ GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(etsm->model);
+ break;
+
+ case ARG_CURSOR_ROW:
+ GTK_VALUE_INT(*arg) = etsm->cursor_row;
+ break;
+
+ case ARG_CURSOR_COL:
+ GTK_VALUE_INT(*arg) = etsm->cursor_col;
+ break;
+ }
+}
+
+static void
+etsm_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+{
+ ETableSelectionModel *etsm = E_TABLE_SELECTION_MODEL (o);
+
+ switch (arg_id){
+ case ARG_MODEL:
+ drop_model(etsm);
+ add_model(etsm, GTK_VALUE_OBJECT (*arg) ? E_TABLE_MODEL(GTK_VALUE_OBJECT (*arg)) : NULL);
+ break;
+
+ case ARG_CURSOR_ROW:
+ e_table_selection_model_do_something(etsm, GTK_VALUE_INT(*arg), etsm->cursor_col, FALSE, FALSE);
+ break;
+
+ case ARG_CURSOR_COL:
+ e_table_selection_model_do_something(etsm, etsm->cursor_row, GTK_VALUE_INT(*arg), FALSE, FALSE);
+ break;
+ }
+}
+
+static void
e_table_selection_model_init (ETableSelectionModel *selection)
{
selection->selection = NULL;
selection->row_count = -1;
+ selection->model = NULL;
}
static void
@@ -160,29 +224,38 @@ e_table_selection_model_class_init (ETableSelectionModelClass *klass)
e_table_selection_model_parent_class = gtk_type_class (gtk_object_get_type ());
object_class = GTK_OBJECT_CLASS(klass);
-
+
object_class->destroy = etsm_destroy;
-#if 0
- e_table_selection_model_signals [SELECTION_MODEL_CHANGED] =
- gtk_signal_new ("selection_model_changed",
+ object_class->get_arg = etsm_get_arg;
+ object_class->set_arg = etsm_set_arg;
+
+ e_table_selection_model_signals [CURSOR_CHANGED] =
+ gtk_signal_new ("cursor_changed",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (ETableSelectionModelClass, selection_model_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
+ GTK_SIGNAL_OFFSET (ETableSelectionModelClass, cursor_changed),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
- e_table_selection_model_signals [GROUP_SELECTION_CHANGED] =
- gtk_signal_new ("group_selection_changed",
+ e_table_selection_model_signals [SELECTION_CHANGED] =
+ gtk_signal_new ("selection_changed",
GTK_RUN_LAST,
object_class->type,
- GTK_SIGNAL_OFFSET (ETableSelectionModelClass, group_selection_changed),
+ GTK_SIGNAL_OFFSET (ETableSelectionModelClass, selection_changed),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
- klass->selection_model_changed = NULL;
- klass->group_selection_changed = NULL;
-#endif
+ klass->cursor_changed = NULL;
+ klass->selection_changed = NULL;
+
gtk_object_class_add_signals (object_class, e_table_selection_model_signals, LAST_SIGNAL);
+
+ gtk_object_add_arg_type ("ETableSelectionModel::model", GTK_TYPE_OBJECT,
+ GTK_ARG_READWRITE, ARG_MODEL);
+ gtk_object_add_arg_type ("ETableSelectionModel::cursor_row", GTK_TYPE_INT,
+ GTK_ARG_READWRITE, ARG_CURSOR_ROW);
+ gtk_object_add_arg_type ("ETableSelectionModel::cursor_col", GTK_TYPE_INT,
+ GTK_ARG_READWRITE, ARG_CURSOR_COL);
}
E_MAKE_TYPE(e_table_selection_model, "ETableSelectionModel", ETableSelectionModel,
@@ -196,12 +269,12 @@ e_table_selection_model_new (void)
gboolean
e_table_selection_model_is_row_selected (ETableSelectionModel *selection,
- guint n)
+ gint n)
{
if (selection->row_count < n)
return 0;
else
- return ((selection->selection[n / 32]) >> (31 - (n % 32))) & 0x1;
+ return (selection->selection[BOX(n)] >> OFFSET(n)) & 0x1;
}
void
@@ -211,12 +284,12 @@ e_table_selection_model_foreach (ETableSelectionModel *selection,
{
int i;
int last = (selection->row_count + 31) / 32;
- for (i = 0; i < last; i--) {
+ for (i = 0; i < last; i++) {
if (selection->selection[i]) {
int j;
guint32 value = selection->selection[i];
- for (j = 0; j < 32; j--) {
- if (value & 0x8000) {
+ for (j = 0; j < 32; j++) {
+ if (value & 0x80000000) {
callback(i * 32 + j, closure);
}
value <<= 1;
@@ -224,3 +297,92 @@ e_table_selection_model_foreach (ETableSelectionModel *selection,
}
}
}
+
+#define OPERATE(object, mask, grow) ((grow) ? ((object) |= ~(mask)) : ((object) &= (mask)))
+
+void e_table_selection_model_do_something (ETableSelectionModel *selection,
+ guint row,
+ guint col,
+ gboolean shift_p,
+ gboolean ctrl_p)
+{
+ if (selection->row_count < 0) {
+ if (selection->model) {
+ selection->row_count = e_table_model_row_count(selection->model);
+ g_free(selection->selection);
+ selection->selection = g_new0(gint, (selection->row_count + 31) / 32);
+ }
+ }
+ if (selection->row_count >= 0 && row < selection->row_count) {
+ if (shift_p) {
+ int grow_selection;
+ int i;
+ int last;
+ int first_row;
+ int last_row;
+ if ((selection->selection_start_row < row && row <= selection->cursor_row) ||
+ (selection->selection_start_row >= row && row >= selection->cursor_row)) {
+ /* In this case, the selection is shrinking. */
+ grow_selection = FALSE;
+ } else if ((selection->selection_start_row <= selection->cursor_row && selection->cursor_row <= row) ||
+ (selection->selection_start_row > selection->cursor_row && selection->cursor_row >= row)) {
+ /* In this case, the selection is growing. */
+ grow_selection = TRUE;
+ } else {
+ /* In this case the selection is changing direction. Ick. Screw it. */
+ return;
+ }
+ first_row = MIN(selection->cursor_row, row);
+ last_row = MAX(selection->cursor_row, row) + 1;
+ if (first_row != last_row) {
+ i = BOX(first_row);
+ last = BOX(last_row);
+
+ if (i == last) {
+ OPERATE(selection->selection[i], BITMASK_LEFT(first_row) | BITMASK_RIGHT(last_row), grow_selection);
+ } else {
+ OPERATE(selection->selection[i], BITMASK_LEFT(first_row), grow_selection);
+ for (i ++; i < last; i++)
+ if (grow_selection)
+ selection->selection[i] = ONES;
+ else
+ selection->selection[i] = 0;
+ OPERATE(selection->selection[i], BITMASK_RIGHT(last_row), grow_selection);
+ }
+ gtk_signal_emit(GTK_OBJECT(selection),
+ e_table_selection_model_signals [SELECTION_CHANGED]);
+ }
+ } else {
+ if (ctrl_p) {
+ if (selection->selection[BOX(row)] & BITMASK(row))
+ selection->selection[BOX(row)] &= ~BITMASK(row);
+ else
+ selection->selection[BOX(row)] |= BITMASK(row);
+ gtk_signal_emit(GTK_OBJECT(selection),
+ e_table_selection_model_signals [SELECTION_CHANGED]);
+ } else {
+ int i;
+ for (i = 0; i < ((selection->row_count + 31) / 32); i++) {
+ if (!((i == BOX(row) && selection->selection[i] == BITMASK(row)) ||
+ (i != BOX(row) && selection->selection[i] == 0))) {
+ g_free(selection->selection);
+ selection->selection = g_new0(gint, (selection->row_count + 31) / 32);
+ selection->selection[BOX(row)] = BITMASK(row);
+
+ gtk_signal_emit(GTK_OBJECT(selection),
+ e_table_selection_model_signals [SELECTION_CHANGED]);
+ break;
+ }
+ }
+ }
+ selection->selection_start_row = row;
+ }
+ if (selection->cursor_row != row ||
+ selection->cursor_col != col) {
+ gtk_signal_emit(GTK_OBJECT(selection),
+ e_table_selection_model_signals[CURSOR_CHANGED], row, col);
+ selection->cursor_row = row;
+ selection->cursor_col = col;
+ }
+ }
+}
diff --git a/widgets/table/e-table-selection-model.h b/widgets/table/e-table-selection-model.h
index 2aaba021f8..251b1ceb00 100644
--- a/widgets/table/e-table-selection-model.h
+++ b/widgets/table/e-table-selection-model.h
@@ -19,13 +19,14 @@ typedef struct {
gint row_count;
guint32 *selection;
-
+
gint cursor_row;
gint cursor_col;
+ gint selection_start_row;
guint model_changed_id;
guint model_row_inserted_id, model_row_deleted_id;
-
+
guint frozen : 1;
guint selection_model_changed : 1;
guint group_info_changed : 1;
@@ -37,20 +38,26 @@ typedef struct {
/*
* Signals
*/
-#if 0
- void (*selection_model_changed) (ETableSelectionModel *selection);
- void (*group_model_changed) (ETableSelectionModel *selection);
-#endif
+
+ void (*cursor_changed) (ETableSelectionModel *selection, int row, int col);
+ void (*selection_changed) (ETableSelectionModel *selection);
+
} ETableSelectionModelClass;
GtkType e_table_selection_model_get_type (void);
-gboolean e_table_selection_model_is_row_selected (ETableSelectionModel *selection,
- guint n);
-void e_table_selection_model_foreach (ETableSelectionModel *selection,
- ETableForeachFunc callback,
- gpointer closure);
+gboolean e_table_selection_model_is_row_selected (ETableSelectionModel *selection,
+ gint n);
+void e_table_selection_model_foreach (ETableSelectionModel *selection,
+ ETableForeachFunc callback,
+ gpointer closure);
+
+void e_table_selection_model_do_something (ETableSelectionModel *selection,
+ guint row,
+ guint col,
+ gboolean shift_p,
+ gboolean ctrl_p);
-ETableSelectionModel *e_table_selection_model_new (void);
+ETableSelectionModel *e_table_selection_model_new (void);
#endif /* _E_TABLE_SELECTION_MODEL_H_ */
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index c20c7cd21e..ae258a5c44 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -40,7 +40,6 @@
static GtkObjectClass *e_table_parent_class;
enum {
- ROW_SELECTION,
CURSOR_CHANGE,
DOUBLE_CLICK,
RIGHT_CLICK,
@@ -183,6 +182,8 @@ e_table_init (GtkObject *object)
e_table->drag_col = -1;
e_table->drop_row = -1;
e_table->drop_col = -1;
+
+ e_table->selection = e_table_selection_model_new();
}
static void
@@ -270,18 +271,6 @@ table_canvas_reflow (GnomeCanvas *canvas, ETable *e_table)
}
static void
-group_row_selection (ETableGroup *etg, int row, gboolean selected, ETable *et)
-{
- gtk_signal_emit (GTK_OBJECT (et),
- et_signals [ROW_SELECTION],
- row, selected);
- if (et->row_selection_active && selected) {
- e_table_click_to_add_commit (E_TABLE_CLICK_TO_ADD(et->click_to_add));
- et->row_selection_active = FALSE;
- }
-}
-
-static void
group_cursor_change (ETableGroup *etg, int row, ETable *et)
{
gtk_signal_emit (GTK_OBJECT (et),
@@ -336,9 +325,8 @@ changed_idle (gpointer data)
"drawfocus", et->draw_focus,
"cursor_mode", et->cursor_mode,
"length_threshold", et->length_threshold,
+ "table_selection_model", et->selection,
NULL);
- gtk_signal_connect (GTK_OBJECT (et->group), "row_selection",
- GTK_SIGNAL_FUNC (group_row_selection), et);
gtk_signal_connect (GTK_OBJECT (et->group), "cursor_change",
GTK_SIGNAL_FUNC (group_cursor_change), et);
gtk_signal_connect (GTK_OBJECT (et->group), "double_click",
@@ -400,14 +388,6 @@ et_table_row_deleted (ETableModel *table_model, int row, ETable *et)
}
static void
-click_to_add_row_selection (ETableClickToAdd *etcta, int row, gboolean selected, ETable *et)
-{
- if ((!et->row_selection_active) && selected) {
- et->row_selection_active = TRUE;
- }
-}
-
-static void
e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *header,
ETableModel *model)
{
@@ -460,9 +440,6 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
"message", e_table->click_to_add_message,
NULL);
- gtk_signal_connect(GTK_OBJECT(e_table->click_to_add), "row_selection",
- GTK_SIGNAL_FUNC(click_to_add_row_selection), e_table);
-
e_canvas_vbox_add_item(E_CANVAS_VBOX(e_table->canvas_vbox), e_table->click_to_add);
}
@@ -477,10 +454,9 @@ e_table_setup_table (ETable *e_table, ETableHeader *full_header, ETableHeader *h
"drawfocus", e_table->draw_focus,
"cursor_mode", e_table->cursor_mode,
"length_threshold", e_table->length_threshold,
+ "table_selection_model", e_table->selection,
NULL);
- gtk_signal_connect (GTK_OBJECT (e_table->group), "row_selection",
- GTK_SIGNAL_FUNC(group_row_selection), e_table);
gtk_signal_connect (GTK_OBJECT (e_table->group), "cursor_change",
GTK_SIGNAL_FUNC(group_cursor_change), e_table);
gtk_signal_connect (GTK_OBJECT (e_table->group), "double_click",
@@ -607,6 +583,9 @@ et_real_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
e_table->model = etm;
gtk_object_ref (GTK_OBJECT (etm));
+ gtk_object_set (GTK_OBJECT (e_table->selection),
+ "model", etm,
+ NULL);
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
@@ -812,9 +791,9 @@ e_table_selected_row_foreach (ETable *e_table,
ETableForeachFunc callback,
gpointer closure)
{
- e_table_group_selected_row_foreach(e_table->group,
- callback,
- closure);
+ e_table_selection_model_foreach(e_table->selection,
+ callback,
+ closure);
}
@@ -1240,7 +1219,6 @@ e_table_class_init (GtkObjectClass *object_class)
object_class->set_arg = et_set_arg;
object_class->get_arg = et_get_arg;
- klass->row_selection = NULL;
klass->cursor_change = NULL;
klass->double_click = NULL;
klass->right_click = NULL;
@@ -1256,14 +1234,6 @@ e_table_class_init (GtkObjectClass *object_class)
klass->table_drag_drop = NULL;
klass->table_drag_data_received = NULL;
- et_signals [ROW_SELECTION] =
- gtk_signal_new ("row_selection",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ETableClass, row_selection),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
et_signals [CURSOR_CHANGE] =
gtk_signal_new ("cursor_change",
GTK_RUN_LAST,
diff --git a/widgets/table/e-table.h b/widgets/table/e-table.h
index 06905a3711..a2e608b41e 100644
--- a/widgets/table/e-table.h
+++ b/widgets/table/e-table.h
@@ -80,7 +80,6 @@ typedef struct {
typedef struct {
GtkTableClass parent_class;
- void (*row_selection) (ETable *et, int row, gboolean selected);
void (*cursor_change) (ETable *et, int row);
void (*double_click) (ETable *et, int row);
gint (*right_click) (ETable *et, int row, int col, GdkEvent *event);