## Filters Filters — A suite of simple DeeFilters for use with DeeFilterModels |

## Synopsis

    #include <dee.h>

                        DeeFilter;
    void                (*DeeFilterMapFunc)                 (DeeModel *orig_model,
                                                             DeeFilterModel *filter_model,
                                                             gpointer user_data);
    gboolean            (*DeeFilterMapNotify)               (DeeModel *orig_model,
                                                             DeeModelIter *orig_iter,
                                                             DeeFilterModel *filter_model,
                                                             gpointer user_data);
    void                dee_filter_destroy                  (DeeFilter *filter);
    void                dee_filter_map                      (DeeFilter *filter,
                                                             DeeModel *orig_model,
                                                             DeeFilterModel *filter_model);
    void                dee_filter_new                      (DeeFilterMapFunc map_func,
                                                             DeeFilterMapNotify map_notify,
                                                             gpointer userdata,
                                                             GDestroyNotify destroy,
                                                             DeeFilter *out_filter);
    void                dee_filter_new_collator             (guint column,
                                                             DeeFilter *out_filter);
    void                dee_filter_new_collator_desc        (guint column,
                                                             DeeFilter *out_filter);
    void                dee_filter_new_for_any_column       (guint column,
                                                             GVariant *value,
                                                             DeeFilter *out_filter);
    void                dee_filter_new_for_key_column       (guint column,
                                                             const gchar *key,
                                                             DeeFilter *out_filter);
    void                dee_filter_new_regex                (guint column,
                                                             GRegex *regex,
                                                             DeeFilter *out_filter);
    void                dee_filter_new_sort                 (DeeCompareRowFunc cmp_row,
                                                             gpointer cmp_user_data,
                                                             GDestroyNotify cmp_destroy,
                                                             DeeFilter *out_filter);
    gboolean            dee_filter_notify                   (DeeFilter *filter,
                                                             DeeModelIter *orig_iter,
                                                             DeeModel *orig_model,
                                                             DeeFilterModel *filter_model);

## Description

DeeFilters are used together with DeeFilterModels to build "views" of some original DeeModel. An example could be to build a view of a model that exposes the rows of the original model sorted by a given column (leaving the original model unaltered):

      DeeModel  *model, *view;
      DeeFilter *collator;

      // Create and populate a model with some unsorted rows
      model = dee_sequence_model_new ();
      dee_model_set_schema (model, "i", "s", NULL);
      dee_model_append (model, 27, "Foo");
      dee_model_append (model, 68, "Bar");

      // Create a collator for column 1
      collator = dee_filter_new_collator (1);

      // Create the sorted view
      view = dee_filter_model_new (collator, model);
      g_free (collator);

      // When accessing the view the row with 'Bar' will be first

## Details

### DeeFilter

    typedef struct {
      DeeFilterMapFunc   map_func;
      DeeFilterMapNotify map_notify;
      GDestroyNotify     destroy;
      gpointer           userdata;
    } DeeFilter;

Structure encapsulating the mapping logic used to construct a DeeFilterModel

DeeFilterMapFunc `map_func`; | The DeeModelMapFunc used to construct the initial contents of a DeeFilterModel. [scope notified]
DeeFilterMapNotify `map_notify`; | Callback invoked when the original model changes. [scope notified]
GDestroyNotify `destroy`; | Callback for freeing the `user_data` `userdata` (closure): Free form user data associated with the filter. This pointer will be passed to `map_func` and `map_notify`
gpointer `userdata`; |

### DeeFilterMapFunc ()

    void                (*DeeFilterMapFunc)                 (DeeModel *orig_model,
                                                             DeeFilterModel *filter_model,
                                                             gpointer user_data);

Function used to collect the rows from a model that should be included in a DeeFilterModel. To add rows to `filter_model` use the methods `dee_filter_model_append_iter()`, `dee_filter_model_prepend_iter()`, `dee_filter_model_insert_iter()`, and `dee_filter_model_insert_iter_before()`.

The iteration over the original model is purposely left to the map func in order to allow optimized iterations if the the caller has a priori knowledge of the sorting and grouping of the data in the original model.

`orig_model` : | The model containing the original data to filter
`filter_model` : | The model that will contain the filtered results. The filter func must iterate over `orig_model` and add all relevant rows to `filter_model`. This model is guaranteed to be empty when the filter func is invoked
`user_data` : | User data passed together with the filter func. [closure]

### DeeFilterMapNotify ()

    gboolean            (*DeeFilterMapNotify)               (DeeModel *orig_model,
                                                             DeeModelIter *orig_iter,
                                                             DeeFilterModel *filter_model,
                                                             gpointer user_data);

Callback invoked when a row is added to `orig_model`. To add rows to `filter_model` use the methods `dee_filter_model_append_iter()`, `dee_filter_model_prepend_iter()`, `dee_filter_model_insert_iter()`, and `dee_filter_model_insert_iter_before()`.

`orig_model` : | The model containing the added row
`orig_iter` : | A DeeModelIter pointing to the new row in `orig_model`
`filter_model` : | The model that was also passed to the DeeModelMapFunc of the DeeFilter this functions is a part of
`user_data` : | User data for the DeeFilter. [closure]
Returns : | `TRUE` if `orig_iter` was added to `filter_model`

### dee_filter_destroy ()

    void                dee_filter_destroy                  (DeeFilter *filter);

Call the GDestroyNotify function on the userdata pointer of a DeeFilter (if the destroy member is set, that is).

When using a DeeFilterModel you should not call this method yourself.

This method will not free the memory allocated for `filter`.

`filter` : | The filter to destroy

### dee_filter_map ()

    void                dee_filter_map                      (DeeFilter *filter,
                                                             DeeModel *orig_model,
                                                             DeeFilterModel *filter_model);

Call the DeeFilterMapFunc function of a DeeFilter. When using a DeeFilterModel you should not call this method yourself.

`filter` : | The filter to apply
`orig_model` : | The model that is being filtered
`filter_model` : | The DeeFilterModel that holds the filtered subset of `orig_model`

### dee_filter_new ()

    void                dee_filter_new                      (DeeFilterMapFunc map_func,
                                                             DeeFilterMapNotify map_notify,
                                                             gpointer userdata,
                                                             GDestroyNotify destroy,
                                                             DeeFilter *out_filter);

Create a new DeeFilter with the given parameters. This call will zero the `out_filter` struct.

`map_func` : | The DeeFilterMapFunc to use for the filter. [scope notified]
`map_notify` : | The DeeFilterMapNotify to use for the filter. [scope notified]
`userdata` : | The user data to pass to `map_func` and `map_notify`. [closure]
`destroy` : | The GDestroyNotify to call on `userdata` when disposing of the filter. [allow-none]
`out_filter` : | A pointer to an uninitialized DeeFilter struct. This struct will zeroed and configured with the filter parameters. [out]

### dee_filter_new_collator ()

    void                dee_filter_new_collator             (guint column,
                                                             DeeFilter *out_filter);

Create a DeeFilter that takes string values from a column in the model and builds a DeeFilterModel with the rows sorted according to the collation rules of the current locale.

`column` : | The index of a column containing the strings to sort after
`out_filter` : | A pointer to an uninitialized DeeFilter struct. This struct will zeroed and configured with the filter parameters. [out]

### dee_filter_new_collator_desc ()

    void                dee_filter_new_collator_desc        (guint column,
                                                             DeeFilter *out_filter);

Create a DeeFilter that takes string values from a column in the model and builds a DeeFilterModel with the rows sorted descending according to the collation rules of the current locale.

`column` : | The index of a column containing the strings to sort after
`out_filter` : | A pointer to an uninitialized DeeFilter struct. This struct will zeroed and configured with the filter parameters. [out]

### dee_filter_new_for_any_column ()

    void                dee_filter_new_for_any_column       (guint column,
                                                             GVariant *value,
                                                             DeeFilter *out_filter);

Create a DeeFilter that only includes rows from the original model which match a variant value in a given column. A DeeFilterModel created with this filter will be ordered in accordance with its parent model.

This method will work on any column, disregarding its schema, since the value comparison is done using `g_variant_equal()`. This means you can use this filter as a convenient fallback when there is no predefined filter for your column type if raw performance is not paramount.

`column` : | The index of a column containing the string to match
`value` : | A GVariant value columns must match exactly. The matching semantics are those of `g_variant_equal()`. If `value` is floating the ownership will be transfered to the filter. [transfer none]
`out_filter` : | A pointer to an uninitialized DeeFilter struct. This struct will zeroed and configured with the filter parameters. [out]

### dee_filter_new_for_key_column ()

    void                dee_filter_new_for_key_column       (guint column,
                                                             const gchar *key,
                                                             DeeFilter *out_filter);

Create a DeeFilter that only includes rows from the original model which has an exact match on some string column. A DeeFilterModel created with this filter will be ordered in accordance with its parent model.

`column` : | The index of a column containing the string key to match
`out_filter` : | A pointer to an uninitialized DeeFilter struct. This struct will zeroed and configured with the filter parameters. [out]

### dee_filter_new_regex ()

    void                dee_filter_new_regex                (guint column,
                                                             GRegex *regex,
                                                             DeeFilter *out_filter);

Create a DeeFilter that only includes rows from the original model which match a regular expression on some string column. A DeeFilterModel created with this filter will be ordered in accordance with its parent model.

`column` : | The index of a column containing the string to match
`regex` : | The regular expression `column` must match. [transfer none]
`out_filter` : | A pointer to an uninitialized DeeFilter struct. This struct will zeroed and configured with the filter parameters. [out]

### dee_filter_new_sort ()

    void                dee_filter_new_sort                 (DeeCompareRowFunc cmp_row,
                                                             gpointer cmp_user_data,
                                                             GDestroyNotify cmp_destroy,
                                                             DeeFilter *out_filter);

Create a new DeeFilter sorting a model according to a DeeCompareRowFunc.

`cmp_row` : | A DeeCompareRowFunc to use for sorting. [scope notified]
`cmp_user_data` : | User data passed to `cmp_row`. [closure]
`cmp_destroy` : | The GDestroyNotify to call on `cmp_user_data` when disposing of the filter. [allow-none]
`out_filter` : | A pointer to an uninitialized DeeFilter struct. This struct will zeroed and configured with the filter parameters. [out]

### dee_filter_notify ()

    gboolean            dee_filter_notify                   (DeeFilter *filter,
                                                             DeeModelIter *orig_iter,
                                                             DeeModel *orig_model,
                                                             DeeFilterModel *filter_model);

Call the DeeFilterMapNotify function of a DeeFilter. When using a DeeFilterModel you should not call this method yourself.

`filter` : | The filter to apply
`orig_iter` : | The DeeModelIter added to `orig_model`
`orig_model` : | The model that is being filtered
`filter_model` : | The DeeFilterModel that holds the filtered subset of `orig_model`
Returns : | The return value from the DeeFilterMapNotify. That is; `TRUE` if `orig_iter` was added to `filter_model`