PIKApp/app/core/pikacontainer-filter.c

176 lines
5.0 KiB
C

/* 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 <sven@gimp.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <glib-object.h>
#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;
}
}