/* PIKA - Photo and Image Kooker Application * a rebranding of The GNU Image Manipulation Program (created with heckimp) * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio * * Original copyright, applying to most contents (license remains unchanged): * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis * * pikacontainer-filter.c * Copyright (C) 2003 Sven Neumann * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "config.h" #include #include #include "core-types.h" #include "pikacontainer.h" #include "pikacontainer-filter.h" #include "pikalist.h" typedef struct { PikaObjectFilterFunc filter; PikaContainer *container; gpointer user_data; } PikaContainerFilterContext; static void pika_container_filter_foreach_func (PikaObject *object, PikaContainerFilterContext *context) { if (context->filter (object, context->user_data)) pika_container_add (context->container, object); } /** * pika_container_filter: * @container: a #PikaContainer to filter * @filter: a #PikaObjectFilterFunc * @user_data: a pointer passed to @filter * * Calls the supplied @filter function on each object in @container. * A return value of %TRUE is interpreted as a match. * * Returns: a weak #PikaContainer filled with matching objects. **/ PikaContainer * pika_container_filter (PikaContainer *container, PikaObjectFilterFunc filter, gpointer user_data) { PikaContainer *result; PikaContainerFilterContext context; g_return_val_if_fail (PIKA_IS_CONTAINER (container), NULL); g_return_val_if_fail (filter != NULL, NULL); result = g_object_new (G_TYPE_FROM_INSTANCE (container), "children-type", pika_container_get_children_type (container), "policy", PIKA_CONTAINER_POLICY_WEAK, NULL); context.filter = filter; context.container = result; context.user_data = user_data; pika_container_foreach (container, (GFunc) pika_container_filter_foreach_func, &context); /* This is somewhat ugly, but it keeps lists in the same order. */ if (PIKA_IS_LIST (result)) pika_list_reverse (PIKA_LIST (result)); return result; } static gboolean pika_object_filter_by_name (PikaObject *object, const GRegex *regex) { return g_regex_match (regex, pika_object_get_name (object), 0, NULL); } /** * pika_container_filter_by_name: * @container: a #PikaContainer to filter * @regexp: a regular expression (as a %NULL-terminated string) * @error: error location to report errors or %NULL * * This function performs a case-insensitive regular expression search * on the names of the PikaObjects in @container. * * Returns: a weak #PikaContainer filled with matching objects. **/ PikaContainer * pika_container_filter_by_name (PikaContainer *container, const gchar *regexp, GError **error) { PikaContainer *result; GRegex *regex; g_return_val_if_fail (PIKA_IS_CONTAINER (container), NULL); g_return_val_if_fail (regexp != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); regex = g_regex_new (regexp, G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0, error); if (! regex) return NULL; result = pika_container_filter (container, (PikaObjectFilterFunc) pika_object_filter_by_name, regex); g_regex_unref (regex); return result; } gchar ** pika_container_get_filtered_name_array (PikaContainer *container, const gchar *regexp) { PikaContainer *weak; GError *error = NULL; g_return_val_if_fail (PIKA_IS_CONTAINER (container), NULL); if (regexp == NULL || strlen (regexp) == 0) return (pika_container_get_name_array (container)); weak = pika_container_filter_by_name (container, regexp, &error); if (weak) { gchar **retval = pika_container_get_name_array (weak); g_object_unref (weak); return retval; } else { g_warning ("%s", error->message); g_error_free (error); return NULL; } }