[gimp] app: turn GimpFilteredContainer into a general purpose filter
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: turn GimpFilteredContainer into a general purpose filter
- Date: Tue, 22 Mar 2011 22:42:22 +0000 (UTC)
commit f3a99ed8f7311818f0ad46832e9ff1a7172c2362
Author: Michael Natterer <mitch gimp org>
Date: Tue Mar 22 23:41:42 2011 +0100
app: turn GimpFilteredContainer into a general purpose filter
app/core/gimpfilteredcontainer.c | 478 ++++++++------------------------------
app/core/gimpfilteredcontainer.h | 28 +--
2 files changed, 103 insertions(+), 403 deletions(-)
---
diff --git a/app/core/gimpfilteredcontainer.c b/app/core/gimpfilteredcontainer.c
index db6ddaf..54d731b 100644
--- a/app/core/gimpfilteredcontainer.c
+++ b/app/core/gimpfilteredcontainer.c
@@ -1,9 +1,9 @@
-#if 0
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* gimpfilteredcontainer.c
* Copyright (C) 2008 Aurimas Juška <aurisj svn gnome org>
+ * 2011 Michael Natterer <mitch 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
@@ -25,108 +25,56 @@
#include "core-types.h"
-#include "gimp.h"
-#include "gimpmarshal.h"
-#include "gimptag.h"
-#include "gimptagged.h"
#include "gimpfilteredcontainer.h"
enum
{
- TAG_COUNT_CHANGED,
- LAST_SIGNAL
-};
-
-enum
-{
PROP_0,
- PROP_SRC_CONTAINER
+ PROP_SRC_CONTAINER,
+ PROP_FILTER_FUNC,
+ PROP_FILTER_DATA
};
-typedef struct _MatchParams
-{
- GimpFilteredContainer *filtered_container;
- GList *items_to_add;
- GList *items_to_remove;
-} MatchParams;
-
-
-static void gimp_filtered_container_constructed (GObject *object);
-static void gimp_filtered_container_dispose (GObject *object);
-static void gimp_filtered_container_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_filtered_container_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static gint64 gimp_filtered_container_get_memsize (GimpObject *object,
- gint64 *gui_size);
-
-static gboolean gimp_filtered_container_object_matches (GimpFilteredContainer *filtered_container,
- GimpObject *object);
-
-static void gimp_filtered_container_filter (GimpFilteredContainer *filtered_container);
-
-static void gimp_filtered_container_src_add (GimpContainer *src_container,
- GimpObject *obj,
- GimpFilteredContainer *filtered_container);
-static void gimp_filtered_container_src_remove (GimpContainer *src_container,
- GimpObject *obj,
- GimpFilteredContainer *filtered_container);
-static void gimp_filtered_container_src_freeze (GimpContainer *src_container,
- GimpFilteredContainer *filtered_container);
-static void gimp_filtered_container_src_thaw (GimpContainer *src_container,
- GimpFilteredContainer *filtered_container);
-static void gimp_filtered_container_tag_added (GimpTagged *tagged,
- GimpTag *tag,
- GimpFilteredContainer *filtered_container);
-static void gimp_filtered_container_tag_removed (GimpTagged *tagged,
- GimpTag *tag,
- GimpFilteredContainer *filtered_container);
-static void gimp_filtered_container_tagged_item_added (GimpTagged *tagged,
- GimpFilteredContainer *filtered_container);
-static void gimp_filtered_container_tagged_item_removed(GimpTagged *tagged,
- GimpFilteredContainer *filtered_container);
-static void gimp_filtered_container_tag_count_changed (GimpFilteredContainer *filtered_container,
- gint tag_count);
+static void gimp_filtered_container_constructed (GObject *object);
+static void gimp_filtered_container_dispose (GObject *object);
+static void gimp_filtered_container_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_filtered_container_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_filtered_container_filter (GimpFilteredContainer *filtered_container);
+static void gimp_filtered_container_src_add (GimpContainer *src_container,
+ GimpObject *obj,
+ GimpFilteredContainer *filtered_container);
+static void gimp_filtered_container_src_remove (GimpContainer *src_container,
+ GimpObject *obj,
+ GimpFilteredContainer *filtered_container);
+static void gimp_filtered_container_src_freeze (GimpContainer *src_container,
+ GimpFilteredContainer *filtered_container);
+static void gimp_filtered_container_src_thaw (GimpContainer *src_container,
+ GimpFilteredContainer *filtered_container);
G_DEFINE_TYPE (GimpFilteredContainer, gimp_filtered_container, GIMP_TYPE_LIST)
#define parent_class gimp_filtered_container_parent_class
-static guint gimp_filtered_container_signals[LAST_SIGNAL] = { 0, };
-
static void
gimp_filtered_container_class_init (GimpFilteredContainerClass *klass)
{
- GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
- GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
-
- g_object_class->constructed = gimp_filtered_container_constructed;
- g_object_class->dispose = gimp_filtered_container_dispose;
- g_object_class->set_property = gimp_filtered_container_set_property;
- g_object_class->get_property = gimp_filtered_container_get_property;
-
- gimp_object_class->get_memsize = gimp_filtered_container_get_memsize;
-
- klass->tag_count_changed = gimp_filtered_container_tag_count_changed;
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
- gimp_filtered_container_signals[TAG_COUNT_CHANGED] =
- g_signal_new ("tag-count-changed",
- GIMP_TYPE_FILTERED_CONTAINER,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GimpFilteredContainerClass, tag_count_changed),
- NULL, NULL,
- gimp_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
+ g_object_class->constructed = gimp_filtered_container_constructed;
+ g_object_class->dispose = gimp_filtered_container_dispose;
+ g_object_class->set_property = gimp_filtered_container_set_property;
+ g_object_class->get_property = gimp_filtered_container_get_property;
g_object_class_install_property (g_object_class, PROP_SRC_CONTAINER,
g_param_spec_object ("src-container",
@@ -134,15 +82,23 @@ gimp_filtered_container_class_init (GimpFilteredContainerClass *klass)
GIMP_TYPE_CONTAINER,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (g_object_class, PROP_FILTER_FUNC,
+ g_param_spec_pointer ("filter-func",
+ NULL, NULL,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (g_object_class, PROP_FILTER_DATA,
+ g_param_spec_pointer ("filter-data",
+ NULL, NULL,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
}
static void
gimp_filtered_container_init (GimpFilteredContainer *filtered_container)
{
- filtered_container->src_container = NULL;
- filtered_container->filter = NULL;
- filtered_container->tag_ref_counts = NULL;
- filtered_container->tag_count = 0;
}
static void
@@ -153,14 +109,11 @@ gimp_filtered_container_constructed (GObject *object)
if (G_OBJECT_CLASS (parent_class)->constructed)
G_OBJECT_CLASS (parent_class)->constructed (object);
- filtered_container->tag_ref_counts =
- g_hash_table_new ((GHashFunc) gimp_tag_get_hash,
- (GEqualFunc) gimp_tag_equals);
+ g_assert (GIMP_IS_CONTAINER (filtered_container->src_container));
+ g_assert (filtered_container->filter_func != NULL);
- gimp_container_foreach (filtered_container->src_container,
- (GFunc) gimp_filtered_container_tagged_item_added,
- filtered_container);
- gimp_filtered_container_filter (filtered_container);
+ if (! gimp_container_frozen (filtered_container->src_container))
+ gimp_filtered_container_filter (filtered_container);
}
static void
@@ -168,12 +121,6 @@ gimp_filtered_container_dispose (GObject *object)
{
GimpFilteredContainer *filtered_container = GIMP_FILTERED_CONTAINER (object);
- if (filtered_container->tag_ref_counts)
- {
- g_hash_table_unref (filtered_container->tag_ref_counts);
- filtered_container->tag_ref_counts = NULL;
- }
-
if (filtered_container->src_container)
{
g_signal_handlers_disconnect_by_func (filtered_container->src_container,
@@ -223,6 +170,14 @@ gimp_filtered_container_set_property (GObject *object,
filtered_container);
break;
+ case PROP_FILTER_FUNC:
+ filtered_container->filter_func = g_value_get_pointer (value);
+ break;
+
+ case PROP_FILTER_DATA:
+ filtered_container->filter_data = g_value_get_pointer (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -243,24 +198,20 @@ gimp_filtered_container_get_property (GObject *object,
g_value_set_object (value, filtered_container->src_container);
break;
+ case PROP_FILTER_FUNC:
+ g_value_set_pointer (value, filtered_container->filter_func);
+ break;
+
+ case PROP_FILTER_DATA:
+ g_value_set_pointer (value, filtered_container->filter_data);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
-static gint64
-gimp_filtered_container_get_memsize (GimpObject *object,
- gint64 *gui_size)
-{
- gint64 memsize = 0;
-
- /* FIXME take members into account */
-
- return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
- gui_size);
-}
-
/**
* gimp_filtered_container_new:
* @src_container: container to be filtered.
@@ -273,164 +224,47 @@ gimp_filtered_container_get_memsize (GimpObject *object,
* Return value: a new #GimpFilteredContainer object.
**/
GimpContainer *
-gimp_filtered_container_new (GimpContainer *src_container,
- GCompareFunc sort_func)
+gimp_filtered_container_new (GimpContainer *src_container,
+ GimpObjectFilterFunc filter_func,
+ gpointer filter_data)
{
- GimpFilteredContainer *filtered_container;
- GType children_type;
+ GType children_type;
+ GCompareFunc sort_func;
- g_return_val_if_fail (GIMP_IS_CONTAINER (src_container), NULL);
+ g_return_val_if_fail (GIMP_IS_LIST (src_container), NULL);
+ g_return_val_if_fail (filter_func != NULL, NULL);
children_type = gimp_container_get_children_type (src_container);
-
- filtered_container = g_object_new (GIMP_TYPE_FILTERED_CONTAINER,
- "sort-func", sort_func,
- "children-type", children_type,
- "policy", GIMP_CONTAINER_POLICY_WEAK,
- "unique-names", FALSE,
- "src-container", src_container,
- NULL);
-
- return GIMP_CONTAINER (filtered_container);
-}
-
-/**
- * gimp_filtered_container_set_filter:
- * @filtered_container: a #GimpFilteredContainer object.
- * @tags: list of #GimpTag objects.
- *
- * Sets list of tags to be used for filtering. Only objects which have all of
- * the tags assigned match filtering criteria.
- **/
-void
-gimp_filtered_container_set_filter (GimpFilteredContainer *filtered_container,
- GList *tags)
-{
- g_return_if_fail (GIMP_IS_FILTERED_CONTAINER (filtered_container));
-
- filtered_container->filter = tags;
-
- gimp_container_freeze (GIMP_CONTAINER (filtered_container));
- gimp_filtered_container_filter (filtered_container);
- gimp_container_thaw (GIMP_CONTAINER (filtered_container));
-}
-
-/**
- * gimp_filtered_container_get_filter:
- * @filtered_container: a #GimpFilteredContainer object.
- *
- * Returns current tag filter. Tag filter is a list of GimpTag objects, which
- * must be contained by each object matching filter criteria.
- *
- * Return value: a list of GimpTag objects used as filter. This value should
- * not be modified or freed.
- **/
-const GList *
-gimp_filtered_container_get_filter (GimpFilteredContainer *filtered_container)
-{
- g_return_val_if_fail (GIMP_IS_FILTERED_CONTAINER (filtered_container), NULL);
-
- return filtered_container->filter;
-}
-
-static gboolean
-gimp_filtered_container_object_matches (GimpFilteredContainer *filtered_container,
- GimpObject *object)
-{
- GList *filter_tag;
- GList *object_tag;
-
- filter_tag = filtered_container->filter;
- while (filter_tag)
- {
- if (! filter_tag->data)
- {
- /* invalid tag - does not match */
- return FALSE;
- }
-
- object_tag = gimp_tagged_get_tags (GIMP_TAGGED (object));
- while (object_tag)
- {
- if (gimp_tag_equals (GIMP_TAG (object_tag->data),
- GIMP_TAG (filter_tag->data)))
- {
- /* found match for the tag */
- break;
- }
- object_tag = g_list_next (object_tag);
- }
-
- if (! object_tag)
- {
- /* match for the tag was not found.
- * since query is of type AND, it whole fails. */
- return FALSE;
- }
-
- filter_tag = g_list_next (filter_tag);
- }
-
- return TRUE;
-}
-
-static void
-gimp_filtered_container_check_needs_remove (GimpObject *object,
- MatchParams *match_params)
-{
- if (! gimp_filtered_container_object_matches (match_params->filtered_container,
- object))
- {
- match_params->items_to_remove = g_list_prepend (match_params->items_to_remove,
- object);
- }
-}
-
-static void
-gimp_filtered_container_check_needs_add (GimpObject *object,
- MatchParams *match_params)
-{
- if (gimp_filtered_container_object_matches (match_params->filtered_container,
- object) &&
- ! gimp_container_have (GIMP_CONTAINER (match_params->filtered_container),
- object))
- {
- match_params->items_to_add = g_list_prepend (match_params->items_to_add,
- object);
- }
+ sort_func = GIMP_LIST (src_container)->sort_func;
+
+ return g_object_new (GIMP_TYPE_FILTERED_CONTAINER,
+ "sort-func", sort_func,
+ "children-type", children_type,
+ "policy", GIMP_CONTAINER_POLICY_WEAK,
+ "unique-names", FALSE,
+ "src-container", src_container,
+ "filter-func", filter_func,
+ "filter-data", filter_data,
+ NULL);
}
static void
gimp_filtered_container_filter (GimpFilteredContainer *filtered_container)
{
- MatchParams match_params;
- GList *list;
-
- match_params.filtered_container = filtered_container;
- match_params.items_to_add = NULL;
- match_params.items_to_remove = NULL;
-
- gimp_container_foreach (GIMP_CONTAINER (filtered_container),
- (GFunc) gimp_filtered_container_check_needs_remove,
- &match_params);
- gimp_container_foreach (GIMP_CONTAINER (filtered_container->src_container),
- (GFunc) gimp_filtered_container_check_needs_add,
- &match_params);
+ GList *list;
- for (list = match_params.items_to_remove; list; list = g_list_next (list))
+ for (list = GIMP_LIST (filtered_container->src_container)->list;
+ list;
+ list = g_list_next (list))
{
- gimp_container_remove (GIMP_CONTAINER (filtered_container),
- GIMP_OBJECT (list->data));
- }
+ GimpObject *child = list->data;
- for (list = match_params.items_to_add; list; list = g_list_next (list))
- {
- gimp_container_add (GIMP_CONTAINER (filtered_container),
- GIMP_OBJECT (list->data));
+ if (filtered_container->filter_func (child,
+ filtered_container->filter_data))
+ {
+ gimp_container_add (GIMP_CONTAINER (filtered_container), child);
+ }
}
-
- g_list_free (match_params.items_to_add);
- g_list_free (match_params.items_to_remove);
}
static void
@@ -438,10 +272,8 @@ gimp_filtered_container_src_add (GimpContainer *src_container,
GimpObject *obj,
GimpFilteredContainer *filtered_container)
{
- gimp_filtered_container_tagged_item_added (GIMP_TAGGED (obj),
- filtered_container);
-
- if (! gimp_container_frozen (src_container))
+ if (! gimp_container_frozen (src_container) &&
+ filtered_container->filter_func (obj, filtered_container->filter_data))
{
gimp_container_add (GIMP_CONTAINER (filtered_container), obj);
}
@@ -452,11 +284,8 @@ gimp_filtered_container_src_remove (GimpContainer *src_container,
GimpObject *obj,
GimpFilteredContainer *filtered_container)
{
- gimp_filtered_container_tagged_item_removed (GIMP_TAGGED (obj),
- filtered_container);
-
if (! gimp_container_frozen (src_container) &&
- gimp_container_have (GIMP_CONTAINER (filtered_container), obj))
+ filtered_container->filter_func (obj, filtered_container->filter_data))
{
gimp_container_remove (GIMP_CONTAINER (filtered_container), obj);
}
@@ -477,122 +306,3 @@ gimp_filtered_container_src_thaw (GimpContainer *src_container,
gimp_filtered_container_filter (filtered_container);
gimp_container_thaw (GIMP_CONTAINER (filtered_container));
}
-
-static void
-gimp_filtered_container_tagged_item_added (GimpTagged *tagged,
- GimpFilteredContainer *filtered_container)
-{
- GList *list;
-
- for (list = gimp_tagged_get_tags (tagged); list; list = g_list_next (list))
- {
- gimp_filtered_container_tag_added (tagged,
- list->data,
- filtered_container);
- }
-
- g_signal_connect (tagged, "tag-added",
- G_CALLBACK (gimp_filtered_container_tag_added),
- filtered_container);
- g_signal_connect (tagged, "tag-removed",
- G_CALLBACK (gimp_filtered_container_tag_removed),
- filtered_container);
-}
-
-static void
-gimp_filtered_container_tagged_item_removed (GimpTagged *tagged,
- GimpFilteredContainer *filtered_container)
-{
- GList *list;
-
- g_signal_handlers_disconnect_by_func (tagged,
- gimp_filtered_container_tag_added,
- filtered_container);
- g_signal_handlers_disconnect_by_func (tagged,
- gimp_filtered_container_tag_removed,
- filtered_container);
-
- for (list = gimp_tagged_get_tags (tagged); list; list = g_list_next (list))
- {
- gimp_filtered_container_tag_removed (tagged,
- GIMP_TAG (list->data),
- filtered_container);
- }
-
-}
-
-static void
-gimp_filtered_container_tag_added (GimpTagged *tagged,
- GimpTag *tag,
- GimpFilteredContainer *filtered_container)
-{
- gint ref_count;
-
- ref_count = GPOINTER_TO_INT (g_hash_table_lookup (filtered_container->tag_ref_counts,
- tag));
- ref_count++;
- g_hash_table_insert (filtered_container->tag_ref_counts,
- tag, GINT_TO_POINTER (ref_count));
- if (ref_count == 1)
- {
- filtered_container->tag_count++;
- g_signal_emit (filtered_container,
- gimp_filtered_container_signals[TAG_COUNT_CHANGED], 0,
- filtered_container->tag_count);
- }
-}
-
-static void
-gimp_filtered_container_tag_removed (GimpTagged *tagged,
- GimpTag *tag,
- GimpFilteredContainer *filtered_container)
-{
- gint ref_count;
-
- ref_count = GPOINTER_TO_INT (g_hash_table_lookup (filtered_container->tag_ref_counts,
- tag));
- ref_count--;
-
- if (ref_count > 0)
- {
- g_hash_table_insert (filtered_container->tag_ref_counts,
- tag, GINT_TO_POINTER (ref_count));
- }
- else
- {
- if (g_hash_table_remove (filtered_container->tag_ref_counts, tag))
- {
- filtered_container->tag_count--;
- g_signal_emit (filtered_container,
- gimp_filtered_container_signals[TAG_COUNT_CHANGED], 0,
- filtered_container->tag_count);
- }
- }
-}
-
-static void
-gimp_filtered_container_tag_count_changed (GimpFilteredContainer *container,
- gint tag_count)
-{
-}
-
-/**
- * gimp_filtered_container_get_tag_count:
- * @container: a #GimpFilteredContainer object.
- *
- * Get number of distinct tags that are currently assigned to all
- * objects in the container. The count is independent of currently
- * used filter, it is provided for all available objects (ie. empty
- * filter).
- *
- * Return value: number of distinct tags assigned to all objects in the
- * container.
- **/
-gint
-gimp_filtered_container_get_tag_count (GimpFilteredContainer *container)
-{
- g_return_val_if_fail (GIMP_IS_FILTERED_CONTAINER (container), 0);
-
- return container->tag_count;
-}
-#endif
diff --git a/app/core/gimpfilteredcontainer.h b/app/core/gimpfilteredcontainer.h
index d45013e..3264ab1 100644
--- a/app/core/gimpfilteredcontainer.h
+++ b/app/core/gimpfilteredcontainer.h
@@ -1,9 +1,9 @@
-#if 0
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* gimpfilteredcontainer.h
* Copyright (C) 2008 Aurimas Juška <aurisj svn gnome org>
+ * 2011 Michael Natterer <mitch 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
@@ -38,34 +38,24 @@ typedef struct _GimpFilteredContainerClass GimpFilteredContainerClass;
struct _GimpFilteredContainer
{
- GimpList parent_instance;
+ GimpList parent_instance;
- GimpContainer *src_container;
- GList *filter;
- GHashTable *tag_ref_counts;
- gint tag_count;
+ GimpContainer *src_container;
+ GimpObjectFilterFunc filter_func;
+ gpointer filter_data;
};
struct _GimpFilteredContainerClass
{
GimpContainerClass parent_class;
-
- void (* tag_count_changed) (GimpFilteredContainer *container,
- gint count);
};
-GType gimp_filtered_container_get_type (void) G_GNUC_CONST;
-
-GimpContainer * gimp_filtered_container_new (GimpContainer *src_container,
- GCompareFunc sort_func);
-
-void gimp_filtered_container_set_filter (GimpFilteredContainer *filtered_container,
- GList *tags);
-const GList * gimp_filtered_container_get_filter (GimpFilteredContainer *filtered_container);
+GType gimp_filtered_container_get_type (void) G_GNUC_CONST;
-gint gimp_filtered_container_get_tag_count (GimpFilteredContainer *container);
+GimpContainer * gimp_filtered_container_new (GimpContainer *src_container,
+ GimpObjectFilterFunc filter_func,
+ gpointer filter_data);
#endif /* __GIMP_FILTERED_CONTAINER_H__ */
-#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]