[gimp] app: fix GimpTaggedContainer to work with multiple views
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: fix GimpTaggedContainer to work with multiple views
- Date: Wed, 23 Mar 2011 20:29:51 +0000 (UTC)
commit b49fdd4fd0276b511f36ef3d8329482f52dac6dd
Author: Michael Natterer <mitch gimp org>
Date: Wed Mar 23 20:57:04 2011 +0100
app: fix GimpTaggedContainer to work with multiple views
Refactor the container so it dynamically inserts/removes items when
their tags change, rather than implicitly relying on the filter logic
that was only triggered when the view called set_filter(). Before,
another view on the same original container would not update
automatically.
app/core/gimptaggedcontainer.c | 266 ++++++++++++++++++----------------------
1 files changed, 119 insertions(+), 147 deletions(-)
---
diff --git a/app/core/gimptaggedcontainer.c b/app/core/gimptaggedcontainer.c
index cc9c26d..77a20d9 100644
--- a/app/core/gimptaggedcontainer.c
+++ b/app/core/gimptaggedcontainer.c
@@ -44,14 +44,6 @@ enum
};
-typedef struct _MatchParams
-{
- GimpTaggedContainer *tagged_container;
- GList *items_to_add;
- GList *items_to_remove;
-} MatchParams;
-
-
static void gimp_tagged_container_constructed (GObject *object);
static void gimp_tagged_container_dispose (GObject *object);
static void gimp_tagged_container_set_property (GObject *object,
@@ -69,13 +61,11 @@ static gint64 gimp_tagged_container_get_memsize (GimpObject *
static gboolean gimp_tagged_container_object_matches (GimpTaggedContainer *tagged_container,
GimpObject *object);
-static void gimp_tagged_container_filter (GimpTaggedContainer *tagged_container);
-
static void gimp_tagged_container_src_add (GimpContainer *src_container,
- GimpObject *obj,
+ GimpObject *object,
GimpTaggedContainer *tagged_container);
static void gimp_tagged_container_src_remove (GimpContainer *src_container,
- GimpObject *obj,
+ GimpObject *object,
GimpTaggedContainer *tagged_container);
static void gimp_tagged_container_src_freeze (GimpContainer *src_container,
GimpTaggedContainer *tagged_container);
@@ -87,10 +77,10 @@ static void gimp_tagged_container_tag_added (GimpTagged *
static void gimp_tagged_container_tag_removed (GimpTagged *tagged,
GimpTag *tag,
GimpTaggedContainer *tagged_container);
-static void gimp_tagged_container_tagged_item_added (GimpTagged *tagged,
- GimpTaggedContainer *tagged_container);
-static void gimp_tagged_container_tagged_item_removed(GimpTagged *tagged,
- GimpTaggedContainer *tagged_container);
+static void gimp_tagged_container_ref_tag (GimpTaggedContainer *tagged_container,
+ GimpTag *tag);
+static void gimp_tagged_container_unref_tag (GimpTaggedContainer *tagged_container,
+ GimpTag *tag);
static void gimp_tagged_container_tag_count_changed (GimpTaggedContainer *tagged_container,
gint tag_count);
@@ -138,10 +128,6 @@ gimp_tagged_container_class_init (GimpTaggedContainerClass *klass)
static void
gimp_tagged_container_init (GimpTaggedContainer *tagged_container)
{
- tagged_container->src_container = NULL;
- tagged_container->filter = NULL;
- tagged_container->tag_ref_counts = NULL;
- tagged_container->tag_count = 0;
}
static void
@@ -156,10 +142,19 @@ gimp_tagged_container_constructed (GObject *object)
g_hash_table_new ((GHashFunc) gimp_tag_get_hash,
(GEqualFunc) gimp_tag_equals);
- gimp_container_foreach (tagged_container->src_container,
- (GFunc) gimp_tagged_container_tagged_item_added,
- tagged_container);
- gimp_tagged_container_filter (tagged_container);
+ if (! gimp_container_frozen (tagged_container->src_container))
+ {
+ GList *list;
+
+ for (list = GIMP_LIST (tagged_container->src_container)->list;
+ list;
+ list = g_list_next (list))
+ {
+ gimp_tagged_container_src_add (tagged_container->src_container,
+ list->data,
+ tagged_container);
+ }
+ }
}
static void
@@ -307,11 +302,13 @@ gimp_tagged_container_set_filter (GimpTaggedContainer *tagged_container,
{
g_return_if_fail (GIMP_IS_TAGGED_CONTAINER (tagged_container));
+ gimp_tagged_container_src_freeze (tagged_container->src_container,
+ tagged_container);
+
tagged_container->filter = tags;
- gimp_container_freeze (GIMP_CONTAINER (tagged_container));
- gimp_tagged_container_filter (tagged_container);
- gimp_container_thaw (GIMP_CONTAINER (tagged_container));
+ gimp_tagged_container_src_thaw (tagged_container->src_container,
+ tagged_container);
}
/**
@@ -336,128 +333,101 @@ static gboolean
gimp_tagged_container_object_matches (GimpTaggedContainer *tagged_container,
GimpObject *object)
{
- GList *filter_tag;
- GList *object_tag;
+ GList *filter_tags;
- filter_tag = tagged_container->filter;
- while (filter_tag)
+ for (filter_tags = tagged_container->filter;
+ filter_tags;
+ filter_tags = g_list_next (filter_tags))
{
- if (! filter_tag->data)
+ GList *object_tags;
+
+ if (! filter_tags->data)
{
/* invalid tag - does not match */
return FALSE;
}
- object_tag = gimp_tagged_get_tags (GIMP_TAGGED (object));
- while (object_tag)
+ for (object_tags = gimp_tagged_get_tags (GIMP_TAGGED (object));
+ object_tags;
+ object_tags = g_list_next (object_tags))
{
- if (gimp_tag_equals (GIMP_TAG (object_tag->data),
- GIMP_TAG (filter_tag->data)))
+ if (gimp_tag_equals (object_tags->data,
+ filter_tags->data))
{
/* found match for the tag */
break;
}
- object_tag = g_list_next (object_tag);
}
- if (! object_tag)
+ if (! object_tags)
{
/* match for the tag was not found.
- * since query is of type AND, it whole fails. */
+ * since query is of type AND, it whole fails.
+ */
return FALSE;
}
-
- filter_tag = g_list_next (filter_tag);
}
return TRUE;
}
static void
-gimp_tagged_container_check_needs_remove (GimpObject *object,
- MatchParams *match_params)
-{
- if (! gimp_tagged_container_object_matches (match_params->tagged_container,
- object))
- {
- match_params->items_to_remove = g_list_prepend (match_params->items_to_remove,
- object);
- }
-}
-
-static void
-gimp_tagged_container_check_needs_add (GimpObject *object,
- MatchParams *match_params)
+gimp_tagged_container_src_add (GimpContainer *src_container,
+ GimpObject *object,
+ GimpTaggedContainer *tagged_container)
{
- if (gimp_tagged_container_object_matches (match_params->tagged_container,
- object) &&
- ! gimp_container_have (GIMP_CONTAINER (match_params->tagged_container),
- object))
+ if (! gimp_container_frozen (src_container))
{
- match_params->items_to_add = g_list_prepend (match_params->items_to_add,
- object);
- }
-}
+ GList *list;
-static void
-gimp_tagged_container_filter (GimpTaggedContainer *tagged_container)
-{
- MatchParams match_params;
- GList *list;
-
- match_params.tagged_container = tagged_container;
- match_params.items_to_add = NULL;
- match_params.items_to_remove = NULL;
-
- gimp_container_foreach (GIMP_CONTAINER (tagged_container),
- (GFunc) gimp_tagged_container_check_needs_remove,
- &match_params);
- gimp_container_foreach (GIMP_CONTAINER (tagged_container->src_container),
- (GFunc) gimp_tagged_container_check_needs_add,
- &match_params);
+ for (list = gimp_tagged_get_tags (GIMP_TAGGED (object));
+ list;
+ list = g_list_next (list))
+ {
+ gimp_tagged_container_ref_tag (tagged_container, list->data);
+ }
- for (list = match_params.items_to_remove; list; list = g_list_next (list))
- {
- gimp_container_remove (GIMP_CONTAINER (tagged_container),
- GIMP_OBJECT (list->data));
- }
+ g_signal_connect (object, "tag-added",
+ G_CALLBACK (gimp_tagged_container_tag_added),
+ tagged_container);
+ g_signal_connect (object, "tag-removed",
+ G_CALLBACK (gimp_tagged_container_tag_removed),
+ tagged_container);
- for (list = match_params.items_to_add; list; list = g_list_next (list))
- {
- gimp_container_add (GIMP_CONTAINER (tagged_container),
- GIMP_OBJECT (list->data));
+ if (gimp_tagged_container_object_matches (tagged_container, object))
+ {
+ gimp_container_add (GIMP_CONTAINER (tagged_container), object);
+ }
}
-
- g_list_free (match_params.items_to_add);
- g_list_free (match_params.items_to_remove);
}
static void
-gimp_tagged_container_src_add (GimpContainer *src_container,
- GimpObject *obj,
- GimpTaggedContainer *tagged_container)
+gimp_tagged_container_src_remove (GimpContainer *src_container,
+ GimpObject *object,
+ GimpTaggedContainer *tagged_container)
{
- gimp_tagged_container_tagged_item_added (GIMP_TAGGED (obj),
- tagged_container);
-
if (! gimp_container_frozen (src_container))
{
- gimp_container_add (GIMP_CONTAINER (tagged_container), obj);
- }
-}
+ GList *list;
-static void
-gimp_tagged_container_src_remove (GimpContainer *src_container,
- GimpObject *obj,
- GimpTaggedContainer *tagged_container)
-{
- gimp_tagged_container_tagged_item_removed (GIMP_TAGGED (obj),
- tagged_container);
+ g_signal_handlers_disconnect_by_func (object,
+ gimp_tagged_container_tag_added,
+ tagged_container);
+ g_signal_handlers_disconnect_by_func (object,
+ gimp_tagged_container_tag_removed,
+ tagged_container);
- if (! gimp_container_frozen (src_container) &&
- gimp_container_have (GIMP_CONTAINER (tagged_container), obj))
- {
- gimp_container_remove (GIMP_CONTAINER (tagged_container), obj);
+ for (list = gimp_tagged_get_tags (GIMP_TAGGED (object));
+ list;
+ list = g_list_next (list))
+ {
+ gimp_tagged_container_unref_tag (tagged_container, list->data);
+ }
+
+ if (gimp_tagged_container_object_matches (tagged_container, object))
+ {
+ gimp_container_remove (GIMP_CONTAINER (tagged_container), object);
+ }
}
}
@@ -466,64 +436,67 @@ gimp_tagged_container_src_freeze (GimpContainer *src_container,
GimpTaggedContainer *tagged_container)
{
gimp_container_freeze (GIMP_CONTAINER (tagged_container));
+
gimp_container_clear (GIMP_CONTAINER (tagged_container));
+ g_hash_table_remove_all (tagged_container->tag_ref_counts);
+ tagged_container->tag_count = 0;
}
static void
gimp_tagged_container_src_thaw (GimpContainer *src_container,
GimpTaggedContainer *tagged_container)
{
- gimp_tagged_container_filter (tagged_container);
+ GList *list;
+
+ for (list = GIMP_LIST (tagged_container->src_container)->list;
+ list;
+ list = g_list_next (list))
+ {
+ gimp_tagged_container_src_add (tagged_container->src_container,
+ list->data,
+ tagged_container);
+ }
+
gimp_container_thaw (GIMP_CONTAINER (tagged_container));
}
static void
-gimp_tagged_container_tagged_item_added (GimpTagged *tagged,
- GimpTaggedContainer *tagged_container)
+gimp_tagged_container_tag_added (GimpTagged *tagged,
+ GimpTag *tag,
+ GimpTaggedContainer *tagged_container)
{
- GList *list;
+ gimp_tagged_container_ref_tag (tagged_container, tag);
- for (list = gimp_tagged_get_tags (tagged); list; list = g_list_next (list))
+ if (gimp_tagged_container_object_matches (tagged_container,
+ GIMP_OBJECT (tagged)) &&
+ ! gimp_container_have (GIMP_CONTAINER (tagged_container),
+ GIMP_OBJECT (tagged)))
{
- gimp_tagged_container_tag_added (tagged,
- list->data,
- tagged_container);
+ gimp_container_add (GIMP_CONTAINER (tagged_container),
+ GIMP_OBJECT (tagged));
}
-
- g_signal_connect (tagged, "tag-added",
- G_CALLBACK (gimp_tagged_container_tag_added),
- tagged_container);
- g_signal_connect (tagged, "tag-removed",
- G_CALLBACK (gimp_tagged_container_tag_removed),
- tagged_container);
}
static void
-gimp_tagged_container_tagged_item_removed (GimpTagged *tagged,
- GimpTaggedContainer *tagged_container)
+gimp_tagged_container_tag_removed (GimpTagged *tagged,
+ GimpTag *tag,
+ GimpTaggedContainer *tagged_container)
{
- GList *list;
-
- g_signal_handlers_disconnect_by_func (tagged,
- gimp_tagged_container_tag_added,
- tagged_container);
- g_signal_handlers_disconnect_by_func (tagged,
- gimp_tagged_container_tag_removed,
- tagged_container);
+ gimp_tagged_container_unref_tag (tagged_container, tag);
- for (list = gimp_tagged_get_tags (tagged); list; list = g_list_next (list))
+ if (! gimp_tagged_container_object_matches (tagged_container,
+ GIMP_OBJECT (tagged)) &&
+ gimp_container_have (GIMP_CONTAINER (tagged_container),
+ GIMP_OBJECT (tagged)))
{
- gimp_tagged_container_tag_removed (tagged,
- GIMP_TAG (list->data),
- tagged_container);
+ gimp_container_remove (GIMP_CONTAINER (tagged_container),
+ GIMP_OBJECT (tagged));
}
-
}
static void
-gimp_tagged_container_tag_added (GimpTagged *tagged,
- GimpTag *tag,
- GimpTaggedContainer *tagged_container)
+gimp_tagged_container_ref_tag (GimpTaggedContainer *tagged_container,
+ GimpTag *tag)
{
gint ref_count;
@@ -542,9 +515,8 @@ gimp_tagged_container_tag_added (GimpTagged *tagged,
}
static void
-gimp_tagged_container_tag_removed (GimpTagged *tagged,
- GimpTag *tag,
- GimpTaggedContainer *tagged_container)
+gimp_tagged_container_unref_tag (GimpTaggedContainer *tagged_container,
+ GimpTag *tag)
{
gint ref_count;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]