[Xfce4-commits] [apps/xfdashboard] 01/02: Move logic to handle mapping of actors for result items from search view to result container of each search provider handled by search view

noreply at xfce.org noreply at xfce.org
Sat Jan 9 09:23:14 CET 2016


This is an automated email from the git hooks/post-receive script.

nomad pushed a commit to branch master
in repository apps/xfdashboard.

commit ee8156fc055e1cd0d5a93d0ec48455434238bbcc
Author: Stephan Haller <nomad at froevel.de>
Date:   Sat Jan 9 09:08:56 2016 +0100

    Move logic to handle mapping of actors for result items from search view to result container of each search provider handled by search view
---
 xfdashboard/search-result-container.c |  406 ++++++++++++++++++++++++++++++---
 xfdashboard/search-result-container.h |    9 +-
 xfdashboard/search-view.c             |  331 +++------------------------
 3 files changed, 418 insertions(+), 328 deletions(-)

diff --git a/xfdashboard/search-result-container.c b/xfdashboard/search-result-container.c
index a4a1436..2788a3b 100644
--- a/xfdashboard/search-result-container.c
+++ b/xfdashboard/search-result-container.c
@@ -37,6 +37,9 @@
 #include "stylable.h"
 #include "dynamic-table-layout.h"
 #include "utils.h"
+#include "click-action.h"
+#include "drag-action.h"
+#include "marshal.h"
 
 /* Define this class in GObject system */
 G_DEFINE_TYPE(XfdashboardSearchResultContainer,
@@ -65,6 +68,9 @@ struct _XfdashboardSearchResultContainerPrivate
 
 	ClutterActor				*selectedItem;
 	guint						selectedItemDestroySignalID;
+
+	GHashTable					*mapping;
+	XfdashboardSearchResultSet	*lastResultSet;
 };
 
 /* Properties */
@@ -89,6 +95,7 @@ static GParamSpec* XfdashboardSearchResultContainerProperties[PROP_LAST]={ 0, };
 enum
 {
 	SIGNAL_ICON_CLICKED,
+	SIGNAL_ITEM_CLICKED,
 
 	SIGNAL_LAST
 };
@@ -237,6 +244,191 @@ static void _xfdashboard_search_result_container_update_title(XfdashboardSearchR
 		}
 }
 
+/* A result item actor is going to be destroyed */
+static void _xfdashboard_search_result_container_on_result_item_actor_destroyed(ClutterActor *inActor, gpointer inUserData)
+{
+	XfdashboardSearchResultContainer			*self;
+	XfdashboardSearchResultContainerPrivate		*priv;
+	GHashTableIter								iter;
+	GVariant									*key;
+	ClutterActor								*value;
+
+	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
+	g_return_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_CONTAINER(inUserData));
+
+	self=XFDASHBOARD_SEARCH_RESULT_CONTAINER(inUserData);
+	priv=self->priv;
+
+	/* First disconnect signal handlers from actor before modifying mapping hash table */
+	g_signal_handlers_disconnect_by_data(inActor, self);
+
+	/* Iterate through mapping and remove each key whose value matches actor
+	 * going to be destroyed and remove it from mapping hash table.
+	 */
+	g_hash_table_iter_init(&iter, priv->mapping);
+	while(g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&value))
+	{
+		/* If value of key iterated matches destroyed actor remove it from mapping */
+		if(value==inActor)
+		{
+			/* Take a reference on value (it is the destroyed actor) because removing
+			 * key from mapping causes unrefencing key and value.
+			 */
+			g_object_ref(inActor);
+			g_hash_table_iter_remove(&iter);
+		}
+	}
+}
+
+/* Activate result item by actor, e.g. actor was clicked */
+static void _xfdashboard_search_result_container_activate_result_item_by_actor(XfdashboardSearchResultContainer *self,
+																				ClutterActor *inActor)
+{
+	XfdashboardSearchResultContainerPrivate		*priv;
+	GHashTableIter								iter;
+	GVariant									*key;
+	ClutterActor								*value;
+
+	g_return_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_CONTAINER(self));
+	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
+
+	priv=self->priv;
+
+	/* Iterate through mapping and at first key whose value matching actor
+	 * tell provider to activate item.
+	 */
+	g_hash_table_iter_init(&iter, priv->mapping);
+	while(g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&value))
+	{
+		/* If value of key iterated matches actor activate item */
+		if(value==inActor)
+		{
+			/* Emit signal that a result item was clicked */
+			g_signal_emit(self,
+							XfdashboardSearchResultContainerSignals[SIGNAL_ITEM_CLICKED],
+							0,
+							key,
+							inActor);
+
+			/* All done so return here */
+			return;
+		}
+	}
+}
+
+/* A result item actor was clicked */
+static void _xfdashboard_search_result_container_on_result_item_actor_clicked(XfdashboardClickAction *inAction,
+																				ClutterActor *inActor,
+																				gpointer inUserData)
+{
+	XfdashboardSearchResultContainer			*self;
+
+	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
+	g_return_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_CONTAINER(inUserData));
+
+	self=XFDASHBOARD_SEARCH_RESULT_CONTAINER(inUserData);
+
+	/* Activate result item by actor clicked */
+	_xfdashboard_search_result_container_activate_result_item_by_actor(self, inActor);
+}
+
+/* Get and set up actor for result item from search provider */
+static ClutterActor* _xfdashboard_search_result_container_result_item_actor_new(XfdashboardSearchResultContainer *self,
+																				GVariant *inResultItem)
+{
+	XfdashboardSearchResultContainerPrivate		*priv;
+	ClutterActor								*actor;
+	ClutterAction								*action;
+	GList										*actions;
+	GList										*actionsIter;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_CONTAINER(self), NULL);
+	g_return_val_if_fail(inResultItem, NULL);
+
+	priv=self->priv;
+
+	/* Check if search provider is set */
+	g_return_if_fail(priv->provider);
+
+	/* Create actor for item */
+	actor=xfdashboard_search_provider_create_result_actor(priv->provider, inResultItem);
+	if(!actor)
+	{
+		gchar			*resultItemText;
+
+		resultItemText=g_variant_print(inResultItem, TRUE);
+		g_warning(_("Failed to add actor for result item %s of provider %s: Could not create actor"),
+					resultItemText,
+					G_OBJECT_TYPE_NAME(priv->provider));
+		g_free(resultItemText);
+
+		return(NULL);
+	}
+
+	if(!CLUTTER_IS_ACTOR(actor))
+	{
+		gchar			*resultItemText;
+
+		resultItemText=g_variant_print(inResultItem, TRUE);
+		g_critical(_("Failed to add actor for result item %s of provider %s: Actor of type %s is not derived from class %s"),
+					resultItemText,
+					G_OBJECT_TYPE_NAME(priv->provider),
+					G_IS_OBJECT(actor) ? G_OBJECT_TYPE_NAME(actor) : "<unknown>",
+					g_type_name(CLUTTER_TYPE_ACTOR));
+		g_free(resultItemText);
+
+		/* Release allocated resources */
+		clutter_actor_destroy(actor);
+
+		return(NULL);
+	}
+
+	/* Connect to 'destroy' signal of actor to remove it from mapping hash table
+	 * if actor was destroyed (accidently)
+	 */
+	g_signal_connect(actor,
+						"destroy",
+						G_CALLBACK(_xfdashboard_search_result_container_on_result_item_actor_destroyed),
+						self);
+
+	/* Add click action to actor and connect signal */
+	action=xfdashboard_click_action_new();
+	clutter_actor_add_action(actor, action);
+	g_signal_connect(action,
+						"clicked",
+						G_CALLBACK(_xfdashboard_search_result_container_on_result_item_actor_clicked),
+						self);
+
+	/* Iterate through all actions of actor and if it has an action of type
+	 * XfdashboardDragAction and has no source set then set this view as source
+	 */
+	actions=clutter_actor_get_actions(actor);
+	for(actionsIter=actions; actionsIter; actionsIter=g_list_next(actionsIter))
+	{
+		if(XFDASHBOARD_IS_DRAG_ACTION(actionsIter->data) &&
+			!xfdashboard_drag_action_get_source(XFDASHBOARD_DRAG_ACTION(actionsIter->data)))
+		{
+			g_object_set(actionsIter->data, "source", self, NULL);
+		}
+	}
+	if(actions) g_list_free(actions);
+
+	/* Set style depending on view mode */
+	if(XFDASHBOARD_IS_STYLABLE(actor))
+	{
+		if(priv->viewMode==XFDASHBOARD_VIEW_MODE_LIST) xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(actor), "view-mode-list");
+			else xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(actor), "view-mode-icon");
+
+		xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(actor), "result-item");
+	}
+
+	/* Set up actor for items container */
+	clutter_actor_set_x_expand(actor, TRUE);
+
+	/* Return newly created actor */
+	return(actor);
+}
+
 /* Sets provider this result container is for */
 static void _xfdashboard_search_result_container_set_provider(XfdashboardSearchResultContainer *self,
 																XfdashboardSearchProvider *inProvider)
@@ -566,6 +758,35 @@ static void _xfdashboard_search_result_container_dispose(GObject *inObject)
 		priv->titleFormat=NULL;
 	}
 
+	if(priv->mapping)
+	{
+		GHashTableIter							hashIter;
+		GVariant								*key;
+		ClutterActor							*value;
+
+		g_hash_table_iter_init(&hashIter, priv->mapping);
+		while(g_hash_table_iter_next(&hashIter, (gpointer*)&key, (gpointer*)&value))
+		{
+			/* First disconnect signal handlers from actor before modifying mapping hash table */
+			g_signal_handlers_disconnect_by_data(value, self);
+
+			/* Take a reference on value (it is the destroyed actor) because removing
+			 * key from mapping causes unrefencing key and value.
+			 */
+			g_object_ref(value);
+			g_hash_table_iter_remove(&hashIter);
+		}
+
+		g_hash_table_unref(priv->mapping);
+		priv->mapping=NULL;
+	}
+
+	if(priv->lastResultSet)
+	{
+		g_object_unref(priv->lastResultSet);
+		priv->lastResultSet=NULL;
+	}
+
 	/* Call parent's class dispose method */
 	G_OBJECT_CLASS(xfdashboard_search_result_container_parent_class)->dispose(inObject);
 }
@@ -729,6 +950,19 @@ static void xfdashboard_search_result_container_class_init(XfdashboardSearchResu
 						g_cclosure_marshal_VOID__VOID,
 						G_TYPE_NONE,
 						0);
+
+	XfdashboardSearchResultContainerSignals[SIGNAL_ITEM_CLICKED]=
+		g_signal_new("item-clicked",
+						G_TYPE_FROM_CLASS(klass),
+						G_SIGNAL_RUN_LAST,
+						G_STRUCT_OFFSET(XfdashboardSearchResultContainerClass, item_clicked),
+						NULL,
+						NULL,
+						_xfdashboard_marshal_VOID__OBJECT_OBJECT,
+						G_TYPE_NONE,
+						2,
+						G_TYPE_VARIANT,
+						CLUTTER_TYPE_ACTOR);
 }
 
 /* Object initialization
@@ -749,6 +983,11 @@ static void xfdashboard_search_result_container_init(XfdashboardSearchResultCont
 	priv->padding=0.0f;
 	priv->selectedItem=NULL;
 	priv->selectedItemDestroySignalID=0;
+	priv->mapping=g_hash_table_new_full(g_variant_hash,
+										g_variant_equal,
+										(GDestroyNotify)g_variant_unref,
+										(GDestroyNotify)g_object_unref);
+	priv->lastResultSet=NULL;
 
 	/* Set up children */
 	clutter_actor_set_reactive(CLUTTER_ACTOR(self), FALSE);
@@ -1011,35 +1250,6 @@ void xfdashboard_search_result_container_set_padding(XfdashboardSearchResultCont
 	}
 }
 
-/* Add actor for a result item to items container */
-void xfdashboard_search_result_container_add_result_actor(XfdashboardSearchResultContainer *self,
-															ClutterActor *inResultActor,
-															ClutterActor *inInsertAfter)
-{
-	XfdashboardSearchResultContainerPrivate		*priv;
-
-	g_return_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_CONTAINER(self));
-	g_return_if_fail(CLUTTER_IS_ACTOR(inResultActor));
-	g_return_if_fail(!inInsertAfter || CLUTTER_IS_ACTOR(inInsertAfter));
-
-	priv=self->priv;
-
-	/* Set style depending on view mode */
-	if(XFDASHBOARD_IS_STYLABLE(inResultActor))
-	{
-		if(priv->viewMode==XFDASHBOARD_VIEW_MODE_LIST) xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(inResultActor), "view-mode-list");
-			else xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(inResultActor), "view-mode-icon");
-
-		xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(inResultActor), "result-item");
-	}
-
-	/* Add actor to items container */
-	clutter_actor_set_x_expand(inResultActor, TRUE);
-
-	if(!inInsertAfter) clutter_actor_insert_child_below(priv->itemsContainer, inResultActor, NULL);
-		else clutter_actor_insert_child_above(priv->itemsContainer, inResultActor, inInsertAfter);
-}
-
 /* Set to or unset focus from container */
 void xfdashboard_search_result_container_set_focus(XfdashboardSearchResultContainer *self, gboolean inSetFocus)
 {
@@ -1189,3 +1399,141 @@ ClutterActor* xfdashboard_search_result_container_find_selection(XfdashboardSear
 
 	return(selection);
 }
+
+/* An result item should be activated */
+void xfdashboard_search_result_container_activate_selection(XfdashboardSearchResultContainer *self,
+																	ClutterActor *inSelection)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_CONTAINER(self), FALSE);
+	g_return_val_if_fail(CLUTTER_IS_ACTOR(inSelection), FALSE);
+
+	/* Check that selection is a child of this actor */
+	if(!clutter_actor_contains(CLUTTER_ACTOR(self), inSelection))
+	{
+		g_warning(_("%s is not a child of %s and cannot be activated"),
+					G_OBJECT_TYPE_NAME(inSelection),
+					G_OBJECT_TYPE_NAME(self));
+
+		return;
+	}
+
+	/* Activate selection */
+	_xfdashboard_search_result_container_activate_result_item_by_actor(self, inSelection);
+}
+
+/* Update result items in container */
+void xfdashboard_search_result_container_update(XfdashboardSearchResultContainer *self, XfdashboardSearchResultSet *inResultSet)
+{
+	XfdashboardSearchResultContainerPrivate		*priv;
+	GList										*allList;
+	GList										*iter;
+	GVariant									*resultItem;
+	ClutterActor								*actor;
+
+	g_return_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_CONTAINER(self));
+	g_return_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_SET(inResultSet));
+
+	priv=self->priv;
+
+	/* Check if search provider is set */
+	g_return_if_fail(priv->provider);
+
+	/* Determine list of items whose actors to remove from container by checking
+	 * which result item was in last known result set but is not in given one
+	 * anymore and remove the actor for each item in this list.
+	 */
+	if(priv->lastResultSet)
+	{
+		GList									*removeList;
+
+		/* Get list of items to remove */
+		removeList=xfdashboard_search_result_set_complement(inResultSet, priv->lastResultSet);
+
+		/* Iterate through list of items to remove and for each one remove actor
+		 * and its entry in mapping hash table.
+		 */
+		for(iter=removeList; iter; iter=g_list_next(iter))
+		{
+			/* Get result item to remove */
+			resultItem=(GVariant*)iter->data;
+
+			/* Get actor to remove */
+			if(g_hash_table_lookup_extended(priv->mapping, resultItem, NULL, (gpointer*)&actor))
+			{
+				/* Check if item has really an actor */
+				if(!CLUTTER_IS_ACTOR(actor))
+				{
+					gchar		*resultItemText;
+
+					resultItemText=g_variant_print(resultItem, TRUE);
+					g_critical(_("Failed to remove actor for result item %s of provider %s: Actor of type %s is not derived from class %s"),
+								resultItemText,
+								G_OBJECT_TYPE_NAME(priv->provider),
+								G_IS_OBJECT(actor) ? G_OBJECT_TYPE_NAME(actor) : "<unknown>",
+								g_type_name(CLUTTER_TYPE_ACTOR));
+					g_free(resultItemText);
+
+					continue;
+				}
+
+				/* First disconnect signal handlers from actor before modifying mapping hash table */
+				g_signal_handlers_disconnect_by_data(actor, self);
+
+				/* Remove actor from mapping hash table before destroying it */
+				g_hash_table_remove(priv->mapping, resultItem);
+
+				/* Destroy actor and remove from hash table */
+				clutter_actor_destroy(actor);
+			}
+		}
+
+		/* Release allocated resources */
+		if(removeList) g_list_free_full(removeList, (GDestroyNotify)g_variant_unref);
+	}
+
+	/* Create actor for each item in list which is new to mapping */
+	allList=xfdashboard_search_result_set_get_all(inResultSet);
+	if(allList)
+	{
+		ClutterActor							*lastActor;
+
+		lastActor=NULL;
+		for(iter=allList; iter; iter=g_list_next(iter))
+		{
+			/* Get item to add */
+			resultItem=(GVariant*)iter->data;
+
+			/* If item does not exist in mapping then create actor and add it to mapping */
+			if(!g_hash_table_lookup_extended(priv->mapping, resultItem, NULL, (gpointer*)&actor))
+			{
+				actor=_xfdashboard_search_result_container_result_item_actor_new(self, resultItem);
+				if(actor)
+				{
+					/* Add newly created actor to container of provider */
+					if(!lastActor) clutter_actor_insert_child_below(priv->itemsContainer, actor, NULL);
+						else clutter_actor_insert_child_above(priv->itemsContainer, actor, lastActor);
+
+					/* Add actor to mapping hash table for result item */
+					g_hash_table_insert(priv->mapping, g_variant_ref(resultItem), g_object_ref(actor));
+				}
+			}
+
+			/* Remember either existing actor from hash table lookup or
+			 * the newly created actor as the last one seen.
+			 */
+			if(actor) lastActor=actor;
+		}
+
+		/* Release allocated resources */
+		if(allList) g_list_free_full(allList, (GDestroyNotify)g_variant_unref);
+	}
+
+	/* Remember new result set for search provider */
+	if(priv->lastResultSet)
+	{
+		g_object_unref(priv->lastResultSet);
+		priv->lastResultSet=NULL;
+	}
+
+	priv->lastResultSet=XFDASHBOARD_SEARCH_RESULT_SET(g_object_ref(inResultSet));
+}
diff --git a/xfdashboard/search-result-container.h b/xfdashboard/search-result-container.h
index 29ba45f..007a4b7 100644
--- a/xfdashboard/search-result-container.h
+++ b/xfdashboard/search-result-container.h
@@ -63,6 +63,7 @@ struct _XfdashboardSearchResultContainerClass
 	/*< public >*/
 	/* Virtual functions */
 	void (*icon_clicked)(XfdashboardSearchResultContainer *self);
+	void (*item_clicked)(XfdashboardSearchResultContainer *self, GVariant *inItem, ClutterActor *inActor);
 };
 
 /* Public API */
@@ -85,10 +86,6 @@ void xfdashboard_search_result_container_set_spacing(XfdashboardSearchResultCont
 gfloat xfdashboard_search_result_container_get_padding(XfdashboardSearchResultContainer *self);
 void xfdashboard_search_result_container_set_padding(XfdashboardSearchResultContainer *self, const gfloat inPadding);
 
-void xfdashboard_search_result_container_add_result_actor(XfdashboardSearchResultContainer *self,
-															ClutterActor *inResultActor,
-															ClutterActor *inInsertAfter);
-
 void xfdashboard_search_result_container_set_focus(XfdashboardSearchResultContainer *self, gboolean inSetFocus);
 
 ClutterActor* xfdashboard_search_result_container_get_selection(XfdashboardSearchResultContainer *self);
@@ -98,6 +95,10 @@ ClutterActor* xfdashboard_search_result_container_find_selection(XfdashboardSear
 																	ClutterActor *inSelection,
 																	XfdashboardSelectionTarget inDirection,
 																	XfdashboardView *inView);
+void xfdashboard_search_result_container_activate_selection(XfdashboardSearchResultContainer *self,
+																	ClutterActor *inSelection);
+
+void xfdashboard_search_result_container_update(XfdashboardSearchResultContainer *self, XfdashboardSearchResultSet *inResults);
 
 G_END_DECLS
 
diff --git a/xfdashboard/search-view.c b/xfdashboard/search-view.c
index 5b7b194..4a5d31d 100644
--- a/xfdashboard/search-view.c
+++ b/xfdashboard/search-view.c
@@ -34,8 +34,6 @@
 #include "focusable.h"
 #include "utils.h"
 #include "search-result-container.h"
-#include "click-action.h"
-#include "drag-action.h"
 #include "focus-manager.h"
 #include "enums.h"
 #include "application.h"
@@ -101,7 +99,6 @@ struct _XfdashboardSearchViewProviderData
 	XfdashboardSearchResultSet			*lastResultSet;
 
 	ClutterActor						*container;
-	GHashTable							*mapping;
 };
 
 struct _XfdashboardSearchViewSearchTerms
@@ -137,40 +134,6 @@ static gboolean _xfdashboard_search_view_on_repaint_after_update_callback(gpoint
 	return(G_SOURCE_REMOVE);
 }
 
-/* Helper to clean up a search provider's container by disconnecting all signals to
- * its result items' actors and clean mapping hash table between actors and
- * result items.
- */
-static void _xfdashboard_search_view_clean_provider_container(XfdashboardSearchViewProviderData *inProviderData)
-{
-	g_return_if_fail(inProviderData);
-
-	/* Iterate through mapping, if available, and for each key disconnect signal
-	 * from the value (which is a ClutterActor) and take a also an additional
-	 * reference at actor because removing it from mapping hash table will unreference
-	 * it again.
-	 */
-	if(inProviderData->mapping)
-	{
-		GHashTableIter		hashIter;
-		GVariant			*key;
-		ClutterActor		*value;
-
-		g_hash_table_iter_init(&hashIter, inProviderData->mapping);
-		while(g_hash_table_iter_next(&hashIter, (gpointer*)&key, (gpointer*)&value))
-		{
-			/* First disconnect signal handlers from actor before modifying mapping hash table */
-			g_signal_handlers_disconnect_by_data(value, inProviderData);
-
-			/* Take a reference on value (it is the destroyed actor) because removing
-			 * key from mapping causes unrefencing key and value.
-			 */
-			g_object_ref(value);
-			g_hash_table_iter_remove(&hashIter);
-		}
-	}
-}
-
 /* Create search term data for a search string */
 static XfdashboardSearchViewSearchTerms* _xfdashboard_search_view_search_terms_new(const gchar *inSearchString)
 {
@@ -247,10 +210,6 @@ static XfdashboardSearchViewProviderData* _xfdashboard_search_view_provider_data
 	data->lastTerms=NULL;
 	data->lastResultSet=NULL;
 	data->container=NULL;
-	data->mapping=g_hash_table_new_full(g_variant_hash,
-										g_variant_equal,
-										(GDestroyNotify)g_variant_unref,
-										(GDestroyNotify)g_object_unref);
 
 	return(data);
 }
@@ -272,9 +231,6 @@ static void _xfdashboard_search_view_provider_data_free(XfdashboardSearchViewPro
 	}
 #endif
 
-	/* Clean provider's container and move focus if necessary */
-	_xfdashboard_search_view_clean_provider_container(inData);
-
 	/* Destroy container */
 	if(inData->container)
 	{
@@ -287,7 +243,6 @@ static void _xfdashboard_search_view_provider_data_free(XfdashboardSearchViewPro
 	}
 
 	/* Release allocated resources */
-	if(inData->mapping) g_hash_table_unref(inData->mapping);
 	if(inData->lastResultSet) g_object_unref(inData->lastResultSet);
 	if(inData->lastTerms) _xfdashboard_search_view_search_terms_unref(inData->lastTerms);
 	if(inData->provider) g_object_unref(inData->provider);
@@ -456,55 +411,41 @@ static void _xfdashboard_search_view_on_search_provider_unregistered(Xfdashboard
 }
 
 /* A result item actor was clicked */
-static void _xfdashboard_search_view_on_provider_item_actor_clicked(XfdashboardClickAction *inAction,
-																	ClutterActor *inActor,
-																	gpointer inUserData)
+static void _xfdashboard_search_view_on_result_item_clicked(XfdashboardSearchResultContainer *inContainer,
+															GVariant *inItem,
+															ClutterActor *inActor,
+															gpointer inUserData)
 {
 	XfdashboardSearchView				*self;
 	XfdashboardSearchViewPrivate		*priv;
 	XfdashboardSearchViewProviderData	*providerData;
-	GHashTableIter						iter;
-	GVariant							*key;
-	ClutterActor						*value;
 	const gchar							**searchTerms;
 	gboolean							success;
 
+	g_return_if_fail(XFDASHBOARD_IS_SEARCH_RESULT_CONTAINER(inContainer));
+	g_return_if_fail(inItem);
 	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
 	g_return_if_fail(inUserData);
 
 	providerData=(XfdashboardSearchViewProviderData*)inUserData;
 
-	/* Iterate through mapping and at first key whose value matching actor
-	 * tell provider to activate item.
-	 */
-	g_hash_table_iter_init(&iter, providerData->mapping);
-	while(g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&value))
-	{
-		/* If value of key iterated matches actor activate item */
-		if(value==inActor)
-		{
-			/* Get search view and private data of view */
-			self=providerData->view;
-			priv=self->priv;
-
-			/* Get search terms to pass them to search provider */
-			searchTerms=NULL;
-			if(priv->lastTerms) searchTerms=(const gchar**)priv->lastTerms->termList;
-
-			/* Tell provider that a result item was clicked */
-			success=xfdashboard_search_provider_activate_result(providerData->provider,
-																key,
-																inActor,
-																searchTerms);
-			if(success)
-			{
-				/* Activating result item seems to be successfuly so quit application */
-				xfdashboard_application_quit();
-			}
+	/* Get search view and private data of view */
+	self=providerData->view;
+	priv=self->priv;
 
-			/* All done so return here */
-			return;
-		}
+	/* Get search terms to pass them to search provider */
+	searchTerms=NULL;
+	if(priv->lastTerms) searchTerms=(const gchar**)priv->lastTerms->termList;
+
+	/* Tell provider to launch search */
+	success=xfdashboard_search_provider_activate_result(providerData->provider,
+														inItem,
+														inActor,
+														searchTerms);
+	if(success)
+	{
+		/* Activating result item seems to be successfuly so quit application */
+		xfdashboard_application_quit();
 	}
 }
 
@@ -655,130 +596,13 @@ static void _xfdashboard_search_view_on_provider_container_destroyed(ClutterActo
 		xfdashboard_focusable_set_selection(XFDASHBOARD_FOCUSABLE(self), newSelection);
 	}
 
-	/* Clean provider's container and move focus if necessary */
-	_xfdashboard_search_view_clean_provider_container(providerData);
-
 	/* Container will be destroyed so unset pointer to it at provider */
 	providerData->container=NULL;
 }
 
-/* A result item actor is going to be destroyed */
-static void _xfdashboard_search_view_on_provider_item_actor_destroy(ClutterActor *inActor, gpointer inUserData)
-{
-	XfdashboardSearchViewProviderData	*providerData;
-	GHashTableIter						iter;
-	GVariant							*key;
-	ClutterActor						*value;
-
-	g_return_if_fail(CLUTTER_IS_ACTOR(inActor));
-	g_return_if_fail(inUserData);
-
-	providerData=(XfdashboardSearchViewProviderData*)inUserData;
-
-	/* First disconnect signal handlers from actor before modifying mapping hash table */
-	g_signal_handlers_disconnect_by_data(inActor, providerData);
-
-	/* Iterate through mapping and remove each key whose value matches actor
-	 * going to be destroyed and remove it from mapping hash table.
-	 */
-	g_hash_table_iter_init(&iter, providerData->mapping);
-	while(g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&value))
-	{
-		/* If value of key iterated matches destroyed actor remove it from mapping */
-		if(value==inActor)
-		{
-			/* Take a reference on value (it is the destroyed actor) because removing
-			 * key from mapping causes unrefencing key and value.
-			 */
-			g_object_ref(inActor);
-			g_hash_table_iter_remove(&iter);
-		}
-	}
-}
-
 /* Updates container of provider with new result set from a last search.
  * Also creates or destroys the container for search provider if needed.
  */
-static ClutterActor* _xfdashboard_search_view_update_provider_actor_new(XfdashboardSearchView *self,
-																			XfdashboardSearchViewProviderData *inProviderData,
-																			GVariant *inItem)
-{
-	ClutterActor		*actor;
-	ClutterAction		*action;
-	GList				*actions;
-	GList				*actionsIter;
-
-	g_return_val_if_fail(XFDASHBOARD_IS_SEARCH_VIEW(self), NULL);
-	g_return_val_if_fail(inProviderData, NULL);
-	g_return_val_if_fail(inItem, NULL);
-
-	/* Create actor for item */
-	actor=xfdashboard_search_provider_create_result_actor(inProviderData->provider, inItem);
-	if(!actor)
-	{
-		gchar			*itemText;
-
-		itemText=g_variant_print(inItem, TRUE);
-		g_warning(_("Failed to add actor for result item %s of provider %s: Could not create actor"),
-					itemText,
-					G_OBJECT_TYPE_NAME(inProviderData->provider));
-		g_free(itemText);
-
-		return(NULL);
-	}
-
-	if(!CLUTTER_IS_ACTOR(actor))
-	{
-		gchar			*itemText;
-
-		itemText=g_variant_print(inItem, TRUE);
-		g_critical(_("Failed to add actor for result item %s of provider %s: Actor of type %s is not derived from class %s"),
-					itemText,
-					G_OBJECT_TYPE_NAME(inProviderData->provider),
-					G_IS_OBJECT(actor) ? G_OBJECT_TYPE_NAME(actor) : "<unknown>",
-					g_type_name(CLUTTER_TYPE_ACTOR));
-		g_free(itemText);
-
-		/* Release allocated resources */
-		clutter_actor_destroy(actor);
-
-		return(NULL);
-	}
-
-	/* Connect to 'destroy' signal of actor to remove it from mapping hash table
-	 * if actor was destroyed (accidently)
-	 */
-	g_signal_connect(actor,
-						"destroy",
-						G_CALLBACK(_xfdashboard_search_view_on_provider_item_actor_destroy),
-						inProviderData);
-
-	/* Add click action to actor and connect signal */
-	action=xfdashboard_click_action_new();
-	clutter_actor_add_action(actor, action);
-	g_signal_connect(action,
-						"clicked",
-						G_CALLBACK(_xfdashboard_search_view_on_provider_item_actor_clicked),
-						inProviderData);
-
-	/* Iterate through all actions of actor and if it has an action of type
-	 * XfdashboardDragAction and has no source set then set this view as source
-	 */
-	actions=clutter_actor_get_actions(actor);
-	for(actionsIter=actions; actionsIter; actionsIter=g_list_next(actionsIter))
-	{
-		if(XFDASHBOARD_IS_DRAG_ACTION(actionsIter->data) &&
-			!xfdashboard_drag_action_get_source(XFDASHBOARD_DRAG_ACTION(actionsIter->data)))
-		{
-			g_object_set(actionsIter->data, "source", self, NULL);
-		}
-	}
-	if(actions) g_list_free(actions);
-
-	/* Return newly created and set up actor */
-	return(actor);
-}
-
 static void _xfdashboard_search_view_update_provider_container(XfdashboardSearchView *self,
 																XfdashboardSearchViewProviderData *inProviderData,
 																XfdashboardSearchResultSet *inNewResultSet)
@@ -793,119 +617,38 @@ static void _xfdashboard_search_view_update_provider_container(XfdashboardSearch
 	if(inNewResultSet &&
 		xfdashboard_search_result_set_get_size(inNewResultSet)>0)
 	{
-		GList					*allList;
-		GList					*removeList;
-		GList					*iter;
-		ClutterActor			*actor;
-		ClutterActor			*lastActor;
-
-		/* Create container for provider if it does not exist yet */
+		/* Create container for search provider if it does not exist yet */
 		if(!inProviderData->container)
 		{
-			actor=xfdashboard_search_result_container_new(inProviderData->provider);
-			if(!actor) return;
+			/* Create container for search provider */
+			inProviderData->container=xfdashboard_search_result_container_new(inProviderData->provider);
+			if(!inProviderData->container) return;
 
-			inProviderData->container=actor;
+			/* Add new container to search view */
 			clutter_actor_add_child(CLUTTER_ACTOR(self), inProviderData->container);
 
+			/* Connect signals */
 			g_signal_connect(inProviderData->container,
 								"icon-clicked",
 								G_CALLBACK(_xfdashboard_search_view_on_provider_icon_clicked),
 								inProviderData);
 
 			g_signal_connect(inProviderData->container,
+								"item-clicked",
+								G_CALLBACK(_xfdashboard_search_view_on_result_item_clicked),
+								inProviderData);
+
+			g_signal_connect(inProviderData->container,
 								"destroy",
 								G_CALLBACK(_xfdashboard_search_view_on_provider_container_destroyed),
 								inProviderData);
 		}
 
-		/* Get list of all items in result set for and a list of items whose actors
-		 * to remove from container.
-		 */
-		allList=xfdashboard_search_result_set_get_all(inNewResultSet);
-
-		removeList=NULL;
-		if(inProviderData->lastResultSet)
-		{
-			removeList=xfdashboard_search_result_set_complement(inNewResultSet, inProviderData->lastResultSet);
-		}
-
-		/* Create actor for each item in list which is new to mapping */
-		lastActor=NULL;
-		for(iter=allList; iter; iter=g_list_next(iter))
-		{
-			GVariant			*item;
-
-			/* Get item to add */
-			item=(GVariant*)iter->data;
-
-			/* If item does not exist in mapping then create actor and add it to mapping */
-			if(!g_hash_table_lookup_extended(inProviderData->mapping, item, NULL, (gpointer*)&actor))
-			{
-				actor=_xfdashboard_search_view_update_provider_actor_new(self, inProviderData, item);
-				if(actor)
-				{
-					/* Add newly created actor to container of provider */
-					xfdashboard_search_result_container_add_result_actor(XFDASHBOARD_SEARCH_RESULT_CONTAINER(inProviderData->container),
-																			actor,
-																			lastActor);
-					g_hash_table_insert(inProviderData->mapping, g_variant_ref(item), g_object_ref(actor));
-				}
-			}
-
-			/* Remember either existing actor from hash table lookup or
-			 * the newly created actor as the last one seen.
-			 */
-			if(actor) lastActor=actor;
-		}
-
-		/* Remove actors for each item in list of removing items */
-		for(iter=removeList; iter; iter=g_list_next(iter))
-		{
-			GVariant			*item;
-
-			/* Get item to add */
-			item=(GVariant*)iter->data;
-
-			/* Get actor to remove */
-			if(g_hash_table_lookup_extended(inProviderData->mapping, item, NULL, (gpointer*)&actor))
-			{
-				if(!CLUTTER_IS_ACTOR(actor))
-				{
-					gchar		*itemText;
-
-					itemText=g_variant_print(item, TRUE);
-					g_critical(_("Failed to remove actor for result item %s of provider %s: Actor of type %s is not derived from class %s"),
-								itemText,
-								G_OBJECT_TYPE_NAME(inProviderData->provider),
-								G_IS_OBJECT(actor) ? G_OBJECT_TYPE_NAME(actor) : "<unknown>",
-								g_type_name(CLUTTER_TYPE_ACTOR));
-					g_free(itemText);
-
-					continue;
-				}
-
-				/* First disconnect signal handlers from actor before modifying mapping hash table */
-				g_signal_handlers_disconnect_by_data(actor, inProviderData);
-
-				/* Remove actor from mapping hash table before destroying it */
-				g_hash_table_remove(inProviderData->mapping, item);
-
-				/* Destroy actor and remove from hash table */
-				clutter_actor_destroy(actor);
-			}
-		}
-
-		/* Release allocated resources */
-		if(removeList) g_list_free_full(removeList, (GDestroyNotify)g_variant_unref);
-		if(allList) g_list_free_full(allList, (GDestroyNotify)g_variant_unref);
+		xfdashboard_search_result_container_update(XFDASHBOARD_SEARCH_RESULT_CONTAINER(inProviderData->container), inNewResultSet);
 	}
 		/* ... but if no result set for provider is given then destroy existing container */
 		else
 		{
-			/* Clean provider's container and move focus if necessary */
-			_xfdashboard_search_view_clean_provider_container(inProviderData);
-
 			/* Destroy container */
 			if(inProviderData->container)
 			{
@@ -1595,7 +1338,8 @@ static gboolean _xfdashboard_search_view_focusable_activate_selection(Xfdashboar
 	}
 
 	/* Activate selection */
-	_xfdashboard_search_view_on_provider_item_actor_clicked(NULL, inSelection, providerData);
+	xfdashboard_search_result_container_activate_selection(XFDASHBOARD_SEARCH_RESULT_CONTAINER(providerData->container),
+															inSelection);
 
 	/* Release allocated resources */
 	_xfdashboard_search_view_provider_data_unref(providerData);
@@ -1810,9 +1554,6 @@ void xfdashboard_search_view_reset_search(XfdashboardSearchView *self)
 		/* Get data for provider to reset */
 		providerData=((XfdashboardSearchViewProviderData*)(iter->data));
 
-		/* Clean provider's container and move focus if necessary */
-		_xfdashboard_search_view_clean_provider_container(providerData);
-
 		/* Destroy container */
 		if(providerData->container)
 		{

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list