[gnome-software: 11/24] gs-app-query: Add a filter-func property




commit d91a35ebfc17285c16eee3b08c525c5ea5117141
Author: Philip Withnall <pwithnall endlessos org>
Date:   Wed Apr 13 22:42:09 2022 +0100

    gs-app-query: Add a filter-func property
    
    This will allow callers to provide their own filtering function, to be
    executed at the same time as other filters while listing apps, before
    sorting and capping the number of results.
    
    It’s not possible for callers to do this currently; they can only filter
    results after sorting and capping have already been done.
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>
    
    Helps: #1472

 lib/gs-app-query.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/gs-app-query.h |   2 +
 2 files changed, 115 insertions(+)
---
diff --git a/lib/gs-app-query.c b/lib/gs-app-query.c
index cb26bbb16..4025d2a77 100644
--- a/lib/gs-app-query.c
+++ b/lib/gs-app-query.c
@@ -32,6 +32,13 @@
  * #GsPluginJobRefine). `max-results` and `dedupe-flags` are used to limit the
  * set of results.
  *
+ * Results must always be processed in this order:
+ *  - Filtering using #GsAppQuery:filter-func (and any other custom filter
+ *    functions the query executor provides).
+ *  - Deduplication using #GsAppQuery:dedupe-flags.
+ *  - Sorting using #GsAppQuery:sort-func.
+ *  - Truncating result list length to #GsAppQuery:max-results.
+ *
  * Since: 43
  */
 
@@ -59,6 +66,10 @@ struct _GsAppQuery
        gpointer sort_user_data;
        GDestroyNotify sort_user_data_notify;
 
+       GsAppListFilterFunc filter_func;
+       gpointer filter_user_data;
+       GDestroyNotify filter_user_data_notify;
+
        /* This is guaranteed to either be %NULL, or a non-empty array */
        gchar **provides_files;  /* (owned) (nullable) (array zero-terminated=1) */
 };
@@ -72,6 +83,9 @@ typedef enum {
        PROP_SORT_FUNC,
        PROP_SORT_USER_DATA,
        PROP_SORT_USER_DATA_NOTIFY,
+       PROP_FILTER_FUNC,
+       PROP_FILTER_USER_DATA,
+       PROP_FILTER_USER_DATA_NOTIFY,
        PROP_PROVIDES_FILES,
 } GsAppQueryProperty;
 
@@ -104,6 +118,15 @@ gs_app_query_get_property (GObject    *object,
        case PROP_SORT_USER_DATA_NOTIFY:
                g_value_set_pointer (value, self->sort_user_data_notify);
                break;
+       case PROP_FILTER_FUNC:
+               g_value_set_pointer (value, self->filter_func);
+               break;
+       case PROP_FILTER_USER_DATA:
+               g_value_set_pointer (value, self->filter_user_data);
+               break;
+       case PROP_FILTER_USER_DATA_NOTIFY:
+               g_value_set_pointer (value, self->filter_user_data_notify);
+               break;
        case PROP_PROVIDES_FILES:
                g_value_set_boxed (value, self->provides_files);
                break;
@@ -152,6 +175,21 @@ gs_app_query_set_property (GObject      *object,
                g_assert (self->sort_user_data_notify == NULL);
                self->sort_user_data_notify = g_value_get_pointer (value);
                break;
+       case PROP_FILTER_FUNC:
+               /* Construct only. */
+               g_assert (self->filter_func == NULL);
+               self->filter_func = g_value_get_pointer (value);
+               break;
+       case PROP_FILTER_USER_DATA:
+               /* Construct only. */
+               g_assert (self->filter_user_data == NULL);
+               self->filter_user_data = g_value_get_pointer (value);
+               break;
+       case PROP_FILTER_USER_DATA_NOTIFY:
+               /* Construct only. */
+               g_assert (self->filter_user_data_notify == NULL);
+               self->filter_user_data_notify = g_value_get_pointer (value);
+               break;
        case PROP_PROVIDES_FILES:
                /* Construct only. */
                g_assert (self->provides_files == NULL);
@@ -178,6 +216,11 @@ gs_app_query_dispose (GObject *object)
                self->sort_user_data_notify = NULL;
        }
 
+       if (self->filter_user_data_notify != NULL && self->filter_user_data != NULL) {
+               self->filter_user_data_notify (g_steal_pointer (&self->filter_user_data));
+               self->filter_user_data_notify = NULL;
+       }
+
        G_OBJECT_CLASS (gs_app_query_parent_class)->dispose (object);
 }
 
@@ -290,6 +333,53 @@ gs_app_query_class_init (GsAppQueryClass *klass)
                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                      G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
 
+       /**
+        * GsAppQuery:filter-func: (nullable)
+        *
+        * A filter function to filter the returned apps.
+        *
+        * This must be of type #GsAppListFilterFunc.
+        *
+        * Since: 43
+        */
+       props[PROP_FILTER_FUNC] =
+               g_param_spec_pointer ("filter-func", "Filter Function",
+                                     "A filter function to filter the returned apps.",
+                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                                     G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+       /**
+        * GsAppQuery:filter-user-data: (nullable)
+        *
+        * User data to pass to #GsAppQuery:filter-func.
+        *
+        * Since: 43
+        */
+       props[PROP_FILTER_USER_DATA] =
+               g_param_spec_pointer ("filter-user-data", "Filter User Data",
+                                     "User data to pass to #GsAppQuery:filter-func.",
+                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                                     G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+       /**
+        * GsAppQuery:filter-user-data-notify: (nullable)
+        *
+        * A function to free #GsAppQuery:filter-user-data once it is no longer
+        * needed.
+        *
+        * This must be of type #GDestroyNotify.
+        *
+        * This will be called exactly once between being set and when the
+        * #GsAppQuery is finalized.
+        *
+        * Since: 43
+        */
+       props[PROP_FILTER_USER_DATA_NOTIFY] =
+               g_param_spec_pointer ("filter-user-data-notify", "Filter User Data Notify",
+                                     "A function to free #GsAppQuery:filter-user-data once it is no longer 
needed.",
+                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                                     G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
        /**
         * GsAppQuery:provides-files: (nullable)
         *
@@ -418,6 +508,29 @@ gs_app_query_get_sort_func (GsAppQuery *self,
        return self->sort_func;
 }
 
+/**
+ * gs_app_query_get_filter_func:
+ * @self: a #GsAppQuery
+ * @user_data_out: (out) (transfer none) (optional) (nullable): return location
+ *   for the #GsAppQuery:filter-user-data, or %NULL to ignore
+ *
+ * Get the value of #GsAppQuery:filter-func.
+ *
+ * Returns: (nullable): the filter function for the query
+ * Since: 43
+ */
+GsAppListFilterFunc
+gs_app_query_get_filter_func (GsAppQuery *self,
+                              gpointer   *user_data_out)
+{
+       g_return_val_if_fail (GS_IS_APP_QUERY (self), NULL);
+
+       if (user_data_out != NULL)
+               *user_data_out = self->filter_user_data;
+
+       return self->filter_func;
+}
+
 /**
  * gs_app_query_get_provides_files:
  * @self: a #GsAppQuery
diff --git a/lib/gs-app-query.h b/lib/gs-app-query.h
index b6adaf5e7..1dc9b143f 100644
--- a/lib/gs-app-query.h
+++ b/lib/gs-app-query.h
@@ -31,6 +31,8 @@ guint                  gs_app_query_get_max_results   (GsAppQuery *self);
 GsAppListFilterFlags    gs_app_query_get_dedupe_flags  (GsAppQuery *self);
 GsAppListSortFunc       gs_app_query_get_sort_func     (GsAppQuery *self,
                                                         gpointer   *user_data_out);
+GsAppListFilterFunc     gs_app_query_get_filter_func   (GsAppQuery *self,
+                                                        gpointer   *user_data_out);
 
 const gchar * const    *gs_app_query_get_provides_files (GsAppQuery *self);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]