summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clutter/clutter-list-model.c100
-rw-r--r--clutter/clutter-model.c125
-rw-r--r--clutter/clutter-model.h2
3 files changed, 138 insertions, 89 deletions
diff --git a/clutter/clutter-list-model.c b/clutter/clutter-list-model.c
index 39d265193..8b560cee7 100644
--- a/clutter/clutter-list-model.c
+++ b/clutter/clutter-list-model.c
@@ -214,13 +214,11 @@ clutter_list_model_iter_is_first (ClutterModelIter *iter)
ClutterModelIter *temp_iter;
GSequence *sequence;
GSequenceIter *begin, *end;
- guint row;
iter_default = CLUTTER_LIST_MODEL_ITER (iter);
g_assert (iter_default->seq_iter != NULL);
model = clutter_model_iter_get_model (iter);
- row = clutter_model_iter_get_row (iter);
sequence = CLUTTER_LIST_MODEL (model)->priv->sequence;
@@ -234,7 +232,6 @@ clutter_list_model_iter_is_first (ClutterModelIter *iter)
while (!g_sequence_iter_is_begin (begin))
{
CLUTTER_LIST_MODEL_ITER (temp_iter)->seq_iter = begin;
- g_object_set (G_OBJECT (temp_iter), "row", row, NULL);
if (clutter_model_filter_iter (model, temp_iter))
{
@@ -243,7 +240,6 @@ clutter_list_model_iter_is_first (ClutterModelIter *iter)
}
begin = g_sequence_iter_next (begin);
- row += 1;
}
g_object_unref (temp_iter);
@@ -264,7 +260,6 @@ clutter_list_model_iter_is_last (ClutterModelIter *iter)
ClutterModel *model;
GSequence *sequence;
GSequenceIter *begin, *end;
- guint row;
iter_default = CLUTTER_LIST_MODEL_ITER (iter);
g_assert (iter_default->seq_iter != NULL);
@@ -273,7 +268,6 @@ clutter_list_model_iter_is_last (ClutterModelIter *iter)
return TRUE;
model = clutter_model_iter_get_model (iter);
- row = clutter_model_iter_get_row (iter);
sequence = CLUTTER_LIST_MODEL (model)->priv->sequence;
@@ -288,7 +282,6 @@ clutter_list_model_iter_is_last (ClutterModelIter *iter)
while (!g_sequence_iter_is_begin (begin))
{
CLUTTER_LIST_MODEL_ITER (temp_iter)->seq_iter = begin;
- g_object_set (G_OBJECT (temp_iter), "row", row, NULL);
if (clutter_model_filter_iter (model, temp_iter))
{
@@ -297,7 +290,6 @@ clutter_list_model_iter_is_last (ClutterModelIter *iter)
}
begin = g_sequence_iter_prev (begin);
- row += 1;
}
g_object_unref (temp_iter);
@@ -323,7 +315,7 @@ clutter_list_model_iter_next (ClutterModelIter *iter)
g_assert (iter_default->seq_iter != NULL);
model = clutter_model_iter_get_model (iter);
- row = clutter_model_iter_get_row (iter) + 1;
+ row = clutter_model_iter_get_row (iter);
filter_next = g_sequence_iter_next (iter_default->seq_iter);
g_assert (filter_next != NULL);
@@ -335,22 +327,20 @@ clutter_list_model_iter_next (ClutterModelIter *iter)
while (!g_sequence_iter_is_end (filter_next))
{
CLUTTER_LIST_MODEL_ITER (temp_iter)->seq_iter = filter_next;
- g_object_set (G_OBJECT (temp_iter), "row", row, NULL);
if (clutter_model_filter_iter (model, temp_iter))
- break;
+ {
+ row += 1;
+ break;
+ }
filter_next = g_sequence_iter_next (filter_next);
- row += 1;
}
g_object_unref (temp_iter);
- /* We do this because the 'end_iter' is always *after* the last valid iter.
- * Otherwise loops will go on forever
- */
- if (filter_next == iter_default->seq_iter)
- filter_next = g_sequence_iter_next (filter_next);
+ if (g_sequence_iter_is_end (filter_next))
+ row += 1;
/* update the iterator and return it */
g_object_set (G_OBJECT (iter_default), "model", model, "row", row, NULL);
@@ -372,7 +362,7 @@ clutter_list_model_iter_prev (ClutterModelIter *iter)
g_assert (iter_default->seq_iter != NULL);
model = clutter_model_iter_get_model (iter);
- row = clutter_model_iter_get_row (iter) - 1;
+ row = clutter_model_iter_get_row (iter);
filter_prev = g_sequence_iter_prev (iter_default->seq_iter);
g_assert (filter_prev != NULL);
@@ -384,22 +374,20 @@ clutter_list_model_iter_prev (ClutterModelIter *iter)
while (!g_sequence_iter_is_begin (filter_prev))
{
CLUTTER_LIST_MODEL_ITER (temp_iter)->seq_iter = filter_prev;
- g_object_set (G_OBJECT (temp_iter), "row", row, NULL);
if (clutter_model_filter_iter (model, temp_iter))
- break;
+ {
+ row -= 1;
+ break;
+ }
filter_prev = g_sequence_iter_prev (filter_prev);
- row -= 1;
}
g_object_unref (temp_iter);
- /* We do this because the 'end_iter' is always *after* the last valid iter.
- * Otherwise loops will go on forever
- */
- if (filter_prev == iter_default->seq_iter)
- filter_prev = g_sequence_iter_prev (filter_prev);
+ if (g_sequence_iter_is_begin (filter_prev))
+ row -= 1;
/* update the iterator and return it */
g_object_set (G_OBJECT (iter_default), "model", model, "row", row, NULL);
@@ -466,16 +454,61 @@ clutter_list_model_get_iter_at_row (ClutterModel *model,
{
ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
GSequence *sequence = model_default->priv->sequence;
+ gint seq_length = g_sequence_get_length (sequence);
ClutterListModelIter *retval;
- if (row >= g_sequence_get_length (sequence))
+ if (row >= seq_length)
return NULL;
retval = g_object_new (CLUTTER_TYPE_LIST_MODEL_ITER,
"model", model,
"row", row,
NULL);
- retval->seq_iter = g_sequence_get_iter_at_pos (sequence, row);
+
+ /* short-circuit in case we don't have a filter in place */
+ if (!clutter_model_get_filter_set (model))
+ {
+ retval->seq_iter = g_sequence_get_iter_at_pos (sequence, row);
+
+ return CLUTTER_MODEL_ITER (retval);
+ }
+
+ if (row == 0)
+ {
+ GSequenceIter *filter_next;
+
+ filter_next = g_sequence_get_begin_iter (sequence);
+ g_assert (filter_next != NULL);
+
+ while (!g_sequence_iter_is_end (filter_next))
+ {
+ retval->seq_iter = filter_next;
+
+ if (clutter_model_filter_iter (model, CLUTTER_MODEL_ITER (retval)))
+ break;
+
+ filter_next = g_sequence_iter_next (filter_next);
+ }
+ }
+ else
+ {
+ GSequenceIter *filter_prev;
+
+ filter_prev = g_sequence_get_end_iter (sequence);
+ g_assert (filter_prev != NULL);
+
+ filter_prev = g_sequence_iter_prev (filter_prev);
+
+ while (!g_sequence_iter_is_begin (filter_prev))
+ {
+ retval->seq_iter = filter_prev;
+
+ if (clutter_model_filter_iter (model, CLUTTER_MODEL_ITER (retval)))
+ break;
+
+ filter_prev = g_sequence_iter_prev (filter_prev);
+ }
+ }
return CLUTTER_MODEL_ITER (retval);
}
@@ -507,7 +540,7 @@ clutter_list_model_insert_row (ClutterModel *model,
if (index_ < 0)
{
seq_iter = g_sequence_append (sequence, array);
- pos = g_sequence_get_length (sequence);
+ pos = g_sequence_get_length (sequence) - 1;
}
else if (index_ == 0)
{
@@ -574,14 +607,6 @@ clutter_list_model_remove_row (ClutterModel *model,
}
}
-static guint
-clutter_list_model_get_n_rows (ClutterModel *model)
-{
- ClutterListModel *model_default = CLUTTER_LIST_MODEL (model);
-
- return g_sequence_get_length (model_default->priv->sequence);
-}
-
typedef struct
{
ClutterModel *model;
@@ -668,7 +693,6 @@ clutter_list_model_class_init (ClutterListModelClass *klass)
gobject_class->finalize = clutter_list_model_finalize;
- model_class->get_n_rows = clutter_list_model_get_n_rows;
model_class->get_iter_at_row = clutter_list_model_get_iter_at_row;
model_class->insert_row = clutter_list_model_insert_row;
model_class->remove_row = clutter_list_model_remove_row;
diff --git a/clutter/clutter-model.c b/clutter/clutter-model.c
index e1380fb74..cfca42897 100644
--- a/clutter/clutter-model.c
+++ b/clutter/clutter-model.c
@@ -208,28 +208,6 @@ clutter_model_real_get_n_columns (ClutterModel *model)
return model->priv->n_columns;
}
-static guint
-clutter_model_real_get_n_rows (ClutterModel *model)
-{
- ClutterModelIter *iter;
- guint n_rows = 0;
-
- iter = clutter_model_get_first_iter (model);
- if (!iter)
- return 0;
-
- while (!clutter_model_iter_is_last (iter))
- {
- n_rows += 1;
-
- clutter_model_iter_next (iter);
- }
-
- g_object_unref (iter);
-
- return n_rows;
-}
-
static void
clutter_model_finalize (GObject *object)
{
@@ -289,7 +267,6 @@ clutter_model_class_init (ClutterModelClass *klass)
klass->get_column_name = clutter_model_real_get_column_name;
klass->get_column_type = clutter_model_real_get_column_type;
klass->get_n_columns = clutter_model_real_get_n_columns;
- klass->get_n_rows = clutter_model_real_get_n_rows;
/**
* ClutterModel:filter-set:
@@ -519,7 +496,7 @@ clutter_model_filter_row (ClutterModel *model,
return TRUE;
iter = clutter_model_get_iter_at_row (model, row);
- if (!iter)
+ if (iter == NULL)
return FALSE;
res = priv->filter_func (model, iter, priv->filter_data);
@@ -1162,6 +1139,10 @@ clutter_model_get_column_type (ClutterModel *model,
*
* Retrieves a #ClutterModelIter representing the row at the given index.
*
+ * If a filter function has been set using clutter_model_set_filter()
+ * then the @model implementation will return the first non filtered
+ * row.
+ *
* Return value: (transfer full): A new #ClutterModelIter, or %NULL if @row was
* out of bounds. When done using the iterator object, call g_object_unref()
* to deallocate its resources
@@ -1188,49 +1169,65 @@ clutter_model_get_iter_at_row (ClutterModel *model,
* clutter_model_get_first_iter:
* @model: a #ClutterModel
*
- * Retrieves a #ClutterModelIter representing the first row in @model.
+ * Retrieves a #ClutterModelIter representing the first non-filtered
+ * row in @model.
*
- * Return value: (transfer full): A new #ClutterModelIter. Call g_object_unref() when
- * done using it
+ * Return value: (transfer full): A new #ClutterModelIter.
+ * Call g_object_unref() when done using it
*
* Since: 0.6
*/
ClutterModelIter *
clutter_model_get_first_iter (ClutterModel *model)
{
+ ClutterModelIter *retval;
+
g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL);
- return clutter_model_get_iter_at_row (model, 0);
+ retval = clutter_model_get_iter_at_row (model, 0);
+ if (retval != NULL)
+ {
+ g_assert (clutter_model_filter_iter (model, retval) != FALSE);
+ g_assert (clutter_model_iter_get_row (retval) == 0);
+ }
+
+ return retval;
}
/**
* clutter_model_get_last_iter:
* @model: a #ClutterModel
*
- * Retrieves a #ClutterModelIter representing the last row in @model.
+ * Retrieves a #ClutterModelIter representing the last non-filtered
+ * row in @model.
*
- * Return value: (transfer full): A new #ClutterModelIter. Call g_object_unref() when
- * done using it
+ * Return value: (transfer full): A new #ClutterModelIter.
+ * Call g_object_unref() when done using it
*
* Since: 0.6
*/
ClutterModelIter *
clutter_model_get_last_iter (ClutterModel *model)
{
+ ClutterModelIter *retval;
guint length;
g_return_val_if_fail (CLUTTER_IS_MODEL (model), NULL);
length = clutter_model_get_n_rows (model);
+ retval = clutter_model_get_iter_at_row (model, length - 1);
+ if (retval != NULL)
+ g_assert (clutter_model_filter_iter (model, retval) != FALSE);
- return clutter_model_get_iter_at_row (model, length - 1);
+ return retval;
}
/**
* clutter_model_get_n_rows:
* @model: a #ClutterModel
*
- * Retrieves the number of rows inside @model.
+ * Retrieves the number of rows inside @model, eventually taking
+ * into account any filtering function set using clutter_model_set_filter().
*
* Return value: The length of the @model. If there is a filter set, then
* the length of the filtered @model is returned.
@@ -1240,9 +1237,35 @@ clutter_model_get_last_iter (ClutterModel *model)
guint
clutter_model_get_n_rows (ClutterModel *model)
{
+ ClutterModelClass *klass;
+ guint row_count;
+
g_return_val_if_fail (CLUTTER_IS_MODEL (model), 0);
- return CLUTTER_MODEL_GET_CLASS (model)->get_n_rows (model);
+ klass = CLUTTER_MODEL_GET_CLASS (model);
+ if (klass->get_n_rows)
+ row_count = klass->get_n_rows (model);
+ else
+ {
+ ClutterModelIter *iter;
+
+ iter = clutter_model_get_first_iter (model);
+ if (iter == NULL)
+ return 0;
+
+ row_count = 0;
+ while (!clutter_model_iter_is_last (iter))
+ {
+ if (clutter_model_filter_iter (model, iter))
+ row_count += 1;
+
+ iter = clutter_model_iter_next (iter);
+ }
+
+ g_object_unref (iter);
+ }
+
+ return row_count;
}
@@ -1358,6 +1381,9 @@ clutter_model_set_sort (ClutterModel *model,
ClutterModelPrivate *priv;
g_return_if_fail (CLUTTER_IS_MODEL (model));
+ g_return_if_fail ((func != NULL && column >= 0) ||
+ (func == NULL && column == -1));
+
priv = model->priv;
if (priv->sort_notify)
@@ -1604,7 +1630,8 @@ clutter_model_iter_set_property (GObject *object,
static void
clutter_model_iter_class_init (ClutterModelIterClass *klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
gobject_class->get_property = clutter_model_iter_get_property;
gobject_class->set_property = clutter_model_iter_set_property;
@@ -1628,28 +1655,26 @@ clutter_model_iter_class_init (ClutterModelIterClass *klass)
*
* Since: 0.6
*/
- g_object_class_install_property (gobject_class,
- ITER_PROP_MODEL,
- g_param_spec_object ("model",
- "Model",
- "The model to which the iterator belongs to",
- CLUTTER_TYPE_MODEL,
- CLUTTER_PARAM_READWRITE));
+ pspec = g_param_spec_object ("model",
+ "Model",
+ "The model to which the iterator belongs to",
+ CLUTTER_TYPE_MODEL,
+ CLUTTER_PARAM_READWRITE);
+ g_object_class_install_property (gobject_class, ITER_PROP_MODEL, pspec);
- /**
+ /**
* ClutterModelIter:row:
*
* The row number to which this iter points to.
*
* Since: 0.6
*/
- g_object_class_install_property (gobject_class,
- ITER_PROP_ROW,
- g_param_spec_uint ("row",
- "Row",
- "The row to which the iterator points to",
- 0, G_MAXUINT, 0,
- CLUTTER_PARAM_READWRITE));
+ pspec = g_param_spec_uint ("row",
+ "Row",
+ "The row to which the iterator points to",
+ 0, G_MAXUINT, 0,
+ CLUTTER_PARAM_READWRITE);
+ g_object_class_install_property (gobject_class, ITER_PROP_ROW, pspec);
g_type_class_add_private (gobject_class, sizeof (ClutterModelIterPrivate));
}
diff --git a/clutter/clutter-model.h b/clutter/clutter-model.h
index 2bf13dabd..bae1faf3b 100644
--- a/clutter/clutter-model.h
+++ b/clutter/clutter-model.h
@@ -129,7 +129,7 @@ struct _ClutterModel
* @get_iter_at_row: virtual function for returning an iterator for the
* given row
* @get_n_rows: virtual function for returning the number of rows
- * of the model, not considering any filter function if present
+ * of the model
* @get_n_columns: virtual function for retuning the number of columns
* of the model
* @resort: virtual function for sorting the model using the passed