diff options
author | Christopher James Lahey <clahey@ximian.com> | 2001-10-31 18:33:51 +0800 |
---|---|---|
committer | Chris Lahey <clahey@src.gnome.org> | 2001-10-31 18:33:51 +0800 |
commit | 23587bebe83c772d08ab2ae7faa31dffa45b0987 (patch) | |
tree | 610958e3503f902d708b7facdbc381315b62f317 /widgets/table | |
parent | a06c0a0d1265e81e0672c859742474c623f3d2d8 (diff) | |
download | gsoc2013-evolution-23587bebe83c772d08ab2ae7faa31dffa45b0987.tar.gz gsoc2013-evolution-23587bebe83c772d08ab2ae7faa31dffa45b0987.tar.zst gsoc2013-evolution-23587bebe83c772d08ab2ae7faa31dffa45b0987.zip |
Added frozen_count variable to know not to show the cursor while a change
2001-10-31 Christopher James Lahey <clahey@ximian.com>
* e-table-item.c, e-table-item.h: Added frozen_count variable to
know not to show the cursor while a change is going on.
* e-table-model.c, e-table-model.h, e-tree-model.c,
e-tree-model.h: Added a model_no_change signal to pair with a
pre_change if there's no change.
* e-table-selection-model.h: Removed an unused frozen field here.
* e-table-sorted.c, e-table-subset.c, e-table-subset.h,
e-table-without.c, e-tree-memory.c, e-tree-sorted.c,
e-tree-table-adapter.c: Made sure pre_changes were all matched by
some change. Proxy no_change signal where appropriate.
* e-tree-selection-model.c: Keep track of the frozen_count
variable to know whether a change is going on.
svn path=/trunk/; revision=14523
Diffstat (limited to 'widgets/table')
-rw-r--r-- | widgets/table/e-table-item.c | 79 | ||||
-rw-r--r-- | widgets/table/e-table-item.h | 5 | ||||
-rw-r--r-- | widgets/table/e-table-model.c | 50 | ||||
-rw-r--r-- | widgets/table/e-table-model.h | 3 | ||||
-rw-r--r-- | widgets/table/e-table-selection-model.h | 1 | ||||
-rw-r--r-- | widgets/table/e-table-sorted.c | 36 | ||||
-rw-r--r-- | widgets/table/e-table-subset.c | 105 | ||||
-rw-r--r-- | widgets/table/e-table-subset.h | 2 | ||||
-rw-r--r-- | widgets/table/e-table-without.c | 23 | ||||
-rw-r--r-- | widgets/table/e-tree-memory.c | 3 | ||||
-rw-r--r-- | widgets/table/e-tree-model.c | 29 | ||||
-rw-r--r-- | widgets/table/e-tree-model.h | 14 | ||||
-rw-r--r-- | widgets/table/e-tree-selection-model.c | 32 | ||||
-rw-r--r-- | widgets/table/e-tree-sorted.c | 39 | ||||
-rw-r--r-- | widgets/table/e-tree-table-adapter.c | 62 |
15 files changed, 393 insertions, 90 deletions
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c index 69b866e910..d090aa9b43 100644 --- a/widgets/table/e-table-item.c +++ b/widgets/table/e-table-item.c @@ -458,6 +458,8 @@ eti_remove_table_model (ETableItem *eti) gtk_signal_disconnect (GTK_OBJECT (eti->table_model), eti->table_model_pre_change_id); gtk_signal_disconnect (GTK_OBJECT (eti->table_model), + eti->table_model_no_change_id); + gtk_signal_disconnect (GTK_OBJECT (eti->table_model), eti->table_model_change_id); gtk_signal_disconnect (GTK_OBJECT (eti->table_model), eti->table_model_row_change_id); @@ -472,6 +474,7 @@ eti_remove_table_model (ETableItem *eti) gtk_object_unref (GTK_OBJECT (eti->source_model)); eti->table_model_pre_change_id = 0; + eti->table_model_no_change_id = 0; eti->table_model_change_id = 0; eti->table_model_row_change_id = 0; eti->table_model_cell_change_id = 0; @@ -840,6 +843,11 @@ eti_show_cursor (ETableItem *eti, int delay) if (!((GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED) && eti->cell_views_realized)) return; + + if (eti->frozen_count > 0) { + eti->queue_show_cursor = TRUE; + return; + } gtk_object_get(GTK_OBJECT(eti->selection), "cursor_row", &cursor_row, @@ -881,6 +889,10 @@ eti_check_cursor_bounds (ETableItem *eti) if (!((GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED) && eti->cell_views_realized)) return; + + if (eti->frozen_count > 0) { + return; + } gtk_object_get(GTK_OBJECT(eti->selection), "cursor_row", &cursor_row, @@ -957,8 +969,25 @@ eti_cancel_drag_due_to_model_change (ETableItem *eti) } } +static void +eti_freeze (ETableItem *eti) +{ + eti->frozen_count ++; +} + +static void +eti_unfreeze (ETableItem *eti) +{ + eti->frozen_count --; + if (eti->frozen_count == 0 && eti->queue_show_cursor) { + eti_show_cursor (eti, 0); + eti_check_cursor_bounds (eti); + eti->queue_show_cursor = FALSE; + } +} + /* - * Callback routine: invoked before the ETableModel has suffers a change + * Callback routine: invoked before the ETableModel suffers a change */ static void eti_table_model_pre_change (ETableModel *table_model, ETableItem *eti) @@ -967,6 +996,16 @@ eti_table_model_pre_change (ETableModel *table_model, ETableItem *eti) eti_check_cursor_bounds (eti); if (eti_editing (eti)) e_table_item_leave_edit_(eti); + eti_freeze (eti); +} + +/* + * Callback routine: invoked when the ETableModel has not suffered a change + */ +static void +eti_table_model_no_change (ETableModel *table_model, ETableItem *eti) +{ + eti_unfreeze (eti); } /* @@ -976,13 +1015,17 @@ eti_table_model_pre_change (ETableModel *table_model, ETableItem *eti) static void eti_table_model_changed (ETableModel *table_model, ETableItem *eti) { - if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) + if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) { + eti_unfreeze (eti); return; + } eti->rows = e_table_model_row_count (eti->table_model); free_height_cache(eti); + eti_unfreeze (eti); + eti->needs_compute_height = 1; e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (eti)); eti->needs_redraw = 1; @@ -994,36 +1037,46 @@ eti_table_model_changed (ETableModel *table_model, ETableItem *eti) static void eti_table_model_row_changed (ETableModel *table_model, int row, ETableItem *eti) { - if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) + if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) { + eti_unfreeze (eti); return; + } if ((!eti->uniform_row_height) && eti->height_cache && eti->height_cache[row] != -1 && eti_row_height_real(eti, row) != eti->height_cache[row]) { eti_table_model_changed (table_model, eti); return; } + eti_unfreeze (eti); + eti_request_region_redraw (eti, 0, row, eti->cols - 1, row, 0); } static void eti_table_model_cell_changed (ETableModel *table_model, int col, int row, ETableItem *eti) { - if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) + if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) { + eti_unfreeze (eti); return; + } if ((!eti->uniform_row_height) && eti->height_cache && eti->height_cache[row] != -1 && eti_row_height_real(eti, row) != eti->height_cache[row]) { eti_table_model_changed (table_model, eti); return; } + eti_unfreeze (eti); + eti_request_region_redraw (eti, 0, row, eti->cols - 1, row, 0); } static void eti_table_model_rows_inserted (ETableModel *table_model, int row, int count, ETableItem *eti) { - if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) + if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) { + eti_unfreeze (eti); return; + } eti->rows = e_table_model_row_count (eti->table_model); if (eti->height_cache) { @@ -1034,6 +1087,8 @@ eti_table_model_rows_inserted (ETableModel *table_model, int row, int count, ETa eti->height_cache[i] = -1; } + eti_unfreeze (eti); + eti_idle_maybe_show_cursor(eti); eti->needs_compute_height = 1; @@ -1045,8 +1100,10 @@ eti_table_model_rows_inserted (ETableModel *table_model, int row, int count, ETa static void eti_table_model_rows_deleted (ETableModel *table_model, int row, int count, ETableItem *eti) { - if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) + if (!(GTK_OBJECT_FLAGS(eti) & GNOME_CANVAS_ITEM_REALIZED)) { + eti_unfreeze (eti); return; + } g_assert (eti->rows == -1 || row + count <= eti->rows); @@ -1058,6 +1115,8 @@ eti_table_model_rows_deleted (ETableModel *table_model, int row, int count, ETab memmove(eti->height_cache + row, eti->height_cache + row + count, (eti->rows - row) * sizeof(int)); } + eti_unfreeze (eti); + eti_idle_maybe_show_cursor(eti); eti->needs_compute_height = 1; @@ -1116,6 +1175,10 @@ eti_add_table_model (ETableItem *eti, ETableModel *table_model) GTK_OBJECT (table_model), "model_pre_change", GTK_SIGNAL_FUNC (eti_table_model_pre_change), eti); + eti->table_model_no_change_id = gtk_signal_connect ( + GTK_OBJECT (table_model), "model_no_change", + GTK_SIGNAL_FUNC (eti_table_model_no_change), eti); + eti->table_model_change_id = gtk_signal_connect ( GTK_OBJECT (table_model), "model_changed", GTK_SIGNAL_FUNC (eti_table_model_changed), eti); @@ -1464,6 +1527,9 @@ eti_init (GnomeCanvasItem *item) eti->rows = -1; + eti->frozen_count = 0; + eti->queue_show_cursor = FALSE; + e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (eti), eti_reflow); } @@ -2834,6 +2900,7 @@ eti_cursor_activated (ESelectionModel *selection, int row, int col, ETableItem * } else { eti_show_cursor(eti, 0); } + eti_check_cursor_bounds (eti); } } diff --git a/widgets/table/e-table-item.h b/widgets/table/e-table-item.h index 26c7d5d3d7..16172771b7 100644 --- a/widgets/table/e-table-item.h +++ b/widgets/table/e-table-item.h @@ -63,6 +63,7 @@ typedef struct { int header_structure_change_id; int header_request_width_id; int table_model_pre_change_id; + int table_model_no_change_id; int table_model_change_id; int table_model_row_change_id; int table_model_cell_change_id; @@ -107,6 +108,10 @@ typedef struct { guint cursor_on_screen : 1; guint gtk_grabbed : 1; + guint queue_show_cursor : 1; + + int frozen_count; + int cursor_x1; int cursor_y1; int cursor_x2; diff --git a/widgets/table/e-table-model.c b/widgets/table/e-table-model.c index 774eb19c3d..89dce2756c 100644 --- a/widgets/table/e-table-model.c +++ b/widgets/table/e-table-model.c @@ -38,6 +38,7 @@ d(static gint depth = 0); static GtkObjectClass *e_table_model_parent_class; enum { + MODEL_NO_CHANGE, MODEL_CHANGED, MODEL_PRE_CHANGE, MODEL_ROW_CHANGED, @@ -272,6 +273,15 @@ e_table_model_class_init (GtkObjectClass *object_class) object_class->destroy = e_table_model_destroy; + e_table_model_signals [MODEL_NO_CHANGE] = + gtk_signal_new ("model_no_change", + GTK_RUN_LAST, + E_OBJECT_CLASS_TYPE (object_class), + GTK_SIGNAL_OFFSET (ETableModelClass, model_no_change), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + e_table_model_signals [MODEL_CHANGED] = gtk_signal_new ("model_changed", GTK_RUN_LAST, @@ -341,6 +351,7 @@ e_table_model_class_init (GtkObjectClass *object_class) klass->value_is_empty = NULL; klass->value_to_string = NULL; + klass->model_no_change = NULL; klass->model_changed = NULL; klass->model_row_changed = NULL; klass->model_cell_changed = NULL; @@ -391,7 +402,7 @@ e_table_model_pre_change (ETableModel *e_table_model) g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); d(print_tabs()); - d(g_print("Emitting pre_change on model 0x%p.\n", e_table_model)); + d(g_print("Emitting pre_change on model 0x%p, a %s.\n", e_table_model, gtk_type_name (GTK_OBJECT(e_table_model)->klass->type))); d(depth++); gtk_signal_emit (GTK_OBJECT (e_table_model), e_table_model_signals [MODEL_PRE_CHANGE]); @@ -399,6 +410,33 @@ e_table_model_pre_change (ETableModel *e_table_model) } /** + * e_table_model_no_change: + * @e_table_model: the table model to notify of the lack of a change + * + * Use this function to notify any views of this table model that + * the contents of the table model have changed. This will emit + * the signal "model_no_change" on the @e_table_model object. + * + * It is preferable to use the e_table_model_row_changed() and + * the e_table_model_cell_changed() to notify of smaller changes + * than to invalidate the entire model, as the views might have + * ways of caching the information they render from the model. + */ +void +e_table_model_no_change (ETableModel *e_table_model) +{ + g_return_if_fail (e_table_model != NULL); + g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); + + d(print_tabs()); + d(g_print("Emitting model_no_change on model 0x%p, a %s.\n", e_table_model, gtk_type_name (GTK_OBJECT(e_table_model)->klass->type))); + d(depth++); + gtk_signal_emit (GTK_OBJECT (e_table_model), + e_table_model_signals [MODEL_NO_CHANGE]); + d(depth--); +} + +/** * e_table_model_changed: * @e_table_model: the table model to notify of the change * @@ -418,7 +456,7 @@ e_table_model_changed (ETableModel *e_table_model) g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); d(print_tabs()); - d(g_print("Emitting model_changed on model 0x%p.\n", e_table_model)); + d(g_print("Emitting model_changed on model 0x%p, a %s.\n", e_table_model, gtk_type_name (GTK_OBJECT(e_table_model)->klass->type))); d(depth++); gtk_signal_emit (GTK_OBJECT (e_table_model), e_table_model_signals [MODEL_CHANGED]); @@ -442,7 +480,7 @@ e_table_model_row_changed (ETableModel *e_table_model, int row) g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); d(print_tabs()); - d(g_print("Emitting row_changed on model 0x%p, row %d.\n", e_table_model, row)); + d(g_print("Emitting row_changed on model 0x%p, a %s, row %d.\n", e_table_model, gtk_type_name (GTK_OBJECT(e_table_model)->klass->type), row)); d(depth++); gtk_signal_emit (GTK_OBJECT (e_table_model), e_table_model_signals [MODEL_ROW_CHANGED], row); @@ -467,7 +505,7 @@ e_table_model_cell_changed (ETableModel *e_table_model, int col, int row) g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); d(print_tabs()); - d(g_print("Emitting cell_changed on model 0x%p, row %d, col %d.\n", e_table_model, row, col)); + d(g_print("Emitting cell_changed on model 0x%p, a %s, row %d, col %d.\n", e_table_model, gtk_type_name (GTK_OBJECT(e_table_model)->klass->type), row, col)); d(depth++); gtk_signal_emit (GTK_OBJECT (e_table_model), e_table_model_signals [MODEL_CELL_CHANGED], col, row); @@ -492,7 +530,7 @@ e_table_model_rows_inserted (ETableModel *e_table_model, int row, int count) g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); d(print_tabs()); - d(g_print("Emitting row_inserted on model 0x%p, row %d.\n", e_table_model, row)); + d(g_print("Emitting row_inserted on model 0x%p, a %s, row %d.\n", e_table_model, gtk_type_name (GTK_OBJECT(e_table_model)->klass->type), row)); d(depth++); gtk_signal_emit (GTK_OBJECT (e_table_model), e_table_model_signals [MODEL_ROWS_INSERTED], row, count); @@ -532,7 +570,7 @@ e_table_model_rows_deleted (ETableModel *e_table_model, int row, int count) g_return_if_fail (E_IS_TABLE_MODEL (e_table_model)); d(print_tabs()); - d(g_print("Emitting row_deleted on model 0x%p, row %d.\n", e_table_model, row)); + d(g_print("Emitting row_deleted on model 0x%p, a %s, row %d.\n", e_table_model, gtk_type_name (GTK_OBJECT(e_table_model)->klass->type), row)); d(depth++); gtk_signal_emit (GTK_OBJECT (e_table_model), e_table_model_signals [MODEL_ROWS_DELETED], row, count); diff --git a/widgets/table/e-table-model.h b/widgets/table/e-table-model.h index 629cce49bc..45731added 100644 --- a/widgets/table/e-table-model.h +++ b/widgets/table/e-table-model.h @@ -77,6 +77,7 @@ typedef struct { /* * These all come after the change has been made. + * No changes, cancel pre_change: no_change * Major structural changes: model_changed * Changes only in a row: row_changed * Only changes in a cell: cell_changed @@ -85,6 +86,7 @@ typedef struct { */ void (*model_pre_change) (ETableModel *etm); + void (*model_no_change) (ETableModel *etm); void (*model_changed) (ETableModel *etm); void (*model_row_changed) (ETableModel *etm, int row); void (*model_cell_changed) (ETableModel *etm, int col, int row); @@ -144,6 +146,7 @@ char *e_table_model_value_to_string (ETableModel *e_table_model, * Routines for emitting signals on the e_table */ void e_table_model_pre_change (ETableModel *e_table_model); +void e_table_model_no_change (ETableModel *e_table_model); void e_table_model_changed (ETableModel *e_table_model); void e_table_model_row_changed (ETableModel *e_table_model, int row); diff --git a/widgets/table/e-table-selection-model.h b/widgets/table/e-table-selection-model.h index cbc96ed48c..93cd6df94e 100644 --- a/widgets/table/e-table-selection-model.h +++ b/widgets/table/e-table-selection-model.h @@ -54,7 +54,6 @@ typedef struct { guint model_changed_idle_id; - guint frozen : 1; guint selection_model_changed : 1; guint group_info_changed : 1; diff --git a/widgets/table/e-table-sorted.c b/widgets/table/e-table-sorted.c index ea2c1d8051..ae42022162 100644 --- a/widgets/table/e-table-sorted.c +++ b/widgets/table/e-table-sorted.c @@ -127,6 +127,9 @@ e_table_sorted_new (ETableModel *source, ETableHeader *full_header, ETableSortIn ETableSorted *ets = gtk_type_new (E_TABLE_SORTED_TYPE); ETableSubset *etss = E_TABLE_SUBSET (ets); + if (ets_parent_class->proxy_model_pre_change) + (ets_parent_class->proxy_model_pre_change) (etss, source); + if (e_table_subset_construct (etss, source, 0) == NULL){ gtk_object_unref (GTK_OBJECT (ets)); return NULL; @@ -198,17 +201,27 @@ ets_proxy_model_rows_inserted (ETableSubset *etss, ETableModel *source, int row, ETableModel *etm = E_TABLE_MODEL(etss); ETableSorted *ets = E_TABLE_SORTED(etss); int i; + gboolean full_change = FALSE; - e_table_model_pre_change (etm); + if (count == 0) { + e_table_model_no_change (etm); + return; + } - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] >= row) - etss->map_table[i] += count; + if (row != etss->n_map) { + full_change = TRUE; + for (i = 0; i < etss->n_map; i++) { + if (etss->map_table[i] >= row) { + etss->map_table[i] += count; + } + } } etss->map_table = g_realloc (etss->map_table, (etss->n_map + count) * sizeof(int)); for (; count > 0; count --) { + if (!full_change) + e_table_model_pre_change (etm); i = etss->n_map; if (ets->sort_idle_id == 0) { /* this is to see if we're inserting a lot of things between idle loops. @@ -228,11 +241,17 @@ ets_proxy_model_rows_inserted (ETableSubset *etss, ETableModel *source, int row, } etss->map_table[i] = row; etss->n_map++; + if (!full_change) { + e_table_model_row_inserted (etm, i); + } - e_table_model_row_inserted (etm, i); d(g_print("inserted row %d", row)); row++; } + if (full_change) + e_table_model_changed (etm); + else + e_table_model_no_change (etm); d(e_table_subset_print_debugging(etss)); } @@ -245,11 +264,12 @@ ets_proxy_model_rows_deleted (ETableSubset *etss, ETableModel *source, int row, int j; shift = row == etss->n_map - count; - + for (j = 0; j < count; j++) { for (i = 0; i < etss->n_map; i++){ if (etss->map_table[i] == row + j) { - e_table_model_pre_change (etm); + if (shift) + e_table_model_pre_change (etm); memmove (etss->map_table + i, etss->map_table + i + 1, (etss->n_map - i - 1) * sizeof(int)); etss->n_map --; if (shift) @@ -264,6 +284,8 @@ ets_proxy_model_rows_deleted (ETableSubset *etss, ETableModel *source, int row, } e_table_model_changed (etm); + } else { + e_table_model_no_change (etm); } d(g_print("deleted row %d count %d", row, count)); diff --git a/widgets/table/e-table-subset.c b/widgets/table/e-table-subset.c index a55f9b4b0f..2f7b455201 100644 --- a/widgets/table/e-table-subset.c +++ b/widgets/table/e-table-subset.c @@ -29,9 +29,12 @@ #include "e-table-subset.h" static void etss_proxy_model_pre_change_real (ETableSubset *etss, ETableModel *etm); +static void etss_proxy_model_no_change_real (ETableSubset *etss, ETableModel *etm); static void etss_proxy_model_changed_real (ETableSubset *etss, ETableModel *etm); static void etss_proxy_model_row_changed_real (ETableSubset *etss, ETableModel *etm, int row); static void etss_proxy_model_cell_changed_real (ETableSubset *etss, ETableModel *etm, int col, int row); +static void etss_proxy_model_rows_inserted_real (ETableSubset *etss, ETableModel *etm, int row, int count); +static void etss_proxy_model_rows_deleted_real (ETableSubset *etss, ETableModel *etm, int row, int count); #define PARENT_TYPE E_TABLE_MODEL_TYPE #define d(x) @@ -88,6 +91,8 @@ etss_destroy (GtkObject *object) gtk_signal_disconnect (GTK_OBJECT (etss->source), etss->table_model_pre_change_id); gtk_signal_disconnect (GTK_OBJECT (etss->source), + etss->table_model_no_change_id); + gtk_signal_disconnect (GTK_OBJECT (etss->source), etss->table_model_changed_id); gtk_signal_disconnect (GTK_OBJECT (etss->source), etss->table_model_row_changed_id); @@ -223,36 +228,37 @@ etss_value_to_string (ETableModel *etm, int col, const void *value) static void etss_class_init (GtkObjectClass *object_class) { - ETableSubsetClass *klass = (ETableSubsetClass *) object_class; - ETableModelClass *table_class = (ETableModelClass *) object_class; + ETableSubsetClass *klass = (ETableSubsetClass *) object_class; + ETableModelClass *table_class = (ETableModelClass *) object_class; - etss_parent_class = gtk_type_class (PARENT_TYPE); + etss_parent_class = gtk_type_class (PARENT_TYPE); - object_class->destroy = etss_destroy; + object_class->destroy = etss_destroy; - table_class->column_count = etss_column_count; - table_class->row_count = etss_row_count; - table_class->append_row = etss_append_row; + table_class->column_count = etss_column_count; + table_class->row_count = etss_row_count; + table_class->append_row = etss_append_row; - table_class->value_at = etss_value_at; - table_class->set_value_at = etss_set_value_at; - table_class->is_cell_editable = etss_is_cell_editable; + table_class->value_at = etss_value_at; + table_class->set_value_at = etss_set_value_at; + table_class->is_cell_editable = etss_is_cell_editable; - table_class->has_save_id = etss_has_save_id; - table_class->get_save_id = etss_get_save_id; + table_class->has_save_id = etss_has_save_id; + table_class->get_save_id = etss_get_save_id; - table_class->duplicate_value = etss_duplicate_value; - table_class->free_value = etss_free_value; - table_class->initialize_value = etss_initialize_value; - table_class->value_is_empty = etss_value_is_empty; - table_class->value_to_string = etss_value_to_string; + table_class->duplicate_value = etss_duplicate_value; + table_class->free_value = etss_free_value; + table_class->initialize_value = etss_initialize_value; + table_class->value_is_empty = etss_value_is_empty; + table_class->value_to_string = etss_value_to_string; - klass->proxy_model_pre_change = etss_proxy_model_pre_change_real; - klass->proxy_model_changed = etss_proxy_model_changed_real; - klass->proxy_model_row_changed = etss_proxy_model_row_changed_real; - klass->proxy_model_cell_changed = etss_proxy_model_cell_changed_real; - klass->proxy_model_rows_inserted = NULL; - klass->proxy_model_rows_deleted = NULL; + klass->proxy_model_pre_change = etss_proxy_model_pre_change_real; + klass->proxy_model_no_change = etss_proxy_model_no_change_real; + klass->proxy_model_changed = etss_proxy_model_changed_real; + klass->proxy_model_row_changed = etss_proxy_model_row_changed_real; + klass->proxy_model_cell_changed = etss_proxy_model_cell_changed_real; + klass->proxy_model_rows_inserted = etss_proxy_model_rows_inserted_real; + klass->proxy_model_rows_deleted = etss_proxy_model_rows_deleted_real; } static void @@ -270,6 +276,12 @@ etss_proxy_model_pre_change_real (ETableSubset *etss, ETableModel *etm) } static void +etss_proxy_model_no_change_real (ETableSubset *etss, ETableModel *etm) +{ + e_table_model_no_change (E_TABLE_MODEL (etss)); +} + +static void etss_proxy_model_changed_real (ETableSubset *etss, ETableModel *etm) { e_table_model_changed (E_TABLE_MODEL (etss)); @@ -281,6 +293,8 @@ etss_proxy_model_row_changed_real (ETableSubset *etss, ETableModel *etm, int row int view_row = etss_get_view_row (etss, row); if (view_row != -1) e_table_model_row_changed (E_TABLE_MODEL (etss), view_row); + else + e_table_model_no_change (E_TABLE_MODEL (etss)); } static void @@ -289,6 +303,20 @@ etss_proxy_model_cell_changed_real (ETableSubset *etss, ETableModel *etm, int co int view_row = etss_get_view_row (etss, row); if (view_row != -1) e_table_model_cell_changed (E_TABLE_MODEL (etss), col, view_row); + else + e_table_model_no_change (E_TABLE_MODEL (etss)); +} + +static void +etss_proxy_model_rows_inserted_real (ETableSubset *etss, ETableModel *etm, int row, int count) +{ + e_table_model_no_change (E_TABLE_MODEL (etss)); +} + +static void +etss_proxy_model_rows_deleted_real (ETableSubset *etss, ETableModel *etm, int row, int count) +{ + e_table_model_no_change (E_TABLE_MODEL (etss)); } static void @@ -299,6 +327,13 @@ etss_proxy_model_pre_change (ETableModel *etm, ETableSubset *etss) } static void +etss_proxy_model_no_change (ETableModel *etm, ETableSubset *etss) +{ + if (ETSS_CLASS(etss)->proxy_model_no_change) + (ETSS_CLASS(etss)->proxy_model_no_change) (etss, etm); +} + +static void etss_proxy_model_changed (ETableModel *etm, ETableSubset *etss) { if (ETSS_CLASS(etss)->proxy_model_changed) @@ -354,18 +389,20 @@ e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals) for (i = 0; i < nvals; i++) etss->map_table [i] = i; - etss->table_model_pre_change_id = gtk_signal_connect (GTK_OBJECT (source), "model_pre_change", - GTK_SIGNAL_FUNC (etss_proxy_model_pre_change), etss); - etss->table_model_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_changed", - GTK_SIGNAL_FUNC (etss_proxy_model_changed), etss); - etss->table_model_row_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_row_changed", - GTK_SIGNAL_FUNC (etss_proxy_model_row_changed), etss); - etss->table_model_cell_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed", - GTK_SIGNAL_FUNC (etss_proxy_model_cell_changed), etss); + etss->table_model_pre_change_id = gtk_signal_connect (GTK_OBJECT (source), "model_pre_change", + GTK_SIGNAL_FUNC (etss_proxy_model_pre_change), etss); + etss->table_model_no_change_id = gtk_signal_connect (GTK_OBJECT (source), "model_no_change", + GTK_SIGNAL_FUNC (etss_proxy_model_no_change), etss); + etss->table_model_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_changed", + GTK_SIGNAL_FUNC (etss_proxy_model_changed), etss); + etss->table_model_row_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_row_changed", + GTK_SIGNAL_FUNC (etss_proxy_model_row_changed), etss); + etss->table_model_cell_changed_id = gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed", + GTK_SIGNAL_FUNC (etss_proxy_model_cell_changed), etss); etss->table_model_rows_inserted_id = gtk_signal_connect (GTK_OBJECT (source), "model_rows_inserted", - GTK_SIGNAL_FUNC (etss_proxy_model_rows_inserted), etss); - etss->table_model_rows_deleted_id = gtk_signal_connect (GTK_OBJECT (source), "model_rows_deleted", - GTK_SIGNAL_FUNC (etss_proxy_model_rows_deleted), etss); + GTK_SIGNAL_FUNC (etss_proxy_model_rows_inserted), etss); + etss->table_model_rows_deleted_id = gtk_signal_connect (GTK_OBJECT (source), "model_rows_deleted", + GTK_SIGNAL_FUNC (etss_proxy_model_rows_deleted), etss); return E_TABLE_MODEL (etss); } diff --git a/widgets/table/e-table-subset.h b/widgets/table/e-table-subset.h index 649004aefa..d677583249 100644 --- a/widgets/table/e-table-subset.h +++ b/widgets/table/e-table-subset.h @@ -48,6 +48,7 @@ typedef struct { int last_access; int table_model_pre_change_id; + int table_model_no_change_id; int table_model_changed_id; int table_model_row_changed_id; int table_model_cell_changed_id; @@ -59,6 +60,7 @@ typedef struct { ETableModelClass parent_class; void (*proxy_model_pre_change) (ETableSubset *etss, ETableModel *etm); + void (*proxy_model_no_change) (ETableSubset *etss, ETableModel *etm); void (*proxy_model_changed) (ETableSubset *etss, ETableModel *etm); void (*proxy_model_row_changed) (ETableSubset *etss, ETableModel *etm, int row); void (*proxy_model_cell_changed) (ETableSubset *etss, ETableModel *etm, int col, int row); diff --git a/widgets/table/e-table-without.c b/widgets/table/e-table-without.c index 7a1989980a..f6d4fe3b86 100644 --- a/widgets/table/e-table-without.c +++ b/widgets/table/e-table-without.c @@ -153,11 +153,15 @@ etw_proxy_model_rows_inserted (ETableSubset *etss, ETableModel *etm, int model_r { int i; ETableWithout *etw = E_TABLE_WITHOUT (etss); + gboolean shift = FALSE; /* i is View row */ - for (i = 0; i < etss->n_map; i++) { - if (etss->map_table[i] > model_row) - etss->map_table[i] += count; + if (model_row != etss->n_map) { + for (i = 0; i < etss->n_map; i++) { + if (etss->map_table[i] > model_row) + etss->map_table[i] += count; + } + shift = TRUE; } /* i is Model row */ @@ -166,6 +170,10 @@ etw_proxy_model_rows_inserted (ETableSubset *etss, ETableModel *etm, int model_r add_row (etw, i); } } + if (shift) + e_table_model_changed (E_TABLE_MODEL (etw)); + else + e_table_model_no_change (E_TABLE_MODEL (etw)); } static void @@ -173,14 +181,21 @@ etw_proxy_model_rows_deleted (ETableSubset *etss, ETableModel *etm, int model_ro { int i; /* View row */ ETableWithout *etw = E_TABLE_WITHOUT (etss); + gboolean shift = FALSE; for (i = 0; i < etss->n_map; i++) { if (etss->map_table[i] >= model_row && etss->map_table[i] < model_row + count) { remove_row (etw, i); i--; - } else if (etss->map_table[i] >= model_row + count) + } else if (etss->map_table[i] >= model_row + count) { etss->map_table[i] -= count; + shift = TRUE; + } } + if (shift) + e_table_model_changed (E_TABLE_MODEL (etw)); + else + e_table_model_no_change (E_TABLE_MODEL (etw)); } static void diff --git a/widgets/table/e-tree-memory.c b/widgets/table/e-tree-memory.c index 094ead125a..1d266ae1d1 100644 --- a/widgets/table/e-tree-memory.c +++ b/widgets/table/e-tree-memory.c @@ -460,8 +460,7 @@ e_tree_memory_node_insert (ETreeMemory *tree_model, e_tree_memory_path_insert (parent_path, position, new_path); if (!tree_model->priv->frozen) e_tree_model_node_inserted (E_TREE_MODEL(tree_model), parent_path, new_path); - } - else { + } else { priv->root = new_path; if (!tree_model->priv->frozen) e_tree_model_node_changed(E_TREE_MODEL(tree_model), new_path); diff --git a/widgets/table/e-tree-model.c b/widgets/table/e-tree-model.c index 1d28d7832d..d6974ada97 100644 --- a/widgets/table/e-tree-model.c +++ b/widgets/table/e-tree-model.c @@ -46,6 +46,7 @@ static GtkObjectClass *parent_class; enum { PRE_CHANGE, + NO_CHANGE, NODE_CHANGED, NODE_DATA_CHANGED, NODE_COL_CHANGED, @@ -72,6 +73,14 @@ e_tree_model_class_init (GtkObjectClass *klass) gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); + e_tree_model_signals [NO_CHANGE] = + gtk_signal_new ("no_change", + GTK_RUN_LAST, + E_OBJECT_CLASS_TYPE (klass), + GTK_SIGNAL_OFFSET (ETreeModelClass, no_change), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + e_tree_model_signals [NODE_CHANGED] = gtk_signal_new ("node_changed", GTK_RUN_LAST, @@ -150,6 +159,7 @@ e_tree_model_class_init (GtkObjectClass *klass) tree_class->value_to_string = NULL; tree_class->pre_change = NULL; + tree_class->no_change = NULL; tree_class->node_changed = NULL; tree_class->node_data_changed = NULL; tree_class->node_col_changed = NULL; @@ -196,6 +206,25 @@ e_tree_model_pre_change (ETreeModel *tree_model) * Return value: **/ void +e_tree_model_no_change (ETreeModel *tree_model) +{ + g_return_if_fail (tree_model != NULL); + g_return_if_fail (E_IS_TREE_MODEL (tree_model)); + + gtk_signal_emit (GTK_OBJECT (tree_model), + e_tree_model_signals [NO_CHANGE]); +} + +/** + * e_tree_model_node_changed: + * @tree_model: + * @node: + * + * + * + * Return value: + **/ +void e_tree_model_node_changed (ETreeModel *tree_model, ETreePath node) { g_return_if_fail (tree_model != NULL); diff --git a/widgets/table/e-tree-model.h b/widgets/table/e-tree-model.h index beeb76aef8..f7d3497841 100644 --- a/widgets/table/e-tree-model.h +++ b/widgets/table/e-tree-model.h @@ -55,13 +55,13 @@ struct ETreeModelClass { /* * Virtual methods */ - ETreePath (*get_root) (ETreeModel *etm); + ETreePath (*get_root) (ETreeModel *etm); - ETreePath (*get_parent) (ETreeModel *etm, ETreePath node); - ETreePath (*get_first_child) (ETreeModel *etm, ETreePath node); - ETreePath (*get_last_child) (ETreeModel *etm, ETreePath node); - ETreePath (*get_next) (ETreeModel *etm, ETreePath node); - ETreePath (*get_prev) (ETreeModel *etm, ETreePath node); + ETreePath (*get_parent) (ETreeModel *etm, ETreePath node); + ETreePath (*get_first_child) (ETreeModel *etm, ETreePath node); + ETreePath (*get_last_child) (ETreeModel *etm, ETreePath node); + ETreePath (*get_next) (ETreeModel *etm, ETreePath node); + ETreePath (*get_prev) (ETreeModel *etm, ETreePath node); gboolean (*is_root) (ETreeModel *etm, ETreePath node); gboolean (*is_expandable) (ETreeModel *etm, ETreePath node); @@ -98,6 +98,7 @@ struct ETreeModelClass { * Signals */ void (*pre_change) (ETreeModel *etm); + void (*no_change) (ETreeModel *etm); void (*node_changed) (ETreeModel *etm, ETreePath node); void (*node_data_changed) (ETreeModel *etm, ETreePath node); void (*node_col_changed) (ETreeModel *etm, ETreePath node, int col); @@ -185,6 +186,7 @@ void e_tree_model_node_traverse_preorder (ETreeModel *model, ** Routines for emitting signals on the ETreeModel */ void e_tree_model_pre_change (ETreeModel *tree_model); +void e_tree_model_no_change (ETreeModel *tree_model); void e_tree_model_node_changed (ETreeModel *tree_model, ETreePath node); void e_tree_model_node_data_changed (ETreeModel *tree_model, diff --git a/widgets/table/e-tree-selection-model.c b/widgets/table/e-tree-selection-model.c index a4efddf2b8..7914cb022a 100644 --- a/widgets/table/e-tree-selection-model.c +++ b/widgets/table/e-tree-selection-model.c @@ -70,7 +70,10 @@ struct ETreeSelectionModelPriv { char *cursor_save_id; + int frozen_count; + int tree_model_pre_change_id; + int tree_model_no_change_id; int tree_model_node_changed_id; int tree_model_node_data_changed_id; int tree_model_node_col_changed_id; @@ -342,6 +345,18 @@ update_parents (ETreeSelectionModel *etsm, ETreePath path) /* Signal handlers */ static void +etsm_freeze (ETreeSelectionModel *etsm) +{ + etsm->priv->frozen_count ++; +} + +static void +etsm_unfreeze (ETreeSelectionModel *etsm) +{ + etsm->priv->frozen_count --; +} + +static void etsm_pre_change (ETreeModel *etm, ETreeSelectionModel *etsm) { g_free (etsm->priv->cursor_save_id); @@ -352,6 +367,14 @@ etsm_pre_change (ETreeModel *etm, ETreeSelectionModel *etsm) etsm->priv->cursor_path) { etsm->priv->cursor_save_id = e_tree_model_get_save_id (etm, etsm->priv->cursor_path); } + + etsm_freeze (etsm); +} + +static void +etsm_no_change (ETreeModel *etm, ETreeSelectionModel *etsm) +{ + etsm_unfreeze (etsm); } static void @@ -384,6 +407,7 @@ etsm_node_changed (ETreeModel *etm, ETreePath node, ETreeSelectionModel *etsm) g_free (etsm->priv->cursor_save_id); etsm->priv->cursor_save_id = NULL; + etsm_unfreeze (etsm); } static void @@ -391,6 +415,7 @@ etsm_node_data_changed (ETreeModel *etm, ETreePath node, ETreeSelectionModel *et { g_free (etsm->priv->cursor_save_id); etsm->priv->cursor_save_id = NULL; + etsm_unfreeze (etsm); } static void @@ -398,6 +423,7 @@ etsm_node_col_changed (ETreeModel *etm, ETreePath node, int col, ETreeSelectionM { g_free (etsm->priv->cursor_save_id); etsm->priv->cursor_save_id = NULL; + etsm_unfreeze (etsm); } static void @@ -454,6 +480,8 @@ add_model(ETreeSelectionModel *etsm, ETreeModel *model) gtk_object_ref(GTK_OBJECT(priv->model)); priv->tree_model_pre_change_id = gtk_signal_connect_after (GTK_OBJECT (priv->model), "pre_change", GTK_SIGNAL_FUNC (etsm_pre_change), etsm); + priv->tree_model_no_change_id = gtk_signal_connect_after (GTK_OBJECT (priv->model), "no_change", + GTK_SIGNAL_FUNC (etsm_no_change), etsm); priv->tree_model_node_changed_id = gtk_signal_connect_after (GTK_OBJECT (priv->model), "node_changed", GTK_SIGNAL_FUNC (etsm_node_changed), etsm); priv->tree_model_node_data_changed_id = gtk_signal_connect_after (GTK_OBJECT (priv->model), "node_data_changed", @@ -477,6 +505,8 @@ drop_model(ETreeSelectionModel *etsm) gtk_signal_disconnect (GTK_OBJECT (priv->model), priv->tree_model_pre_change_id); gtk_signal_disconnect (GTK_OBJECT (priv->model), + priv->tree_model_no_change_id); + gtk_signal_disconnect (GTK_OBJECT (priv->model), priv->tree_model_node_changed_id); gtk_signal_disconnect (GTK_OBJECT (priv->model), priv->tree_model_node_data_changed_id); @@ -491,6 +521,7 @@ drop_model(ETreeSelectionModel *etsm) priv->model = 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; @@ -1194,6 +1225,7 @@ e_tree_selection_model_init (ETreeSelectionModel *etsm) 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; diff --git a/widgets/table/e-tree-sorted.c b/widgets/table/e-tree-sorted.c index 632fc650dd..21b49b339c 100644 --- a/widgets/table/e-tree-sorted.c +++ b/widgets/table/e-tree-sorted.c @@ -93,6 +93,7 @@ struct ETreeSortedPriv { ETreeSortedPath *last_access; int tree_model_pre_change_id; + int tree_model_no_change_id; int tree_model_node_changed_id; int tree_model_node_data_changed_id; int tree_model_node_col_changed_id; @@ -390,12 +391,13 @@ new_path (ETreeSortedPath *parent, ETreePath corresponding) return path; } -static void +static gboolean reposition_path (ETreeSorted *ets, ETreeSortedPath *path) { int new_index; int old_index = path->position; ETreeSortedPath *parent = path->parent; + gboolean changed = FALSE; if (parent) { if (ets->priv->sort_idle_id == 0) { if (ets->priv->insert_count > ETS_INSERT_MAX) { @@ -422,9 +424,9 @@ reposition_path (ETreeSorted *ets, ETreeSortedPath *path) parent->children[new_index] = path; for (i = old_index; i <= new_index; i++) parent->children[i]->position = i; + changed = TRUE; e_tree_model_node_changed(E_TREE_MODEL(ets), parent); e_tree_sorted_node_resorted(ets, parent); - e_tree_model_pre_change(E_TREE_MODEL(ets)); } else if (new_index < old_index) { int i; ets->priv->insert_count++; @@ -432,14 +434,15 @@ reposition_path (ETreeSorted *ets, ETreeSortedPath *path) parent->children[new_index] = path; for (i = new_index; i <= old_index; i++) parent->children[i]->position = i; + changed = TRUE; e_tree_model_node_changed(E_TREE_MODEL(ets), parent); e_tree_sorted_node_resorted(ets, parent); - e_tree_model_pre_change(E_TREE_MODEL(ets)); } } } else mark_path_needs_resort(ets, parent, TRUE, FALSE); } + return changed; } static void @@ -597,6 +600,8 @@ ets_destroy (GtkObject *object) gtk_signal_disconnect (GTK_OBJECT (priv->source), priv->tree_model_pre_change_id); gtk_signal_disconnect (GTK_OBJECT (priv->source), + priv->tree_model_no_change_id); + gtk_signal_disconnect (GTK_OBJECT (priv->source), priv->tree_model_node_changed_id); gtk_signal_disconnect (GTK_OBJECT (priv->source), priv->tree_model_node_data_changed_id); @@ -611,6 +616,7 @@ ets_destroy (GtkObject *object) priv->source = 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; @@ -991,6 +997,12 @@ ets_proxy_pre_change (ETreeModel *etm, ETreeSorted *ets) } static void +ets_proxy_no_change (ETreeModel *etm, ETreeSorted *ets) +{ + e_tree_model_no_change(E_TREE_MODEL(ets)); +} + +static void ets_proxy_node_changed (ETreeModel *etm, ETreePath node, ETreeSorted *ets) { ets->priv->last_access = NULL; @@ -1009,8 +1021,8 @@ ets_proxy_node_changed (ETreeModel *etm, ETreePath node, ETreeSorted *ets) if (path) { free_children(path); - reposition_path(ets, path); - e_tree_model_node_changed(E_TREE_MODEL(ets), path); + if (!reposition_path(ets, path)) + e_tree_model_node_changed(E_TREE_MODEL(ets), path); } } } @@ -1021,8 +1033,8 @@ ets_proxy_node_data_changed (ETreeModel *etm, ETreePath node, ETreeSorted *ets) ETreeSortedPath *path = find_path(ets, node); if (path) { - reposition_path(ets, path); - e_tree_model_node_data_changed(E_TREE_MODEL(ets), path); + if (!reposition_path(ets, path)) + e_tree_model_node_data_changed(E_TREE_MODEL(ets), path); } } @@ -1032,9 +1044,11 @@ ets_proxy_node_col_changed (ETreeModel *etm, ETreePath node, int col, ETreeSorte ETreeSortedPath *path = find_path(ets, node); if (path) { + gboolean changed = FALSE; if (e_table_sorting_utils_affects_sort(ets->priv->sort_info, ets->priv->full_header, col)) - reposition_path(ets, path); - e_tree_model_node_col_changed(E_TREE_MODEL(ets), path, col); + changed = reposition_path(ets, path); + if (!changed) + e_tree_model_node_col_changed(E_TREE_MODEL(ets), path, col); } } @@ -1236,6 +1250,7 @@ e_tree_sorted_init (GtkObject *object) priv->last_access = 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; @@ -1271,8 +1286,10 @@ e_tree_sorted_construct (ETreeSorted *ets, ETreeModel *source, ETableHeader *ful ets->priv->sort_info = sort_info; if (sort_info) gtk_object_ref(GTK_OBJECT(sort_info)); - ets->priv->tree_model_pre_change_id = gtk_signal_connect (GTK_OBJECT (source), "pre_change", - GTK_SIGNAL_FUNC (ets_proxy_pre_change), ets); + ets->priv->tree_model_pre_change_id = gtk_signal_connect (GTK_OBJECT (source), "pre_change", + GTK_SIGNAL_FUNC (ets_proxy_pre_change), ets); + ets->priv->tree_model_no_change_id = gtk_signal_connect (GTK_OBJECT (source), "no_change", + GTK_SIGNAL_FUNC (ets_proxy_no_change), ets); ets->priv->tree_model_node_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_changed", GTK_SIGNAL_FUNC (ets_proxy_node_changed), ets); ets->priv->tree_model_node_data_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_data_changed", diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c index 862c540b6c..634240d8f7 100644 --- a/widgets/table/e-tree-table-adapter.c +++ b/widgets/table/e-tree-table-adapter.c @@ -52,6 +52,7 @@ struct ETreeTableAdapterPriv { int last_access; int tree_model_pre_change_id; + int tree_model_no_change_id; int tree_model_node_changed_id; int tree_model_node_data_changed_id; int tree_model_node_col_changed_id; @@ -392,6 +393,8 @@ etta_destroy (GtkObject *object) gtk_signal_disconnect (GTK_OBJECT (etta->priv->source), etta->priv->tree_model_pre_change_id); gtk_signal_disconnect (GTK_OBJECT (etta->priv->source), + etta->priv->tree_model_no_change_id); + gtk_signal_disconnect (GTK_OBJECT (etta->priv->source), etta->priv->tree_model_node_changed_id); gtk_signal_disconnect (GTK_OBJECT (etta->priv->source), etta->priv->tree_model_node_data_changed_id); @@ -406,6 +409,7 @@ etta_destroy (GtkObject *object) etta->priv->source = NULL; etta->priv->tree_model_pre_change_id = 0; + etta->priv->tree_model_no_change_id = 0; etta->priv->tree_model_node_changed_id = 0; etta->priv->tree_model_node_data_changed_id = 0; etta->priv->tree_model_node_col_changed_id = 0; @@ -618,6 +622,7 @@ etta_init (ETreeTableAdapter *etta) etta->priv->last_access = 0; etta->priv->tree_model_pre_change_id = 0; + etta->priv->tree_model_no_change_id = 0; etta->priv->tree_model_node_changed_id = 0; etta->priv->tree_model_node_data_changed_id = 0; etta->priv->tree_model_node_col_changed_id = 0; @@ -634,6 +639,12 @@ etta_proxy_pre_change (ETreeModel *etm, ETreeTableAdapter *etta) } static void +etta_proxy_no_change (ETreeModel *etm, ETreeTableAdapter *etta) +{ + e_table_model_no_change(E_TABLE_MODEL(etta)); +} + +static void etta_proxy_node_changed (ETreeModel *etm, ETreePath path, ETreeTableAdapter *etta) { if (e_tree_model_node_is_root(etm, path)) { @@ -681,7 +692,10 @@ etta_proxy_node_data_changed (ETreeModel *etm, ETreePath path, ETreeTableAdapter e_table_model_row_changed(E_TABLE_MODEL(etta), row); else if (row != 0) e_table_model_row_changed(E_TABLE_MODEL(etta), row - 1); - } + else + e_table_model_no_change(E_TABLE_MODEL(etta)); + } else + e_table_model_no_change(E_TABLE_MODEL(etta)); } static void @@ -693,7 +707,10 @@ etta_proxy_node_col_changed (ETreeModel *etm, ETreePath path, int col, ETreeTabl e_table_model_cell_changed(E_TABLE_MODEL(etta), col, row); else if (row != 0) e_table_model_cell_changed(E_TABLE_MODEL(etta), col, row - 1); - } + else + e_table_model_no_change(E_TABLE_MODEL(etta)); + } else + e_table_model_no_change(E_TABLE_MODEL(etta)); } static void @@ -709,19 +726,26 @@ etta_proxy_node_inserted (ETreeModel *etm, ETreePath parent, ETreePath child, ET ETreeTableAdapterNode *parent_node; parent_row = find_row_num(etta, parent); - if (parent_row == -1) + if (parent_row == -1) { + e_table_model_no_change(E_TABLE_MODEL(etta)); return; + } parent_node = find_or_create_node(etta, parent); if (parent_node->expandable != e_tree_model_node_is_expandable(etta->priv->source, parent)) { + e_table_model_pre_change(E_TABLE_MODEL(etta)); parent_node->expandable = e_tree_model_node_is_expandable(etta->priv->source, parent); if (etta->priv->root_visible) e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row); else if (parent_row != 0) e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row - 1); + else + e_table_model_no_change(E_TABLE_MODEL(etta)); } - if (!parent_node->expanded) + if (!parent_node->expanded) { + e_table_model_no_change(E_TABLE_MODEL(etta)); return; + } row = find_first_child_node(etta, parent_row); children = e_tree_model_node_get_first_child(etta->priv->source, parent); @@ -755,7 +779,8 @@ etta_proxy_node_inserted (ETreeModel *etm, ETreePath parent, ETreePath child, ET e_table_model_rows_inserted(E_TABLE_MODEL(etta), row - 1, size); else e_table_model_rows_inserted(E_TABLE_MODEL(etta), 0, size - 1); - } + } else + e_table_model_no_change(E_TABLE_MODEL(etta)); } static void @@ -766,13 +791,17 @@ etta_proxy_node_removed (ETableModel *etm, ETreePath parent, ETreePath child, in ETreeTableAdapterNode *parent_node = find_node(etta, parent); if (parent_row != -1 && parent_node) { if (parent_node->expandable != e_tree_model_node_is_expandable(etta->priv->source, parent)) { + e_table_model_pre_change(E_TABLE_MODEL(etta)); parent_node->expandable = e_tree_model_node_is_expandable(etta->priv->source, parent); if (etta->priv->root_visible) e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row); else if (parent_row != 0) e_table_model_row_changed(E_TABLE_MODEL(etta), parent_row - 1); + else + e_table_model_no_change(E_TABLE_MODEL(etta)); } } + if (row != -1) { ETreeTableAdapterNode *node = find_node(etta, child); int to_remove = (node ? node->num_visible_children : 0) + 1; @@ -792,7 +821,8 @@ etta_proxy_node_removed (ETableModel *etm, ETreePath parent, ETreePath child, in e_table_model_rows_deleted(E_TABLE_MODEL(etta), row - 1, to_remove); else e_table_model_rows_deleted(E_TABLE_MODEL(etta), 0, to_remove - 1); - } + } else + e_table_model_no_change(E_TABLE_MODEL(etta)); } ETableModel * @@ -819,6 +849,8 @@ e_tree_table_adapter_construct (ETreeTableAdapter *etta, ETreeModel *source) etta->priv->tree_model_pre_change_id = gtk_signal_connect (GTK_OBJECT (source), "pre_change", GTK_SIGNAL_FUNC (etta_proxy_pre_change), etta); + etta->priv->tree_model_no_change_id = gtk_signal_connect (GTK_OBJECT (source), "no_change", + GTK_SIGNAL_FUNC (etta_proxy_no_change), etta); etta->priv->tree_model_node_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_changed", GTK_SIGNAL_FUNC (etta_proxy_node_changed), etta); etta->priv->tree_model_node_data_changed_id = gtk_signal_connect (GTK_OBJECT (source), "node_data_changed", @@ -973,18 +1005,20 @@ void e_tree_table_adapter_node_set_expanded (ETreeTableAdapter *etta, ET node = find_or_create_node(etta, path); if (expanded != node->expanded) { - e_table_model_pre_change (E_TABLE_MODEL(etta)); - node->expanded = expanded; row = find_row_num(etta, path); if (row != -1) { - if (etta->priv->root_visible) + e_table_model_pre_change (E_TABLE_MODEL(etta)); + + if (etta->priv->root_visible) { + e_table_model_pre_change (E_TABLE_MODEL(etta)); e_table_model_row_changed(E_TABLE_MODEL(etta), row); - else if (row != 0) + } else if (row != 0) { + e_table_model_pre_change (E_TABLE_MODEL(etta)); e_table_model_row_changed(E_TABLE_MODEL(etta), row - 1); + } - e_table_model_pre_change (E_TABLE_MODEL(etta)); if (expanded) { int num_children = array_size_from_path(etta, path) - 1; etta_expand_to(etta, etta->priv->n_map + num_children); @@ -998,7 +1032,8 @@ void e_tree_table_adapter_node_set_expanded (ETreeTableAdapter *etta, ET e_table_model_rows_inserted(E_TABLE_MODEL(etta), row + 1, num_children); else e_table_model_rows_inserted(E_TABLE_MODEL(etta), row, num_children); - } + } else + e_table_model_no_change(E_TABLE_MODEL(etta)); } else { int num_children = node->num_visible_children; g_assert (etta->priv->n_map >= row + 1 + num_children); @@ -1012,7 +1047,8 @@ void e_tree_table_adapter_node_set_expanded (ETreeTableAdapter *etta, ET e_table_model_rows_deleted(E_TABLE_MODEL(etta), row + 1, num_children); else e_table_model_rows_deleted(E_TABLE_MODEL(etta), row, num_children); - } + } else + e_table_model_no_change(E_TABLE_MODEL(etta)); } } } |