diff options
Diffstat (limited to 'widgets')
-rw-r--r-- | widgets/table/e-tree-selection-model.c | 68 | ||||
-rw-r--r-- | widgets/table/e-tree-selection-model.h | 12 | ||||
-rw-r--r-- | widgets/table/e-tree-sorted.c | 91 | ||||
-rw-r--r-- | widgets/table/e-tree-table-adapter.c | 20 | ||||
-rw-r--r-- | widgets/table/e-tree.c | 6 |
5 files changed, 150 insertions, 47 deletions
diff --git a/widgets/table/e-tree-selection-model.c b/widgets/table/e-tree-selection-model.c index bfca69472a..b57efb5e11 100644 --- a/widgets/table/e-tree-selection-model.c +++ b/widgets/table/e-tree-selection-model.c @@ -52,7 +52,7 @@ struct ETreeSelectionModelPriv { ETreePath cursor_path; gint cursor_col; - gint selection_start_row; + ETreePath selection_start_path; int tree_model_pre_change_id; int tree_model_node_changed_id; @@ -789,7 +789,7 @@ etsm_select_all (ESelectionModel *selection) etsm->priv->cursor_col = 0; if (etsm->priv->cursor_path == NULL) etsm->priv->cursor_path = etsm_node_at_row(etsm, 0); - etsm->priv->selection_start_row = 0; + etsm->priv->selection_start_path = etsm_node_at_row(etsm, 0); 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); } @@ -839,7 +839,7 @@ etsm_invert_selection (ESelectionModel *selection) etsm->priv->cursor_col = -1; etsm->priv->cursor_path = NULL; - etsm->priv->selection_start_row = 0; + etsm->priv->selection_start_path = etsm_node_at_row(etsm, 0); e_selection_model_selection_changed(E_SELECTION_MODEL(etsm)); e_selection_model_cursor_changed(E_SELECTION_MODEL(etsm), -1, -1); } @@ -870,6 +870,27 @@ 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; @@ -924,7 +945,7 @@ etsm_select_single_row (ESelectionModel *selection, int row) etsm_real_clear (etsm); etsm_change_one_row(selection, row, TRUE); - etsm->priv->selection_start_row = row; + etsm->priv->selection_start_path = etsm_node_at_row(etsm, row); e_selection_model_selection_changed(E_SELECTION_MODEL(etsm)); } @@ -934,7 +955,7 @@ etsm_toggle_single_row (ESelectionModel *selection, int row) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - etsm->priv->selection_start_row = row; + etsm->priv->selection_start_path = etsm_node_at_row(etsm, row); etsm_change_one_row(selection, row, !etsm_is_row_selected(selection, row)); @@ -949,20 +970,21 @@ etsm_move_selection_end (ESelectionModel *selection, int row) int old_end; int new_start; int new_end; + int start_row = etsm_row_of_node(etsm, etsm->priv->selection_start_path); if (selection->sorter && e_sorter_needs_sorting(selection->sorter)) { - old_start = MIN (e_sorter_model_to_sorted(selection->sorter, etsm->priv->selection_start_row), + old_start = MIN (e_sorter_model_to_sorted(selection->sorter, start_row), e_sorter_model_to_sorted(selection->sorter, etsm_cursor_row_real(etsm))); - old_end = MAX (e_sorter_model_to_sorted(selection->sorter, etsm->priv->selection_start_row), + old_end = MAX (e_sorter_model_to_sorted(selection->sorter, start_row), e_sorter_model_to_sorted(selection->sorter, etsm_cursor_row_real(etsm))) + 1; - new_start = MIN (e_sorter_model_to_sorted(selection->sorter, etsm->priv->selection_start_row), + new_start = MIN (e_sorter_model_to_sorted(selection->sorter, start_row), e_sorter_model_to_sorted(selection->sorter, row)); - new_end = MAX (e_sorter_model_to_sorted(selection->sorter, etsm->priv->selection_start_row), + new_end = MAX (e_sorter_model_to_sorted(selection->sorter, start_row), e_sorter_model_to_sorted(selection->sorter, row)) + 1; } else { - old_start = MIN (etsm->priv->selection_start_row, etsm_cursor_row_real(etsm)); - old_end = MAX (etsm->priv->selection_start_row, etsm_cursor_row_real(etsm)) + 1; - new_start = MIN (etsm->priv->selection_start_row, row); - new_end = MAX (etsm->priv->selection_start_row, row) + 1; + old_start = MIN (start_row, etsm_cursor_row_real(etsm)); + old_end = MAX (start_row, etsm_cursor_row_real(etsm)) + 1; + new_start = MIN (start_row, row); + new_end = MAX (start_row, row) + 1; } /* This wouldn't work nearly so smoothly if one end of the selection weren't held in place. */ if (old_start < new_start) @@ -980,11 +1002,8 @@ static void etsm_set_selection_end (ESelectionModel *selection, int row) { ETreeSelectionModel *etsm = E_TREE_SELECTION_MODEL(selection); - etsm_select_single_row(selection, etsm->priv->selection_start_row); - if (etsm->priv->selection_start_row != -1) - etsm->priv->cursor_path = etsm_node_at_row(etsm, etsm->priv->selection_start_row); - else - etsm->priv->cursor_path = NULL; + e_tree_selection_model_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); } @@ -1046,6 +1065,16 @@ 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; + + e_selection_model_selection_changed(E_SELECTION_MODEL(etsm)); +} + static void e_tree_selection_model_init (ETreeSelectionModel *etsm) @@ -1062,7 +1091,7 @@ e_tree_selection_model_init (ETreeSelectionModel *etsm) priv->cursor_path = NULL; priv->cursor_col = -1; - priv->selection_start_row = 0; + priv->selection_start_path = NULL; priv->tree_model_pre_change_id = 0; priv->tree_model_node_changed_id = 0; @@ -1134,4 +1163,3 @@ e_tree_selection_model_new (void) E_MAKE_TYPE(e_tree_selection_model, "ETreeSelectionModel", ETreeSelectionModel, e_tree_selection_model_class_init, e_tree_selection_model_init, PARENT_TYPE); - diff --git a/widgets/table/e-tree-selection-model.h b/widgets/table/e-tree-selection-model.h index e95ce97e68..624d527b07 100644 --- a/widgets/table/e-tree-selection-model.h +++ b/widgets/table/e-tree-selection-model.h @@ -34,11 +34,13 @@ typedef struct { } ETreeSelectionModelClass; -GtkType e_tree_selection_model_get_type (void); -ESelectionModel *e_tree_selection_model_new (void); -void e_tree_selection_model_foreach (ETreeSelectionModel *etsm, - ETreeForeachFunc callback, - gpointer closure); +GtkType e_tree_selection_model_get_type (void); +ESelectionModel *e_tree_selection_model_new (void); +void e_tree_selection_model_foreach (ETreeSelectionModel *etsm, + ETreeForeachFunc callback, + gpointer closure); +void e_tree_selection_model_select_single_path (ETreeSelectionModel *etsm, + ETreePath path); #ifdef __cplusplus } diff --git a/widgets/table/e-tree-sorted.c b/widgets/table/e-tree-sorted.c index 7c3ca95287..3d70e019e4 100644 --- a/widgets/table/e-tree-sorted.c +++ b/widgets/table/e-tree-sorted.c @@ -68,6 +68,8 @@ struct ETreeSortedPriv { ETableSortInfo *sort_info; ETableHeader *full_header; + ETreeSortedPath *last_access; + int tree_model_pre_change_id; int tree_model_node_changed_id; int tree_model_node_data_changed_id; @@ -122,6 +124,45 @@ ets_insert_idle(ETreeSorted *ets) /* Helper functions */ +static inline ETreeSortedPath * +check_last_access (ETreeSorted *ets, ETreePath corresponding) +{ + ETreeSortedPath *parent; + int end; + int start; + int i; + + if (ets->priv->last_access == NULL) + return NULL; + + if (ets->priv->last_access == corresponding) { + d(g_print("Found last access %p at %p.", ets->priv->last_access, ets->priv->last_access)); + return ets->priv->last_access; + } + + parent = ets->priv->last_access->parent; + if (parent && parent->children) { + i = ets->priv->last_access->position; + end = MIN(parent->num_children, i + 10); + for (; i < end; i++) { + if (parent->children[i] && parent->children[i]->corresponding == corresponding) { + d(g_print("Found last access %p at %p.", ets->priv->last_access, parent->children[i])); + return parent->children[i]; + } + } + + i = ets->priv->last_access->position - 1; + start = MAX(0, i - 10); + for (; i >= start; i--) { + if (parent->children[i] && parent->children[i]->corresponding == corresponding) { + d(g_print("Found last access %p at %p.", ets->priv->last_access, parent->children[i])); + return parent->children[i]; + } + } + } + return NULL; +} + static ETreeSortedPath * find_path(ETreeSorted *ets, ETreePath corresponding) { @@ -129,14 +170,16 @@ find_path(ETreeSorted *ets, ETreePath corresponding) ETreePath *sequence; int i; ETreeSortedPath *path; + ETreeSortedPath *check_last; if (corresponding == NULL) return NULL; -#if 0 - if (etta->priv->last_access != -1 && etta->priv->map_table[etta->priv->last_access] == path) - return etta->priv->last_access; -#endif + check_last = check_last_access (ets, corresponding); + if (check_last) { + d(g_print(" (find_path)\n")); + return check_last; + } depth = e_tree_model_node_depth(ets->priv->source, corresponding); @@ -171,9 +214,8 @@ find_path(ETreeSorted *ets, ETreePath corresponding) } g_free (sequence); -#if 0 - ets->priv->last_access = row; -#endif + d(g_print("Didn't find last access %p. Setting to %p. (find_path)\n", ets->priv->last_access, path)); + ets->priv->last_access = path; return path; } @@ -204,14 +246,16 @@ find_or_create_path(ETreeSorted *ets, ETreePath corresponding) ETreePath *sequence; int i; ETreeSortedPath *path; + ETreeSortedPath *check_last; if (corresponding == NULL) return NULL; -#if 0 - if (etta->priv->last_access != -1 && etta->priv->map_table[etta->priv->last_access] == path) - return etta->priv->last_access; -#endif + check_last = check_last_access (ets, corresponding); + if (check_last) { + d(g_print(" (find_or_create_path)\n")); + return check_last; + } depth = e_tree_model_node_depth(ets->priv->source, corresponding); @@ -245,9 +289,8 @@ find_or_create_path(ETreeSorted *ets, ETreePath corresponding) } g_free (sequence); -#if 0 - ets->priv->last_access = row; -#endif + d(g_print("Didn't find last access %p. Setting to %p. (find_or_create_path)\n", ets->priv->last_access, path)); + ets->priv->last_access = path; return path; } @@ -864,6 +907,9 @@ ets_proxy_pre_change (ETreeModel *etm, ETreeSorted *ets) static void ets_proxy_node_changed (ETreeModel *etm, ETreePath node, ETreeSorted *ets) { + ets->priv->last_access = NULL; + d(g_print("Setting last access %p. (ets_proxy_node_changed)\n", ets->priv->last_access)); + if (e_tree_model_node_is_root(ets->priv->source, node)) { if (ets->priv->root) { free_path(ets->priv->root); @@ -979,6 +1025,9 @@ ets_proxy_node_removed (ETreeModel *etm, ETreePath parent, ETreePath child, int else path = find_path(ets, child); + d(g_print("Setting last access %p. (ets_proxy_node_removed)\n ", ets->priv->last_access)); + ets->priv->last_access = NULL; + if (path && parent_path && parent_path->num_children != -1) { int i; for (i = 0; i < parent_path->num_children; i++) { @@ -1078,7 +1127,9 @@ e_tree_sorted_init (GtkObject *object) priv->sort_info = NULL; priv->full_header = NULL; - priv->tree_model_pre_change_id = 0; + priv->last_access = NULL; + + priv->tree_model_pre_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; @@ -1152,9 +1203,11 @@ e_tree_sorted_view_to_model_path (ETreeSorted *ets, ETreePath view_path) { ETreeSortedPath *path = view_path; - if (path) + if (path) { + ets->priv->last_access = path; + d(g_print("Setting last access %p. (e_tree_sorted_view_to_model_path)\n", ets->priv->last_access)); return path->corresponding; - else + } else return NULL; } @@ -1162,9 +1215,7 @@ ETreePath e_tree_sorted_model_to_view_path (ETreeSorted *ets, ETreePath model_path) { - ETreeSortedPath *path = find_or_create_path(ets, model_path); - - return path; + return find_or_create_path(ets, model_path); } int diff --git a/widgets/table/e-tree-table-adapter.c b/widgets/table/e-tree-table-adapter.c index 5498d82358..71c73d7724 100644 --- a/widgets/table/e-tree-table-adapter.c +++ b/widgets/table/e-tree-table-adapter.c @@ -233,8 +233,23 @@ find_row_num(ETreeTableAdapter *etta, ETreePath path) if (path == NULL) return -1; - if (etta->priv->last_access != -1 && etta->priv->map_table[etta->priv->last_access] == path) - return etta->priv->last_access; + if (etta->priv->last_access != -1) { + int end = MIN(etta->priv->n_map, etta->priv->last_access + 10); + int start = MAX(0, etta->priv->last_access - 10); + for (i = etta->priv->last_access; i < end; i++) { + if(etta->priv->map_table[i] == path) { + d(g_print("Found last access %d at row %d. (find_row_num)\n", etta->priv->last_access, i)); + return i; + } + } + for (i = etta->priv->last_access - 1; i <= start; i++) { + if(etta->priv->map_table[i] == path) { + d(g_print("Found last access %d at row %d. (find_row_num)\n", etta->priv->last_access, i)); + return i; + } + } + } + depth = e_tree_model_node_depth(etta->priv->source, path); @@ -268,6 +283,7 @@ find_row_num(ETreeTableAdapter *etta, ETreePath path) } g_free (sequence); + d(g_print("Didn't find last access %d. Setting to %d. (find_row_num)\n", etta->priv->last_access, row)); etta->priv->last_access = row; return row; } diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c index 42b279bef3..0aa2668546 100644 --- a/widgets/table/e-tree.c +++ b/widgets/table/e-tree.c @@ -1033,11 +1033,16 @@ e_tree_new_from_spec_file (ETreeModel *etm, ETableExtras *ete, const char *spec_ void e_tree_set_cursor (ETree *e_tree, ETreePath path) { +#ifndef E_TREE_USE_TREE_SELECTION int row; +#endif g_return_if_fail(e_tree != NULL); g_return_if_fail(E_IS_TREE(e_tree)); g_return_if_fail(path != NULL); +#ifdef E_TREE_USE_TREE_SELECTION + e_tree_selection_model_select_single_path (E_TREE_SELECTION_MODEL(e_tree->priv->selection), path); +#else path = e_tree_sorted_model_to_view_path(e_tree->priv->sorted, path); row = e_tree_table_adapter_row_of_node(E_TREE_TABLE_ADAPTER(e_tree->priv->etta), path); @@ -1048,6 +1053,7 @@ e_tree_set_cursor (ETree *e_tree, ETreePath path) gtk_object_set(GTK_OBJECT(e_tree->priv->selection), "cursor_row", row, NULL); +#endif } ETreePath |