176 lines
5.0 KiB
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;
|
|
}
|
|
}
|