From f8cbf86bbc84292974146504dfa287b119c0ba8e Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Sun, 15 Jun 2003 13:21:21 +0000 Subject: *** empty log message *** --- lib/egg/eggtreemodelfilter.c | 349 +++++++++++++++++-------------------------- 1 file changed, 136 insertions(+), 213 deletions(-) (limited to 'lib') diff --git a/lib/egg/eggtreemodelfilter.c b/lib/egg/eggtreemodelfilter.c index 0465e2d6d..89debc559 100644 --- a/lib/egg/eggtreemodelfilter.c +++ b/lib/egg/eggtreemodelfilter.c @@ -182,19 +182,15 @@ static GtkTreePath *egg_real_tree_model_filter_convert_child_path_to_path (EggTr gboolean build_levels, gboolean fetch_childs); -static FilterElt *egg_tree_model_filter_fetch_child (EggTreeModelFilter *filter, +static gboolean egg_tree_model_filter_fetch_child (EggTreeModelFilter *filter, FilterLevel *level, - gint offset, - gint *index); + gint offset); static void egg_tree_model_filter_remove_node (EggTreeModelFilter *filter, GtkTreeIter *iter, gboolean emit_signal); static void egg_tree_model_filter_update_childs (EggTreeModelFilter *filter, FilterLevel *level, FilterElt *elt); -static FilterElt *bsearch_elt_with_offset (GArray *array, - gint offset, - gint *index); static GObjectClass *parent_class = NULL; @@ -663,14 +659,12 @@ egg_tree_model_filter_clear_cache_helper (EggTreeModelFilter *filter, } } -static FilterElt * +static gboolean egg_tree_model_filter_fetch_child (EggTreeModelFilter *filter, FilterLevel *level, - gint offset, - gint *index) + gint offset) { gint i = 0; - gint start, middle, end; gint len; GtkTreePath *c_path = NULL; GtkTreeIter c_iter; @@ -686,7 +680,7 @@ egg_tree_model_filter_fetch_child (EggTreeModelFilter *filter, level->parent_elt, filter->virtual_root); if (!c_parent_path) - return NULL; + return FALSE; } else { @@ -718,7 +712,7 @@ egg_tree_model_filter_fetch_child (EggTreeModelFilter *filter, gtk_tree_path_free (c_path); if (offset >= len || !egg_tree_model_filter_visible (filter, &c_iter)) - return NULL; + return FALSE; /* add child */ elt.offset = offset; @@ -731,41 +725,21 @@ egg_tree_model_filter_fetch_child (EggTreeModelFilter *filter, if (EGG_TREE_MODEL_FILTER_CACHE_CHILD_ITERS (filter)) elt.iter = c_iter; - /* find index (binary search on offset) */ - start = 0; - end = level->array->len; - - if (start != end) - { - while (start != end) - { - middle = (start + end) / 2; - - if (g_array_index (level->array, FilterElt, middle).offset <= offset) - start = middle + 1; - else - end = middle; - } - - if (g_array_index (level->array, FilterElt, middle).offset <= offset) - i = middle + 1; - else - i = middle; - } - else - i = 0; + /* find index */ + for (i = 0; i < level->array->len; i++) + if (g_array_index (level->array, FilterElt, i).offset > offset) + break; g_array_insert_val (level->array, i, elt); - *index = i; - for (--i; i < level->array->len; i++) + for (i = 0; i < level->array->len; i++) { FilterElt *e = &(g_array_index (level->array, FilterElt, i)); if (e->children) e->children->parent_elt = e; } - return &g_array_index (level->array, FilterElt, *index); + return TRUE; } static void @@ -825,24 +799,21 @@ egg_tree_model_filter_remove_node (EggTreeModelFilter *filter, } else { - FilterElt *tmp; - /* remove the node */ - tmp = bsearch_elt_with_offset (level->array, elt->offset, &i); + for (i = 0; i < level->array->len; i++) + if (elt->offset == g_array_index (level->array, FilterElt, i).offset) + break; - if (tmp) - { - g_array_remove_index (level->array, i); + g_array_remove_index (level->array, i); - for (--i; i < level->array->len; i++) - { - /* NOTE: here we do *not* decrease offsets, because the node was - * not removed from the child model - */ - elt = &g_array_index (level->array, FilterElt, i); - if (elt->children) - elt->children->parent_elt = elt; - } + for (i = 0; i < level->array->len; i++) + { + /* NOTE: here we do *not* decrease offsets, because the node was + * not removed from the child model + */ + elt = &g_array_index (level->array, FilterElt, i); + if (elt->children) + elt->children->parent_elt = elt; } } @@ -899,56 +870,6 @@ egg_tree_model_filter_update_childs (EggTreeModelFilter *filter, } } -static FilterElt * -bsearch_elt_with_offset (GArray *array, - gint offset, - gint *index) -{ - gint start, middle, end; - FilterElt *elt; - - start = 0; - end = array->len; - - if (array->len < 1) - return NULL; - - if (start == end) - { - elt = &g_array_index (array, FilterElt, 0); - - if (elt->offset == offset) - { - *index = 0; - return elt; - } - else - return NULL; - } - - while (start != end) - { - middle = (start + end) / 2; - - elt = &g_array_index (array, FilterElt, middle); - - if (elt->offset < offset) - start = middle + 1; - else if (elt->offset > offset) - end = middle; - else - break; - } - - if (elt->offset == offset) - { - *index = middle; - return elt; - } - - return NULL; -} - /* TreeModel signals */ static void egg_tree_model_filter_row_changed (GtkTreeModel *c_model, @@ -958,15 +879,14 @@ egg_tree_model_filter_row_changed (GtkTreeModel *c_model, { EggTreeModelFilter *filter = EGG_TREE_MODEL_FILTER (data); GtkTreeIter iter; - GtkTreeIter childs; GtkTreeIter real_c_iter; - GtkTreePath *path = NULL; + GtkTreePath *path; FilterElt *elt; FilterLevel *level; + gint offset; - gboolean requested_state; - gboolean current_state; + gboolean new; gboolean free_c_path = FALSE; g_return_if_fail (c_path != NULL || c_iter != NULL); @@ -982,72 +902,21 @@ egg_tree_model_filter_row_changed (GtkTreeModel *c_model, else gtk_tree_model_get_iter (c_model, &real_c_iter, c_path); - /* what's the requested state? */ - requested_state = egg_tree_model_filter_visible (filter, &real_c_iter); - - /* now, let's see whether the item is there */ - path = egg_real_tree_model_filter_convert_child_path_to_path (filter, - c_path, - FALSE, - FALSE); - - if (path) - { - gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path); - current_state = FILTER_ELT (iter.user_data2)->visible; - } - else - current_state = FALSE; - - if (current_state == FALSE && requested_state == FALSE) - /* no changes required */ - goto done; - - if (current_state == TRUE && requested_state == FALSE) - { - /* get rid of this node */ - gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path); - egg_tree_model_filter_remove_node (filter, &iter, TRUE); - - level = FILTER_LEVEL (iter.user_data); - - if (!level->parent_level) - filter->root_level_visible--; - - goto done; - } - - if (current_state == TRUE && requested_state == TRUE) - { - /* progate the signal */ - gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path); - gtk_tree_model_row_changed (GTK_TREE_MODEL (filter), path, &iter); - - level = FILTER_LEVEL (iter.user_data); - elt = FILTER_ELT (iter.user_data2); - - /* and update the childs */ - if (gtk_tree_model_iter_children (c_model, &childs, &real_c_iter)) - egg_tree_model_filter_update_childs (filter, level, elt); - - goto done; - } - - /* only current == FALSE and requested == TRUE is left, - * pull in the child - */ - g_return_if_fail (current_state == FALSE && requested_state == TRUE); - - /* make sure the new item has been pulled in */ if (!filter->root) { gint i; FilterLevel *root; + /* build root level */ egg_tree_model_filter_build_level (filter, NULL, NULL); root = FILTER_LEVEL (filter->root); + /* FIXME: + * we set the visibilities to FALSE here, so we ever emit + * a row_inserted. maybe it's even better to emit row_inserted + * here, not sure. + */ if (root) { for (i = 0; i < root->array->len; i++) @@ -1056,35 +925,63 @@ egg_tree_model_filter_row_changed (GtkTreeModel *c_model, } } + path = egg_real_tree_model_filter_convert_child_path_to_path (filter, + c_path, + FALSE, + TRUE); if (!path) - path = egg_real_tree_model_filter_convert_child_path_to_path (filter, - c_path, - FALSE, - TRUE); - - g_return_if_fail (path != NULL); + goto done; - egg_tree_model_filter_increment_stamp (filter); gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path); level = FILTER_LEVEL (iter.user_data); elt = FILTER_ELT (iter.user_data2); + offset = elt->offset; + new = egg_tree_model_filter_visible (filter, c_iter); - elt->visible = TRUE; + if (elt->visible == TRUE && new == FALSE) + { + egg_tree_model_filter_remove_node (filter, &iter, TRUE); - if (!level->parent_level) - filter->root_level_visible++; + if (!level->parent_level) + filter->root_level_visible--; + } + else if (elt->visible == FALSE && new == TRUE) + { + GtkTreeIter childs; - /* update stamp */ - gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter); + elt->visible = TRUE; - if (gtk_tree_model_iter_children (c_model, &childs, c_iter)) - egg_tree_model_filter_update_childs (filter, level, elt); + egg_tree_model_filter_increment_stamp (filter); -done: - if (path) - gtk_tree_path_free (path); + if (!level->parent_level) + filter->root_level_visible++; + /* update stamp */ + gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), &iter, path); + gtk_tree_model_row_inserted (GTK_TREE_MODEL (filter), path, &iter); + + if (gtk_tree_model_iter_children (c_model, &childs, c_iter)) + egg_tree_model_filter_update_childs (filter, level, elt); + } + else if (elt->visible == FALSE && new == FALSE) + { + egg_tree_model_filter_remove_node (filter, &iter, FALSE); + } + else + { + GtkTreeIter childs; + + gtk_tree_model_row_changed (GTK_TREE_MODEL (filter), path, &iter); + + if (gtk_tree_model_iter_children (c_model, &childs, c_iter) && + elt->visible) + egg_tree_model_filter_update_childs (filter, level, elt); + } + + gtk_tree_path_free (path); + +done: if (free_c_path) gtk_tree_path_free (c_path); } @@ -1176,9 +1073,14 @@ egg_tree_model_filter_row_inserted (GtkTreeModel *c_model, /* we don't cover this signal */ goto done; - elt = bsearch_elt_with_offset (level->array, - gtk_tree_path_get_indices (real_path)[i], - &j); + elt = NULL; + for (j = 0; j < level->array->len; j++) + if (g_array_index (level->array, FilterElt, j).offset == + gtk_tree_path_get_indices (real_path)[i]) + { + elt = &g_array_index (level->array, FilterElt, j); + break; + } if (!elt) /* parent is probably being filtered out */ @@ -1430,10 +1332,14 @@ egg_tree_model_filter_row_deleted (GtkTreeModel *c_model, return; } - elt = bsearch_elt_with_offset (level->array, - gtk_tree_path_get_indices (real_path)[i], - &j); - + elt = NULL; + for (j = 0; j < level->array->len; j++) + if (g_array_index (level->array, FilterElt, j).offset == + gtk_tree_path_get_indices (real_path)[i]) + { + elt = &g_array_index (level->array, FilterElt, j); + break; + } if (!elt || !elt->children) { @@ -1508,15 +1414,15 @@ egg_tree_model_filter_row_deleted (GtkTreeModel *c_model, } else { - FilterElt *tmp; - /* remove the row */ - tmp = bsearch_elt_with_offset (level->array, elt->offset, &i); + for (i = 0; i < level->array->len; i++) + if (elt->offset == g_array_index (level->array, FilterElt, i).offset) + break; - offset = tmp->offset; + offset = g_array_index (level->array, FilterElt, i).offset; g_array_remove_index (level->array, i); - for (--i; i < level->array->len; i++) + for (i = 0; i < level->array->len; i++) { elt = &g_array_index (level->array, FilterElt, i); if (elt->offset > offset) @@ -2485,7 +2391,6 @@ egg_real_tree_model_filter_convert_child_path_to_path (EggTreeModelFilter *filte GtkTreePath *retval; GtkTreePath *real_path; FilterLevel *level; - FilterElt *tmp; gint i; g_return_val_if_fail (EGG_IS_TREE_MODEL_FILTER (filter), NULL); @@ -2520,24 +2425,25 @@ egg_real_tree_model_filter_convert_child_path_to_path (EggTreeModelFilter *filte return NULL; } - tmp = bsearch_elt_with_offset (level->array, child_indices[i], &j); - if (tmp) + for (j = 0; j < level->array->len; j++) { - gtk_tree_path_append_index (retval, j); - if (!tmp->children && build_levels) - egg_tree_model_filter_build_level (filter, level, tmp); - level = tmp->children; - found_child = TRUE; + if ((g_array_index (level->array, FilterElt, j)).offset == child_indices[i]) + { + gtk_tree_path_append_index (retval, j); + if (g_array_index (level->array, FilterElt, j).children == NULL && build_levels) + egg_tree_model_filter_build_level (filter, + level, + &g_array_index (level->array, FilterElt, j)); + level = g_array_index (level->array, FilterElt, j).children; + found_child = TRUE; + break; + } } if (!found_child && fetch_childs) { - tmp = egg_tree_model_filter_fetch_child (filter, level, - child_indices[i], - &j); - /* didn't find the child, let's try to bring it back */ - if (!tmp || tmp->offset != child_indices[i]) + if (!egg_tree_model_filter_fetch_child (filter, level, child_indices[i])) { /* not there */ gtk_tree_path_free (real_path); @@ -2545,11 +2451,29 @@ egg_real_tree_model_filter_convert_child_path_to_path (EggTreeModelFilter *filte return NULL; } - gtk_tree_path_append_index (retval, j); - if (!tmp->children && build_levels) - egg_tree_model_filter_build_level (filter, level, tmp); - level = tmp->children; - found_child = TRUE; + /* yay, let's search for the child again */ + for (j = 0; j < level->array->len; j++) + { + if ((g_array_index (level->array, FilterElt, j)).offset == child_indices[i]) + { + gtk_tree_path_append_index (retval, j); + if (g_array_index (level->array, FilterElt, j).children == NULL && build_levels) + egg_tree_model_filter_build_level (filter, + level, + &g_array_index (level->array, FilterElt, j)); + level = g_array_index (level->array, FilterElt, j).children; + found_child = TRUE; + break; + } + } + + if (!found_child) + { + /* our happy fun fetch attempt failed ?!?!?! no child! */ + gtk_tree_path_free (real_path); + gtk_tree_path_free (retval); + return NULL; + } } else if (!found_child && !fetch_childs) { @@ -2664,8 +2588,7 @@ egg_tree_model_filter_refilter_helper (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { - /* evil, don't try this at home, but certainly speeds things up */ - egg_tree_model_filter_row_changed (model, path, iter, data); + gtk_tree_model_row_changed (model, path, iter); return FALSE; } -- cgit v1.2.3