[nautilus-actions] Connect and load the NactAction list at startup time



commit 6e29a21442e08d03c44bb1a1efe69578e67493d4
Author: Pierre Wieser <pwieser trychlos org>
Date:   Tue Jun 2 09:29:01 2009 +0200

    Connect and load the NactAction list at startup time
---
 ChangeLog                        |   25 +++
 src/common/nact-action-profile.c |   36 ++---
 src/common/nact-action.c         |  121 ++++----------
 src/common/nact-gconf.c          |  348 ++++++++++++++++++++++----------------
 src/common/nact-gconf.h          |   11 +-
 src/common/nact-storage.c        |  135 ++++++++++-----
 src/common/nact-storage.h        |   14 +-
 src/common/uti-lists.c           |   33 ++++
 src/common/uti-lists.h           |    3 +
 src/plugin/nautilus-actions.c    |    5 +-
 10 files changed, 415 insertions(+), 316 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b5870cd..1a2b536 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2009-06-02 Pierre Wieser <pwieser trychlos org>
+
+	* src/plugin/nautilus-actions.c:
+	* src/plugin/nautilus-actions.h:
+	Connect and load list of NactAction actions.
+
+	* src/common/nact-gconf.c:
+	* src/common/nact-gconf.h
+	(nact_gconf_dispose, nact_gconf_dump): New functions.
+
+	* src/common/uti-lists.c:
+	* src/common/util-lists.h
+	(nactuti_free_string_list, nactuti_duplicate_string_list):
+	New functions.
+
+	* src/common/nact-action.c:
+	* src/common/nact-action.h:
+	* src/common/nact-action-profile.c:
+	* src/common/nact-action-profile.h:
+	* src/common/nact-gconf.c:
+	* src/common/nact-gconf.h:
+	* src/common/nact-storage.c:
+	* src/common/nact-storage.h:
+	Updated accordingly.
+
 2009-06-01 Pierre Wieser <pwieser trychlos org>
 
 	* configure.ac: Have a more funny package string.
diff --git a/src/common/nact-action-profile.c b/src/common/nact-action-profile.c
index 2e906a3..ad1a162 100644
--- a/src/common/nact-action-profile.c
+++ b/src/common/nact-action-profile.c
@@ -34,6 +34,7 @@
 #include <libnautilus-extension/nautilus-file-info.h>
 #include <string.h>
 #include "nact-action-profile.h"
+#include "uti-lists.h"
 
 static NactStorageClass *st_parent_class = NULL;
 
@@ -47,7 +48,6 @@ static void   instance_finalize( GObject *object );
 static gchar *get_id( const NactStorage *profile );
 static void   do_dump( const NactStorage *profile );
 static void   do_dump_list( const gchar *thisfn, const gchar *label, GSList *list );
-static void   free_string_list( GSList *list );
 static int    validate_schemes( GSList* schemes2test, NautilusFileInfo* file );
 
 enum {
@@ -237,7 +237,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	NactActionProfile* self = NACT_ACTION_PROFILE( instance );
 
 	self->private = g_new0( NactActionProfilePrivate, 1 );
-
 	self->private->dispose_has_run = FALSE;
 }
 
@@ -245,9 +244,10 @@ static void
 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
 {
 	g_assert( NACT_IS_ACTION_PROFILE( object ));
-
 	NactActionProfile *self = NACT_ACTION_PROFILE( object );
 
+	GSList *list;
+
 	switch( property_id ){
 		case PROP_ACTION:
 			g_value_set_pointer( value, self->private->action );
@@ -274,7 +274,8 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 			break;
 
 		case PROP_BASENAMES:
-			g_value_set_pointer( value, self->private->basenames );
+			list = nactuti_duplicate_string_list( self->private->basenames );
+			g_value_set_pointer( value, list );
 			break;
 
 		case PROP_ISDIR:
@@ -290,11 +291,13 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 			break;
 
 		case PROP_MIMETYPES:
-			g_value_set_pointer( value, self->private->mimetypes );
+			list = nactuti_duplicate_string_list( self->private->mimetypes );
+			g_value_set_pointer( value, list );
 			break;
 
 		case PROP_SCHEMES:
-			g_value_set_pointer( value, self->private->schemes );
+			list = nactuti_duplicate_string_list( self->private->schemes );
+			g_value_set_pointer( value, list );
 			break;
 
 		default:
@@ -340,8 +343,8 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 			break;
 
 		case PROP_BASENAMES:
-			free_string_list( self->private->basenames );
-			self->private->basenames = g_value_get_pointer( value );
+			nactuti_free_string_list( self->private->basenames );
+			self->private->basenames = nactuti_duplicate_string_list( g_value_get_pointer( value ));
 			break;
 
 		case PROP_ISDIR:
@@ -357,13 +360,13 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 			break;
 
 		case PROP_MIMETYPES:
-			free_string_list( self->private->mimetypes );
-			self->private->mimetypes = g_value_get_pointer( value );
+			nactuti_free_string_list( self->private->mimetypes );
+			self->private->mimetypes = nactuti_duplicate_string_list( g_value_get_pointer( value ));
 			break;
 
 		case PROP_SCHEMES:
-			free_string_list( self->private->schemes );
-			self->private->schemes = g_value_get_pointer( value );
+			nactuti_free_string_list( self->private->schemes );
+			self->private->schemes = nactuti_duplicate_string_list( g_value_get_pointer( value ));
 			break;
 
 		default:
@@ -475,15 +478,6 @@ do_dump_list( const gchar *thisfn, const gchar *label, GSList *list )
 	g_string_free( str, TRUE );
 }
 
-static void
-free_string_list( GSList *list ){
-	GSList *item;
-	for( item = list ; item != NULL ; item = item->next ){
-		g_free(( gchar * ) item->data );
-	}
-	g_slist_free( list );
-}
-
 gchar *
 nact_action_profile_get_path( const NactActionProfile *profile )
 {
diff --git a/src/common/nact-action.c b/src/common/nact-action.c
index 9e18f71..e06d9ad 100644
--- a/src/common/nact-action.c
+++ b/src/common/nact-action.c
@@ -45,10 +45,8 @@ static void        instance_dispose( GObject *object );
 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_finalize( GObject *object );
-static NactAction *new_action( const gchar *uuid );
 static gchar      *get_id( const NactStorage *action );
 static void        do_dump( const NactStorage *action );
-static NactAction *load_action( const gchar *uuid );
 
 enum {
 	PROP_UUID = 1,
@@ -169,15 +167,13 @@ class_init( NactActionClass *klass )
 static void
 instance_init( GTypeInstance *instance, gpointer klass )
 {
-	static const gchar *thisfn = "nact_action_instance_init";
-	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );
+	/*static const gchar *thisfn = "nact_action_instance_init";
+	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );*/
 
 	g_assert( NACT_IS_ACTION( instance ));
-
 	NactAction* self = NACT_ACTION( instance );
 
 	self->private = g_new0( NactActionPrivate, 1 );
-
 	self->private->dispose_has_run = FALSE;
 }
 
@@ -185,7 +181,6 @@ static void
 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
 {
 	g_assert( NACT_IS_ACTION( object ));
-
 	NactAction *self = NACT_ACTION( object );
 
 	switch( property_id ){
@@ -219,7 +214,6 @@ static void
 instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
 {
 	g_assert( NACT_IS_ACTION( object ));
-
 	NactAction *self = NACT_ACTION( object );
 
 	switch( property_id ){
@@ -261,7 +255,6 @@ instance_dispose( GObject *object )
 	g_debug( "%s: object=%p", thisfn, object );
 
 	g_assert( NACT_IS_ACTION( object ));
-
 	NactAction *self = NACT_ACTION( object );
 
 	if( !self->private->dispose_has_run ){
@@ -285,7 +278,6 @@ instance_finalize( GObject *object )
 	g_debug( "%s: object=%p", thisfn, object );
 
 	g_assert( NACT_IS_ACTION( object ));
-
 	NactAction *self = ( NactAction * ) object;
 
 	g_free( self->private->uuid );
@@ -300,13 +292,6 @@ instance_finalize( GObject *object )
 	}
 }
 
-static NactAction *
-new_action( const gchar *uuid )
-{
-	NactAction *action = g_object_new( NACT_ACTION_TYPE, "uuid", uuid, NULL );
-	return( action );
-}
-
 static gchar *
 get_id( const NactStorage *action )
 {
@@ -343,66 +328,16 @@ do_dump( const NactStorage *action )
 	}
 }
 
-/*
- * load action
- *
- * +- load_action_properties
- *
- * +- load_profile_names
- *
- * +
- */
-static NactAction *
-load_action( const gchar *uuid )
-{
-	g_assert( uuid && strlen( uuid ));
-
-	NactAction *action = new_action( uuid );
-
-	if( !nact_storage_load_action_properties( NACT_STORAGE( action ))){
-		g_object_unref( action );
-		return( NULL );
-	}
-
-	GSList *list = nact_storage_load_profile_ids( NACT_STORAGE( action ));
-	if( !list ){
-		g_object_unref( action );
-		return( NULL );
-	}
-
-	GSList *profile_id;
-	for( profile_id = list ; profile_id != NULL ; profile_id = profile_id->next ){
-
-		NactActionProfile *profile_obj =
-			nact_action_profile_new( NACT_STORAGE( action), ( const gchar * ) profile_id->data );
-
-		if( !nact_storage_load_profile_properties( NACT_STORAGE( profile_obj ))){
-			g_object_unref( profile_obj );
-			g_object_unref( action );
-			return( NULL );
-		}
-
-		action->private->profiles = g_slist_prepend( action->private->profiles, profile_obj );
-	}
-
-	return( action );
-}
-
-/*
- * nautilus-actions_instance_init
- * +- nautilus_actions_load_list_actions
+/**
+ * Allocate and return the list of defined actions.
  *
- *    +- nact_action_load_actions
+ * Delegate to NactStorage how to search for locations of actions. The
+ * class will ask for this to each registered storage subsystem (GConf
+ * only for now).
  *
- *       +- nact_action_load_uuids
- *       |  +- nact_storage_load_uuids
- *       |     retrieve all storage subsystems (gconf only for now)
- *       |     foreach subsystem, do
- *       |     +- nact_<subsystem>_load_uuids
- *       |
- *       + foreach uuid, do
- *         +- new NactAction
- *         +- load_action
+ * NactStorage concatenates received lists and return the result as a
+ * list of pre-initialized NactStorage (actually NactAction) objects,
+ * each of them being able to address its own location.
  */
 GSList *
 nact_action_load_actions( void )
@@ -410,25 +345,20 @@ nact_action_load_actions( void )
 	static gchar *thisfn = "nact_action_load_actions";
 	g_debug( "%s", thisfn );
 
-	GSList *actions = NULL;
+	/* we read a first list which contains the list of actions
+	 * as NactStorage-initialized objects
+	 */
+	GSList *actions = nact_storage_load_actions( NACT_ACTION_TYPE );
 
-	/* we read a first list which contains the list of action keys */
-	GSList *list = nact_storage_load_action_ids();
+	GSList *item;
+	for( item = actions ; item != NULL ; item = item->next ){
 
-	/* for each item (uuid) of the list, we allocate a new NactAction
-	 * object and prepend it to the returned list
-	 */
-	GSList *key;
-	for( key = list ; key != NULL ; key = key->next ){
-		NactAction *action_obj = load_action(( gchar *) key->data );
-		if( action_obj ){
-			nact_storage_dump( NACT_STORAGE( action_obj ));
-			actions = g_slist_prepend( actions, action_obj );
-		}
-	}
+		NactAction *obj = ( NactAction * ) item->data;
+		obj->private->profiles =
+				nact_storage_load_profiles(( NactStorage * ) obj, NACT_ACTION_PROFILE_TYPE );
 
-	/* eventually, free the list of action keys */
-	nact_storage_free_action_ids( list );
+		nact_storage_dump( NACT_STORAGE( item->data ));
+	}
 
 	return( actions );
 }
@@ -516,6 +446,15 @@ nact_action_get_verified_icon_name( const NactAction *action )
 	return( icon_name );
 }
 
+/**
+ * Returns the list of profiles of the actions as a GSList of
+ * NactActionProfile GObjects.
+ *
+ * @action: the action whose profiles has to be retrieved.
+ *
+ * The returned pointer is owned by the @action object ; the caller
+ * should not try to free or unref it.
+ */
 GSList *
 nact_action_get_profiles( const NactAction *action )
 {
diff --git a/src/common/nact-gconf.c b/src/common/nact-gconf.c
index 5d4471e..c9ee56f 100644
--- a/src/common/nact-gconf.c
+++ b/src/common/nact-gconf.c
@@ -38,15 +38,36 @@
 #include "nact-gconf-keys.h"
 #include "uti-lists.h"
 
+typedef struct {
+	gchar *key;
+	gchar *path;
+}
+	NactGConfIO;
+
 static GConfClient *st_gconf = NULL;
 
-static void     initialize( void );
-static gchar   *get_object_path( NactStorage *object );
-static gchar   *path_to_key( const gchar *path );
-static GSList  *load_subdirs( const gchar *path );
-static GSList  *load_keys_values( const gchar *path );
-static void     free_keys_values( GSList *list );
-static GSList  *duplicate_list( GSList *list );
+static void         free_keys_values( GSList *list );
+static void         initialize( void );
+static void         load_action_properties( NactStorage *action );
+static GSList      *load_items( const gchar *root, GType type );
+static GSList      *load_keys_values( const gchar *path );
+static GSList      *load_list_actions( GType type );
+static GSList      *load_list_profiles( NactStorage *action, GType type );
+static void         load_profile_properties( NactStorage *profile );
+static GSList      *load_subdirs( const gchar *path );
+static gchar       *path_to_key( const gchar *path );
+static NactGConfIO *path_to_struct( const gchar *path );
+
+static void
+free_keys_values( GSList *list )
+{
+	GSList *item;
+	for( item = list ; item != NULL ; item = item->next ){
+		GConfEntry *entry = ( GConfEntry * ) item->data;
+		gconf_entry_unref( entry );
+	}
+	g_slist_free( list );
+}
 
 /*
  * we have to initialize this early in the process as nautilus-actions
@@ -61,97 +82,33 @@ initialize( void )
 	st_gconf = gconf_client_get_default();
 }
 
-gchar *
-get_object_path( NactStorage *object )
-{
-	g_assert( NACT_IS_STORAGE( object ));
-
-	gchar *id = nact_storage_get_id( object );
-	gchar *path = g_strdup_printf( "%s/%s", NACT_GCONF_CONFIG, id );
-	g_free( id );
-
-	return( path );
-}
-
 /*
- * Returns a list of the keys which appear as subdirectories
- *
- * The returned list contains allocated strings. Each string is the
- * relative path of a subdirectory. You should g_free() each string
- * in the list, then g_slist_free() the list itself.
+ * allocate the whole list of items under the specified dir.
+ * each item of the list is a NactStorage-derived initialized GObject
  */
-static gchar *
-path_to_key( const gchar *path )
+static GSList *
+load_items( const gchar *root, GType type )
 {
-	gchar **split = g_strsplit( path, "/", -1 );
-	guint count = g_strv_length( split );
-	gchar *key = g_strdup( split[count-1] );
-	g_strfreev( split );
+	GSList *items = NULL;
 
-	return( key );
-}
+	GSList *listpath = load_subdirs( root );
+	GSList *path;
+	for( path = listpath ; path != NULL ; path = path->next ){
 
-GSList *
-load_subdirs( const gchar *path )
-{
-	static const gchar *thisfn = "nact_gconf_load_subdirs";
-	g_debug( "%s: path=%s", thisfn, path );
+		NactGConfIO *io = path_to_struct(( const gchar * ) path->data );
 
-	if( !st_gconf ){
-		initialize();
-	}
+		GObject *object = g_object_new(
+				type, PROP_ORIGIN_STR, ORIGIN_GCONF, PROP_SUBSYSTEM_STR, io, NULL  );
 
-	GError *error = NULL;
-	GSList *list_path = gconf_client_all_dirs( st_gconf, path, &error );
-	if( error ){
-		g_error( "%s: %s", thisfn, error->message );
-		g_error_free( error );
-		return(( GSList * ) NULL );
+		items = g_slist_prepend( items, object );
 	}
+	nactuti_free_string_list( listpath );
 
-	GSList *list_keys = NULL;
-	GSList *item;
-	for( item = list_path ; item != NULL ; item = item->next ){
-		gchar *key = path_to_key(( gchar * ) item->data );
-		list_keys = g_slist_prepend( list_keys, key );
-	}
-
-	nactuti_free_string_list( list_path );
-
-	return( list_keys );
-}
-
-/**
- * Return the list of uuids.
- *
- * The list of UUIDs is returned as a GSList of newly allocation strings.
- * This list should be freed by calling nact_gconf_free_uuids.
- */
-GSList *
-nact_gconf_load_uuids( void )
-{
-	static const gchar *thisfn = "nact_gconf_load_uuids";
-	g_debug( "%s", thisfn );
-
-	return( load_subdirs( NACT_GCONF_CONFIG ));
-}
-
-/**
- * Free a previously allocated list of UUIDs.
- *
- * @list: list of UUIDs to be freed.
- */
-void
-nact_gconf_free_uuids( GSList *list )
-{
-	static const gchar *thisfn = "nact_gconf_free_uuids";
-	g_debug( "%s: list=%p", thisfn, list );
-	nactuti_free_string_list( list );
+	return( items );
 }
 
 /*
- * Load all the key=value pairs of this key
- *
+ * load all the key=value pairs of this key (specified as a full path)
  * The list is not recursive, it contains only the immediate children of
  * path. To free the returned list, gconf_entry_free() each list element,
  * then g_slist_free() the list itself.
@@ -188,37 +145,98 @@ load_keys_values( const gchar *path )
 	return( list_keys );
 }
 
-static void
-free_keys_values( GSList *list )
+/*
+ * load the keys which are the subdirs of the given path
+ * returns a list of keys as full path
+ */
+GSList *
+load_subdirs( const gchar *path )
 {
-	GSList *item;
-	for( item = list ; item != NULL ; item = item->next ){
-		GConfEntry *entry = ( GConfEntry * ) item->data;
-		gconf_entry_unref( entry );
+	static const gchar *thisfn = "nact_gconf_load_subdirs";
+
+	if( !st_gconf ){
+		initialize();
 	}
-	g_slist_free( list );
+
+	GError *error = NULL;
+	GSList *list = gconf_client_all_dirs( st_gconf, path, &error );
+	if( error ){
+		g_error( "%s: %s", thisfn, error->message );
+		g_error_free( error );
+		return(( GSList * ) NULL );
+	}
+
+	return( list );
 }
 
 /*
- * load the action properties from GConf repository and setup action
- * instance accordingly
+ * extract the key part (the last part) of a full path
+ * returns a newly allocated string which must be g_freed by the caller
+ */
+static gchar *
+path_to_key( const gchar *path )
+{
+	gchar **split = g_strsplit( path, "/", -1 );
+	guint count = g_strv_length( split );
+	gchar *key = g_strdup( split[count-1] );
+	g_strfreev( split );
+	return( key );
+}
+
+/*
+ * allocate a new NactGConfIO structure
+ * to be freed via nact_gconf_dispose
  */
-gboolean
-nact_gconf_load_action_properties( NactStorage *action )
+static NactGConfIO *
+path_to_struct( const gchar *path )
 {
-	g_object_set( G_OBJECT( action ), "origin", ORIG_GCONF, NULL );
+	NactGConfIO *io = g_new0( NactGConfIO, 1 );
+	io->key = path_to_key( path );
+	io->path = g_strdup( path );
+	return( io );
+}
 
-	gchar *path = get_object_path( action );
+/**
+ * to be called from NactStorage instance_finalize to free the allocated
+ * NactGConfIO structure.
+ */
+void
+nact_gconf_dispose( gpointer ptr )
+{
+	NactGConfIO *io = ( NactGConfIO * ) ptr;
+	g_free( io->key );
+	g_free( io->path );
+	g_free( io );
+}
 
-	g_object_set( G_OBJECT( action ), "gconf-path", path, NULL );
+/**
+ * Dump the NactGConfIO structure.
+ *
+ * @pio: a gpointer to the NactGConfIO structure to be dumped.
+ */
+void
+nact_gconf_dump( gpointer pio )
+{
+	static const gchar *thisfn = "nact_gconf_dump";
+	NactGConfIO *io = ( NactGConfIO * ) pio;
+	g_debug( "%s: path='%s'", thisfn, io->path );
+	g_debug( "%s: key='%s'", thisfn, io->key );
+}
 
-	GSList *list = load_keys_values( path );
+/*
+ * load the action properties from GConf repository and setup action
+ * instance accordingly.
+ */
+static void
+load_action_properties( NactStorage *action )
+{
+	g_assert( NACT_IS_STORAGE( action ));
 
-	g_free( path );
+	gpointer pio;
+	g_object_get( G_OBJECT( action ), PROP_SUBSYSTEM_STR, &pio, NULL );
+	NactGConfIO *io = ( NactGConfIO * ) pio;
 
-	if( !list ){
-		return( FALSE );
-	}
+	GSList *list = load_keys_values( io->path );
 
 	GSList *item;
 	for( item = list ; item != NULL ; item = item->next ){
@@ -236,59 +254,55 @@ nact_gconf_load_action_properties( NactStorage *action )
 	}
 
 	free_keys_values( list );
+}
 
-	return( TRUE );
+/*
+ * allocate the whole list of the actions
+ * each item of the list is an action GObject, with the NactStorage
+ * stuff being initialized
+ */
+static GSList *
+load_list_actions( GType type )
+{
+	return( load_items( NACT_GCONF_CONFIG, type ));
 }
 
+/**
+ * Return the list of actions as NactStorage-initialized objects.
+ *
+ * @type: actual GObject type to be allocated.
+ */
 GSList *
-nact_gconf_load_profile_names( NactStorage *action )
+nact_gconf_load_actions( GType type )
 {
-	gchar *path = get_object_path( action );
+	static const gchar *thisfn = "nact_gconf_load_actions";
+	g_debug( "%s", thisfn );
 
-	GSList *list = load_subdirs( path );
+	GSList *list = load_list_actions( type );
 
-	g_free( path );
+	GSList *it;
+	for( it = list ; it ; it = it->next ){
+		load_action_properties( NACT_STORAGE( it->data ));
+	}
 
 	return( list );
 }
 
-static GSList *
-duplicate_list( GSList *list )
-{
-	GSList *newlist = NULL;
-	GSList *item;
-	for( item = list ; item != NULL ; item = item->next ){
-		gchar *value = g_strdup(( gchar * ) item->data );
-		g_debug( "duplicate '%s'", value );
-		newlist = g_slist_prepend( newlist, value );
-	}
-	return( newlist );
-}
-
-gboolean
-nact_gconf_load_profile_properties( NactStorage *profile )
+/*
+ * read the properties of the profile and fill-up the object accordingly.
+ */
+static void
+load_profile_properties( NactStorage *profile )
 {
-	g_object_set( G_OBJECT( profile ), "origin", ORIG_GCONF, NULL );
-
-	NactStorage *action;
-	g_object_get( G_OBJECT( profile ), "action", &action, NULL );
-	gchar *path_action = get_object_path( action );
-
-	gchar *profile_name;
-	g_object_get( G_OBJECT( profile ), "name", &profile_name, NULL );
-	gchar *profile_path = g_strdup_printf( "%s/%s", path_action, profile_name );
-	g_free( profile_name );
-	g_free( path_action );
+	GSList *listvalues, *iv, *strings;
 
-	g_object_set( G_OBJECT( profile ), "gconf-path", profile_path, NULL );
+	g_assert( NACT_IS_STORAGE( profile ));
 
-	GSList *list = load_keys_values( profile_path );
+	gpointer pio;
+	g_object_get( G_OBJECT( profile ), PROP_SUBSYSTEM_STR, &pio, NULL );
+	NactGConfIO *io = ( NactGConfIO * ) pio;
 
-	g_free( profile_path );
-
-	if( !list ){
-		return( FALSE );
-	}
+	GSList *list = load_keys_values( io->path );
 
 	GSList *item;
 	for( item = list ; item != NULL ; item = item->next ){
@@ -309,7 +323,15 @@ nact_gconf_load_profile_properties( NactStorage *profile )
 				break;
 
 			case GCONF_VALUE_LIST:
-				g_object_set( G_OBJECT( profile ), key, duplicate_list( gconf_value_get_list( value )), NULL );
+				listvalues = gconf_value_get_list( value );
+				strings = NULL;
+				for( iv = listvalues ; iv != NULL ; iv = iv->next ){
+					/*g_debug( "get '%s'", gconf_value_get_string(( GConfValue * ) iv->data ));*/
+					strings = g_slist_prepend( strings,
+							( gpointer ) gconf_value_get_string(( GConfValue * ) iv->data ));
+				}
+				g_object_set( G_OBJECT( profile ), key, strings, NULL );
+				/*g_slist_free( strings );*/
 				break;
 
 			default:
@@ -318,12 +340,42 @@ nact_gconf_load_profile_properties( NactStorage *profile )
 	}
 
 	free_keys_values( list );
+}
+
+/*
+ * allocate the whole list of the profile for the action
+ * each item of the list is a profile GObject, with the NactStorage
+ * stuff being initialized
+ */
+static GSList *
+load_list_profiles( NactStorage *action, GType type )
+{
+	gpointer pio;
+	g_object_get( G_OBJECT( action ), PROP_SUBSYSTEM_STR, &pio, NULL );
+	NactGConfIO *io = ( NactGConfIO * ) pio;
 
-	return( TRUE );
+	return( load_items( io->path, type ));
 }
 
-void
-nact_gconf_free_profile_names( GSList *list )
+/**
+ * Return the list of profiles as NactStorage-initialized objects.
+ *
+ * @action: the action.
+ *
+ * @type: actual GObject type to be allocated.
+ */
+GSList *
+nact_gconf_load_profiles( NactStorage *action, GType type )
 {
-	nactuti_free_string_list( list );
+	static const gchar *thisfn = "nact_gconf_load_profiles";
+	g_debug( "%s", thisfn );
+
+	GSList *list = load_list_profiles( action, type );
+
+	GSList *it;
+	for( it = list ; it ; it = it->next ){
+		load_profile_properties( NACT_STORAGE( it->data ));
+	}
+
+	return( list );
 }
diff --git a/src/common/nact-gconf.h b/src/common/nact-gconf.h
index c143ac2..f016ce6 100644
--- a/src/common/nact-gconf.h
+++ b/src/common/nact-gconf.h
@@ -40,13 +40,12 @@
 
 G_BEGIN_DECLS
 
-GSList  *nact_gconf_load_uuids( void );
-gboolean nact_gconf_load_action_properties( NactStorage *action );
-void     nact_gconf_free_uuids( GSList *list );
+void     nact_gconf_dispose( gpointer io );
+void     nact_gconf_dump( gpointer io );
 
-GSList  *nact_gconf_load_profile_names( NactStorage *action );
-gboolean nact_gconf_load_profile_properties( NactStorage *profile );
-void     nact_gconf_free_profile_names( GSList *list );
+GSList  *nact_gconf_load_actions( GType type );
+
+GSList  *nact_gconf_load_profiles( NactStorage *action, GType type );
 
 G_END_DECLS
 
diff --git a/src/common/nact-storage.c b/src/common/nact-storage.c
index b53d667..84c6730 100644
--- a/src/common/nact-storage.c
+++ b/src/common/nact-storage.c
@@ -33,6 +33,7 @@
 #endif
 #include "nact-gconf.h"
 #include "nact-storage.h"
+#include "uti-lists.h"
 
 static GObjectClass *st_parent_class = NULL;
 
@@ -47,14 +48,16 @@ static void    do_dump( const NactStorage *object );
 
 struct NactStoragePrivate {
 	gboolean dispose_has_run;
-	int      origin;
+	int      io_origin;
+	gpointer io_subsystem;
 };
 
 struct NactStorageClassPrivate {
 };
 
 enum {
-	PROP_ORIGIN = 1
+	PROP_ORIGIN = 1,
+	PROP_SUBSYSTEM
 };
 
 GType
@@ -103,12 +106,19 @@ class_init( NactStorageClass *klass )
 
 	GParamSpec *spec;
 	spec = g_param_spec_int(
-			"origin",
-			"origin",
+			PROP_ORIGIN_STR,
+			PROP_ORIGIN_STR,
 			"Internal identifiant of the storage subsystem", 0, ORIGIN_LAST, 0,
-			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_ORIGIN, spec );
 
+	spec = g_param_spec_pointer(
+			PROP_SUBSYSTEM_STR,
+			PROP_SUBSYSTEM_STR,
+			"Pointer to a private are for the I/O subsystem",
+			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_SUBSYSTEM, spec );
+
 	klass->private = g_new0( NactStorageClassPrivate, 1 );
 
 	klass->do_dump = do_dump;
@@ -117,13 +127,17 @@ class_init( NactStorageClass *klass )
 static void
 instance_init( GTypeInstance *instance, gpointer klass )
 {
+	/*static const gchar *thisfn = "nact_storage_instance_init";
+	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );*/
+
 	g_assert( NACT_IS_STORAGE( instance ));
 	NactStorage *self = NACT_STORAGE( instance );
 
 	self->private = g_new0( NactStoragePrivate, 1 );
 
 	self->private->dispose_has_run = FALSE;
-	self->private->origin = 0;
+	self->private->io_origin = 0;
+	self->private->io_subsystem = NULL;
 }
 
 static void
@@ -134,7 +148,14 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 
 	switch( property_id ){
 		case PROP_ORIGIN:
-			g_value_set_int( value, self->private->origin );
+			g_value_set_int( value, self->private->io_origin );
+			break;
+
+		/* returns the initially provided gpointer
+		 * the caller must not try to free or unref it
+		 */
+		case PROP_SUBSYSTEM:
+			g_value_set_pointer( value, self->private->io_subsystem );
 			break;
 
 		default:
@@ -146,12 +167,20 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 static void
 instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
 {
+	/*static const gchar *thisfn = "nact_storage_instance_set_property";*/
+
 	g_assert( NACT_IS_STORAGE( object ));
 	NactStorage *self = NACT_STORAGE( object );
 
 	switch( property_id ){
 		case PROP_ORIGIN:
-			self->private->origin = g_value_get_int( value );
+			self->private->io_origin = g_value_get_int( value );
+			/*g_debug( "%s: io_origin=%d", thisfn, self->private->io_origin );*/
+			break;
+
+		case PROP_SUBSYSTEM:
+			self->private->io_subsystem = g_value_get_pointer( value );
+			/*g_debug( "%s: io_subsystem=%p", thisfn, self->private->io_subsystem );*/
 			break;
 
 		default:
@@ -179,7 +208,18 @@ static void
 instance_finalize( GObject *object )
 {
 	g_assert( NACT_IS_STORAGE( object ));
-	/*NactStorage *self = ( NactStorage * ) object;*/
+	NactStorage *self = ( NactStorage * ) object;
+
+	gpointer io;
+	g_object_get( object, PROP_SUBSYSTEM_STR, &io, NULL );
+
+	switch( self->private->io_origin ){
+		case ORIGIN_GCONF:
+			nact_gconf_dispose( io );
+			break;
+		default:
+			break;
+	}
 
 	/* chain call to parent class */
 	if( st_parent_class->finalize ){
@@ -190,8 +230,11 @@ instance_finalize( GObject *object )
 /**
  * Returns the id of the object as a newly allocated string.
  *
- * This is a pure virtual function, which has to be implemented by
- * the derived class.
+ * This is a virtual function, which may be implemented by the derived
+ * class.
+ *
+ * This class defaults to ask to the storage subsystem for an i/o id.
+ * Eventually returns an empty string.
  *
  * @object: object whose id is to be returned.
  *
@@ -211,7 +254,16 @@ do_dump( const NactStorage *object )
 
 	g_assert( NACT_IS_STORAGE( object ));
 
-	g_debug( "%s: origin=%d", thisfn, object->private->origin );
+	g_debug( "%s: origin=%d", thisfn, object->private->io_origin );
+
+	switch( object->private->io_origin ){
+		case ORIGIN_GCONF:
+			nact_gconf_dump( object->private->io_subsystem );
+			break;
+		default:
+			g_assert_not_reached();
+			break;
+	}
 }
 
 /**
@@ -230,45 +282,44 @@ nact_storage_dump( const NactStorage *object )
 	NACT_STORAGE_GET_CLASS( object )->do_dump( object );
 }
 
+/**
+ * Load all defined actions.
+ *
+ * Ask to each registered storage subsystem for its list of actions,
+ * then concatenates them in the returned list.
+ *
+ * @type: GObject type to allocate.
+ *
+ * The returned list is a GSList of NactStorage-derived GObjects.
+ */
 GSList *
-nact_storage_load_action_ids( void )
+nact_storage_load_actions( GType type )
 {
-	static const gchar *thisfn = "nact_storage_load_action_ids";
+	static const gchar *thisfn = "nact_storage_load_actions";
 	g_debug( "%s", thisfn );
-	return( nact_gconf_load_uuids());
-}
 
-gboolean
-nact_storage_load_action_properties( NactStorage *action )
-{
-	g_assert( NACT_IS_STORAGE( action ));
-	return( nact_gconf_load_action_properties( action ));
-}
+	GSList *actions = NULL;
 
-void
-nact_storage_free_action_ids( GSList *list )
-{
-	static const gchar *thisfn = "nact_storage_free_action_ids";
-	g_debug( "%s: list=%p", thisfn, list );
-	nact_gconf_free_uuids( list );
+	/* GConf storage subsystem */
+	GSList *list_gconf = nact_gconf_load_actions( type );
+	actions = g_slist_concat( actions, list_gconf );
+
+	return( actions );
 }
 
 GSList *
-nact_storage_load_profile_ids( NactStorage *action )
+nact_storage_load_profiles( NactStorage *action, GType type )
 {
 	g_assert( NACT_IS_STORAGE( action ));
-	return( nact_gconf_load_profile_names( action ));
-}
+	GSList *profiles = NULL;
 
-gboolean
-nact_storage_load_profile_properties( NactStorage *profile )
-{
-	g_assert( NACT_IS_STORAGE( profile ));
-	return( nact_gconf_load_profile_properties( profile ));
-}
-
-void
-nact_storage_free_profile_ids( GSList *list )
-{
-	return( nact_gconf_free_profile_names( list ));
+	switch( action->private->io_origin ){
+		case ORIGIN_GCONF:
+			profiles = nact_gconf_load_profiles( action, type );
+			break;
+		default:
+			g_assert_not_reached();
+			break;
+	}
+	return( profiles );
 }
diff --git a/src/common/nact-storage.h b/src/common/nact-storage.h
index 4c50ca5..a48c6f6 100644
--- a/src/common/nact-storage.h
+++ b/src/common/nact-storage.h
@@ -52,10 +52,14 @@ G_BEGIN_DECLS
 
 /* identifiers for various storage subsystems */
 enum {
-	ORIG_GCONF = 1,
+	ORIGIN_GCONF = 1,
 	ORIGIN_LAST
 };
 
+/* property names */
+#define PROP_ORIGIN_STR						"origin"
+#define PROP_SUBSYSTEM_STR					"subsystem"
+
 #define NACT_STORAGE_TYPE					( nact_storage_get_type())
 #define NACT_STORAGE( object )				( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_STORAGE_TYPE, NactStorage ))
 #define NACT_STORAGE_CLASS( klass )			( G_TYPE_CHECK_CLASS_CAST( klass, NACT_STORAGE_TYPE, NactStorageClass ))
@@ -89,13 +93,9 @@ gchar   *nact_storage_get_id( const NactStorage *object );
 
 void     nact_storage_dump( const NactStorage *object );
 
-GSList  *nact_storage_load_action_ids( void );
-gboolean nact_storage_load_action_properties( NactStorage *action );
-void     nact_storage_free_action_ids( GSList *list );
+GSList  *nact_storage_load_actions( GType type );
 
-GSList  *nact_storage_load_profile_ids( NactStorage *action );
-gboolean nact_storage_load_profile_properties( NactStorage *profile );
-void     nact_storage_free_profile_ids( GSList *list );
+GSList  *nact_storage_load_profiles( NactStorage *action, GType type );
 
 G_END_DECLS
 
diff --git a/src/common/uti-lists.c b/src/common/uti-lists.c
index 37f92c1..c72072a 100644
--- a/src/common/uti-lists.c
+++ b/src/common/uti-lists.c
@@ -31,9 +31,42 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+#include <glib-object.h>
 #include "uti-lists.h"
 
 /**
+ * Free a GSList of GObjects.
+ *
+ * @list: the GSList to be freed.
+ */
+void
+nactuti_free_object_list( GSList *list )
+{
+	GSList *item;
+	for( item = list ; item != NULL ; item = item->next ){
+		g_object_unref( G_OBJECT( item->data ));
+	}
+	g_slist_free( list );
+}
+
+/**
+ * Duplicate a GSList of strings.
+ *
+ * @list: the GSList to be freed.
+ */
+GSList *
+nactuti_duplicate_string_list( GSList *list )
+{
+	GSList *duplist = NULL;
+	GSList *it;
+	for( it = list ; it != NULL ; it = it->next ){
+		gchar *dupstr = g_strdup(( gchar * ) it->data );
+		duplist = g_slist_prepend( duplist, dupstr );
+	}
+	return( duplist );
+}
+
+/**
  * Free a GSList of strings.
  *
  * @list: the GSList to be freed.
diff --git a/src/common/uti-lists.h b/src/common/uti-lists.h
index 9d7465e..9a8dd2b 100644
--- a/src/common/uti-lists.h
+++ b/src/common/uti-lists.h
@@ -39,6 +39,9 @@
 
 G_BEGIN_DECLS
 
+void     nactuti_free_object_list( GSList *list );
+
+GSList  *nactuti_duplicate_string_list( GSList *list );
 void     nactuti_free_string_list( GSList *list );
 
 G_END_DECLS
diff --git a/src/plugin/nautilus-actions.c b/src/plugin/nautilus-actions.c
index 991e305..2e1da84 100644
--- a/src/plugin/nautilus-actions.c
+++ b/src/plugin/nautilus-actions.c
@@ -39,9 +39,10 @@
 #include <libnautilus-extension/nautilus-extension-types.h>
 #include <libnautilus-extension/nautilus-file-info.h>
 #include <libnautilus-extension/nautilus-menu-provider.h>
-#include "nautilus-actions.h"
+#include <common/nact-action.h>
 #include <common/nautilus-actions-config.h>
 #include <common/nautilus-actions-config-gconf-reader.h>
+#include "nautilus-actions.h"
 #include "nautilus-actions-test.h"
 #include "nautilus-actions-utils.h"
 
@@ -63,6 +64,7 @@ static NautilusMenuItem *create_menu_item( NautilusActionsConfigAction *action,
 
 struct NautilusActionsPrivate {
 	gboolean  dispose_has_run;
+	GSList   *actions;
 	NautilusActionsConfigGconfReader* configs;
 	GSList* config_list;
 };
@@ -158,6 +160,7 @@ instance_init( GTypeInstance *instance, gpointer klass )
 
 	self->private = g_new0( NautilusActionsPrivate, 1 );
 
+	self->private->actions = nact_action_load_actions();
 	self->private->configs = NULL;
 	self->private->configs = nautilus_actions_config_gconf_reader_get ();
 	self->private->config_list = NULL;



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