aboutsummaryrefslogtreecommitdiffstats
path: root/lib/egg
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <mpeseng@src.gnome.org>2003-06-15 21:21:21 +0800
committerMarco Pesenti Gritti <mpeseng@src.gnome.org>2003-06-15 21:21:21 +0800
commitf8cbf86bbc84292974146504dfa287b119c0ba8e (patch)
treee2178038f1362863abf451ebcedd37589e1146c7 /lib/egg
parentedb7d2cc2c5c40ad9c8ecf167b760a7cf9ce4240 (diff)
downloadgsoc2013-epiphany-f8cbf86bbc84292974146504dfa287b119c0ba8e.tar
gsoc2013-epiphany-f8cbf86bbc84292974146504dfa287b119c0ba8e.tar.gz
gsoc2013-epiphany-f8cbf86bbc84292974146504dfa287b119c0ba8e.tar.bz2
gsoc2013-epiphany-f8cbf86bbc84292974146504dfa287b119c0ba8e.tar.lz
gsoc2013-epiphany-f8cbf86bbc84292974146504dfa287b119c0ba8e.tar.xz
gsoc2013-epiphany-f8cbf86bbc84292974146504dfa287b119c0ba8e.tar.zst
gsoc2013-epiphany-f8cbf86bbc84292974146504dfa287b119c0ba8e.zip
*** empty log message ***
Diffstat (limited to 'lib/egg')
-rw-r--r--lib/egg/eggtreemodelfilter.c349
1 files changed, 136 insertions, 213 deletions
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;
}