diff options
-rw-r--r-- | widgets/misc/e-reflow.c | 40 | ||||
-rw-r--r-- | widgets/misc/e-reflow.h | 1 | ||||
-rw-r--r-- | widgets/misc/e-selection-model-array.c | 71 | ||||
-rw-r--r-- | widgets/misc/e-selection-model-array.h | 9 | ||||
-rw-r--r-- | widgets/misc/e-selection-model.c | 65 | ||||
-rw-r--r-- | widgets/misc/e-selection-model.h | 147 | ||||
-rw-r--r-- | widgets/table/e-table-item.c | 52 | ||||
-rw-r--r-- | widgets/table/e-table-item.h | 4 | ||||
-rw-r--r-- | widgets/table/e-table.c | 13 | ||||
-rw-r--r-- | widgets/table/e-tree-selection-model.c | 168 | ||||
-rw-r--r-- | widgets/table/e-tree.c | 13 |
11 files changed, 411 insertions, 172 deletions
diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c index 6287ce45ad..ed83956232 100644 --- a/widgets/misc/e-reflow.c +++ b/widgets/misc/e-reflow.c @@ -117,6 +117,22 @@ e_reflow_resize_children (GnomeCanvasItem *item) } } +static inline void +e_reflow_update_selection_row (EReflow *reflow, int row) +{ + if (reflow->items[row]) { + gtk_object_set(GTK_OBJECT(reflow->items[row]), + "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), row), + NULL); + } else if (e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), row)) { + reflow->items[row] = e_reflow_model_incarnate (reflow->model, row, GNOME_CANVAS_GROUP (reflow)); + gtk_object_set (GTK_OBJECT (reflow->items[row]), + "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), row), + "width", (double) reflow->column_width, + NULL); + } +} + static void e_reflow_update_selection (EReflow *reflow) { @@ -125,17 +141,7 @@ e_reflow_update_selection (EReflow *reflow) count = reflow->count; for (i = 0; i < count; i++) { - if (reflow->items[i]) { - gtk_object_set(GTK_OBJECT(reflow->items[i]), - "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), i), - NULL); - } else if (e_selection_model_is_row_selected (E_SELECTION_MODEL (reflow->selection), i)) { - reflow->items[i] = e_reflow_model_incarnate (reflow->model, i, GNOME_CANVAS_GROUP (reflow)); - gtk_object_set (GTK_OBJECT (reflow->items[i]), - "selected", e_selection_model_is_row_selected(E_SELECTION_MODEL(reflow->selection), i), - "width", (double) reflow->column_width, - NULL); - } + e_reflow_update_selection_row (reflow, i); } } @@ -146,6 +152,12 @@ selection_changed (ESelectionModel *selection, EReflow *reflow) } static void +selection_row_changed (ESelectionModel *selection, int row, EReflow *reflow) +{ + e_reflow_update_selection_row (reflow, row); +} + +static void cursor_changed (ESelectionModel *selection, int row, int col, EReflow *reflow) { int count = reflow->count; @@ -453,10 +465,13 @@ disconnect_selection (EReflow *reflow) gtk_signal_disconnect (GTK_OBJECT (reflow->selection), reflow->selection_changed_id); gtk_signal_disconnect (GTK_OBJECT (reflow->selection), + reflow->selection_row_changed_id); + gtk_signal_disconnect (GTK_OBJECT (reflow->selection), reflow->cursor_changed_id); gtk_object_unref (GTK_OBJECT (reflow->selection)); reflow->selection_changed_id = 0; + reflow->selection_row_changed_id = 0; reflow->cursor_changed_id = 0; reflow->selection = NULL; } @@ -1308,6 +1323,9 @@ e_reflow_init (EReflow *reflow) reflow->selection_changed_id = gtk_signal_connect(GTK_OBJECT(reflow->selection), "selection_changed", GTK_SIGNAL_FUNC(selection_changed), reflow); + reflow->selection_row_changed_id = + gtk_signal_connect(GTK_OBJECT(reflow->selection), "selection_row_changed", + GTK_SIGNAL_FUNC(selection_row_changed), reflow); reflow->cursor_changed_id = gtk_signal_connect(GTK_OBJECT(reflow->selection), "cursor_changed", GTK_SIGNAL_FUNC(cursor_changed), reflow); diff --git a/widgets/misc/e-reflow.h b/widgets/misc/e-reflow.h index 0e0a7b273d..5b699431cc 100644 --- a/widgets/misc/e-reflow.h +++ b/widgets/misc/e-reflow.h @@ -69,6 +69,7 @@ struct _EReflow ESelectionModel *selection; guint selection_changed_id; + guint selection_row_changed_id; guint cursor_changed_id; ESorterArray *sorter; diff --git a/widgets/misc/e-selection-model-array.c b/widgets/misc/e-selection-model-array.c index 13c964bfba..dd81fb2554 100644 --- a/widgets/misc/e-selection-model-array.c +++ b/widgets/misc/e-selection-model-array.c @@ -70,6 +70,8 @@ e_selection_model_array_delete_rows(ESelectionModelArray *esma, int row, int cou if (esma->cursor_row >= 0) e_bit_array_change_one_row(esma->eba, esma->cursor_row, TRUE); + esma->selected_row = -1; + esma->selected_range_end = -1; e_selection_model_selection_changed(E_SELECTION_MODEL(esma)); e_selection_model_cursor_changed(E_SELECTION_MODEL(esma), esma->cursor_row, esma->cursor_col); } @@ -84,6 +86,8 @@ e_selection_model_array_insert_rows(ESelectionModelArray *esma, int row, int cou if (esma->cursor_row >= row) esma->cursor_row += count; + esma->selected_row = -1; + esma->selected_range_end = -1; e_selection_model_selection_changed(E_SELECTION_MODEL(esma)); e_selection_model_cursor_changed(E_SELECTION_MODEL(esma), esma->cursor_row, esma->cursor_col); } @@ -114,6 +118,8 @@ e_selection_model_array_move_row(ESelectionModelArray *esma, int old_row, int ne if (cursor) { esma->cursor_row = new_row; } + esma->selected_row = -1; + esma->selected_range_end = -1; e_selection_model_selection_changed(esm); e_selection_model_cursor_changed(esm, esma->cursor_row, esma->cursor_col); } @@ -223,6 +229,8 @@ esma_clear(ESelectionModel *selection) } esma->cursor_row = -1; esma->cursor_col = -1; + esma->selected_row = -1; + esma->selected_range_end = -1; e_selection_model_selection_changed(E_SELECTION_MODEL(esma)); e_selection_model_cursor_changed(E_SELECTION_MODEL(esma), -1, -1); } @@ -267,6 +275,8 @@ esma_select_all (ESelectionModel *selection) esma->cursor_col = 0; esma->cursor_row = 0; esma->selection_start_row = 0; + esma->selected_row = -1; + esma->selected_range_end = -1; e_selection_model_selection_changed(E_SELECTION_MODEL(esma)); e_selection_model_cursor_changed(E_SELECTION_MODEL(esma), 0, 0); } @@ -290,6 +300,8 @@ esma_invert_selection (ESelectionModel *selection) esma->cursor_col = -1; esma->cursor_row = -1; esma->selection_start_row = 0; + esma->selected_row = -1; + esma->selected_range_end = -1; e_selection_model_selection_changed(E_SELECTION_MODEL(esma)); e_selection_model_cursor_changed(E_SELECTION_MODEL(esma), -1, -1); } @@ -356,15 +368,33 @@ esma_cursor_col (ESelectionModel *selection) } static void -esma_select_single_row (ESelectionModel *selection, int row) +esma_real_select_single_row (ESelectionModel *selection, int row) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); e_selection_model_array_confirm_row_count(esma); + e_bit_array_select_single_row(esma->eba, row); - e_selection_model_selection_changed(E_SELECTION_MODEL(esma)); esma->selection_start_row = row; + esma->selected_row = row; + esma->selected_range_end = row; +} + +static void +esma_select_single_row (ESelectionModel *selection, int row) +{ + int selected_row = E_SELECTION_MODEL_ARRAY(selection)->selected_row; + esma_real_select_single_row (selection, row); + + if (selected_row != -1) { + if (selected_row != row) { + e_selection_model_selection_row_changed(selection, selected_row); + e_selection_model_selection_row_changed(selection, row); + } + } else { + e_selection_model_selection_changed(selection); + } } static void @@ -376,11 +406,13 @@ esma_toggle_single_row (ESelectionModel *selection, int row) e_bit_array_toggle_single_row(esma->eba, row); esma->selection_start_row = row; - e_selection_model_selection_changed(E_SELECTION_MODEL(esma)); + esma->selected_row = -1; + esma->selected_range_end = -1; + e_selection_model_selection_row_changed(E_SELECTION_MODEL(esma), row); } static void -esma_move_selection_end (ESelectionModel *selection, int row) +esma_real_move_selection_end (ESelectionModel *selection, int row) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); int old_start; @@ -411,16 +443,38 @@ esma_move_selection_end (ESelectionModel *selection, int row) esma_change_range(selection, old_end, new_end, TRUE); if (new_end < old_end) esma_change_range(selection, new_end, old_end, FALSE); - e_selection_model_selection_changed(E_SELECTION_MODEL(esma)); + esma->selected_row = -1; + esma->selected_range_end = -1; +} + +static void +esma_move_selection_end (ESelectionModel *selection, int row) +{ + esma_real_move_selection_end (selection, row); + e_selection_model_selection_changed(selection); } static void esma_set_selection_end (ESelectionModel *selection, int row) { ESelectionModelArray *esma = E_SELECTION_MODEL_ARRAY(selection); - esma_select_single_row(selection, esma->selection_start_row); + int selected_range_end = esma->selected_range_end; + int view_row = e_sorter_model_to_sorted(selection->sorter, row); + + esma_real_select_single_row(selection, esma->selection_start_row); esma->cursor_row = esma->selection_start_row; - esma_move_selection_end(selection, row); + esma_real_move_selection_end(selection, row); + + esma->selected_range_end = view_row; + if (selected_range_end != -1 && view_row != -1) { + if (selected_range_end == view_row - 1 || + selected_range_end == view_row + 1) { + e_selection_model_selection_row_changed(selection, selected_range_end); + e_selection_model_selection_row_changed(selection, view_row); + return; + } + } + e_selection_model_selection_changed(selection); } int @@ -443,6 +497,9 @@ e_selection_model_array_init (ESelectionModelArray *esma) esma->selection_start_row = 0; esma->cursor_row = -1; esma->cursor_col = -1; + + esma->selected_row = -1; + esma->selected_range_end = -1; } static void diff --git a/widgets/misc/e-selection-model-array.h b/widgets/misc/e-selection-model-array.h index cf336eebb7..805f331e88 100644 --- a/widgets/misc/e-selection-model-array.h +++ b/widgets/misc/e-selection-model-array.h @@ -50,6 +50,15 @@ typedef struct { guint model_changed_id; guint model_row_inserted_id, model_row_deleted_id; + /* Anything other than -1 means that the selection is a single + * row. This being -1 does not impart any information. */ + gint 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. */ + gint selected_range_end; + guint frozen : 1; guint selection_model_changed : 1; guint group_info_changed : 1; diff --git a/widgets/misc/e-selection-model.c b/widgets/misc/e-selection-model.c index 3aa78af31d..b7472e99f5 100644 --- a/widgets/misc/e-selection-model.c +++ b/widgets/misc/e-selection-model.c @@ -37,6 +37,7 @@ enum { CURSOR_CHANGED, CURSOR_ACTIVATED, SELECTION_CHANGED, + SELECTION_ROW_CHANGED, LAST_SIGNAL }; @@ -171,27 +172,36 @@ e_selection_model_class_init (ESelectionModelClass *klass) gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); - klass->cursor_changed = NULL; - klass->cursor_activated = NULL; - klass->selection_changed = NULL; - - klass->is_row_selected = NULL; - klass->foreach = NULL; - klass->clear = NULL; - klass->selected_count = NULL; - klass->select_all = NULL; - klass->invert_selection = NULL; - klass->row_count = NULL; - - klass->change_one_row = NULL; - klass->change_cursor = NULL; - klass->cursor_row = NULL; - klass->cursor_col = NULL; - - klass->select_single_row = NULL; - klass->toggle_single_row = NULL; - klass->move_selection_end = NULL; - klass->set_selection_end = NULL; + e_selection_model_signals [SELECTION_ROW_CHANGED] = + gtk_signal_new ("selection_row_changed", + GTK_RUN_LAST, + E_OBJECT_CLASS_TYPE (object_class), + GTK_SIGNAL_OFFSET (ESelectionModelClass, selection_row_changed), + gtk_marshal_NONE__INT, + GTK_TYPE_NONE, 1, GTK_TYPE_INT); + + klass->cursor_changed = NULL; + klass->cursor_activated = NULL; + klass->selection_changed = NULL; + klass->selection_row_changed = NULL; + + klass->is_row_selected = NULL; + klass->foreach = NULL; + klass->clear = NULL; + klass->selected_count = NULL; + klass->select_all = NULL; + klass->invert_selection = NULL; + klass->row_count = NULL; + + klass->change_one_row = NULL; + klass->change_cursor = NULL; + klass->cursor_row = NULL; + klass->cursor_col = NULL; + + klass->select_single_row = NULL; + klass->toggle_single_row = NULL; + klass->move_selection_end = NULL; + klass->set_selection_end = NULL; E_OBJECT_CLASS_ADD_SIGNALS (object_class, e_selection_model_signals, LAST_SIGNAL); @@ -495,6 +505,8 @@ e_selection_model_select_as_key_press (ESelectionModel *selection, switch (selection->mode) { case GTK_SELECTION_BROWSE: + case GTK_SELECTION_MULTIPLE: + case GTK_SELECTION_EXTENDED: if (shift_p) { e_selection_model_set_selection_end (selection, row); } else if (!ctrl_p) { @@ -503,8 +515,6 @@ e_selection_model_select_as_key_press (ESelectionModel *selection, cursor_activated = FALSE; break; case GTK_SELECTION_SINGLE: - case GTK_SELECTION_MULTIPLE: - case GTK_SELECTION_EXTENDED: e_selection_model_select_single_row (selection, row); break; } @@ -640,3 +650,12 @@ e_selection_model_selection_changed (ESelectionModel *selection) gtk_signal_emit(GTK_OBJECT(selection), e_selection_model_signals[SELECTION_CHANGED]); } + +void +e_selection_model_selection_row_changed (ESelectionModel *selection, + int row) +{ + gtk_signal_emit(GTK_OBJECT(selection), + e_selection_model_signals[SELECTION_ROW_CHANGED], + row); +} diff --git a/widgets/misc/e-selection-model.h b/widgets/misc/e-selection-model.h index 611add91c9..fde97a0035 100644 --- a/widgets/misc/e-selection-model.h +++ b/widgets/misc/e-selection-model.h @@ -66,94 +66,99 @@ typedef struct { GtkObjectClass parent_class; /* Virtual methods */ - gboolean (*is_row_selected) (ESelectionModel *esm, int row); - void (*foreach) (ESelectionModel *esm, EForeachFunc callback, gpointer closure); - void (*clear) (ESelectionModel *esm); - gint (*selected_count) (ESelectionModel *esm); - void (*select_all) (ESelectionModel *esm); - void (*invert_selection) (ESelectionModel *esm); - int (*row_count) (ESelectionModel *esm); + gboolean (*is_row_selected) (ESelectionModel *esm, int row); + void (*foreach) (ESelectionModel *esm, EForeachFunc callback, gpointer closure); + void (*clear) (ESelectionModel *esm); + gint (*selected_count) (ESelectionModel *esm); + void (*select_all) (ESelectionModel *esm); + void (*invert_selection) (ESelectionModel *esm); + int (*row_count) (ESelectionModel *esm); /* Protected virtual methods. */ - void (*change_one_row) (ESelectionModel *esm, int row, gboolean on); - void (*change_cursor) (ESelectionModel *esm, int row, int col); - int (*cursor_row) (ESelectionModel *esm); - int (*cursor_col) (ESelectionModel *esm); + void (*change_one_row) (ESelectionModel *esm, int row, gboolean on); + void (*change_cursor) (ESelectionModel *esm, int row, int col); + int (*cursor_row) (ESelectionModel *esm); + int (*cursor_col) (ESelectionModel *esm); - void (*select_single_row) (ESelectionModel *selection, int row); - void (*toggle_single_row) (ESelectionModel *selection, int row); - void (*move_selection_end) (ESelectionModel *selection, int row); - void (*set_selection_end) (ESelectionModel *selection, int row); + void (*select_single_row) (ESelectionModel *selection, int row); + void (*toggle_single_row) (ESelectionModel *selection, int row); + void (*move_selection_end) (ESelectionModel *selection, int row); + void (*set_selection_end) (ESelectionModel *selection, int row); /* * Signals */ - void (*cursor_changed) (ESelectionModel *esm, int row, int col); - void (*cursor_activated) (ESelectionModel *esm, int row, int col); - void (*selection_changed) (ESelectionModel *esm); + void (*cursor_changed) (ESelectionModel *esm, int row, int col); + void (*cursor_activated) (ESelectionModel *esm, int row, int col); + void (*selection_row_changed) (ESelectionModel *esm, int row); + void (*selection_changed) (ESelectionModel *esm); } ESelectionModelClass; -GtkType e_selection_model_get_type (void); -void e_selection_model_do_something (ESelectionModel *esm, - guint row, - guint col, - GdkModifierType state); -gboolean e_selection_model_maybe_do_something (ESelectionModel *esm, - guint row, - guint col, - GdkModifierType state); -void e_selection_model_right_click_down (ESelectionModel *selection, - guint row, - guint col, - GdkModifierType state); -void e_selection_model_right_click_up (ESelectionModel *selection); -gint e_selection_model_key_press (ESelectionModel *esm, - GdkEventKey *key); -void e_selection_model_select_as_key_press (ESelectionModel *esm, - guint row, - guint col, - GdkModifierType state); + + +GtkType e_selection_model_get_type (void); +void e_selection_model_do_something (ESelectionModel *esm, + guint row, + guint col, + GdkModifierType state); +gboolean e_selection_model_maybe_do_something (ESelectionModel *esm, + guint row, + guint col, + GdkModifierType state); +void e_selection_model_right_click_down (ESelectionModel *selection, + guint row, + guint col, + GdkModifierType state); +void e_selection_model_right_click_up (ESelectionModel *selection); +gint e_selection_model_key_press (ESelectionModel *esm, + GdkEventKey *key); +void e_selection_model_select_as_key_press (ESelectionModel *esm, + guint row, + guint col, + GdkModifierType state); /* Virtual functions */ -gboolean e_selection_model_is_row_selected (ESelectionModel *esm, - gint n); -void e_selection_model_foreach (ESelectionModel *esm, - EForeachFunc callback, - gpointer closure); -void e_selection_model_clear (ESelectionModel *esm); -gint e_selection_model_selected_count (ESelectionModel *esm); -void e_selection_model_select_all (ESelectionModel *esm); -void e_selection_model_invert_selection (ESelectionModel *esm); -int e_selection_model_row_count (ESelectionModel *esm); +gboolean e_selection_model_is_row_selected (ESelectionModel *esm, + gint n); +void e_selection_model_foreach (ESelectionModel *esm, + EForeachFunc callback, + gpointer closure); +void e_selection_model_clear (ESelectionModel *esm); +gint e_selection_model_selected_count (ESelectionModel *esm); +void e_selection_model_select_all (ESelectionModel *esm); +void e_selection_model_invert_selection (ESelectionModel *esm); +int e_selection_model_row_count (ESelectionModel *esm); /* Private virtual Functions */ -void e_selection_model_change_one_row (ESelectionModel *esm, - int row, - gboolean on); -void e_selection_model_change_cursor (ESelectionModel *esm, - int row, - int col); -int e_selection_model_cursor_row (ESelectionModel *esm); -int e_selection_model_cursor_col (ESelectionModel *esm); -void e_selection_model_select_single_row (ESelectionModel *selection, - int row); -void e_selection_model_toggle_single_row (ESelectionModel *selection, - int row); -void e_selection_model_move_selection_end (ESelectionModel *selection, - int row); -void e_selection_model_set_selection_end (ESelectionModel *selection, - int row); +void e_selection_model_change_one_row (ESelectionModel *esm, + int row, + gboolean on); +void e_selection_model_change_cursor (ESelectionModel *esm, + int row, + int col); +int e_selection_model_cursor_row (ESelectionModel *esm); +int e_selection_model_cursor_col (ESelectionModel *esm); +void e_selection_model_select_single_row (ESelectionModel *selection, + int row); +void e_selection_model_toggle_single_row (ESelectionModel *selection, + int row); +void e_selection_model_move_selection_end (ESelectionModel *selection, + int row); +void e_selection_model_set_selection_end (ESelectionModel *selection, + int row); /* Signals */ -void e_selection_model_cursor_changed (ESelectionModel *selection, - int row, - int col); -void e_selection_model_cursor_activated (ESelectionModel *selection, - int row, - int col); -void e_selection_model_selection_changed (ESelectionModel *selection); +void e_selection_model_cursor_changed (ESelectionModel *selection, + int row, + int col); +void e_selection_model_cursor_activated (ESelectionModel *selection, + int row, + int col); +void e_selection_model_selection_row_changed (ESelectionModel *selection, + int row); +void e_selection_model_selection_changed (ESelectionModel *selection); #ifdef __cplusplus } 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); |