[nautilus-actions: 2/19] Remove NactIIOClient interface



commit ea23fae8d0a5db1e0bdf17ba44efbcc16a507ce8
Author: Pierre Wieser <pwieser trychlos org>
Date:   Sat Jun 6 00:20:02 2009 +0200

    Remove NactIIOClient interface
---
 ChangeLog                        |   23 +++
 src/common/Makefile.am           |    4 -
 src/common/nact-action-profile.c |  126 +++++++++--------
 src/common/nact-action-profile.h |    2 +-
 src/common/nact-action.c         |  131 +++++++++----------
 src/common/nact-action.h         |    8 +-
 src/common/nact-gconf.c          |  277 +++++++++++++++-----------------------
 src/common/nact-gconf.h          |    2 +-
 src/common/nact-iio-client.c     |  154 ---------------------
 src/common/nact-iio-client.h     |   73 ----------
 src/common/nact-iio-provider.c   |   90 ------------
 src/common/nact-iio-provider.h   |   12 +--
 src/common/nact-io-client.c      |  245 ---------------------------------
 src/common/nact-io-client.h      |   78 -----------
 src/common/nact-pivot.c          |  272 ++++++++++++++++++++++++++++++++++++-
 src/common/nact-pivot.h          |   12 +-
 16 files changed, 540 insertions(+), 969 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a48b756..0cf1dfb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2009-06-06 Pierre Wieser <pwieser trychlos org>
+
+	Remove NactIIOClient interface.
+
+	* src/common/nact-iio-client.c:
+	* src/common/nact-iio-client.h:
+	* src/common/nact-io-client.c:
+	* src/common/nact-io-client.c:
+	Remove files.
+
+	* src/common/Makefile.am:
+	* src/common/nact-action-profile.c:
+	* src/common/nact-action-profile.h:
+	* src/common/nact-action.c:
+	* src/common/nact-action.h:
+	* src/common/nact-gconf.c:
+	* src/common/nact-gconf.h:
+	* src/common/nact-iio-provider.c:
+	* src/common/nact-iio-provider.h:
+	* src/common/nact-pivot.c:
+	* src/common/nact-pivot.h:
+	Updated accordingly.
+
 2009-06-05 Pierre Wieser <pwieser trychlos org>
 
 	Create pivot data structure NactPivotValue
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 83b1804..ad56004 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -42,12 +42,8 @@ libnact_la_SOURCES = \
 	nact-gconf.c								\
 	nact-gconf.h								\
 	nact-gconf-keys.h							\
-	nact-iio-client.c							\
-	nact-iio-client.h							\
 	nact-iio-provider.c							\
 	nact-iio-provider.h							\
-	nact-io-client.c							\
-	nact-io-client.h							\
 	nact-object.c								\
 	nact-object.h								\
 	nact-pivot.c								\
diff --git a/src/common/nact-action-profile.c b/src/common/nact-action-profile.c
index a895997..54d70f7 100644
--- a/src/common/nact-action-profile.c
+++ b/src/common/nact-action-profile.c
@@ -36,9 +36,8 @@
 
 #include <libnautilus-extension/nautilus-file-info.h>
 
+#include "nact-action.h"
 #include "nact-action-profile.h"
-#include "nact-iio-client.h"
-#include "nact-iio-provider.h"
 #include "uti-lists.h"
 
 struct NactActionProfilePrivate {
@@ -50,7 +49,7 @@ struct NactActionProfilePrivate {
 
 	/* profile properties
 	 */
-	gchar    *name;		/* GConf key = id */
+	gchar    *name;
 	gchar    *label;
 	gchar    *path;
 	gchar    *parameters;
@@ -81,6 +80,22 @@ enum {
 	PROP_SCHEMES
 };
 
+/* please note that property names must have the same spelling as the
+ * NactIIOProvider parameters
+ */
+#define PROP_ACTION_STR					"action"
+#define PROP_PROFILE_NAME_STR			"name"
+#define PROP_LABEL_STR					"desc-name"
+#define PROP_PATH_STR					"path"
+#define PROP_PARAMETERS_STR				"parameters"
+#define PROP_ACCEPT_MULTIPLE_STR		"accept-multiple-files"
+#define PROP_BASENAMES_STR				"basenames"
+#define PROP_ISDIR_STR					"isdir"
+#define PROP_ISFILE_STR					"isfile"
+#define PROP_MATCHCASE_STR				"matchcase"
+#define PROP_MIMETYPES_STR				"mimetypes"
+#define PROP_SCHEMES_STR				"schemes"
+
 static NactObjectClass *st_parent_class = NULL;
 
 static GType register_type( void );
@@ -95,6 +110,20 @@ static void  do_dump( const NactObject *profile );
 static void  do_dump_list( const gchar *thisfn, const gchar *label, GSList *list );
 static int   validate_schemes( GSList* schemes2test, NautilusFileInfo* file );
 
+NactActionProfile *
+nact_action_profile_new( const NactObject *action, const gchar *name )
+{
+	g_assert( NACT_IS_ACTION( action ));
+	g_assert( name && strlen( name ));
+
+	NactActionProfile *profile =
+		g_object_new(
+				NACT_ACTION_PROFILE_TYPE,
+				PROP_ACTION_STR, action, PROP_PROFILE_NAME_STR, name, NULL );
+
+	return( profile );
+}
+
 GType
 nact_action_profile_get_type( void )
 {
@@ -141,86 +170,86 @@ class_init( NactActionProfileClass *klass )
 
 	GParamSpec *spec;
 	spec = g_param_spec_pointer(
-			"action",
-			"action",
+			PROP_ACTION_STR,
+			PROP_ACTION_STR,
 			"The NactAction object",
 			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_ACTION, spec );
 
 	/* the id of the object is marked as G_PARAM_CONSTRUCT_ONLY */
 	spec = g_param_spec_string(
-			"name",
-			"name",
+			PROP_PROFILE_NAME_STR,
+			PROP_PROFILE_NAME_STR,
 			"Internal profile's name", "",
 			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_PROFILE_NAME, spec );
 
 	spec = g_param_spec_string(
-			"desc-name",
-			"desc-name",
+			PROP_LABEL_STR,
+			PROP_LABEL_STR,
 			"Displayable profile's name", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_LABEL, spec );
 
 	spec = g_param_spec_string(
-			"path",
-			"path",
+			PROP_PATH_STR,
+			PROP_PATH_STR,
 			"Command path", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_PATH, spec );
 
 	spec = g_param_spec_string(
-			"parameters",
-			"parameters",
+			PROP_PARAMETERS_STR,
+			PROP_PARAMETERS_STR,
 			"Command parameters", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_PARAMETERS, spec );
 
 	spec = g_param_spec_boolean(
-			"accept-multiple-files",
-			"accept-multiple-files",
+			PROP_ACCEPT_MULTIPLE_STR,
+			PROP_ACCEPT_MULTIPLE_STR,
 			"Whether apply when multiple files may be selected", TRUE,
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_ACCEPT_MULTIPLE, spec );
 
 	spec = g_param_spec_pointer(
-			"basenames",
-			"basenames",
+			PROP_BASENAMES_STR,
+			PROP_BASENAMES_STR,
 			"Filenames mask",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_BASENAMES, spec );
 
 	spec = g_param_spec_boolean(
-			"isdir",
-			"isdir",
+			PROP_ISDIR_STR,
+			PROP_ISDIR_STR,
 			"Whether apply when a dir is selected", FALSE,
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_ISDIR, spec );
 
 	spec = g_param_spec_boolean(
-			"isfile",
-			"isfile",
+			PROP_ISFILE_STR,
+			PROP_ISFILE_STR,
 			"Whether apply when a file is selected", TRUE,
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_ISFILE, spec );
 
 	spec = g_param_spec_boolean(
-			"matchcase",
-			"matchcase",
+			PROP_MATCHCASE_STR,
+			PROP_MATCHCASE_STR,
 			"Whether the filenames are case sensitive", TRUE,
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_MATCHCASE, spec );
 
 	spec = g_param_spec_pointer(
-			"mimetypes",
-			"mimetypes",
+			PROP_MIMETYPES_STR,
+			PROP_MIMETYPES_STR,
 			"List of selectable mimetypes",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_MIMETYPES, spec );
 
 	spec = g_param_spec_pointer(
-			"schemes",
-			"schemes",
+			PROP_SCHEMES_STR,
+			PROP_SCHEMES_STR,
 			"list of selectable schemes",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_SCHEMES, spec );
@@ -408,6 +437,9 @@ instance_finalize( GObject *object )
 	g_free( self->private->label );
 	g_free( self->private->path );
 	g_free( self->private->parameters );
+	nactuti_free_string_list( self->private->basenames );
+	nactuti_free_string_list( self->private->mimetypes );
+	nactuti_free_string_list( self->private->schemes );
 
 	/* chain call to parent class */
 	if((( GObjectClass * ) st_parent_class )->finalize ){
@@ -415,32 +447,6 @@ instance_finalize( GObject *object )
 	}
 }
 
-NactActionProfile *
-nact_action_profile_new( const NactObject *action, const gchar *name )
-{
-	g_assert( NACT_IS_OBJECT( action ));
-	g_assert( name && strlen( name ));
-
-	NactActionProfile *profile =
-		g_object_new( NACT_ACTION_PROFILE_TYPE, "action", action, "name", name, NULL );
-	return( profile );
-}
-
-/**
- * Load an action.
- *
- * @action: a NactAction previously allocated via nact_action_new.
- */
-void
-nact_action_profile_load( NactObject *object )
-{
-	g_assert( NACT_IS_ACTION_PROFILE( object ));
-
-	/*NactActionProfile *profile = NACT_ACTION_PROFILE( object );*/
-
-	nact_iio_provider_load_profile_properties( object );
-}
-
 static void
 do_dump( const NactObject *object )
 {
@@ -492,7 +498,7 @@ nact_action_profile_get_action( const NactActionProfile *profile )
 	g_assert( NACT_IS_ACTION_PROFILE( profile ));
 
 	gpointer action;
-	g_object_get( G_OBJECT( profile ), "action", &action, NULL );
+	g_object_get( G_OBJECT( profile ), PROP_ACTION_STR, &action, NULL );
 
 	return( NACT_OBJECT( action ));
 }
@@ -505,14 +511,14 @@ nact_action_profile_get_action( const NactActionProfile *profile )
  * The profile name is also the GConf-key of the profile.
  */
 gchar *
-nact_action_profile_get_id( const NactActionProfile *profile )
+nact_action_profile_get_name( const NactActionProfile *profile )
 {
 	g_assert( NACT_IS_ACTION_PROFILE( profile ));
 
-	gchar *id;
-	g_object_get( G_OBJECT( profile ), "name", &id, NULL );
+	gchar *name;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_NAME_STR, &name, NULL );
 
-	return( id );
+	return( name );
 }
 
 /**
@@ -526,7 +532,7 @@ nact_action_profile_get_path( const NactActionProfile *profile )
 	g_assert( NACT_IS_ACTION_PROFILE( profile ));
 
 	gchar *path;
-	g_object_get( G_OBJECT( profile ), "path", &path, NULL );
+	g_object_get( G_OBJECT( profile ), PROP_PATH_STR, &path, NULL );
 
 	return( path );
 }
@@ -542,7 +548,7 @@ nact_action_profile_get_parameters( const NactActionProfile *profile )
 	g_assert( NACT_IS_ACTION_PROFILE( profile ));
 
 	gchar *parameters;
-	g_object_get( G_OBJECT( profile ), "parameters", &parameters, NULL );
+	g_object_get( G_OBJECT( profile ), PROP_PARAMETERS_STR, &parameters, NULL );
 
 	return( parameters );
 }
diff --git a/src/common/nact-action-profile.h b/src/common/nact-action-profile.h
index 3a3529f..eede629 100644
--- a/src/common/nact-action-profile.h
+++ b/src/common/nact-action-profile.h
@@ -75,7 +75,7 @@ NactActionProfile *nact_action_profile_new( const NactObject *action, const gcha
 void               nact_action_profile_load( NactObject *profile );
 
 NactObject        *nact_action_profile_get_action( const NactActionProfile *profile );
-gchar             *nact_action_profile_get_id( const NactActionProfile *profile );
+gchar             *nact_action_profile_get_name( const NactActionProfile *profile );
 gchar             *nact_action_profile_get_path( const NactActionProfile *profile );
 gchar             *nact_action_profile_get_parameters( const NactActionProfile *profile );
 
diff --git a/src/common/nact-action.c b/src/common/nact-action.c
index 63f022a..22c018a 100644
--- a/src/common/nact-action.c
+++ b/src/common/nact-action.c
@@ -36,20 +36,14 @@
 
 #include "nact-action.h"
 #include "nact-action-profile.h"
-#include "nact-iio-client.h"
-#include "nact-iio-provider.h"
-#include "nact-io-client.h"
 #include "uti-lists.h"
 
 struct NactActionPrivate {
 	gboolean  dispose_has_run;
 
-	/* io client
-	 */
-	NactIOClient *io;
-
 	/* action properties
 	 */
+	gchar    *uuid;
 	gchar    *version;
 	gchar    *label;
 	gchar    *tooltip;
@@ -65,17 +59,26 @@ struct NactActionClassPrivate {
 };
 
 enum {
-	PROP_VERSION = 1,
+	PROP_UUID = 1,
+	PROP_VERSION,
 	PROP_LABEL,
 	PROP_TOOLTIP,
 	PROP_ICON
 };
 
+/* please note that property names must have the same spelling as the
+ * NactIIOProvider parameters
+ */
+#define PROP_UUID_STR		"uuid"
+#define PROP_VERSION_STR	"version"
+#define PROP_LABEL_STR		"label"
+#define PROP_TOOLTIP_STR	"tooltip"
+#define PROP_ICON_STR		"icon"
+
 static NactObjectClass *st_parent_class = NULL;
 
 static GType    register_type( void );
 static void     class_init( NactActionClass *klass );
-static void     iio_client_iface_init( NactIIOClientInterface *iface );
 static void     instance_init( GTypeInstance *instance, gpointer klass );
 static void     instance_dispose( GObject *object );
 static void     instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
@@ -84,7 +87,6 @@ static void     instance_finalize( GObject *object );
 
 static void     free_profiles( NactAction *action );
 
-static GObject *do_get_io_client( const NactIIOClient *client );
 static void     do_dump( const NactObject *action );
 
 /**
@@ -99,10 +101,9 @@ static void     do_dump( const NactObject *action );
  * basis.
  */
 NactAction *
-nact_action_new( gpointer provider, gpointer data )
+nact_action_new( const gchar *uuid )
 {
-	NactAction *action = g_object_new( NACT_ACTION_TYPE, NULL );
-	action->private->io = nact_io_client_new( provider, data );
+	NactAction *action = g_object_new( NACT_ACTION_TYPE, PROP_UUID_STR, uuid, NULL );
 	return( action );
 }
 
@@ -133,17 +134,7 @@ register_type( void )
 		( GInstanceInitFunc ) instance_init
 	};
 
-	GType type = g_type_register_static( NACT_OBJECT_TYPE, "NactAction", &info, 0 );
-
-	static const GInterfaceInfo iio_client_iface_info = {
-		( GInterfaceInitFunc ) iio_client_iface_init,
-		NULL,
-		NULL
-	};
-
-	g_type_add_interface_static( type, NACT_IIO_CLIENT_TYPE, &iio_client_iface_info );
-
-	return( type );
+	return( g_type_register_static( NACT_OBJECT_TYPE, "NactAction", &info, 0 ));
 }
 
 static void
@@ -164,29 +155,36 @@ class_init( NactActionClass *klass )
 
 	/* the id of the object is marked as G_PARAM_CONSTRUCT_ONLY */
 	spec = g_param_spec_string(
-			"version",
-			"version",
+			PROP_UUID_STR,
+			PROP_UUID_STR,
+			"Globally unique identifier (UUID) of the action", "",
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_UUID, spec );
+
+	spec = g_param_spec_string(
+			PROP_VERSION_STR,
+			PROP_VERSION_STR,
 			"Version of the schema", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_VERSION, spec );
 
 	spec = g_param_spec_string(
-			"label",
-			"label",
+			PROP_LABEL_STR,
+			PROP_LABEL_STR,
 			"Context menu displayable label", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_LABEL, spec );
 
 	spec = g_param_spec_string(
-			"tooltip",
-			"tooltip",
+			PROP_TOOLTIP_STR,
+			PROP_TOOLTIP_STR,
 			"Context menu tooltip", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_TOOLTIP, spec );
 
 	spec = g_param_spec_string(
-			"icon",
-			"icon",
+			PROP_ICON_STR,
+			PROP_ICON_STR,
 			"Context menu displayable icon", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_ICON, spec );
@@ -197,15 +195,6 @@ class_init( NactActionClass *klass )
 }
 
 static void
-iio_client_iface_init( NactIIOClientInterface *iface )
-{
-	static const gchar *thisfn = "nact_action_iio_client_iface_init";
-	g_debug( "%s: iface=%p", thisfn, iface );
-
-	iface->get_io_client = do_get_io_client;
-}
-
-static void
 instance_init( GTypeInstance *instance, gpointer klass )
 {
 	/*static const gchar *thisfn = "nact_action_instance_init";
@@ -225,6 +214,10 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 	NactAction *self = NACT_ACTION( object );
 
 	switch( property_id ){
+		case PROP_UUID:
+			g_value_set_string( value, self->private->uuid );
+			break;
+
 		case PROP_VERSION:
 			g_value_set_string( value, self->private->version );
 			break;
@@ -254,6 +247,11 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 	NactAction *self = NACT_ACTION( object );
 
 	switch( property_id ){
+		case PROP_UUID:
+			g_free( self->private->uuid );
+			self->private->uuid = g_value_dup_string( value );
+			break;
+
 		case PROP_VERSION:
 			g_free( self->private->version );
 			self->private->version = g_value_dup_string( value );
@@ -293,15 +291,9 @@ instance_dispose( GObject *object )
 
 		self->private->dispose_has_run = TRUE;
 
-		/* release the io_client object */
-		g_object_unref( self->private->io );
-
 		/* release the profiles */
 		free_profiles( self );
 
-		/* release the provider data */
-		nact_iio_provider_release_data( NACT_IIO_CLIENT( self ));
-
 		/* chain up to the parent class */
 		G_OBJECT_CLASS( st_parent_class )->dispose( object );
 	}
@@ -316,6 +308,7 @@ instance_finalize( GObject *object )
 	g_assert( NACT_IS_ACTION( object ));
 	NactAction *self = ( NactAction * ) object;
 
+	g_free( self->private->uuid );
 	g_free( self->private->version );
 	g_free( self->private->label );
 	g_free( self->private->tooltip );
@@ -340,31 +333,30 @@ free_profiles( NactAction *action )
 	action->private->profiles = NULL;
 }
 
-static GObject *
-do_get_io_client( const NactIIOClient *client )
+/**
+ * Create a new NactAction object, with the given parm and value.
+ *
+ * Note that the parm may actually be a profile's parm.
+ */
+NactAction *
+nact_action_create( const gchar *key, const gchar *parm, const NactPivotValue *value )
 {
-	g_assert( NACT_IS_IIO_CLIENT( client ));
-	g_assert( NACT_IS_ACTION( client ));
-	NactAction *action = NACT_ACTION( client );
-	return( G_OBJECT( action->private->io ));
+	static const gchar *thisfn = "nact_action_create";
+	g_debug( "%s: key='%s', parm='%s', value=%p", thisfn, key, parm, value );
+
+	NactAction *action = g_object_new( NACT_ACTION_TYPE, NULL );
+	nact_action_update( action, parm, value );
+	return( action );
 }
 
 /**
- * Load an action.
- *
- * @action: a NactAction previously allocated via nact_action_new.
+ * Update the given parameter of an action.
  */
 void
-nact_action_load( NactAction *action )
+nact_action_update( NactAction *action, const gchar *parm, const NactPivotValue *value )
 {
-	g_assert( NACT_IS_ACTION( action ));
-	g_assert( NACT_IS_IIO_CLIENT( action ));
-
-	nact_iio_provider_load_action_properties( NACT_IIO_CLIENT( action ));
-
-	action->private->profiles = nact_iio_provider_load_profiles( NACT_IIO_CLIENT( action ));
-
-	nact_object_dump( NACT_OBJECT( action ));
+	static const gchar *thisfn = "nact_action_update";
+	g_debug( "%s: action=%p, parm='%s', value=%p", thisfn, action, parm, value );
 }
 
 static void
@@ -379,6 +371,7 @@ do_dump( const NactObject *action )
 		st_parent_class->dump( action );
 	}
 
+	g_debug( "%s:    uuid='%s'", thisfn, self->private->uuid );
 	g_debug( "%s: version='%s'", thisfn, self->private->version );
 	g_debug( "%s:   label='%s'", thisfn, self->private->label );
 	g_debug( "%s: tooltip='%s'", thisfn, self->private->tooltip );
@@ -405,7 +398,7 @@ nact_action_get_uuid( const NactAction *action )
 	g_assert( NACT_IS_ACTION( action ));
 
 	gchar *uuid;
-	g_object_get( G_OBJECT( action ), "uuid", &uuid, NULL );
+	g_object_get( G_OBJECT( action ), PROP_UUID_STR, &uuid, NULL );
 
 	return( uuid );
 }
@@ -423,7 +416,7 @@ nact_action_get_label( const NactAction *action )
 	g_assert( NACT_IS_ACTION( action ));
 
 	gchar *label;
-	g_object_get( G_OBJECT( action ), "label", &label, NULL );
+	g_object_get( G_OBJECT( action ), PROP_LABEL_STR, &label, NULL );
 
 	return( label );
 }
@@ -441,7 +434,7 @@ nact_action_get_tooltip( const NactAction *action )
 	g_assert( NACT_IS_ACTION( action ));
 
 	gchar *tooltip;
-	g_object_get( G_OBJECT( action ), "tooltip", &tooltip, NULL );
+	g_object_get( G_OBJECT( action ), PROP_TOOLTIP_STR, &tooltip, NULL );
 
 	return( tooltip );
 }
@@ -460,7 +453,7 @@ nact_action_get_verified_icon_name( const NactAction *action )
 	g_assert( NACT_IS_ACTION( action ));
 
 	gchar *icon_name;
-	g_object_get( G_OBJECT( action ), "icon", &icon_name, NULL );
+	g_object_get( G_OBJECT( action ), PROP_ICON_STR, &icon_name, NULL );
 
 	if( icon_name[0] == '/' ){
 		if( !g_file_test( icon_name, G_FILE_TEST_IS_REGULAR )){
diff --git a/src/common/nact-action.h b/src/common/nact-action.h
index 827de03..5e017bb 100644
--- a/src/common/nact-action.h
+++ b/src/common/nact-action.h
@@ -40,6 +40,7 @@
  */
 
 #include "nact-object.h"
+#include "nact-pivot.h"
 
 G_BEGIN_DECLS
 
@@ -68,9 +69,12 @@ typedef struct {
 
 GType       nact_action_get_type( void );
 
-NactAction *nact_action_new( gpointer provider, gpointer data );
+NactAction *nact_action_new( const gchar *uuid );
 
-void        nact_action_load( NactAction *action );
+NactAction *nact_action_create( const gchar *key, const gchar *parm, const NactPivotValue *value );
+void        nact_action_update( NactAction *action, const gchar *parm, const NactPivotValue *value );
+
+gboolean    nact_action_is_empty( const NactAction *action );
 
 gchar      *nact_action_get_uuid( const NactAction *action );
 gchar      *nact_action_get_label( const NactAction *action );
diff --git a/src/common/nact-gconf.c b/src/common/nact-gconf.c
index db81b2f..b69ea1e 100644
--- a/src/common/nact-gconf.c
+++ b/src/common/nact-gconf.c
@@ -41,14 +41,12 @@
 #include "nact-action-profile.h"
 #include "nact-gconf.h"
 #include "nact-gconf-keys.h"
-#include "nact-iio-client.h"
 #include "nact-iio-provider.h"
-#include "nact-pivot.h"
 #include "uti-lists.h"
 
 struct NactGConfPrivate {
 	gboolean     dispose_has_run;
-	NactPivot   *pivot;
+	GObject     *notification_handler;
 	GConfClient *gconf;
 	guint        notify_id;
 };
@@ -56,16 +54,12 @@ struct NactGConfPrivate {
 struct NactGConfClassPrivate {
 };
 
-typedef struct {
-	gchar *key;
-	gchar *path;
-}
-	NactGConfIO;
-
 enum {
-	PROP_PIVOT = 1
+	PROP_NOTIFICATION_HANDLER = 1
 };
 
+#define PROP_NOTIFICATION_HANDLER_STR	"notification-handler"
+
 static GObjectClass *st_parent_class = NULL;
 
 static GType          register_type( void );
@@ -79,27 +73,25 @@ static void           instance_finalize( GObject *object );
 static guint          install_gconf_watch( NactGConf *gconf );
 static void           remove_gconf_watch( NactGConf *gconf );
 
-static void           actions_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data );
+static void           action_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data );
 
 static void           free_keys_values( GSList *keys );
 static GSList        *load_keys_values( const NactGConf *gconf, const gchar *path );
 static GSList        *load_subdirs( const NactGConf *gconf, const gchar *path );
 static gchar         *path_to_key( const gchar *path );
-static NactGConfIO   *path_to_struct( const gchar *path );
+/*static NactGConfIO   *path_to_struct( const gchar *path );*/
 static void           set_item_properties( NactObject *object, GSList *properties );
 static NactPivotValue *value_to_pivot( const GConfValue *value );
 
+static void           load_action_properties( NactGConf *gconf, NactAction *action );
+static GSList        *load_profiles( NactGConf *gconf, NactAction *action );
+static void           load_profile_properties( NactGConf *gconf, NactActionProfile *profile );
 static GSList        *do_load_actions( NactIIOProvider *provider );
-static   void         do_load_action_properties( NactIIOClient *client );
-static GSList        *do_load_profiles( NactIIOClient *client );
-static void           do_load_profile_properties( NactObject *profile );
-static void           do_release_data( NactIIOClient *client );
 
 NactGConf *
-nact_gconf_new( const GObject *pivot )
+nact_gconf_new( const GObject *handler )
 {
-	g_assert( NACT_IS_PIVOT( pivot ));
-	return( g_object_new( NACT_GCONF_TYPE, "pivot", pivot, NULL ));
+	return( g_object_new( NACT_GCONF_TYPE, PROP_NOTIFICATION_HANDLER_STR, handler, NULL ));
 }
 
 GType
@@ -158,11 +150,11 @@ class_init( NactGConfClass *klass )
 
 	GParamSpec *spec;
 	spec = g_param_spec_pointer(
-			"pivot",
-			"pivot",
-			"A pointer to NactPivot object",
+			PROP_NOTIFICATION_HANDLER_STR,
+			PROP_NOTIFICATION_HANDLER_STR,
+			"A pointer to a GObject which will receive action_changed notifications",
 			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_PIVOT, spec );
+	g_object_class_install_property( object_class, PROP_NOTIFICATION_HANDLER, spec );
 
 	klass->private = g_new0( NactGConfClassPrivate, 1 );
 }
@@ -174,10 +166,6 @@ iio_provider_iface_init( NactIIOProviderInterface *iface )
 	g_debug( "%s: iface=%p", thisfn, iface );
 
 	iface->load_actions = do_load_actions;
-	iface->load_action_properties = do_load_action_properties;
-	iface->load_profiles = do_load_profiles;
-	iface->load_profile_properties = do_load_profile_properties;
-	iface->release_data = do_release_data;
 }
 
 static void
@@ -203,8 +191,8 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 	NactGConf *self = NACT_GCONF( object );
 
 	switch( property_id ){
-		case PROP_PIVOT:
-			g_value_set_pointer( value, self->private->pivot );
+		case PROP_NOTIFICATION_HANDLER:
+			g_value_set_pointer( value, self->private->notification_handler );
 			break;
 
 		default:
@@ -220,8 +208,8 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 	NactGConf *self = NACT_GCONF( object );
 
 	switch( property_id ){
-		case PROP_PIVOT:
-			self->private->pivot = g_value_get_pointer( value );
+		case PROP_NOTIFICATION_HANDLER:
+			self->private->notification_handler = g_value_get_pointer( value );
 			break;
 
 		default:
@@ -261,6 +249,13 @@ instance_finalize( GObject *object )
 	}
 }
 
+/*
+ * note that we need the NactPivot object in action_changed_cb handler
+ * but it is initialized as a construction property, and this watch is
+ * installed from instance_init, i.e. before properties are set..
+ *
+ * we so pass NactGConf pointer which is already valid at this time.
+ */
 static guint
 install_gconf_watch( NactGConf *gconf )
 {
@@ -279,8 +274,8 @@ install_gconf_watch( NactGConf *gconf )
 		gconf_client_notify_add(
 			gconf->private->gconf,
 			NACT_GCONF_CONFIG_PATH,
-			( GConfClientNotifyFunc ) actions_changed_cb,
-			gconf->private->pivot,
+			( GConfClientNotifyFunc ) action_changed_cb,
+			gconf,
 			NULL,
 			&error
 		);
@@ -328,75 +323,30 @@ remove_gconf_watch( NactGConf *gconf )
  *
  * if the modification is made elsewhere (an action is imported as a
  * xml file in gconf, of gconf is directly edited), we'd have to rely
- * on the key of the value
- *
- * user_data is a ptr to NactPivot object.
+ * on the standard watch mechanism
  */
 static void
-actions_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data )
+action_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data )
 {
-	static const gchar *thisfn = "actions_changed_cb";
-	g_debug( "%s: client=%p, cnxnid=%u, entry=%p, user_data=%p", thisfn, client, cnxn_id, entry, user_data );
+	/*static const gchar *thisfn = "action_changed_cb";
+	g_debug( "%s: client=%p, cnxnid=%u, entry=%p, user_data=%p", thisfn, client, cnxn_id, entry, user_data );*/
 
-	g_assert( NACT_IS_PIVOT( user_data ));
+	g_assert( NACT_IS_GCONF( user_data ));
+	NactGConf *gconf = NACT_GCONF( user_data );
 
-	const GConfValue* value = gconf_entry_get_value( entry );
 	const gchar *path = gconf_entry_get_key( entry );
 	const gchar *subpath = path + strlen( NACT_GCONF_CONFIG_PATH ) + 1;
-
 	gchar **split = g_strsplit( subpath, "/", 2 );
 	gchar *key = g_strdup( split[0] );
+	gchar *parm = g_strdup( split[1] );
 	g_strfreev( split );
 
-	/*nact_pivot_on_action_changed( NACT_PIVOT( user_data ), key, parm, value );*/
-	g_free( key );
-
-	/*NactGConf *gconf = NACT_GCONF( user_data );*/
-
-	/* The Key value format is XXX:YYYY-YYYY-... where XXX is an number incremented to make key
-	 * effectively changed each time and YYYY-YYYY-... is the modified uuid */
-	const gchar* notify_value = gconf_value_get_string (value);
-	g_debug( "%s: notify_value='%s', key='%s'", thisfn, notify_value, key );
-	/*const gchar* uuid = notify_value + 4;*/
-
-	/* Get the modified action from the internal list if any */
-	/*NautilusActionsConfigAction *old_action = nautilus_actions_config_get_action (config, uuid);*/
+	NactPivotValue *value = value_to_pivot( gconf_entry_get_value( entry ));
 
-	/* Get the new version from GConf if any */
-	/*NautilusActionsConfigAction *new_action = nautilus_actions_config_gconf_get_action (NAUTILUS_ACTIONS_CONFIG_GCONF (config), uuid);*/
+	nact_pivot_on_action_changed( NACT_PIVOT( gconf->private->notification_handler ), key, parm, value );
 
-	/* If modified action is unknown internally */
-	/*if (old_action == NULL)
-	{
-		if (new_action != NULL)
-		{*/
-			/* new action */
-			/*nautilus_actions_config_add_action (config, new_action, NULL);
-		}
-		else
-		{*/
-			/* This case should not happen */
-			/*g_assert_not_reached ();
-		}
-	}
-	else
-	{
-		if (new_action != NULL)
-		{*/
-			/* action modified */
-			/*nautilus_actions_config_update_action (config, new_action);
-		}
-		else
-		{*/
-			/* action removed */
-			/*nautilus_actions_config_remove_action (config, uuid);
-		}
-	}*/
-
-	/* Add & change handler duplicate actions before adding them,
-	 * so we can free the new action
-	 */
-	/*nautilus_actions_config_action_free (new_action);*/
+	g_free( key );
+	nact_pivot_free_pivot_value( value );
 }
 
 static void
@@ -482,14 +432,14 @@ path_to_key( const gchar *path )
  * allocate a new NactGConfIO structure
  * to be freed via nact_gconf_dispose
  */
-static NactGConfIO *
+/*static NactGConfIO *
 path_to_struct( const gchar *path )
 {
 	NactGConfIO *io = g_new0( NactGConfIO, 1 );
 	io->key = path_to_key( path );
 	io->path = g_strdup( path );
 	return( io );
-}
+}*/
 
 /*
  * set the item properties into the object
@@ -533,6 +483,10 @@ value_to_pivot( const GConfValue *value )
 	NactPivotValue *pivot_value = NULL;
 	GSList *listvalues, *iv, *strings;
 
+	if( !value ){
+		return(( NactPivotValue * ) NULL );
+	}
+
 	switch( value->type ){
 
 		case GCONF_VALUE_STRING:
@@ -570,141 +524,128 @@ value_to_pivot( const GConfValue *value )
 }
 
 /*
- * NactIIOProviderInterface implementation
- * load the list of actions and returns them as a GSList
- */
-static GSList *
-do_load_actions( NactIIOProvider *provider )
-{
-	static const gchar *thisfn = "nacf_gconf_do_load_actions";
-	g_debug( "%s: provider=%p", thisfn, provider );
-
-	g_assert( NACT_IS_IIO_PROVIDER( provider ));
-	g_assert( NACT_IS_GCONF( provider ));
-	NactGConf *self = NACT_GCONF( provider );
-
-	GSList *items = NULL;
-
-	GSList *listpath = load_subdirs( self, NACT_GCONF_CONFIG_PATH );
-	GSList *ip;
-	for( ip = listpath ; ip ; ip = ip->next ){
-
-		NactGConfIO *io = path_to_struct(( const gchar * ) ip->data );
-
-		NactAction *action = nact_action_new( self, io );
-		nact_action_load( action );
-
-		items = g_slist_prepend( items, action );
-	}
-	nactuti_free_string_list( listpath );
-
-	return( items );
-}
-
-/*
- * NactIIOProviderInterface implementation
  * load and set the properties of the specified action
  */
 static void
-do_load_action_properties( NactIIOClient *client )
+load_action_properties( NactGConf *gconf, NactAction *action )
 {
-	static const gchar *thisfn = "nacf_gconf_do_load_action_properties";
-	g_debug( "%s: client=%p", thisfn, client );
+	/*static const gchar *thisfn = "nacf_gconf_load_action_properties";
+	g_debug( "%s: gconf=%p, action=%p", thisfn, gconf, action );*/
 
-	g_assert( NACT_IS_IIO_CLIENT( client ));
-	g_assert( NACT_IS_ACTION( client ));
-	NactAction *action = NACT_ACTION( client );
+	g_assert( NACT_IS_GCONF( gconf ));
+	g_assert( NACT_IS_ACTION( action ));
 
-	NactGConfIO *io = ( NactGConfIO * ) nact_iio_client_get_provider_data( client );
-	NactGConf *self = NACT_GCONF( nact_iio_client_get_provider_id( client ));
+	gchar *uuid = nact_action_get_uuid( action );
+	gchar *path = g_strdup_printf( "%s/%s", NACT_GCONF_CONFIG_PATH, uuid );
 
-	GSList *properties = load_keys_values( self, io->path );
+	GSList *properties = load_keys_values( gconf, path );
 
 	set_item_properties( NACT_OBJECT( action ), properties );
 
 	free_keys_values( properties );
+	g_free( uuid );
+	g_free( path );
 }
 
 /*
- * NactIIOProviderInterface implementation
  * load the list of profiles for an action and returns them as a GSList
  */
 static GSList *
-do_load_profiles( NactIIOClient *client )
+load_profiles( NactGConf *gconf, NactAction *action )
 {
-	static const gchar *thisfn = "nacf_gconf_do_load_profiles";
-	g_debug( "%s: client=%p", thisfn, client );
+	/*static const gchar *thisfn = "nacf_gconf_load_profiles";
+	g_debug( "%s: gconf=%p, action=%p", thisfn, gconf, action );*/
 
-	g_assert( NACT_IS_IIO_CLIENT( client ));
-	g_assert( NACT_IS_ACTION( client ));
-	NactAction *action = NACT_ACTION( client );
+	g_assert( NACT_IS_GCONF( gconf ));
+	g_assert( NACT_IS_ACTION( action ));
 
-	NactGConfIO *io = ( NactGConfIO * ) nact_iio_client_get_provider_data( client );
-	NactGConf *self = NACT_GCONF( nact_iio_client_get_provider_id( client ));
+	gchar *uuid = nact_action_get_uuid( action );
+	gchar *path = g_strdup_printf( "%s/%s", NACT_GCONF_CONFIG_PATH, uuid );
 
+	GSList *ip;
 	GSList *items = NULL;
+	GSList *listpath = load_subdirs( gconf, path );
 
-	GSList *listpath = load_subdirs( self, io->path );
-	GSList *ip;
 	for( ip = listpath ; ip ; ip = ip->next ){
 
 		gchar *key = path_to_key(( const gchar * ) ip->data );
 		NactActionProfile *profile = nact_action_profile_new( NACT_OBJECT( action ), key );
-		nact_action_profile_load( NACT_OBJECT( profile ));
+		load_profile_properties( gconf, profile );
 
 		items = g_slist_prepend( items, profile );
 	}
+
 	nactuti_free_string_list( listpath );
+	g_free( path );
+	g_free( uuid );
 
 	return( items );
 }
 
 /*
- * NactIIOProviderInterface implementation
  * load and set the properties of the specified profile
  */
 static void
-do_load_profile_properties( NactObject *profile )
+load_profile_properties( NactGConf *gconf, NactActionProfile *profile )
 {
-	static const gchar *thisfn = "nacf_gconf_do_load_profile_properties";
-	g_debug( "%s: profile=%p", thisfn, profile );
+	/*static const gchar *thisfn = "nacf_gconf_load_profile_properties";
+	g_debug( "%s: gconf=%p, profile=%p", thisfn, gconf, profile );*/
 
+	g_assert( NACT_IS_GCONF( gconf ));
 	g_assert( NACT_IS_ACTION_PROFILE( profile ));
 
 	NactAction *action =
 		NACT_ACTION( nact_action_profile_get_action( NACT_ACTION_PROFILE( profile )));
-
 	g_assert( NACT_IS_ACTION( action ));
-	g_assert( NACT_IS_IIO_CLIENT( action ));
-
-	NactIIOClient *client = NACT_IIO_CLIENT( action );
-
-	NactGConfIO *io = ( NactGConfIO * ) nact_iio_client_get_provider_data( client );
-	NactGConf *self = NACT_GCONF( nact_iio_client_get_provider_id( client ));
 
+	gchar *uuid = nact_action_get_uuid( action );
 	gchar *path = g_strdup_printf(
-			"%s/%s", io->path, nact_action_profile_get_id( NACT_ACTION_PROFILE( profile )));
-
-	GSList *properties = load_keys_values( self, path );
+			"%s/%s/%s", NACT_GCONF_CONFIG_PATH, uuid, nact_action_profile_get_name( profile ));
 
-	g_free( path );
+	GSList *properties = load_keys_values( gconf, path );
 
-	set_item_properties( profile, properties );
+	set_item_properties( NACT_OBJECT( profile ), properties );
 
 	free_keys_values( properties );
+	g_free( path );
+	g_free( uuid );
 }
 
 /*
  * NactIIOProviderInterface implementation
+ * load the list of actions and returns them as a GSList
  */
-static void
-do_release_data( NactIIOClient *client )
+static GSList *
+do_load_actions( NactIIOProvider *provider )
 {
-	g_assert( NACT_IS_IIO_CLIENT( client ));
+	static const gchar *thisfn = "nacf_gconf_do_load_actions";
+	g_debug( "%s: provider=%p", thisfn, provider );
+
+	g_assert( NACT_IS_IIO_PROVIDER( provider ));
+	g_assert( NACT_IS_GCONF( provider ));
+	NactGConf *self = NACT_GCONF( provider );
 
-	NactGConfIO *io = ( NactGConfIO * ) nact_iio_client_get_provider_data( client );
+	GSList *items = NULL;
+	GSList *ip;
+	GSList *listpath = load_subdirs( self, NACT_GCONF_CONFIG_PATH );
 
-	g_free( io->key );
-	g_free( io->path );
-	g_free( io );
+	for( ip = listpath ; ip ; ip = ip->next ){
+
+		gchar *key = path_to_key(( const gchar * ) ip->data );
+
+		NactAction *action = nact_action_new( key );
+		load_action_properties( self, action );
+		nact_action_set_profiles( action, load_profiles( self, action ));
+
+#ifdef NACT_MAINTAINER_MODE
+		nact_object_dump( NACT_OBJECT( action ));
+#endif
+
+		items = g_slist_prepend( items, action );
+		g_free( key );
+	}
+
+	nactuti_free_string_list( listpath );
+
+	return( items );
 }
diff --git a/src/common/nact-gconf.h b/src/common/nact-gconf.h
index 74d2ee1..b04d821 100644
--- a/src/common/nact-gconf.h
+++ b/src/common/nact-gconf.h
@@ -66,7 +66,7 @@ typedef struct {
 
 GType      nact_gconf_get_type( void );
 
-NactGConf *nact_gconf_new( const GObject *pivot );
+NactGConf *nact_gconf_new( const GObject *notification_handler );
 
 G_END_DECLS
 
diff --git a/src/common/nact-iio-client.c b/src/common/nact-iio-client.c
deleted file mode 100644
index 09d16ec..0000000
--- a/src/common/nact-iio-client.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Nautilus Actions
- * A Nautilus extension which offers configurable context menu actions.
- *
- * Copyright (C) 2005 The GNOME Foundation
- * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
- * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
- *
- * 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 2 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 Library; see the file COPYING.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place,
- * Suite 330, Boston, MA 02111-1307, USA.
- *
- * Authors:
- *   Frederic Ruaudel <grumz grumz net>
- *   Rodrigo Moya <rodrigo gnome-db org>
- *   Pierre Wieser <pwieser trychlos org>
- *   ... and many others (see AUTHORS)
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "nact-iio-client.h"
-#include "nact-io-client.h"
-
-struct NactIIOClientInterfacePrivate {
-};
-
-static GType register_type( void );
-static void  interface_base_init( NactIIOClientInterface *klass );
-static void  interface_base_finalize( NactIIOClientInterface *klass );
-
-GType
-nact_iio_client_get_type( void )
-{
-	static GType object_type = 0;
-
-	if( !object_type ){
-		object_type = register_type();
-	}
-
-	return( object_type );
-}
-
-static GType
-register_type( void )
-{
-	static const GTypeInfo info = {
-		sizeof( NactIIOClientInterface ),
-		( GBaseInitFunc ) interface_base_init,
-		( GBaseFinalizeFunc ) interface_base_finalize,
-		NULL,
-		NULL,
-		NULL,
-		0,
-		0,
-		NULL
-	};
-
-	GType type = g_type_register_static( G_TYPE_INTERFACE, "NactIIOClient", &info, 0 );
-
-	g_type_interface_add_prerequisite( type, G_TYPE_OBJECT );
-
-	return( type );
-}
-
-static void
-interface_base_init( NactIIOClientInterface *klass )
-{
-	static const gchar *thisfn = "nact_iio_client_interface_base_init";
-	static gboolean initialized = FALSE;
-
-	if( !initialized ){
-		g_debug( "%s: klass=%p", thisfn, klass );
-
-		klass->private = g_new0( NactIIOClientInterfacePrivate, 1 );
-
-		klass->get_io_client = NULL;
-
-		initialized = TRUE;
-	}
-}
-
-static void
-interface_base_finalize( NactIIOClientInterface *klass )
-{
-	static const gchar *thisfn = "nact_iio_client_interface_base_finalize";
-	static gboolean finalized = FALSE ;
-
-	if( !finalized ){
-		g_debug( "%s: klass=%p", thisfn, klass );
-
-		g_free( klass->private );
-
-		finalized = TRUE;
-	}
-}
-
-/**
- * Returns the provider id, usually a pointer to an object which
- * implements the NactIIOProvider interface.
- *
- * @client: a pointer to an object which implements the NactIIOClient
- * interface.
- */
-gpointer
-nact_iio_client_get_provider_id( const NactIIOClient *client )
-{
-	g_return_val_if_fail( NACT_IS_IIO_CLIENT( client ), NULL );
-
-	if( NACT_IIO_CLIENT_GET_INTERFACE( client )->get_io_client ){
-
-		NactIOClient *io_client =
-			NACT_IO_CLIENT( NACT_IIO_CLIENT_GET_INTERFACE( client )->get_io_client( client ));
-
-		return( nact_io_client_get_provider_id( io_client ));
-	}
-
-	return( NULL );
-}
-
-/**
- * Returns the provider data, usually a pointer to some data structure
- * allocated by the provider to handle object treatments.
- *
- * @client: a pointer to an object which implements the NactIIOClient
- * interface.
- */
-gpointer
-nact_iio_client_get_provider_data( const NactIIOClient *client )
-{
-	g_return_val_if_fail( NACT_IS_IIO_CLIENT( client ), NULL );
-
-	if( NACT_IIO_CLIENT_GET_INTERFACE( client )->get_io_client ){
-
-		NactIOClient *io_client =
-			NACT_IO_CLIENT( NACT_IIO_CLIENT_GET_INTERFACE( client )->get_io_client( client ));
-
-		return( nact_io_client_get_provider_data( io_client ));
-	}
-
-	return( NULL );
-}
diff --git a/src/common/nact-iio-client.h b/src/common/nact-iio-client.h
deleted file mode 100644
index cab26dc..0000000
--- a/src/common/nact-iio-client.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Nautilus Actions
- * A Nautilus extension which offers configurable context menu actions.
- *
- * Copyright (C) 2005 The GNOME Foundation
- * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
- * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
- *
- * 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 2 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 Library; see the file COPYING.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place,
- * Suite 330, Boston, MA 02111-1307, USA.
- *
- * Authors:
- *   Frederic Ruaudel <grumz grumz net>
- *   Rodrigo Moya <rodrigo gnome-db org>
- *   Pierre Wieser <pwieser trychlos org>
- *   ... and many others (see AUTHORS)
- */
-
-#ifndef __NACT_IIO_CLIENT_H__
-#define __NACT_IIO_CLIENT_H__
-
-/*
- * NactIIOClient interface definition.
- *
- * This is the NactAction base class.
- *
- * All objects which take advantage of an NactIIOProvider should
- * implement this interface ; it will give them an easy access to
- * NactIIOProvider data.
- */
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define NACT_IIO_CLIENT_TYPE					( nact_iio_client_get_type())
-#define NACT_IIO_CLIENT( object )				( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_IIO_CLIENT_TYPE, NactIIOClient ))
-#define NACT_IS_IIO_CLIENT( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_IIO_CLIENT_TYPE ))
-#define NACT_IIO_CLIENT_GET_INTERFACE( object )	( G_TYPE_INSTANCE_GET_INTERFACE(( object ), NACT_IIO_CLIENT_TYPE, NactIIOClientInterface ))
-
-typedef struct NactIIOClient NactIIOClient;
-
-typedef struct NactIIOClientInterfacePrivate NactIIOClientInterfacePrivate;
-
-typedef struct {
-	GTypeInterface                 parent;
-	NactIIOClientInterfacePrivate *private;
-
-	/* api */
-	GObject * ( *get_io_client )( const NactIIOClient *client );
-}
-	NactIIOClientInterface;
-
-GType    nact_iio_client_get_type( void );
-
-gpointer nact_iio_client_get_provider_id( const NactIIOClient *client );
-gpointer nact_iio_client_get_provider_data( const NactIIOClient *client );
-
-G_END_DECLS
-
-#endif /* __NACT_IIO_CLIENT_H__ */
diff --git a/src/common/nact-iio-provider.c b/src/common/nact-iio-provider.c
index 1fd565f..2c5bfe8 100644
--- a/src/common/nact-iio-provider.c
+++ b/src/common/nact-iio-provider.c
@@ -32,8 +32,6 @@
 #include <config.h>
 #endif
 
-#include "nact-action.h"
-#include "nact-action-profile.h"
 #include "nact-iio-provider.h"
 #include "nact-pivot.h"
 
@@ -96,10 +94,6 @@ interface_base_init( NactIIOProviderInterface *klass )
 		klass->private = g_new0( NactIIOProviderInterfacePrivate, 1 );
 
 		klass->load_actions = NULL;
-		klass->load_action_properties = NULL;
-		klass->load_profiles = NULL;
-		klass->load_profile_properties = NULL;
-		klass->release_data = NULL;
 
 		initialized = TRUE;
 	}
@@ -153,87 +147,3 @@ nact_iio_provider_load_actions( const GObject *object )
 
 	return( actions );
 }
-
-/**
- * Load and set properties of the action.
- */
-void
-nact_iio_provider_load_action_properties( NactIIOClient *client )
-{
-	static const gchar *thisfn = "nact_iio_provider_load_action_properties";
-	g_debug( "%s: client=%p", thisfn, client );
-
-	g_assert( NACT_IS_IIO_CLIENT( client ));
-	g_assert( NACT_IS_ACTION( client ));
-
-	NactIIOProvider *provider = nact_iio_client_get_provider_id( client );
-
-	if( NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_action_properties ){
-		NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_action_properties( client );
-	}
-}
-
-/**
- * Load the defined profiles for the action.
- *
- * Return a GSList of NactActionProfile objects.
- */
-GSList *
-nact_iio_provider_load_profiles( NactIIOClient *client )
-{
-	static const gchar *thisfn = "nact_iio_provider_load_profiles";
-	g_debug( "%s: client=%p", thisfn, client );
-
-	g_assert( NACT_IS_IIO_CLIENT( client ));
-	g_assert( NACT_IS_ACTION( client ));
-
-	NactIIOProvider *provider = nact_iio_client_get_provider_id( client );
-
-	GSList *profiles = NULL;
-
-	if( NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_profiles ){
-		GSList *list = NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_profiles( client );
-		profiles = g_slist_concat( profiles, list );
-	}
-
-	return( profiles );
-}
-
-/**
- * Load and set properties of the profile.
- */
-void
-nact_iio_provider_load_profile_properties( NactObject *profile )
-{
-	static const gchar *thisfn = "nact_iio_provider_load_profile_properties";
-	g_debug( "%s", thisfn );
-
-	g_assert( NACT_IS_ACTION_PROFILE( profile ));
-
-	NactIIOClient *client =
-		NACT_IIO_CLIENT( nact_action_profile_get_action( NACT_ACTION_PROFILE( profile )));
-
-	g_assert( NACT_IS_IIO_CLIENT( client ));
-	g_assert( NACT_IS_ACTION( client ));
-
-	NactIIOProvider *provider = nact_iio_client_get_provider_id( client );
-
-	if( NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_profile_properties ){
-		NACT_IIO_PROVIDER_GET_INTERFACE( provider )->load_profile_properties( profile );
-	}
-}
-
-/**
- * Called by nact_io_client_instance_dispose.
- */
-void
-nact_iio_provider_release_data( NactIIOClient *client )
-{
-	g_assert( NACT_IS_IIO_CLIENT( client ));
-
-	NactIIOProvider *provider = nact_iio_client_get_provider_id( client );
-
-	if( NACT_IIO_PROVIDER_GET_INTERFACE( provider )->release_data ){
-		NACT_IIO_PROVIDER_GET_INTERFACE( provider )->release_data( client );
-	}
-}
diff --git a/src/common/nact-iio-provider.h b/src/common/nact-iio-provider.h
index 87aa410..b58697b 100644
--- a/src/common/nact-iio-provider.h
+++ b/src/common/nact-iio-provider.h
@@ -42,8 +42,7 @@
  * startup time (e.g. on the model of provider interfaces in Nautilus).
  */
 
-#include "nact-object.h"
-#include "nact-iio-client.h"
+#include "glib-object.h"
 
 G_BEGIN_DECLS
 
@@ -62,21 +61,12 @@ typedef struct {
 
 	/* i/o api */
 	GSList * ( *load_actions )( NactIIOProvider *instance );
-	void     ( *load_action_properties )( NactIIOClient *client );
-	GSList * ( *load_profiles )( NactIIOClient *client );
-	void     ( *load_profile_properties )( NactObject *profile );
-	void     ( *release_data )( NactIIOClient *client );
 }
 	NactIIOProviderInterface;
 
 GType   nact_iio_provider_get_type( void );
 
 GSList *nact_iio_provider_load_actions( const GObject *pivot );
-void    nact_iio_provider_load_action_properties( NactIIOClient *client );
-GSList *nact_iio_provider_load_profiles( NactIIOClient *client );
-void    nact_iio_provider_load_profile_properties( NactObject *profile );
-
-void    nact_iio_provider_release_data( NactIIOClient *client );
 
 G_END_DECLS
 
diff --git a/src/common/nact-io-client.c b/src/common/nact-io-client.c
deleted file mode 100644
index fabd006..0000000
--- a/src/common/nact-io-client.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Nautilus Actions
- * A Nautilus extension which offers configurable context menu actions.
- *
- * Copyright (C) 2005 The GNOME Foundation
- * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
- * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
- *
- * 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 2 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 Library; see the file COPYING.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place,
- * Suite 330, Boston, MA 02111-1307, USA.
- *
- * Authors:
- *   Frederic Ruaudel <grumz grumz net>
- *   Rodrigo Moya <rodrigo gnome-db org>
- *   Pierre Wieser <pwieser trychlos org>
- *   ... and many others (see AUTHORS)
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "nact-io-client.h"
-
-struct NactIOClientPrivate {
-	gboolean dispose_has_run;
-	gpointer provider_id;
-	gpointer provider_data;
-};
-
-struct NactIOClientClassPrivate {
-};
-
-enum {
-	PROP_PROVIDER_ID = 1,
-	PROP_PROVIDER_DATA
-};
-
-static GObjectClass *st_parent_class = NULL;
-
-static GType   register_type( void );
-static void    class_init( NactIOClientClass *klass );
-static void    instance_init( GTypeInstance *instance, gpointer klass );
-static void    instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
-static void    instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
-static void    instance_dispose( GObject *object );
-static void    instance_finalize( GObject *object );
-
-NactIOClient *
-nact_io_client_new( gpointer provider, gpointer data )
-{
-	return( g_object_new( NACT_IO_CLIENT_TYPE, "provider-id", provider, "provider-data", data, NULL ));
-}
-
-GType
-nact_io_client_get_type( void )
-{
-	static GType object_type = 0;
-
-	if( !object_type ){
-		object_type = register_type();
-	}
-
-	return( object_type );
-}
-
-static GType
-register_type( void )
-{
-	static GTypeInfo info = {
-		sizeof( NactIOClientClass ),
-		( GBaseInitFunc ) NULL,
-		( GBaseFinalizeFunc ) NULL,
-		( GClassInitFunc ) class_init,
-		NULL,
-		NULL,
-		sizeof( NactIOClient ),
-		0,
-		( GInstanceInitFunc ) instance_init
-	};
-
-	return( g_type_register_static( G_TYPE_OBJECT, "NactIOClient", &info, 0 ));
-}
-
-static void
-class_init( NactIOClientClass *klass )
-{
-	static const gchar *thisfn = "nact_io_client_class_init";
-	g_debug( "%s: klass=%p", thisfn, klass );
-
-	st_parent_class = g_type_class_peek_parent( klass );
-
-	GObjectClass *object_class = G_OBJECT_CLASS( klass );
-	object_class->dispose = instance_dispose;
-	object_class->finalize = instance_finalize;
-	object_class->set_property = instance_set_property;
-	object_class->get_property = instance_get_property;
-
-	GParamSpec *spec;
-	spec = g_param_spec_pointer(
-			"provider-id",
-			"provider-id",
-			"IIO Provider internal id.",
-			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_PROVIDER_ID, spec );
-
-	spec = g_param_spec_pointer(
-			"provider-data",
-			"provider-data",
-			"IIO Provider internal data area pointer",
-			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_PROVIDER_DATA, spec );
-
-	klass->private = g_new0( NactIOClientClassPrivate, 1 );
-}
-
-static void
-instance_init( GTypeInstance *instance, gpointer klass )
-{
-	/*static const gchar *thisfn = "nact_io_client_instance_init";
-	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );*/
-
-	g_assert( NACT_IS_IO_CLIENT( instance ));
-	NactIOClient *self = NACT_IO_CLIENT( instance );
-
-	self->private = g_new0( NactIOClientPrivate, 1 );
-
-	self->private->dispose_has_run = FALSE;
-	self->private->provider_id = NULL;
-	self->private->provider_data = NULL;
-}
-
-static void
-instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
-{
-	g_assert( NACT_IS_IO_CLIENT( object ));
-	NactIOClient *self = NACT_IO_CLIENT( object );
-
-	switch( property_id ){
-		case PROP_PROVIDER_ID:
-			g_value_set_pointer( value, self->private->provider_id );
-			break;
-
-		case PROP_PROVIDER_DATA:
-			g_value_set_pointer( value, self->private->provider_data );
-			break;
-
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
-			break;
-	}
-}
-
-static void
-instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
-{
-	/*static const gchar *thisfn = "nact_object_instance_set_property";*/
-
-	g_assert( NACT_IS_IO_CLIENT( object ));
-	NactIOClient *self = NACT_IO_CLIENT( object );
-
-	switch( property_id ){
-		case PROP_PROVIDER_ID:
-			self->private->provider_id = g_value_get_pointer( value );
-			/*g_debug( "%s: io_origin=%d", thisfn, self->private->io_origin );*/
-			break;
-
-		case PROP_PROVIDER_DATA:
-			self->private->provider_data = g_value_get_pointer( value );
-			/*g_debug( "%s: io_subsystem=%p", thisfn, self->private->io_subsystem );*/
-			break;
-
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
-			break;
-	}
-}
-
-static void
-instance_dispose( GObject *object )
-{
-	g_assert( NACT_IS_IO_CLIENT( object ));
-	NactIOClient *self = NACT_IO_CLIENT( object );
-
-	if( !self->private->dispose_has_run ){
-
-		self->private->dispose_has_run = TRUE;
-
-		/* chain up to the parent class */
-		G_OBJECT_CLASS( st_parent_class )->dispose( object );
-	}
-}
-
-static void
-instance_finalize( GObject *object )
-{
-	g_assert( NACT_IS_IO_CLIENT( object ));
-	/*NactIOClient *self = ( NactIOClient * ) object;*/
-
-	/* chain call to parent class */
-	if( st_parent_class->finalize ){
-		G_OBJECT_CLASS( st_parent_class )->finalize( object );
-	}
-}
-
-/**
- * Returns the provider id, usually a pointer to an object which
- * implements the NactIIOProvider interface.
- *
- * @client: a pointer to a NactIOClient object.
- */
-gpointer
-nact_io_client_get_provider_id( const NactIOClient *client )
-{
-	g_assert( NACT_IS_IO_CLIENT( client ));
-	gpointer id;
-	g_object_get( G_OBJECT( client ), "provider-id", &id, NULL );
-	return( id );
-}
-
-/**
- * Returns the provider data, usually a pointer to a structure which
- * holds some NactIIOProvider-relative data.
- *
- * @client: a pointer to a NactIOClient object.
- */
-gpointer
-nact_io_client_get_provider_data( const NactIOClient *client )
-{
-	g_assert( NACT_IS_IO_CLIENT( client ));
-	gpointer data;
-	g_object_get( G_OBJECT( client ), "provider-data", &data, NULL );
-	return( data );
-}
diff --git a/src/common/nact-io-client.h b/src/common/nact-io-client.h
deleted file mode 100644
index b077fd1..0000000
--- a/src/common/nact-io-client.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Nautilus Actions
- * A Nautilus extension which offers configurable context menu actions.
- *
- * Copyright (C) 2005 The GNOME Foundation
- * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
- * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
- *
- * 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 2 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 Library; see the file COPYING.  If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place,
- * Suite 330, Boston, MA 02111-1307, USA.
- *
- * Authors:
- *   Frederic Ruaudel <grumz grumz net>
- *   Rodrigo Moya <rodrigo gnome-db org>
- *   Pierre Wieser <pwieser trychlos org>
- *   ... and many others (see AUTHORS)
- */
-
-#ifndef __NACT_IO_CLIENT_H__
-#define __NACT_IO_CLIENT_H__
-
-/*
- * NactIOClient class definition.
- *
- * A NactIOClient object should be embedded in every class which
- * implements NactIIOClient interface. This acts as a companion class
- * for NactIIOProvider interface.
- */
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define NACT_IO_CLIENT_TYPE					( nact_io_client_get_type())
-#define NACT_IO_CLIENT( object )			( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_IO_CLIENT_TYPE, NactIOClient ))
-#define NACT_IO_CLIENT_CLASS( klass )		( G_TYPE_CHECK_CLASS_CAST( klass, NACT_IO_CLIENT_TYPE, NactIOClientClass ))
-#define NACT_IS_IO_CLIENT( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_IO_CLIENT_TYPE ))
-#define NACT_IS_IO_CLIENT_CLASS( klass )	( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_IO_CLIENT_TYPE ))
-#define NACT_IO_CLIENT_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_IO_CLIENT_TYPE, NactIOClientClass ))
-
-typedef struct NactIOClientPrivate NactIOClientPrivate;
-
-typedef struct {
-	GObject              parent;
-	NactIOClientPrivate *private;
-}
-	NactIOClient;
-
-typedef struct NactIOClientClassPrivate NactIOClientClassPrivate;
-
-typedef struct {
-	GObjectClass              parent;
-	NactIOClientClassPrivate *private;
-}
-	NactIOClientClass;
-
-GType         nact_io_client_get_type( void );
-
-NactIOClient *nact_io_client_new( gpointer provider, gpointer data );
-
-gpointer      nact_io_client_get_provider_id( const NactIOClient *client );
-gpointer      nact_io_client_get_provider_data( const NactIOClient *client );
-
-G_END_DECLS
-
-#endif /* __NACT_IO_CLIENT_H__ */
diff --git a/src/common/nact-pivot.c b/src/common/nact-pivot.c
index 46fe846..45fe1d0 100644
--- a/src/common/nact-pivot.c
+++ b/src/common/nact-pivot.c
@@ -32,11 +32,22 @@
 #include <config.h>
 #endif
 
+#include "nact-action.h"
 #include "nact-gconf.h"
 #include "nact-pivot.h"
 #include "nact-iio-provider.h"
 #include "uti-lists.h"
 
+/* action_changed_cb send events which are stacked in a static GSList
+ * we so hope to optimize updating the global list of actions
+ */
+typedef struct {
+	gchar          *uuid;
+	gchar          *parm;
+	NactPivotValue *value;
+}
+	stackItem;
+
 struct NactPivotPrivate {
 	gboolean  dispose_has_run;
 
@@ -55,14 +66,27 @@ struct NactPivotPrivate {
 struct NactPivotClassPrivate {
 };
 
-static GObjectClass   *st_parent_class = NULL;
-
-static GType   register_type( void );
-static void    class_init( NactPivotClass *klass );
-static void    instance_init( GTypeInstance *instance, gpointer klass );
-static GSList *register_interface_providers( const NactPivot *pivot );
-static void    instance_dispose( GObject *object );
-static void    instance_finalize( GObject *object );
+static GObjectClass *st_parent_class = NULL;
+static GSList       *st_stack_events = NULL;
+static GTimeVal      st_last_event;
+static guint         st_event_source_id = 0;
+
+static GType       register_type( void );
+static void        class_init( NactPivotClass *klass );
+static void        instance_init( GTypeInstance *instance, gpointer klass );
+static GSList     *register_interface_providers( const NactPivot *pivot );
+static void        instance_dispose( GObject *object );
+static void        instance_finalize( GObject *object );
+
+static void        check_for_remove_action( NactPivot *pivot, NactAction *action );
+static gint        cmp_events( gconstpointer a, gconstpointer b );
+static void        free_stack_events( GSList *stack );
+static gboolean    on_action_changed_timeout( gpointer user_data );
+static stackItem  *stack_item_new( const gchar *uuid, const gchar *parm, const NactPivotValue *value );
+static void        stack_item_free( stackItem *item );
+static gulong      time_val_diff( const GTimeVal *recent, const GTimeVal *old );
+static void        update_actions( NactPivot *pivot, GSList *stack );
+static NactAction *get_action( GSList *list, const gchar *uuid );
 
 NactPivot *
 nact_pivot_new( void )
@@ -215,6 +239,75 @@ nact_pivot_get_providers( const NactPivot *pivot, GType type )
 }
 
 /**
+ * This function should be called when a storage subsystem detects that
+ * a stored action has changed.
+ * As a Nautilus extension, NactPivot will take care of updating menu
+ * characteristics accordingly.
+ *
+ * @pivot: the NactPivot object.
+ *
+ * @uuid: identifiant of the action.
+ *
+ * @parm: the parameter path (e.g. "profile-main/path")
+ *
+ * @value: the new value as a NactPivotValue structure ; do not free it
+ * here as it is the responsability of the allocater subsystem.
+ *
+ * Depending of the sort of update which occurs, we may receive many
+ * notifications for the same action. We so stack the notifications and
+ * start a one sec. timeout before updating the whole stack.
+ */
+void
+nact_pivot_on_action_changed( NactPivot *pivot, const gchar *uuid, const gchar *parm, NactPivotValue *value )
+{
+	static const gchar *thisfn = "nact_pivot_on_action_changed";
+	g_debug( "%s: pivot=%p, uuid='%s', parm='%s', value=%p", thisfn, pivot, uuid, parm, value );
+
+	stackItem *item = ( stackItem * ) stack_item_new( uuid, parm, value );
+	st_stack_events = g_slist_prepend( st_stack_events, item );
+
+	g_get_current_time( &st_last_event );
+
+	if( !st_event_source_id ){
+		st_event_source_id = g_timeout_add_seconds( 1, ( GSourceFunc ) on_action_changed_timeout, pivot );
+	}
+}
+
+/**
+ * Duplicate a NactPivotValue structure and its content.
+ */
+NactPivotValue *
+nact_pivot_duplicate_pivot_value( const NactPivotValue *value )
+{
+	if( !value ){
+		return(( NactPivotValue * ) NULL );
+	}
+
+	NactPivotValue *newvalue = g_new0( NactPivotValue, 1 );
+
+	switch( value->type ){
+
+		case NACT_PIVOT_STR:
+			newvalue->data = g_strdup(( gchar * ) value->data );
+			break;
+
+		case NACT_PIVOT_BOOL:
+			newvalue->data = value->data;
+			break;
+
+		case NACT_PIVOT_STRLIST:
+			newvalue->data = nactuti_duplicate_string_list(( GSList * ) value->data );
+			break;
+
+		default:
+			g_assert_not_reached();
+			break;
+	}
+
+	return( newvalue );
+}
+
+/**
  * Free a NactPivotValue structure and its content.
  */
 void
@@ -241,3 +334,166 @@ nact_pivot_free_pivot_value( NactPivotValue *value )
 		g_free( value );
 	}
 }
+
+static void
+check_for_remove_action( NactPivot *pivot, NactAction *action )
+{
+	static const gchar *thisfn ="check_for_remove_action";
+
+	g_assert( NACT_IS_PIVOT( pivot ));
+	g_assert( NACT_IS_ACTION( action ));
+
+	if( nact_action_is_empty( action )){
+		g_debug( "%s: removing action %p", thisfn, action );
+		pivot->private->actions = g_slist_remove( pivot->private->actions, action );
+	}
+}
+
+/*
+ * comparaison function between two stack items
+ */
+static gint
+cmp_events( gconstpointer a, gconstpointer b )
+{
+	stackItem *sa = ( stackItem * ) a;
+	stackItem *sb = ( stackItem * ) b;
+	return( g_strcmp0( sa->uuid, sb->uuid ));
+}
+
+static void
+free_stack_events( GSList *stack )
+{
+	GSList *is;
+	for( is = stack ; is ; is = is->next ){
+		stack_item_free(( stackItem * ) is->data );
+	}
+	g_slist_free( stack );
+}
+
+/*
+ * this timer is set when we receive the first event of a serie
+ * we continue to loop until last event is at least one half of a
+ * second old
+ *
+ * there is no race condition here as we are not multithreaded
+ */
+static gboolean
+on_action_changed_timeout( gpointer user_data )
+{
+	static const gchar *thisfn = "on_action_changed_timeout";
+	GTimeVal now;
+
+	g_assert( NACT_IS_PIVOT( user_data ));
+
+	g_get_current_time( &now );
+	gulong diff = time_val_diff( &now, &st_last_event );
+	if( diff < 500000 ){
+		return( TRUE );
+	}
+
+	g_debug( "%s: treating stack with %d events", thisfn, g_slist_length( st_stack_events ));
+	update_actions( NACT_PIVOT( user_data ), st_stack_events );
+
+	st_event_source_id = 0;
+	free_stack_events( st_stack_events );
+	st_stack_events = NULL;
+	return( FALSE );
+}
+
+static stackItem *
+stack_item_new( const gchar *uuid, const gchar *parm, const NactPivotValue *value )
+{
+	stackItem *item = g_new0( stackItem, 1 );
+	item->uuid = g_strdup( uuid );
+	item->parm = g_strdup( parm );
+	item->value = nact_pivot_duplicate_pivot_value( value );
+	return( item );
+}
+
+static void
+stack_item_free( stackItem *item )
+{
+	g_free( item->uuid );
+	g_free( item->parm );
+	nact_pivot_free_pivot_value( item->value );
+	g_free( item );
+}
+
+/*
+ * returns the difference in microseconds.
+ */
+static gulong
+time_val_diff( const GTimeVal *recent, const GTimeVal *old )
+{
+	gulong microsec = 1000000 * ( recent->tv_sec - old->tv_sec );
+	microsec += recent->tv_usec  - old->tv_usec;
+	return( microsec );
+}
+
+/*
+ * iterate through the list of events, sorted by action id
+ * on new action, add it to the list, creating the object
+ * when all events have been treated, check to see if the action was
+ * actually removed (all fields, including key, are blank or null)
+ *
+ * remove = key + parm=null and value=null
+ */
+static void
+update_actions( NactPivot *pivot, GSList *stack )
+{
+	GSList *it;
+	NactAction *action = NULL;
+	gchar *previd = NULL;
+
+	GSList *sorted = g_slist_sort( stack, cmp_events );
+
+	for( it = sorted ; it ; it = it->next ){
+		stackItem *item = ( stackItem * ) it->data;
+
+		if( action && g_strcmp0( previd, item->uuid )){
+			g_assert( action && NACT_IS_ACTION( action ));
+			check_for_remove_action( pivot, action );
+			g_free( previd );
+		}
+		previd = g_strdup( item->uuid );
+		action = get_action( pivot->private->actions, item->uuid );
+
+		if( action ){
+			nact_action_update( action, item->parm, item->value );
+		} else {
+			action = nact_action_create( item->uuid, item->parm, item->value );
+			pivot->private->actions = g_slist_prepend( pivot->private->actions, action );
+		}
+	}
+	if( action ){
+		g_assert( action && NACT_IS_ACTION( action ));
+		check_for_remove_action( pivot, action );
+		g_free( previd );
+	}
+}
+
+static NactAction *
+get_action( GSList *list, const gchar *uuid )
+{
+	NactAction *found = NULL;
+	GSList *ia;
+	for( ia = list ; ia && !found ; ia = ia->next ){
+		NactAction *action = ( NactAction * ) ia->data;
+		gchar *id = nact_action_get_uuid( action );
+		if( !g_strcmp0( id, uuid )){
+			found = action;
+		}
+		g_free( id );
+	}
+	return( found );
+}
+
+/**
+ * Returns the searched NactAction, or NULL.
+ */
+GObject *
+nact_pivot_get_action( NactPivot *pivot, const gchar *uuid )
+{
+	g_assert( NACT_IS_PIVOT( pivot ));
+	return( G_OBJECT( get_action( pivot->private->actions, uuid )));
+}
diff --git a/src/common/nact-pivot.h b/src/common/nact-pivot.h
index c0871af..0ea8b0e 100644
--- a/src/common/nact-pivot.h
+++ b/src/common/nact-pivot.h
@@ -85,15 +85,17 @@ typedef struct {
 }
 	NactPivotClass;
 
-GType      nact_pivot_get_type( void );
+GType           nact_pivot_get_type( void );
 
-NactPivot *nact_pivot_new( void );
+NactPivot      *nact_pivot_new( void );
 
-GSList    *nact_pivot_get_providers( const NactPivot *pivot, GType type );
+GSList         *nact_pivot_get_providers( const NactPivot *pivot, GType type );
 
-void       nact_pivot_on_action_changed( NactPivot *pivot, const gchar *uuid, const gchar *parm, NactPivotValue *value );
+GObject        *nact_pivot_get_action( NactPivot *pivot, const gchar *uuid );
+void            nact_pivot_on_action_changed( NactPivot *pivot, const gchar *uuid, const gchar *parm, NactPivotValue *value );
 
-void       nact_pivot_free_pivot_value( NactPivotValue *value );
+NactPivotValue *nact_pivot_duplicate_pivot_value( const NactPivotValue *value );
+void            nact_pivot_free_pivot_value( NactPivotValue *value );
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]