dee

Merge lp:~kamstrup/dee/filter-models-ng into lp:dee

Proposed by Mikkel Kamstrup Erlandsen
Status: Merged
Approved by: Michal Hruby
Approved revision: 324
Merged at revision: 320
Proposed branch: lp:~kamstrup/dee/filter-models-ng
Merge into: lp:dee
Diff against target: 1257 lines (+420/-277)
12 files modified
dee/Makefile.am (+2/-2)
dee/dee-filter-model.c (+23/-26)
dee/dee-filter-model.h (+4/-61)
dee/dee-filter.c (+198/-96)
dee/dee-filter.h (+103/-9)
dee/dee-model-reader.c (+2/-2)
dee/dee-model-reader.h (+5/-2)
dee/dee.h (+1/-1)
doc/reference/dee-1.0/dee-1.0-docs.sgml (+1/-1)
tests/test-filter-model.c (+52/-39)
vapi/Dee-1.0-custom.vala (+6/-14)
vapi/dee-1.0.vapi (+23/-24)
To merge this branch: bzr merge lp:~kamstrup/dee/filter-models-ng
Reviewer Review Type Date Requested Status
Michal Hruby (community) Approve
Review via email: mp+85706@code.launchpad.net

This proposal supersedes a proposal from 2011-12-14.

Description of the change

Overhaul DeeFilter and DeeFilterModel to work with GI and be more like DeeModelReader and DeeIndex

This branch gives a slight API break in how DeeFilters are created and reverses the order of the arguments to dee_filter_model_new() to match the order in dee_{hash,tree}_index_new(). I tested manually that Python works with DeeFilterModel now.

(resubmitted because of quantum entanglement with the no-const branch)

To post a comment you must log in.
Revision history for this message
Michal Hruby (mhr3) wrote : Posted in a previous version of this proposal

Seems to be mixed up with the no-const branch, can you please merge trunk/resubmit, or whatever is necessary?

Revision history for this message
Michal Hruby (mhr3) wrote :

I'm getting: `Warning: multiple "IDs" for constraint linkend: DeeFilter.` when generating the documentation, not sure what's the root cause of that, but it wasn't there in trunk.

What's missing is regenerated vapi (we really need to hook that up into the build system properly) + no longer forcing Dee.Filter to be compact class.

One of the things I was never sure about is whether GI-langs are able to use functions that have in the C signature two function pointers and a single userdata + destroy (ie current dee_filter_new), but it doesn't seem likely.

review: Needs Information
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

> I'm getting: `Warning: multiple "IDs" for constraint linkend: DeeFilter.` when
> generating the documentation, not sure what's the root cause of that, but it
> wasn't there in trunk.

I'll take a quick look; but it doesn't worry me too much right now as the docs themselves look fine. So I think we can land even if I don't find a fix right away.

> What's missing is regenerated vapi (we really need to hook that up into the
> build system properly) + no longer forcing Dee.Filter to be compact class.

Done

> One of the things I was never sure about is whether GI-langs are able to use
> functions that have in the C signature two function pointers and a single
> userdata + destroy (ie current dee_filter_new), but it doesn't seem likely.

This did cross my mind, and I thin you're right that it might now work. GDBus and other APIsdoes this as well though - but since we can easily expand the set of DeeFilters we distribute I am not too concerned about this.

lp:~kamstrup/dee/filter-models-ng updated
323. By Mikkel Kamstrup Erlandsen

Update VAPI for DeeFilter and DeeFilterModel

324. By Mikkel Kamstrup Erlandsen

Make DeeFilterMapNotify and dee_filter_notify() return a gboolean. TRUE if the iter was added to the filter model.

Also fix (scope notified) annotaitons in DeeFilter and DeeModelReader.

Update VAPI accordingly

Revision history for this message
Michal Hruby (mhr3) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dee/Makefile.am'
2--- dee/Makefile.am 2011-11-24 15:47:41 +0000
3+++ dee/Makefile.am 2011-12-15 11:35:14 +0000
4@@ -31,7 +31,7 @@
5 dee-model.h \
6 dee-model-reader.h \
7 dee-filter-model.h \
8- dee-filters.h \
9+ dee-filter.h \
10 dee-peer.h \
11 dee-proxy-model.h \
12 dee-sequence-model.h \
13@@ -65,7 +65,7 @@
14 dee-peer.c \
15 dee-proxy-model.c \
16 dee-filter-model.c \
17- dee-filters.c \
18+ dee-filter.c \
19 dee-sequence-model.c \
20 dee-shared-model.c \
21 dee-serializable-model.c \
22
23=== modified file 'dee/dee-filter-model.c'
24--- dee/dee-filter-model.c 2011-10-26 15:08:16 +0000
25+++ dee/dee-filter-model.c 2011-12-15 11:35:14 +0000
26@@ -51,8 +51,11 @@
27 #include <config.h>
28 #endif
29
30+#include <string.h> // memcpy()
31+
32 #include "dee-peer.h"
33 #include "dee-model.h"
34+#include "dee-filter.h"
35 #include "dee-proxy-model.h"
36 #include "dee-filter-model.h"
37 #include "dee-serializable-model.h"
38@@ -161,20 +164,20 @@
39
40 if (priv->filter)
41 {
42- if (priv->filter->user_data && priv->filter->destroy)
43- {
44- priv->filter->destroy (priv->filter->user_data);
45- }
46+ dee_filter_destroy (priv->filter);
47 g_free (priv->filter);
48+ priv->filter = NULL;
49 }
50
51 if (priv->iter_map)
52 {
53 g_hash_table_destroy (priv->iter_map);
54+ priv->iter_map = NULL;
55 }
56 if (priv->iter_list)
57 {
58 g_sequence_free (priv->iter_list);
59+ priv->iter_list = NULL;
60 }
61
62 if (priv->on_orig_row_added_id != 0)
63@@ -184,9 +187,14 @@
64 if (priv->on_orig_row_changed_id != 0)
65 g_signal_handler_disconnect (priv->orig_model, priv->on_orig_row_changed_id);
66
67+ priv->on_orig_row_added_id = 0;
68+ priv->on_orig_row_removed_id = 0;
69+ priv->on_orig_row_changed_id = 0;
70+
71 if (priv->orig_model)
72 {
73 g_object_unref (priv->orig_model);
74+ priv->orig_model = NULL;
75 }
76
77 G_OBJECT_CLASS (dee_filter_model_parent_class)->finalize (object);
78@@ -196,9 +204,8 @@
79 dee_filter_model_constructed (GObject *object)
80 {
81 DeeFilterModelPrivate *priv = DEE_FILTER_MODEL (object)->priv;
82- DeeFilter *filter = priv->filter;
83
84- if (filter == NULL)
85+ if (priv->filter == NULL)
86 {
87 g_critical ("You must set the 'filter' property when "
88 "creating a DeeFilterModel");
89@@ -214,9 +221,7 @@
90 g_sequence_get_end_iter (priv->iter_list));
91
92 /* Apply filter to orig_model in order to fill this model */
93- filter->map_func (priv->orig_model,
94- DEE_FILTER_MODEL (object),
95- filter->user_data);
96+ dee_filter_map (priv->filter, priv->orig_model, DEE_FILTER_MODEL (object));
97
98 /* Listen for changes to orig_model */
99 priv->on_orig_row_added_id =
100@@ -243,11 +248,12 @@
101 {
102 DeeFilterModelPrivate *priv = DEE_FILTER_MODEL (object)->priv;
103
104+
105 switch (id)
106 {
107 case PROP_FILTER:
108- /* Assume ownership of filter */
109- priv->filter = g_value_get_pointer (value);
110+ priv->filter = g_new0 (DeeFilter, 1);
111+ memcpy (priv->filter, g_value_get_pointer (value), sizeof (DeeFilter));
112 break;
113 default:
114 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, id, pspec);
115@@ -350,20 +356,13 @@
116 * Returns: (transfer full) (type DeeFilterModel): A newly allocated #DeeFilterModel. Free with g_object_unref().
117 */
118 DeeModel*
119-dee_filter_model_new (const DeeFilter *filter,
120- DeeModel *orig_model)
121+dee_filter_model_new (DeeModel *orig_model,
122+ DeeFilter *filter)
123 {
124 DeeModel *self;
125- DeeFilter *_filter;
126-
127- _filter = g_new0 (DeeFilter, 1);
128- _filter->map_func = filter->map_func;
129- _filter->map_notify = filter->map_notify;
130- _filter->destroy = filter->destroy;
131- _filter->user_data = filter->user_data;
132
133 self = DEE_MODEL (g_object_new (DEE_TYPE_FILTER_MODEL,
134- "filter", _filter,
135+ "filter", filter,
136 "back-end", orig_model,
137 "proxy-signals", FALSE,
138 NULL));
139@@ -618,15 +617,13 @@
140 DeeModelIter *iter)
141 {
142 DeeFilterModelPrivate *priv;
143- DeeFilter *filter;
144
145 priv = self->priv;
146- filter = priv->filter;
147
148 if (priv->ignore_orig_signals)
149 return;
150
151- filter->map_notify (priv->orig_model, iter, self, filter->user_data);
152+ dee_filter_notify (priv->filter, iter, priv->orig_model, self);
153
154 }
155
156@@ -978,7 +975,7 @@
157 DeeFilterModelPrivate *priv;
158 GSequenceIter *seq_iter;
159
160- g_return_val_if_fail (DEE_IS_FILTER_MODEL (self), -1);
161+ g_return_val_if_fail (DEE_IS_FILTER_MODEL (self), 0);
162
163 priv = DEE_FILTER_MODEL (self)->priv;
164 seq_iter = (GSequenceIter*) g_hash_table_lookup (priv->iter_map, iter);
165@@ -986,7 +983,7 @@
166 if (seq_iter == NULL)
167 {
168 g_critical ("Can not find next iter for unknown iter");
169- return -1;
170+ return 0;
171 }
172
173 return (guint) ABS(g_sequence_iter_get_position (seq_iter));
174
175=== modified file 'dee/dee-filter-model.h'
176--- dee/dee-filter-model.h 2011-12-14 10:59:40 +0000
177+++ dee/dee-filter-model.h 2011-12-15 11:35:14 +0000
178@@ -52,68 +52,11 @@
179 typedef struct _DeeFilterModel DeeFilterModel;
180 typedef struct _DeeFilterModelClass DeeFilterModelClass;
181 typedef struct _DeeFilterModelPrivate DeeFilterModelPrivate;
182+
183+/* We need this one here to avoid circular refs */
184 typedef struct _DeeFilter DeeFilter;
185
186 /**
187- * DeeModelMapFunc:
188- * @orig_model: The model containing the original data to filter
189- * @filter_model: The model that will contain the filtered results. The
190- * filter func must iterate over @orig_model and add all relevant
191- * rows to @filter_model. This model is guaranteed to be empty
192- * when the filter func is invoked
193- * @user_data: User data passed together with the filter func
194- *
195- * Function used to collect the rows from a model that should be included in
196- * a #DeeFilterModel. To add rows to @filter_model use the methods
197- * dee_filter_model_append_iter(), dee_filter_model_prepend_iter(),
198- * dee_filter_model_insert_iter(), and dee_filter_model_insert_iter_before().
199- *
200- * The iteration over the original model is purposely left to the map func
201- * in order to allow optimized iterations if the the caller has a priori
202- * knowledge of the sorting and grouping of the data in the original model.
203- */
204-typedef void (*DeeModelMapFunc) (DeeModel *orig_model,
205- DeeFilterModel *filter_model,
206- gpointer user_data);
207-
208-/**
209- * DeeModelMapNotify:
210- * @orig_model: The model containing the added row
211- * @orig_iter: A #DeeModelIter pointing to the new row in @orig_model
212- * @filter_model: The model that was also passed to the #DeeModelMapFunc
213- * of the #DeeFilter this functions is a part of
214- * @user_data: User data for the #DeeFilter
215- *
216- * Callback invoked when a row is added to @orig_model. To add rows to
217- * @filter_model use the methods dee_filter_model_append_iter(),
218- * dee_filter_model_prepend_iter(), dee_filter_model_insert_iter(),
219- * and dee_filter_model_insert_iter_before().
220- */
221-typedef void (*DeeModelMapNotify) (DeeModel *orig_model,
222- DeeModelIter *orig_iter,
223- DeeFilterModel *filter_model,
224- gpointer user_data);
225-
226-/**
227- * DeeFilter:
228- * @map_func: The #DeeModelMapFunc used to construct the initial contents of
229- * a #DeeFilterModel
230- * @map_notify: Callback invoked when the original model changes
231- * @destroy: Callback for freeing the @user_data
232- * @user_data: Free form user data associated with the filter. This pointer will
233- * be passed to @map_func and @map_notify
234- *
235- * Structure encapsulating the mapping logic used to construct a #DeeFilterModel
236- */
237-struct _DeeFilter
238-{
239- DeeModelMapFunc map_func;
240- DeeModelMapNotify map_notify;
241- GDestroyNotify destroy;
242- gpointer user_data;
243-} ;
244-
245-/**
246 * DeeFilterModel:
247 *
248 * All fields in the DeeFilterModel structure are private and should never be
249@@ -148,8 +91,8 @@
250 **/
251 GType dee_filter_model_get_type (void);
252
253-DeeModel* dee_filter_model_new (const DeeFilter *filter,
254- DeeModel *orig_model);
255+DeeModel* dee_filter_model_new (DeeModel *orig_model,
256+ DeeFilter *filter);
257
258 gboolean dee_filter_model_contains (DeeFilterModel *self,
259 DeeModelIter *iter);
260
261=== renamed file 'dee/dee-filters.c' => 'dee/dee-filter.c'
262--- dee/dee-filters.c 2011-06-09 20:18:22 +0000
263+++ dee/dee-filter.c 2011-12-15 11:35:14 +0000
264@@ -19,7 +19,7 @@
265 */
266
267 /**
268- * SECTION:dee-filters
269+ * SECTION:dee-filter
270 * @title: Filters
271 * @short_description: A suite of simple #DeeFilter<!-- -->s for use with #DeeFilterModel<!-- -->s
272 * @include: dee.h
273@@ -52,7 +52,10 @@
274 #include <config.h>
275 #endif
276
277+#include <string.h> // memset()
278+
279 #include "dee-filter-model.h"
280+#include "dee-filter.h"
281 #include "trace-log.h"
282
283 /* The CollatorFilter stores collation keys for the columns in a DeeModelTag */
284@@ -79,15 +82,15 @@
285 /*
286 * Private impl
287 */
288-static void _dee_filter_collator_map_notify (DeeModel *orig_model,
289- DeeModelIter *orig_iter,
290- DeeFilterModel *filter_model,
291- gpointer user_data);
292+static gboolean _dee_filter_collator_map_notify (DeeModel *orig_model,
293+ DeeModelIter *orig_iter,
294+ DeeFilterModel *filter_model,
295+ gpointer user_data);
296
297-static void _dee_filter_collator_desc_map_notify (DeeModel *orig_model,
298- DeeModelIter *orig_iter,
299- DeeFilterModel *filter_model,
300- gpointer user_data);
301+static gboolean _dee_filter_collator_desc_map_notify (DeeModel *orig_model,
302+ DeeModelIter *orig_iter,
303+ DeeFilterModel *filter_model,
304+ gpointer user_data);
305
306 static void
307 _dee_filter_collator_map_func (DeeModel *orig_model,
308@@ -137,7 +140,7 @@
309
310 }
311
312-static void
313+static gboolean
314 _dee_filter_collator_map_notify (DeeModel *orig_model,
315 DeeModelIter *orig_iter,
316 DeeFilterModel *filter_model,
317@@ -148,8 +151,8 @@
318 const gchar *column_value, *test_value;
319 gchar *collation_key;
320
321- g_return_if_fail (user_data != NULL);
322- g_return_if_fail (orig_iter != NULL);
323+ g_return_val_if_fail (user_data != NULL, FALSE);
324+ g_return_val_if_fail (orig_iter != NULL, FALSE);
325
326 filter = (CollatorFilter *) user_data;
327
328@@ -180,9 +183,11 @@
329 {
330 dee_filter_model_append_iter(filter_model, orig_iter);
331 }
332+
333+ return TRUE;
334 }
335
336-static void
337+static gboolean
338 _dee_filter_collator_desc_map_notify (DeeModel *orig_model,
339 DeeModelIter *orig_iter,
340 DeeFilterModel *filter_model,
341@@ -193,8 +198,8 @@
342 const gchar *column_value, *test_value;
343 gchar *collation_key;
344
345- g_return_if_fail (user_data != NULL);
346- g_return_if_fail (orig_iter != NULL);
347+ g_return_val_if_fail (user_data != NULL, FALSE);
348+ g_return_val_if_fail (orig_iter != NULL, FALSE);
349
350 filter = (CollatorFilter *) user_data;
351
352@@ -225,6 +230,8 @@
353 {
354 dee_filter_model_append_iter(filter_model, orig_iter);
355 }
356+
357+ return TRUE;
358 }
359
360 static void
361@@ -256,7 +263,7 @@
362 }
363 }
364
365-static void
366+static gboolean
367 _dee_filter_key_map_notify (DeeModel *orig_model,
368 DeeModelIter *orig_iter,
369 DeeFilterModel *filter_model,
370@@ -265,16 +272,17 @@
371 KeyFilter *filter;
372 const gchar *val;
373
374- g_return_if_fail (user_data != NULL);
375+ g_return_val_if_fail (user_data != NULL, FALSE);
376
377 filter = (KeyFilter *) user_data;
378 val = dee_model_get_string (orig_model, orig_iter, filter->column);
379
380 /* Ignore rows that don't match the key */
381 if (g_strcmp0 (filter->key, val) != 0)
382- return;
383+ return FALSE;
384
385 dee_filter_model_insert_iter_with_original_order (filter_model, orig_iter);
386+ return TRUE;
387 }
388
389 static void
390@@ -303,7 +311,7 @@
391 }
392 }
393
394-static void
395+static gboolean
396 _dee_filter_value_map_notify (DeeModel *orig_model,
397 DeeModelIter *orig_iter,
398 DeeFilterModel *filter_model,
399@@ -312,16 +320,17 @@
400 ValueFilter *filter;
401 GVariant *val;
402
403- g_return_if_fail (user_data != NULL);
404+ g_return_val_if_fail (user_data != NULL, FALSE);
405
406 filter = (ValueFilter *) user_data;
407 val = dee_model_get_value (orig_model, orig_iter, filter->column);
408
409 /* Ignore rows that don't match the value */
410 if (!g_variant_equal (filter->value, val))
411- return;
412+ return FALSE;
413
414 dee_filter_model_insert_iter_with_original_order (filter_model, orig_iter);
415+ return TRUE;
416 }
417
418 static void
419@@ -354,7 +363,7 @@
420 }
421 }
422
423-static void
424+static gboolean
425 _dee_filter_regex_map_notify (DeeModel *orig_model,
426 DeeModelIter *orig_iter,
427 DeeFilterModel *filter_model,
428@@ -363,16 +372,17 @@
429 RegexFilter *filter;
430 const gchar *val;
431
432- g_return_if_fail (user_data != NULL);
433+ g_return_val_if_fail (user_data != NULL, FALSE);
434
435 filter = (RegexFilter *) user_data;
436 val = dee_model_get_string (orig_model, orig_iter, filter->column);
437
438 /* Ignore rows that don't match the key */
439 if (!g_regex_match (filter->regex, val, 0, NULL))
440- return;
441+ return FALSE;
442
443 dee_filter_model_insert_iter_with_original_order (filter_model, orig_iter);
444+ return TRUE;
445 }
446
447 static void
448@@ -401,95 +411,190 @@
449 */
450
451 /**
452+ * dee_filter_notify:
453+ * @filter: The filter to apply
454+ * @orig_iter: The #DeeModelIter added to @orig_model
455+ * @orig_model: The model that is being filtered
456+ * @filter_model: The #DeeFilterModel that holds the
457+ * filtered subset of @orig_model
458+ *
459+ * Call the #DeeFilterMapNotify function of a #DeeFilter.
460+ * When using a #DeeFilterModel you should not call this method yourself.
461+ *
462+ * Returns: The return value from the #DeeFilterMapNotify. That is; %TRUE
463+ * if @orig_iter was added to @filter_model
464+ */
465+gboolean
466+dee_filter_notify (DeeFilter *filter,
467+ DeeModelIter *orig_iter,
468+ DeeModel *orig_model,
469+ DeeFilterModel *filter_model)
470+{
471+ g_return_val_if_fail (filter != NULL, FALSE);
472+
473+ return filter->map_notify (orig_model, orig_iter,
474+ filter_model, filter->userdata);
475+}
476+
477+/**
478+ * dee_filter_map:
479+ * @filter: The filter to apply
480+ * @orig_model: The model that is being filtered
481+ * @filter_model: The #DeeFilterModel that holds the
482+ * filtered subset of @orig_model
483+ *
484+ * Call the #DeeFilterMapFunc function of a #DeeFilter.
485+ * When using a #DeeFilterModel you should not call this method yourself.
486+ */
487+void
488+dee_filter_map (DeeFilter *filter,
489+ DeeModel *orig_model,
490+ DeeFilterModel *filter_model)
491+{
492+ g_return_if_fail (filter != NULL);
493+
494+ filter->map_func (orig_model, filter_model, filter->userdata);
495+}
496+
497+/**
498+ * dee_filter_destroy:
499+ * @filter: The filter to destroy
500+ *
501+ * Call the #GDestroyNotify function on the userdata pointer of a #DeeFilter
502+ * (if the destroy member is set, that is).
503+ *
504+ * When using a #DeeFilterModel you should not call this method yourself.
505+ *
506+ * This method will not free the memory allocated for @filter.
507+ */
508+void
509+dee_filter_destroy (DeeFilter *filter)
510+{
511+ g_return_if_fail (filter != NULL);
512+
513+ if (filter->destroy)
514+ filter->destroy (filter->userdata);
515+}
516+
517+/**
518+ * dee_filter_new:
519+ * @map_func: (scope notified): The #DeeFilterMapFunc to use for the filter
520+ * @map_notify: (scope notified): The #DeeFilterMapNotify to use for the filter
521+ * @userdata: (closure) (allow-none): The user data to pass to
522+ @map_func and @map_notify
523+ * @destroy: (allow-none): The #GDestroyNotify to call on
524+ * @userdata when disposing of the filter
525+ * @out_filter: (out): A pointer to an uninitialized #DeeFilter struct.
526+ * This struct will zeroed and configured with the filter
527+ * parameters
528+ *
529+ * Create a new #DeeFilter with the given parameters. This call will zero
530+ * the @out_filter struct.
531+ *
532+ */
533+void
534+dee_filter_new (DeeFilterMapFunc map_func,
535+ DeeFilterMapNotify map_notify,
536+ GDestroyNotify destroy,
537+ gpointer userdata,
538+ DeeFilter *out_filter)
539+{
540+ g_return_if_fail (map_func != NULL);
541+ g_return_if_fail (map_notify != NULL);
542+ g_return_if_fail (out_filter != NULL);
543+
544+ memset (out_filter, 0, sizeof (DeeFilter));
545+
546+ out_filter->map_func = map_func;
547+ out_filter->map_notify = map_notify;
548+ out_filter->userdata = userdata;
549+ out_filter->destroy = destroy;
550+}
551+
552+/**
553 * dee_filter_new_collator:
554 * @column: The index of a column containing the strings to sort after
555+ * @out_filter: (out): A pointer to an uninitialized #DeeFilter struct.
556+ * This struct will zeroed and configured with the filter
557+ * parameters
558 *
559 * Create a #DeeFilter that takes string values from a column in the model
560 * and builds a #DeeFilterModel with the rows sorted according to the
561 * collation rules of the current locale.
562- *
563- * Returns: (transfer full): A newly allocated #DeeFilter. Do not modify it.
564- * Free with g_free().
565 */
566-DeeFilter*
567-dee_filter_new_collator (guint column)
568+void
569+dee_filter_new_collator (guint column,
570+ DeeFilter *out_filter)
571 {
572- DeeFilter *filter;
573 CollatorFilter *collator;
574
575- filter = g_new0 (DeeFilter, 1);
576- filter->map_func = _dee_filter_collator_map_func;
577- filter->map_notify = _dee_filter_collator_map_notify;
578-
579 collator = g_new0 (CollatorFilter, 1);
580 collator->column = column;
581
582- filter->destroy = (GDestroyNotify) g_free;
583- filter->user_data =collator;
584-
585- return filter;
586+ dee_filter_new (_dee_filter_collator_map_func,
587+ _dee_filter_collator_map_notify,
588+ (GDestroyNotify) g_free,
589+ collator,
590+ out_filter);
591 }
592
593 /**
594 * dee_filter_new_collator_desc:
595 * @column: The index of a column containing the strings to sort after
596+ * @out_filter: (out): A pointer to an uninitialized #DeeFilter struct.
597+ * This struct will zeroed and configured with the filter
598+ * parameters
599 *
600 * Create a #DeeFilter that takes string values from a column in the model
601 * and builds a #DeeFilterModel with the rows sorted descending according to the
602 * collation rules of the current locale.
603- *
604- * Returns: (transfer full): A newly allocated #DeeFilter. Do not modify it.
605- * Free with g_free().
606 */
607-DeeFilter*
608-dee_filter_new_collator_desc (guint column)
609+void
610+dee_filter_new_collator_desc (guint column,
611+ DeeFilter *out_filter)
612 {
613- DeeFilter *filter;
614 CollatorFilter *collator;
615-
616- filter = g_new0 (DeeFilter, 1);
617- filter->map_func = _dee_filter_collator_desc_map_func;
618- filter->map_notify = _dee_filter_collator_desc_map_notify;
619-
620+
621 collator = g_new0 (CollatorFilter, 1);
622 collator->column = column;
623
624- filter->destroy = (GDestroyNotify) g_free;
625- filter->user_data =collator;
626-
627- return filter;
628+ dee_filter_new (_dee_filter_collator_desc_map_func,
629+ _dee_filter_collator_desc_map_notify,
630+ (GDestroyNotify) g_free,
631+ collator,
632+ out_filter);
633 }
634
635
636 /**
637 * dee_filter_new_for_key_column:
638 * @column: The index of a column containing the string key to match
639+ * @out_filter: (out): A pointer to an uninitialized #DeeFilter struct.
640+ * This struct will zeroed and configured with the filter
641+ * parameters
642 *
643 * Create a #DeeFilter that only includes rows from the original model
644 * which has an exact match on some string column. A #DeeFilterModel created
645 * with this filter will be ordered in accordance with its parent model.
646- *
647- * Returns: (transfer full): A newly allocated #DeeFilter. Do not modify it.
648- * Free with g_free().
649 */
650-DeeFilter*
651-dee_filter_new_for_key_column (guint column, const gchar *key)
652+void
653+dee_filter_new_for_key_column (guint column,
654+ const gchar *key,
655+ DeeFilter *out_filter)
656 {
657- DeeFilter *filter;
658 KeyFilter *key_filter;
659
660- filter = g_new0 (DeeFilter, 1);
661- filter->map_func = _dee_filter_key_map_func;
662- filter->map_notify = _dee_filter_key_map_notify;
663+ g_return_if_fail (key != NULL);
664
665 key_filter = g_new0 (KeyFilter, 1);
666 key_filter->column = column;
667 key_filter->key = g_strdup (key);
668
669- filter->destroy = (GDestroyNotify) key_filter_free;
670- filter->user_data = key_filter;
671-
672- return filter;
673+ dee_filter_new (_dee_filter_key_map_func,
674+ _dee_filter_key_map_notify,
675+ (GDestroyNotify) key_filter_free,
676+ key_filter,
677+ out_filter);
678 }
679
680 /**
681@@ -498,6 +603,9 @@
682 * @value: (transfer none): A #GVariant value columns must match exactly.
683 * The matching semantics are those of g_variant_equal(). If @value
684 * is floating the ownership will be transfered to the filter
685+ * @out_filter: (out): A pointer to an uninitialized #DeeFilter struct.
686+ * This struct will zeroed and configured with the filter
687+ * parameters
688 *
689 * Create a #DeeFilter that only includes rows from the original model
690 * which match a variant value in a given column. A #DeeFilterModel
691@@ -507,62 +615,56 @@
692 * value comparison is done using g_variant_equal(). This means you can use
693 * this filter as a convenient fallback when there is no predefined filter
694 * for your column type if raw performance is not paramount.
695- *
696- * Returns: (transfer full): A newly allocated #DeeFilter. Do not modify it.
697- * Free with g_free().
698 */
699-DeeFilter*
700-dee_filter_new_for_any_column (guint column, GVariant *value)
701+void
702+dee_filter_new_for_any_column (guint column,
703+ GVariant *value,
704+ DeeFilter *out_filter)
705 {
706- DeeFilter *filter;
707 ValueFilter *v_filter;
708
709- g_return_val_if_fail (value != NULL, NULL);
710-
711- filter = g_new0 (DeeFilter, 1);
712- filter->map_func = _dee_filter_value_map_func;
713- filter->map_notify = _dee_filter_value_map_notify;
714+ g_return_if_fail (value != NULL);
715
716 v_filter = g_new0 (ValueFilter, 1);
717 v_filter->column = column;
718 v_filter->value = g_variant_ref_sink (value);
719
720- filter->destroy = (GDestroyNotify) value_filter_free;
721- filter->user_data = v_filter;
722-
723- return filter;
724+ dee_filter_new (_dee_filter_value_map_func,
725+ _dee_filter_value_map_notify,
726+ (GDestroyNotify) value_filter_free,
727+ v_filter,
728+ out_filter);
729 }
730
731 /**
732 * dee_filter_new_regex:
733 * @column: The index of a column containing the string to match
734 * @regex: (transfer none):The regular expression @column must match
735+ * @out_filter: (out): A pointer to an uninitialized #DeeFilter struct.
736+ * This struct will zeroed and configured with the filter
737+ * parameters
738 *
739 * Create a #DeeFilter that only includes rows from the original model
740 * which match a regular expression on some string column. A #DeeFilterModel
741 * created with this filter will be ordered in accordance with its parent model.
742- *
743- * Returns: (transfer full): A newly allocated #DeeFilter. Do not modify it.
744- * Free with g_free().
745 */
746-DeeFilter*
747-dee_filter_new_regex (guint column, GRegex *regex)
748+void
749+dee_filter_new_regex (guint column,
750+ GRegex *regex,
751+ DeeFilter *out_filter)
752 {
753- DeeFilter *filter;
754 RegexFilter *r_filter;
755
756- g_return_val_if_fail (regex != NULL, NULL);
757-
758- filter = g_new0 (DeeFilter, 1);
759- filter->map_func = _dee_filter_regex_map_func;
760- filter->map_notify = _dee_filter_regex_map_notify;
761+ g_return_if_fail (regex != NULL);
762
763 r_filter = g_new0 (RegexFilter, 1);
764 r_filter->column = column;
765 r_filter->regex = g_regex_ref (regex);
766
767- filter->destroy = (GDestroyNotify) regex_filter_free;
768- filter->user_data = r_filter;
769-
770- return filter;
771+ dee_filter_new (_dee_filter_regex_map_func,
772+ _dee_filter_regex_map_notify,
773+ (GDestroyNotify) regex_filter_free,
774+ r_filter,
775+ out_filter);
776 }
777+
778
779=== renamed file 'dee/dee-filters.h' => 'dee/dee-filter.h'
780--- dee/dee-filters.h 2011-06-09 20:18:22 +0000
781+++ dee/dee-filter.h 2011-12-15 11:35:14 +0000
782@@ -30,15 +30,109 @@
783
784 G_BEGIN_DECLS
785
786-DeeFilter* dee_filter_new_collator (guint column);
787-
788-DeeFilter* dee_filter_new_collator_desc (guint column);
789-
790-DeeFilter* dee_filter_new_for_key_column (guint column, const gchar *key);
791-
792-DeeFilter* dee_filter_new_for_any_column (guint column, GVariant *value);
793-
794-DeeFilter* dee_filter_new_regex (guint column, GRegex *regex);
795+typedef struct _DeeFilter DeeFilter;
796+
797+/**
798+ * DeeFilterMapFunc:
799+ * @orig_model: The model containing the original data to filter
800+ * @filter_model: The model that will contain the filtered results. The
801+ * filter func must iterate over @orig_model and add all relevant
802+ * rows to @filter_model. This model is guaranteed to be empty
803+ * when the filter func is invoked
804+ * @user_data: (closure): User data passed together with the filter func
805+ *
806+ * Function used to collect the rows from a model that should be included in
807+ * a #DeeFilterModel. To add rows to @filter_model use the methods
808+ * dee_filter_model_append_iter(), dee_filter_model_prepend_iter(),
809+ * dee_filter_model_insert_iter(), and dee_filter_model_insert_iter_before().
810+ *
811+ * The iteration over the original model is purposely left to the map func
812+ * in order to allow optimized iterations if the the caller has a priori
813+ * knowledge of the sorting and grouping of the data in the original model.
814+ */
815+typedef void (*DeeFilterMapFunc) (DeeModel *orig_model,
816+ DeeFilterModel *filter_model,
817+ gpointer user_data);
818+
819+/**
820+ * DeeFilterMapNotify:
821+ * @orig_model: The model containing the added row
822+ * @orig_iter: A #DeeModelIter pointing to the new row in @orig_model
823+ * @filter_model: The model that was also passed to the #DeeModelMapFunc
824+ * of the #DeeFilter this functions is a part of
825+ * @user_data: (closure): User data for the #DeeFilter
826+ *
827+ * Callback invoked when a row is added to @orig_model. To add rows to
828+ * @filter_model use the methods dee_filter_model_append_iter(),
829+ * dee_filter_model_prepend_iter(), dee_filter_model_insert_iter(),
830+ * and dee_filter_model_insert_iter_before().
831+ *
832+ * Returns: %TRUE if @orig_iter was added to @filter_model
833+ */
834+typedef gboolean (*DeeFilterMapNotify) (DeeModel *orig_model,
835+ DeeModelIter *orig_iter,
836+ DeeFilterModel *filter_model,
837+ gpointer user_data);
838+
839+/**
840+ * DeeFilter:
841+ * @map_func: (scope notified): The #DeeModelMapFunc used to construct
842+ * the initial contents of a #DeeFilterModel
843+ * @map_notify: (scope notified): Callback invoked when the original model changes
844+ * @destroy: Callback for freeing the @user_data
845+ * @userdata (closure): Free form user data associated with the filter.
846+ * This pointer will be passed to @map_func and @map_notify
847+ *
848+ * Structure encapsulating the mapping logic used to construct a #DeeFilterModel
849+ */
850+struct _DeeFilter
851+{
852+ DeeFilterMapFunc map_func;
853+ DeeFilterMapNotify map_notify;
854+ GDestroyNotify destroy;
855+ gpointer userdata;
856+
857+ /*< private >*/
858+ gpointer _padding_1;
859+ gpointer _padding_2;
860+ gpointer _padding_3;
861+ gpointer _padding_4;
862+};
863+
864+gboolean dee_filter_notify (DeeFilter *filter,
865+ DeeModelIter *orig_iter,
866+ DeeModel *orig_model,
867+ DeeFilterModel *filter_model);
868+
869+void dee_filter_map (DeeFilter *filter,
870+ DeeModel *orig_model,
871+ DeeFilterModel *filter_model);
872+
873+void dee_filter_destroy (DeeFilter *filter);
874+
875+void dee_filter_new (DeeFilterMapFunc map_func,
876+ DeeFilterMapNotify map_notify,
877+ GDestroyNotify destroy,
878+ gpointer userdata,
879+ DeeFilter *out_filter);
880+
881+void dee_filter_new_collator (guint column,
882+ DeeFilter *out_filter);
883+
884+void dee_filter_new_collator_desc (guint column,
885+ DeeFilter *out_filter);
886+
887+void dee_filter_new_for_key_column (guint column,
888+ const gchar *key,
889+ DeeFilter *out_filter);
890+
891+void dee_filter_new_for_any_column (guint column,
892+ GVariant *value,
893+ DeeFilter *out_filter);
894+
895+void dee_filter_new_regex (guint column,
896+ GRegex *regex,
897+ DeeFilter *out_filter);
898
899 G_END_DECLS
900
901
902=== modified file 'dee/dee-model-reader.c'
903--- dee/dee-model-reader.c 2011-11-28 13:35:14 +0000
904+++ dee/dee-model-reader.c 2011-12-15 11:35:14 +0000
905@@ -85,9 +85,9 @@
906
907 /**
908 * dee_model_reader_new:
909- * @reader_func: The #DeeModelReaderFunc to use for the reader
910+ * @reader_func: (scope notified): The #DeeModelReaderFunc to use for the reader
911 * @userdata: (closure) (allow-none): The user data to pass to @reader_func
912- * @destroy: (scope notify) (allow-none): The #GDestroyNotify to call on
913+ * @destroy: (allow-none): The #GDestroyNotify to call on
914 * @userdata when disposing of the reader
915 * @out_reader: (out): A pointer to an uninitialized #DeeModelReader struct
916 *
917
918=== modified file 'dee/dee-model-reader.h'
919--- dee/dee-model-reader.h 2011-11-25 08:18:32 +0000
920+++ dee/dee-model-reader.h 2011-12-15 11:35:14 +0000
921@@ -30,6 +30,8 @@
922
923 G_BEGIN_DECLS
924
925+typedef struct _DeeFilter DeeFilter;
926+
927 /**
928 * DeeModelReaderFunc:
929 * @model: The model being indexed
930@@ -47,9 +49,10 @@
931
932 /**
933 * DeeModelReader:
934- * @reader_func: The #DeeModelReaderFunc used to extract string from a model
935+ * @reader_func: (scope notified): The #DeeModelReaderFunc used to extract
936+ * string from a model
937 * @userdata: (closure): user data to pass to @reader_func
938- * @destroy: (scope notified): Called when the reader is destroyed
939+ * @destroy: Called when the reader is destroyed
940 *
941 * Structure encapsulating the information needed to read strings from a
942 * model. Used for example by #DeeIndex.
943
944=== modified file 'dee/dee.h'
945--- dee/dee.h 2011-11-24 15:47:41 +0000
946+++ dee/dee.h 2011-12-15 11:35:14 +0000
947@@ -37,7 +37,7 @@
948 #include <dee-sequence-model.h>
949 #include <dee-shared-model.h>
950 #include <dee-filter-model.h>
951-#include <dee-filters.h>
952+#include <dee-filter.h>
953 #include <dee-index.h>
954 #include <dee-hash-index.h>
955 #include <dee-tree-index.h>
956
957=== modified file 'doc/reference/dee-1.0/dee-1.0-docs.sgml'
958--- doc/reference/dee-1.0/dee-1.0-docs.sgml 2011-11-24 15:47:41 +0000
959+++ doc/reference/dee-1.0/dee-1.0-docs.sgml 2011-12-15 11:35:14 +0000
960@@ -22,7 +22,7 @@
961 <xi:include href="xml/dee-proxy-model.xml"/>
962 <xi:include href="xml/dee-serializable-model.xml"/>
963 <xi:include href="xml/dee-filter-model.xml"/>
964- <xi:include href="xml/dee-filters.xml"/>
965+ <xi:include href="xml/dee-filter.xml"/>
966 </chapter>
967
968 <chapter>
969
970=== modified file 'tests/test-filter-model.c'
971--- tests/test-filter-model.c 2011-06-09 20:18:22 +0000
972+++ tests/test-filter-model.c 2011-12-15 11:35:14 +0000
973@@ -150,15 +150,18 @@
974 static void
975 test_empty_orig (FilterFixture *fix, gconstpointer data)
976 {
977- DeeFilter *filter = g_new0 (DeeFilter, 1);
978- filter->map_func = append_all_model_map;
979- filter->map_notify = append_all_model_notify;
980- filter->user_data = fix;
981+ DeeFilter filter;
982+
983+ dee_filter_new (append_all_model_map,
984+ append_all_model_notify,
985+ NULL,
986+ fix,
987+ &filter);
988
989 dee_model_clear (fix->model);
990 g_assert_cmpint (0, ==, dee_model_get_n_rows (fix->model));
991
992- DeeModel *m = dee_filter_model_new (filter, fix->model);
993+ DeeModel *m = dee_filter_model_new (fix->model, &filter);
994 g_assert_cmpint (0, ==, dee_model_get_n_rows (fix->model));
995
996 DeeModelIter *iter = dee_model_get_first_iter (m);
997@@ -170,12 +173,15 @@
998 static void
999 test_append_all (FilterFixture *fix, gconstpointer data)
1000 {
1001- DeeFilter filter = { 0 };
1002- filter.map_func = append_all_model_map;
1003- filter.map_notify = append_all_model_notify;
1004- filter.user_data = fix;
1005+ DeeFilter filter;
1006+
1007+ dee_filter_new (append_all_model_map,
1008+ append_all_model_notify,
1009+ NULL,
1010+ fix,
1011+ &filter);
1012
1013- DeeModel *m = dee_filter_model_new (&filter, fix->model);
1014+ DeeModel *m = dee_filter_model_new (fix->model, &filter);
1015 g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
1016
1017 DeeModelIter *iter = dee_model_get_first_iter (m);
1018@@ -207,12 +213,15 @@
1019 static void
1020 test_discard_all (FilterFixture *fix, gconstpointer data)
1021 {
1022- DeeFilter filter = { 0 };
1023- filter.map_func = discard_all_model_map;
1024- filter.map_notify = discard_all_model_notify;
1025- filter.user_data = fix;
1026+ DeeFilter filter;
1027+
1028+ dee_filter_new (discard_all_model_map,
1029+ discard_all_model_notify,
1030+ NULL,
1031+ fix,
1032+ &filter);
1033
1034- DeeModel *m = dee_filter_model_new (&filter, fix->model);
1035+ DeeModel *m = dee_filter_model_new (fix->model, &filter);
1036
1037 /* Check expected sizes */
1038 g_return_if_fail (DEE_IS_FILTER_MODEL (m));
1039@@ -261,12 +270,15 @@
1040 static void
1041 test_discard_all_append_notify (FilterFixture *fix, gconstpointer data)
1042 {
1043- DeeFilter filter = { 0 };
1044- filter.map_func = discard_all_model_map;
1045- filter.map_notify = append_all_model_notify;
1046- filter.user_data = fix;
1047+ DeeFilter filter;
1048
1049- DeeModel *m = dee_filter_model_new (&filter, fix->model);
1050+ dee_filter_new (discard_all_model_map,
1051+ append_all_model_notify,
1052+ NULL,
1053+ fix,
1054+ &filter);
1055+
1056+ DeeModel *m = dee_filter_model_new (fix->model, &filter);
1057
1058 guint filter_add_count = 0;
1059 guint orig_add_count = 0;
1060@@ -310,10 +322,11 @@
1061 test_collator_asc (FilterFixture *fix, gconstpointer data)
1062 {
1063 DeeModelIter *r0, *r1, *r2, *r3, *r4, *r5;
1064- DeeFilter *collator = dee_filter_new_collator (1);
1065- DeeModel *m = dee_filter_model_new (collator, fix->model);
1066+ DeeFilter collator;
1067+ DeeModel *m;
1068
1069- g_free (collator);
1070+ dee_filter_new_collator (1, &collator);
1071+ m = dee_filter_model_new (fix->model, &collator);
1072
1073 /* Test alphabetic sorting after initial construction */
1074 r0 = dee_model_get_iter_at_row (m, 0);
1075@@ -353,10 +366,11 @@
1076 test_collator_desc (FilterFixture *fix, gconstpointer data)
1077 {
1078 DeeModelIter *r0, *r1, *r2, *r3, *r4, *r5;
1079- DeeFilter *collator = dee_filter_new_collator_desc (1);
1080- DeeModel *m = dee_filter_model_new (collator, fix->model);
1081+ DeeFilter collator;
1082+ DeeModel *m;
1083
1084- g_free (collator);
1085+ dee_filter_new_collator_desc (1, &collator);
1086+ m = dee_filter_model_new (fix->model, &collator);
1087
1088 /* Test alphabetic sorting after initial construction */
1089 r0 = dee_model_get_iter_at_row (m, 0);
1090@@ -396,7 +410,7 @@
1091 DeeFilter *filter)
1092 {
1093 DeeModelIter *r0, *r1, *r2, *r3, *r4;//, *r5;
1094- DeeModel *m = dee_filter_model_new (filter, fix->model);
1095+ DeeModel *m = dee_filter_model_new (fix->model, filter);
1096
1097 /* Assert that the initial filtering is good:
1098 * { [ 0, "Zero" ] } { [ 0, "Zero" ],
1099@@ -492,34 +506,33 @@
1100 static void
1101 test_key (FilterFixture *fix, gconstpointer data)
1102 {
1103- DeeFilter *filter = dee_filter_new_for_key_column (1, "Zero");
1104+ DeeFilter filter;
1105
1106- _test_orig_ordering (fix, filter);
1107- g_free (filter);
1108+ dee_filter_new_for_key_column (1, "Zero", &filter);
1109+ _test_orig_ordering (fix, &filter);
1110 }
1111
1112 /* Test dee_filter_new_for_any_column() */
1113 static void
1114 test_any (FilterFixture *fix, gconstpointer data)
1115 {
1116- DeeFilter *filter =
1117- dee_filter_new_for_any_column (1, g_variant_new_string ("Zero"));
1118-
1119- _test_orig_ordering (fix, filter);
1120- g_free (filter);
1121+ DeeFilter filter;
1122+
1123+ dee_filter_new_for_any_column (1, g_variant_new_string ("Zero"), &filter);
1124+
1125+ _test_orig_ordering (fix, &filter);
1126 }
1127
1128 /* Test dee_filter_new_regex() */
1129 static void
1130 test_regex (FilterFixture *fix, gconstpointer data)
1131 {
1132- DeeFilter *filter;
1133+ DeeFilter filter;
1134 GRegex *regex;
1135
1136 regex = g_regex_new (".ero", 0, 0, NULL);
1137- filter = dee_filter_new_regex (1, regex);
1138+ dee_filter_new_regex (1, regex, &filter);
1139
1140- _test_orig_ordering (fix, filter);
1141+ _test_orig_ordering (fix, &filter);
1142 g_regex_unref (regex);
1143- g_free (filter);
1144 }
1145
1146=== modified file 'vapi/Dee-1.0-custom.vala'
1147--- vapi/Dee-1.0-custom.vala 2011-12-05 09:53:29 +0000
1148+++ vapi/Dee-1.0-custom.vala 2011-12-15 11:35:14 +0000
1149@@ -1,18 +1,10 @@
1150 namespace Dee {
1151- [CCode (free_function = "g_free")]
1152- [Compact]
1153- public class Filter {
1154- [CCode (has_construct_function = false)]
1155- public Filter.collator (uint column);
1156- [CCode (has_construct_function = false)]
1157- public Filter.collator_desc (uint column);
1158- [CCode (has_construct_function = false)]
1159- public Filter.for_any_column (uint column, GLib.Variant value);
1160- [CCode (has_construct_function = false)]
1161- public Filter.for_key_column (uint column, string key);
1162- [CCode (has_construct_function = false)]
1163- public Filter.regex (uint column, GLib.Regex regex);
1164- }
1165+
1166+ public struct Filter {
1167+ [CCode (cname = "destroy")]
1168+ public GLib.DestroyNotify destroy_notify;
1169+ }
1170+
1171 [CCode (ref_function = "", unref_function = "")]
1172 [Compact]
1173 public class ModelIter {
1174
1175=== modified file 'vapi/dee-1.0.vapi'
1176--- vapi/dee-1.0.vapi 2011-12-05 09:53:29 +0000
1177+++ vapi/dee-1.0.vapi 2011-12-15 11:35:14 +0000
1178@@ -21,28 +21,10 @@
1179 public unowned string get_primary_path ();
1180 public string primary_path { get; construct; }
1181 }
1182- [CCode (cheader_filename = "dee.h", free_function = "g_free")]
1183- [Compact]
1184- public class Filter {
1185- public weak GLib.DestroyNotify destroy;
1186- public weak Dee.ModelMapFunc map_func;
1187- public weak Dee.ModelMapNotify map_notify;
1188- public void* user_data;
1189- [CCode (has_construct_function = false)]
1190- public Filter.collator (uint column);
1191- [CCode (has_construct_function = false)]
1192- public Filter.collator_desc (uint column);
1193- [CCode (has_construct_function = false)]
1194- public Filter.for_any_column (uint column, GLib.Variant value);
1195- [CCode (has_construct_function = false)]
1196- public Filter.for_key_column (uint column, string key);
1197- [CCode (has_construct_function = false)]
1198- public Filter.regex (uint column, GLib.Regex regex);
1199- }
1200 [CCode (cheader_filename = "dee.h", type_id = "dee_filter_model_get_type ()")]
1201 public class FilterModel : Dee.ProxyModel, Dee.Model, Dee.Serializable {
1202 [CCode (has_construct_function = false, type = "DeeModel*")]
1203- public FilterModel (Dee.Filter filter, Dee.Model orig_model);
1204+ public FilterModel (Dee.Model orig_model, Dee.Filter filter);
1205 public unowned Dee.ModelIter append_iter (Dee.ModelIter iter);
1206 public bool contains (Dee.ModelIter iter);
1207 public unowned Dee.ModelIter insert_iter (Dee.ModelIter iter, uint pos);
1208@@ -50,7 +32,7 @@
1209 public unowned Dee.ModelIter insert_iter_with_original_order (Dee.ModelIter iter);
1210 public unowned Dee.ModelIter prepend_iter (Dee.ModelIter iter);
1211 [NoAccessorMethod]
1212- public Dee.Filter filter { owned get; construct; }
1213+ public Dee.Filter filter { get; construct; }
1214 }
1215 [CCode (cheader_filename = "dee.h", type_id = "dee_hash_index_get_type ()")]
1216 public class HashIndex : Dee.Index {
1217@@ -234,6 +216,23 @@
1218 public abstract GLib.Variant serialize ();
1219 }
1220 [CCode (cheader_filename = "dee.h")]
1221+ public struct Filter {
1222+ [CCode (cname = "destroy")]
1223+ public GLib.DestroyNotify destroy_notify;
1224+ public weak Dee.FilterMapFunc map_func;
1225+ public weak Dee.FilterMapNotify map_notify;
1226+ public void* userdata;
1227+ public void destroy ();
1228+ public void map (Dee.Model orig_model, Dee.FilterModel filter_model);
1229+ public static Dee.Filter @new (Dee.FilterMapFunc map_func, [CCode (delegate_target_pos = 2.2, destroy_notify_pos = 2.1)] owned Dee.FilterMapNotify map_notify);
1230+ public static Dee.Filter new_collator (uint column);
1231+ public static Dee.Filter new_collator_desc (uint column);
1232+ public static Dee.Filter new_for_any_column (uint column, GLib.Variant value);
1233+ public static Dee.Filter new_for_key_column (uint column, string key);
1234+ public static Dee.Filter new_regex (uint column, GLib.Regex regex);
1235+ public bool notify (Dee.ModelIter orig_iter, Dee.Model orig_model, Dee.FilterModel filter_model);
1236+ }
1237+ [CCode (cheader_filename = "dee.h")]
1238 public struct ModelReader {
1239 public weak Dee.ModelReaderFunc reader_func;
1240 public void* userdata;
1241@@ -258,12 +257,12 @@
1242 [CCode (cheader_filename = "dee.h", instance_pos = 1.9)]
1243 public delegate string CollatorFunc (string input);
1244 [CCode (cheader_filename = "dee.h", instance_pos = 2.9)]
1245+ public delegate void FilterMapFunc (Dee.Model orig_model, Dee.FilterModel filter_model);
1246+ [CCode (cheader_filename = "dee.h", instance_pos = 3.9)]
1247+ public delegate bool FilterMapNotify (Dee.Model orig_model, Dee.ModelIter orig_iter, Dee.FilterModel filter_model);
1248+ [CCode (cheader_filename = "dee.h", instance_pos = 2.9)]
1249 public delegate bool IndexIterFunc (string key, Dee.ResultSet rows);
1250 [CCode (cheader_filename = "dee.h", instance_pos = 2.9)]
1251- public delegate void ModelMapFunc (Dee.Model orig_model, Dee.FilterModel filter_model);
1252- [CCode (cheader_filename = "dee.h", instance_pos = 3.9)]
1253- public delegate void ModelMapNotify (Dee.Model orig_model, Dee.ModelIter orig_iter, Dee.FilterModel filter_model);
1254- [CCode (cheader_filename = "dee.h", instance_pos = 2.9)]
1255 public delegate string ModelReaderFunc (Dee.Model model, Dee.ModelIter iter);
1256 [CCode (cheader_filename = "dee.h", has_target = false)]
1257 public delegate GLib.Object SerializableParseFunc (GLib.Variant data);

Subscribers

People subscribed via source and target branches