aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/table
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/table')
-rw-r--r--widgets/table/e-table-item.c52
-rw-r--r--widgets/table/e-table-item.h4
-rw-r--r--widgets/table/e-table.c13
-rw-r--r--widgets/table/e-tree-selection-model.c168
-rw-r--r--widgets/table/e-tree.c13
5 files changed, 190 insertions, 60 deletions
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index 76be881ffd..c324d3a90c 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -41,6 +41,7 @@
#include "gal/widgets/e-canvas-utils.h"
#include "gal/util/e-util.h"
#include <string.h>
+#include <stdlib.h>
#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
@@ -104,6 +105,8 @@ static void e_table_item_focus (ETableItem *eti, int col, int row, GdkModifierTy
static void eti_cursor_change (ESelectionModel *selection, int row, int col, ETableItem *eti);
static void eti_cursor_activated (ESelectionModel *selection, int row, int col, ETableItem *eti);
static void eti_selection_change (ESelectionModel *selection, ETableItem *eti);
+static void eti_selection_row_change (ESelectionModel *selection, int row, ETableItem *eti);
+static void e_table_item_redraw_row (ETableItem *eti, int row);
#define ETI_SINGLE_ROW_HEIGHT(eti) ((eti)->uniform_row_height_cache != -1 ? (eti)->uniform_row_height_cache : eti_row_height((eti), -1))
#define ETI_MULTIPLE_ROW_HEIGHT(eti,row) ((eti)->height_cache && (eti)->height_cache[(row)] != -1 ? (eti)->height_cache[(row)] : eti_row_height((eti),(row)))
@@ -499,12 +502,15 @@ eti_remove_selection_model (ETableItem *eti)
gtk_signal_disconnect (GTK_OBJECT (eti->selection),
eti->selection_change_id);
gtk_signal_disconnect (GTK_OBJECT (eti->selection),
+ eti->selection_row_change_id);
+ gtk_signal_disconnect (GTK_OBJECT (eti->selection),
eti->cursor_change_id);
gtk_signal_disconnect (GTK_OBJECT (eti->selection),
eti->cursor_activated_id);
gtk_object_unref (GTK_OBJECT (eti->selection));
eti->selection_change_id = 0;
+ eti->selection_row_change_id = 0;
eti->cursor_activated_id = 0;
eti->selection = NULL;
}
@@ -973,13 +979,15 @@ static void
eti_freeze (ETableItem *eti)
{
eti->frozen_count ++;
+ d(g_print ("%s: %d\n", __FUNCTION__, eti->frozen_count));
}
static void
eti_unfreeze (ETableItem *eti)
{
- g_return_if_fail (eti->frozen_count != 0);
+ g_return_if_fail (eti->frozen_count > 0);
eti->frozen_count --;
+ d(g_print ("%s: %d\n", __FUNCTION__, eti->frozen_count));
if (eti->frozen_count == 0 && eti->queue_show_cursor) {
eti_show_cursor (eti, 0);
eti_check_cursor_bounds (eti);
@@ -1050,7 +1058,7 @@ eti_table_model_row_changed (ETableModel *table_model, int row, ETableItem *eti)
eti_unfreeze (eti);
- eti_request_region_redraw (eti, 0, row, eti->cols - 1, row, 0);
+ e_table_item_redraw_row (eti, row);
}
static void
@@ -1068,7 +1076,7 @@ eti_table_model_cell_changed (ETableModel *table_model, int col, int row, ETable
eti_unfreeze (eti);
- eti_request_region_redraw (eti, 0, row, eti->cols - 1, row, 0);
+ e_table_item_redraw_row (eti, row);
}
static void
@@ -1165,6 +1173,13 @@ e_table_item_redraw_range (ETableItem *eti,
}
static void
+e_table_item_redraw_row (ETableItem *eti,
+ int row)
+{
+ e_table_item_redraw_range (eti, 0, row, eti->cols - 1, row);
+}
+
+static void
eti_add_table_model (ETableItem *eti, ETableModel *table_model)
{
g_assert (eti->table_model == NULL);
@@ -1228,6 +1243,10 @@ eti_add_selection_model (ETableItem *eti, ESelectionModel *selection)
GTK_OBJECT (selection), "selection_changed",
GTK_SIGNAL_FUNC (eti_selection_change), eti);
+ eti->selection_row_change_id = gtk_signal_connect (
+ GTK_OBJECT (selection), "selection_row_changed",
+ GTK_SIGNAL_FUNC (eti_selection_row_change), eti);
+
eti->cursor_change_id = gtk_signal_connect (
GTK_OBJECT (selection), "cursor_changed",
GTK_SIGNAL_FUNC (eti_cursor_change), eti);
@@ -1494,10 +1513,13 @@ eti_init (GnomeCanvasItem *item)
eti->cursor_mode = E_CURSOR_SIMPLE;
eti->selection_change_id = 0;
+ eti->selection_row_change_id = 0;
eti->cursor_change_id = 0;
eti->cursor_activated_id = 0;
eti->selection = NULL;
+ eti->old_cursor_row = -1;
+
eti->needs_redraw = 0;
eti->needs_compute_height = 0;
@@ -2663,7 +2685,7 @@ eti_event (GnomeCanvasItem *item, GdkEvent *e)
default:
return_val = FALSE;
}
- d(g_print("%s: returning: %s\n", __FUNCTION__, return_val?"true":"false"));
+ /* d(g_print("%s: returning: %s\n", __FUNCTION__, return_val?"true":"false"));*/
return return_val;
}
@@ -2880,6 +2902,7 @@ eti_cursor_change (ESelectionModel *selection, int row, int col, ETableItem *eti
if (view_row == -1 || view_col == -1) {
e_table_item_leave_edit_(eti);
+ eti->old_cursor_row = -1;
return;
}
@@ -2896,8 +2919,14 @@ eti_cursor_change (ESelectionModel *selection, int row, int col, ETableItem *eti
e_table_item_leave_edit_(eti);
gtk_signal_emit (GTK_OBJECT (eti), eti_signals [CURSOR_CHANGE],
view_row);
- eti->needs_redraw = TRUE;
- gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(eti));
+ if (eti->old_cursor_row != -1) {
+ e_table_item_redraw_row (eti, eti->old_cursor_row);
+ e_table_item_redraw_row (eti, view_row);
+ } else {
+ eti->needs_redraw = TRUE;
+ gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(eti));
+ }
+ eti->old_cursor_row = view_row;
}
static void
@@ -2939,6 +2968,17 @@ eti_selection_change (ESelectionModel *selection, ETableItem *eti)
gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(eti));
}
+static void
+eti_selection_row_change (ESelectionModel *selection, int row, ETableItem *eti)
+{
+ if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED))
+ return;
+
+ if (!eti->needs_redraw) {
+ e_table_item_redraw_row (eti, model_to_view_row(eti, row));
+ }
+}
+
/**
* e_table_item_enter_edit
diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h
index 16172771b7..4956c279dd 100644
--- a/widgets/table/e-table-item.h
+++ b/widgets/table/e-table-item.h
@@ -71,9 +71,13 @@ typedef struct {
int table_model_rows_deleted_id;
int selection_change_id;
+ int selection_row_change_id;
int cursor_change_id;
int cursor_activated_id;
+ /* View row, -1 means unknown */
+ int old_cursor_row;
+
int hadjustment_change_id;
int hadjustment_value_change_id;
int vadjustment_change_id;
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index d9afb4804f..1b0784b6ed 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -1102,7 +1102,14 @@ e_table_save_state (ETable *e_table,
}
static void
-et_selection_model_selection_change (ETableGroup *etg, ETable *et)
+et_selection_model_selection_changed (ETableGroup *etg, ETable *et)
+{
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [SELECTION_CHANGE]);
+}
+
+static void
+et_selection_model_selection_row_changed (ETableGroup *etg, int row, ETable *et)
{
gtk_signal_emit (GTK_OBJECT (et),
et_signals [SELECTION_CHANGE]);
@@ -1166,7 +1173,9 @@ et_real_construct (ETable *e_table, ETableModel *etm, ETableExtras *ete,
NULL);
gtk_signal_connect(GTK_OBJECT(e_table->selection), "selection_changed",
- GTK_SIGNAL_FUNC(et_selection_model_selection_change), e_table);
+ GTK_SIGNAL_FUNC(et_selection_model_selection_changed), e_table);
+ gtk_signal_connect(GTK_OBJECT(e_table->selection), "selection_row_changed",
+ GTK_SIGNAL_FUNC(et_selection_model_selection_row_changed), e_table);
if (!specification->no_headers) {
e_table_setup_header (e_table);
diff --git a/widgets/table/e-tree-selection-model.c b/widgets/table/e-tree-selection-model.c
index 9cdf9e9d4a..b8e63fb79f 100644
--- a/widgets/table/e-tree-selection-model.c
+++ b/widgets/table/e-tree-selection-model.c
@@ -82,6 +82,15 @@ struct ETreeSelectionModelPriv {
int tree_model_node_deleted_id;
int sorted_model_node_resorted_id;
+
+ /* Anything other than -1 means that the selection is a single
+ * row. This being -1 does not impart any information. */
+ int selected_row;
+ /* Anything other than -1 means that the selection is a all
+ * rows between selection_start_path and cursor_path where
+ * selected_range_end is the rwo number of cursor_path. This
+ * being -1 does not impart any information. */
+ int selected_range_end;
};
/* ETreeSelectionModelNode helpers */
@@ -343,6 +352,38 @@ update_parents (ETreeSelectionModel *etsm, ETreePath path)
}
+static void
+etsm_change_one_path(ETreeSelectionModel *etsm, ETreePath path, gboolean grow)
+{
+ ETreeSelectionModelNode *node;
+
+ if (!path)
+ return;
+
+ path = e_tree_sorted_model_to_view_path(etsm->priv->ets, path);
+
+ if (!path)
+ return;
+
+ node = etsm_find_node_unless_equals (etsm, path, grow);
+
+ if (node) {
+ node->selected = grow;
+ update_parents(etsm, path);
+ }
+}
+
+static void
+etsm_real_select_single_path (ETreeSelectionModel *etsm, ETreePath path)
+{
+ etsm_real_clear (etsm);
+ etsm_change_one_path(etsm, path, TRUE);
+ etsm->priv->selection_start_path = path;
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
+}
+
+
/* Signal handlers */
static void
@@ -394,10 +435,12 @@ clear_tree (ETreeSelectionModel *etsm, ETreeModel *etm)
if (cursor_path != NULL && etsm->priv->cursor_col == -1)
etsm->priv->cursor_col = 0;
- e_tree_selection_model_select_single_path(etsm, cursor_path);
+ etsm_real_select_single_path(etsm, cursor_path);
}
cursor_row = etsm_cursor_row_real (etsm);
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
if (cursor_row != -1)
e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), cursor_row, etsm->priv->cursor_col);
@@ -473,6 +516,9 @@ static void
etsm_sorted_node_resorted (ETreeModel *etm, ETreePath node, ETreeSelectionModel *etsm)
{
int cursor_row = etsm_cursor_row_real (etsm);
+
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
if (cursor_row != -1)
@@ -808,6 +854,8 @@ etsm_clear(ESelectionModel *selection)
etsm->priv->cursor_path = NULL;
etsm->priv->cursor_col = -1;
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), -1, -1);
}
@@ -914,6 +962,8 @@ etsm_select_all (ESelectionModel *selection)
if (etsm->priv->cursor_path == NULL)
etsm->priv->cursor_path = etsm_node_at_row(etsm, 0);
etsm->priv->selection_start_path = etsm_node_at_row(etsm, 0);
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), etsm_cursor_row_real(etsm), etsm->priv->cursor_col);
}
@@ -964,6 +1014,8 @@ etsm_invert_selection (ESelectionModel *selection)
etsm->priv->cursor_col = -1;
etsm->priv->cursor_path = NULL;
etsm->priv->selection_start_path = etsm_node_at_row(etsm, 0);
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), -1, -1);
}
@@ -1000,27 +1052,6 @@ etsm_change_one_row(ESelectionModel *selection, int row, gboolean grow)
}
static void
-etsm_change_one_path(ETreeSelectionModel *etsm, ETreePath path, gboolean grow)
-{
- ETreeSelectionModelNode *node;
-
- if (!path)
- return;
-
- path = e_tree_sorted_model_to_view_path(etsm->priv->ets, path);
-
- if (!path)
- return;
-
- node = etsm_find_node_unless_equals (etsm, path, grow);
-
- if (node) {
- node->selected = grow;
- update_parents(etsm, path);
- }
-}
-
-static void
etsm_change_cursor (ESelectionModel *selection, int row, int col)
{
ETreeSelectionModel *etsm;
@@ -1072,12 +1103,22 @@ static void
etsm_select_single_row (ESelectionModel *selection, int row)
{
ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection);
+ int selected_row = etsm->priv->selected_row;
etsm_real_clear (etsm);
etsm_change_one_row(selection, row, TRUE);
etsm->priv->selection_start_path = etsm_node_at_row(etsm, row);
- e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
+ etsm->priv->selected_row = row;
+ etsm->priv->selected_range_end = -1;
+ if (selected_row != -1) {
+ if (selected_row != etsm->priv->selected_row) {
+ e_selection_model_selection_row_changed(E_SELECTION_MODEL(etsm), selected_row);
+ e_selection_model_selection_row_changed(E_SELECTION_MODEL(etsm), row);
+ }
+ } else {
+ e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
+ }
}
static void
@@ -1089,13 +1130,15 @@ etsm_toggle_single_row (ESelectionModel *selection, int row)
etsm_change_one_row(selection, row, !etsm_is_row_selected(selection, row));
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
}
static void
-etsm_move_selection_end (ESelectionModel *selection, int row)
+etsm_real_move_selection_end (ETreeSelectionModel *etsm, int row)
{
- ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection);
+ ESelectionModel *selection = E_SELECTION_MODEL (etsm);
int old_start;
int old_end;
int new_start;
@@ -1125,16 +1168,38 @@ etsm_move_selection_end (ESelectionModel *selection, int row)
etsm_change_range(selection, old_end, new_end, TRUE);
if (new_end < old_end)
etsm_change_range(selection, new_end, old_end, FALSE);
- e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
+}
+
+static void
+etsm_move_selection_end (ESelectionModel *selection, int row)
+{
+ ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection);
+
+ etsm_real_move_selection_end (etsm, row);
+ e_selection_model_selection_changed(E_SELECTION_MODEL(selection));
}
static void
etsm_set_selection_end (ESelectionModel *selection, int row)
{
ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection);
- e_tree_selection_model_select_single_path(etsm, etsm->priv->selection_start_path);
+ int selected_range_end = etsm->priv->selected_range_end;
+
+ etsm_real_select_single_path(etsm, etsm->priv->selection_start_path);
etsm->priv->cursor_path = etsm->priv->selection_start_path;
- e_selection_model_move_selection_end(selection, row);
+ etsm_real_move_selection_end(etsm, row);
+ etsm->priv->selected_range_end = row;
+ if (selected_range_end != -1 && row != -1) {
+ if (selected_range_end == row - 1 ||
+ selected_range_end == row + 1) {
+ e_selection_model_selection_row_changed(E_SELECTION_MODEL(etsm), selected_range_end);
+ e_selection_model_selection_row_changed(E_SELECTION_MODEL(etsm), row);
+ return;
+ }
+ }
+ e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
}
@@ -1198,9 +1263,7 @@ e_tree_selection_model_foreach (ETreeSelectionModel *etsm,
void
e_tree_selection_model_select_single_path (ETreeSelectionModel *etsm, ETreePath path)
{
- etsm_real_clear (etsm);
- etsm_change_one_path(etsm, path, TRUE);
- etsm->priv->selection_start_path = path;
+ etsm_real_select_single_path (etsm, path);
e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
}
@@ -1210,6 +1273,8 @@ e_tree_selection_model_add_to_selection (ETreeSelectionModel *etsm, ETreePath pa
{
etsm_change_one_path(etsm, path, TRUE);
etsm->priv->selection_start_path = path;
+ etsm->priv->selected_row = -1;
+ etsm->priv->selected_range_end = -1;
e_selection_model_selection_changed(E_SELECTION_MODEL(etsm));
}
@@ -1232,32 +1297,35 @@ static void
e_tree_selection_model_init (ETreeSelectionModel *etsm)
{
ETreeSelectionModelPriv *priv;
- priv = g_new(ETreeSelectionModelPriv, 1);
- etsm->priv = priv;
+ priv = g_new(ETreeSelectionModelPriv, 1);
+ etsm->priv = priv;
- priv->etta = NULL;
- priv->ets = NULL;
- priv->model = NULL;
+ priv->etta = NULL;
+ priv->ets = NULL;
+ priv->model = NULL;
- priv->root = NULL;
+ priv->root = NULL;
- priv->cursor_path = NULL;
- priv->cursor_col = -1;
- priv->selection_start_path = NULL;
+ priv->cursor_path = NULL;
+ priv->cursor_col = -1;
+ priv->selection_start_path = NULL;
- priv->cursor_save_id = NULL;
+ priv->cursor_save_id = NULL;
- priv->tree_model_pre_change_id = 0;
- priv->tree_model_no_change_id = 0;
- priv->tree_model_node_changed_id = 0;
- priv->tree_model_node_data_changed_id = 0;
- priv->tree_model_node_col_changed_id = 0;
- priv->tree_model_node_inserted_id = 0;
- priv->tree_model_node_removed_id = 0;
- priv->tree_model_node_deleted_id = 0;
+ priv->tree_model_pre_change_id = 0;
+ priv->tree_model_no_change_id = 0;
+ priv->tree_model_node_changed_id = 0;
+ priv->tree_model_node_data_changed_id = 0;
+ priv->tree_model_node_col_changed_id = 0;
+ priv->tree_model_node_inserted_id = 0;
+ priv->tree_model_node_removed_id = 0;
+ priv->tree_model_node_deleted_id = 0;
+
+ priv->sorted_model_node_resorted_id = 0;
- priv->sorted_model_node_resorted_id = 0;
+ priv->selected_row = -1;
+ priv->selected_range_end = -1;
}
static void
diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c
index 3e15e1db94..9e08ccfbae 100644
--- a/widgets/table/e-tree.c
+++ b/widgets/table/e-tree.c
@@ -669,7 +669,14 @@ item_start_drag (ETableItem *eti, int row, int col, GdkEvent *event, ETree *et)
}
static void
-et_selection_model_selection_change (ETableSelectionModel *etsm, ETable *et)
+et_selection_model_selection_changed (ETableSelectionModel *etsm, ETree *et)
+{
+ gtk_signal_emit (GTK_OBJECT (et),
+ et_signals [SELECTION_CHANGE]);
+}
+
+static void
+et_selection_model_selection_row_changed (ETableSelectionModel *etsm, int row, ETree *et)
{
gtk_signal_emit (GTK_OBJECT (et),
et_signals [SELECTION_CHANGE]);
@@ -1127,7 +1134,9 @@ et_real_construct (ETree *e_tree, ETreeModel *etm, ETableExtras *ete,
NULL);
gtk_signal_connect(GTK_OBJECT(e_tree->priv->selection), "selection_changed",
- GTK_SIGNAL_FUNC(et_selection_model_selection_change), e_tree);
+ GTK_SIGNAL_FUNC(et_selection_model_selection_changed), e_tree);
+ gtk_signal_connect(GTK_OBJECT(e_tree->priv->selection), "selection_row_changed",
+ GTK_SIGNAL_FUNC(et_selection_model_selection_row_changed), e_tree);
if (!specification->no_headers) {
e_tree_setup_header (e_tree);