[nautilus-actions] Load old versions, write current, test for writable i/o subsystem



commit ecdf6afda6876164b7ade8a282e7fdb90d47d354
Author: Pierre Wieser <pwieser trychlos org>
Date:   Sat Jun 20 23:57:06 2009 +0200

    Load old versions, write current, test for writable i/o subsystem

 ChangeLog                      |   17 ++
 src/common/na-action-profile.c |  317 +++++++++++++++++--------
 src/common/na-action-profile.h |   24 ++
 src/common/na-action.c         |  152 ++++++++----
 src/common/na-action.h         |   12 +
 src/common/na-gconf-keys.h     |   20 ++-
 src/common/na-gconf.c          |  515 +++++++++++++++++++++++++++++++++++++---
 src/common/na-iio-provider.c   |   40 +++-
 src/common/na-iio-provider.h   |   17 +-
 src/plugin/nautilus-actions.c  |    2 +-
 10 files changed, 918 insertions(+), 198 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 816321c..fa95337 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2009-06-20 Pierre Wieser <pwieser trychlos org>
 
+	* src/common/na-gconf.c:
+	Implement loading of old versions.
+	Implement writing an action.
+
+	* src/common/na-action.c:
+	* src/common/na-action.h:
+	* src/common/na-gconf.c:
+	Add read-only attribute set when GConf key is not writable.
+
+	* src/common/na-action.c:
+	* src/common/na-action.h:
+	* src/common/na-action-profile.c:
+	* src/common/na-action-profile.h:
+	Object properties are renamed, and moved to include file.
+	Objects are created with suitable default values.
+	Finalize helper functions.
+
 	* src/common/na-iio-provider.c:
 	Record the provider in each NAAction object.
 
diff --git a/src/common/na-action-profile.c b/src/common/na-action-profile.c
index ccdbb8f..e207744 100644
--- a/src/common/na-action-profile.c
+++ b/src/common/na-action-profile.c
@@ -33,6 +33,7 @@
 #endif
 
 #include <string.h>
+#include <glib/gi18n.h>
 
 #include <libnautilus-extension/nautilus-file-info.h>
 
@@ -69,38 +70,25 @@ struct NAActionProfilePrivate {
 	GSList   *schemes;
 };
 
-/* private instance properties
+/* instance properties
  * please note that property names must have the same spelling as the
  * NactIIOProvider parameters
  */
 enum {
-	PROP_ACTION = 1,
+	PROP_PROFILE_ACTION = 1,
 	PROP_PROFILE_NAME,
-	PROP_LABEL,
-	PROP_PATH,
-	PROP_PARAMETERS,
-	PROP_ACCEPT_MULTIPLE,
-	PROP_BASENAMES,
-	PROP_ISDIR,
-	PROP_ISFILE,
-	PROP_MATCHCASE,
-	PROP_MIMETYPES,
-	PROP_SCHEMES
+	PROP_PROFILE_LABEL,
+	PROP_PROFILE_PATH,
+	PROP_PROFILE_PARAMETERS,
+	PROP_PROFILE_ACCEPT_MULTIPLE,
+	PROP_PROFILE_BASENAMES,
+	PROP_PROFILE_ISDIR,
+	PROP_PROFILE_ISFILE,
+	PROP_PROFILE_MATCHCASE,
+	PROP_PROFILE_MIMETYPES,
+	PROP_PROFILE_SCHEMES
 };
 
-#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 NAObjectClass *st_parent_class = NULL;
 
 static GType  register_type( void );
@@ -163,11 +151,11 @@ class_init( NAActionProfileClass *klass )
 
 	GParamSpec *spec;
 	spec = g_param_spec_pointer(
-			PROP_ACTION_STR,
-			PROP_ACTION_STR,
+			PROP_PROFILE_ACTION_STR,
+			PROP_PROFILE_ACTION_STR,
 			"The NAAction object",
 			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_ACTION, spec );
+	g_object_class_install_property( object_class, PROP_PROFILE_ACTION, spec );
 
 	/* the id of the object is marked as G_PARAM_CONSTRUCT_ONLY */
 	spec = g_param_spec_string(
@@ -178,74 +166,74 @@ class_init( NAActionProfileClass *klass )
 	g_object_class_install_property( object_class, PROP_PROFILE_NAME, spec );
 
 	spec = g_param_spec_string(
-			PROP_LABEL_STR,
-			PROP_LABEL_STR,
+			PROP_PROFILE_LABEL_STR,
+			PROP_PROFILE_LABEL_STR,
 			"Displayable profile's name", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_LABEL, spec );
+	g_object_class_install_property( object_class, PROP_PROFILE_LABEL, spec );
 
 	spec = g_param_spec_string(
-			PROP_PATH_STR,
-			PROP_PATH_STR,
+			PROP_PROFILE_PATH_STR,
+			PROP_PROFILE_PATH_STR,
 			"Command path", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_PATH, spec );
+	g_object_class_install_property( object_class, PROP_PROFILE_PATH, spec );
 
 	spec = g_param_spec_string(
-			PROP_PARAMETERS_STR,
-			PROP_PARAMETERS_STR,
+			PROP_PROFILE_PARAMETERS_STR,
+			PROP_PROFILE_PARAMETERS_STR,
 			"Command parameters", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_PARAMETERS, spec );
+	g_object_class_install_property( object_class, PROP_PROFILE_PARAMETERS, spec );
 
 	spec = g_param_spec_boolean(
-			PROP_ACCEPT_MULTIPLE_STR,
-			PROP_ACCEPT_MULTIPLE_STR,
+			PROP_PROFILE_ACCEPT_MULTIPLE_STR,
+			PROP_PROFILE_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 );
+	g_object_class_install_property( object_class, PROP_PROFILE_ACCEPT_MULTIPLE, spec );
 
 	spec = g_param_spec_pointer(
-			PROP_BASENAMES_STR,
-			PROP_BASENAMES_STR,
+			PROP_PROFILE_BASENAMES_STR,
+			PROP_PROFILE_BASENAMES_STR,
 			"Filenames mask",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_BASENAMES, spec );
+	g_object_class_install_property( object_class, PROP_PROFILE_BASENAMES, spec );
 
 	spec = g_param_spec_boolean(
-			PROP_ISDIR_STR,
-			PROP_ISDIR_STR,
+			PROP_PROFILE_ISDIR_STR,
+			PROP_PROFILE_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 );
+	g_object_class_install_property( object_class, PROP_PROFILE_ISDIR, spec );
 
 	spec = g_param_spec_boolean(
-			PROP_ISFILE_STR,
-			PROP_ISFILE_STR,
+			PROP_PROFILE_ISFILE_STR,
+			PROP_PROFILE_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 );
+	g_object_class_install_property( object_class, PROP_PROFILE_ISFILE, spec );
 
 	spec = g_param_spec_boolean(
-			PROP_MATCHCASE_STR,
-			PROP_MATCHCASE_STR,
+			PROP_PROFILE_MATCHCASE_STR,
+			PROP_PROFILE_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 );
+	g_object_class_install_property( object_class, PROP_PROFILE_MATCHCASE, spec );
 
 	spec = g_param_spec_pointer(
-			PROP_MIMETYPES_STR,
-			PROP_MIMETYPES_STR,
+			PROP_PROFILE_MIMETYPES_STR,
+			PROP_PROFILE_MIMETYPES_STR,
 			"List of selectable mimetypes",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_MIMETYPES, spec );
+	g_object_class_install_property( object_class, PROP_PROFILE_MIMETYPES, spec );
 
 	spec = g_param_spec_pointer(
-			PROP_SCHEMES_STR,
-			PROP_SCHEMES_STR,
+			PROP_PROFILE_SCHEMES_STR,
+			PROP_PROFILE_SCHEMES_STR,
 			"list of selectable schemes",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_SCHEMES, spec );
+	g_object_class_install_property( object_class, PROP_PROFILE_SCHEMES, spec );
 
 	klass->private = g_new0( NAActionProfileClassPrivate, 1 );
 
@@ -264,7 +252,25 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	NAActionProfile* self = NA_ACTION_PROFILE( instance );
 
 	self->private = g_new0( NAActionProfilePrivate, 1 );
+
 	self->private->dispose_has_run = FALSE;
+
+	/* initialize suitable default values
+	 * i18n: default label for the default profile
+	 */
+	self->private->label = g_strdup( _( "Default profile" ));
+	self->private->path = g_strdup( "" );
+	self->private->parameters = g_strdup( "" );
+	self->private->accept_multiple_files = FALSE;
+	self->private->basenames = NULL;
+	self->private->basenames = g_slist_append( self->private->basenames, g_strdup( "*" ));
+	self->private->is_dir = FALSE;
+	self->private->is_file = TRUE;
+	self->private->match_case = TRUE;
+	self->private->mimetypes = NULL;
+	self->private->mimetypes = g_slist_append( self->private->mimetypes, g_strdup( "*/*" ));
+	self->private->schemes = NULL;
+	self->private->schemes = g_slist_append( self->private->schemes, g_strdup( "file" ));
 }
 
 static void
@@ -276,7 +282,7 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 	GSList *list;
 
 	switch( property_id ){
-		case PROP_ACTION:
+		case PROP_PROFILE_ACTION:
 			g_value_set_pointer( value, self->private->action );
 			break;
 
@@ -284,45 +290,45 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 			g_value_set_string( value, self->private->name );
 			break;
 
-		case PROP_LABEL:
+		case PROP_PROFILE_LABEL:
 			g_value_set_string( value, self->private->label );
 			break;
 
-		case PROP_PATH:
+		case PROP_PROFILE_PATH:
 			g_value_set_string( value, self->private->path );
 			break;
 
-		case PROP_PARAMETERS:
+		case PROP_PROFILE_PARAMETERS:
 			g_value_set_string( value, self->private->parameters );
 			break;
 
-		case PROP_ACCEPT_MULTIPLE:
+		case PROP_PROFILE_ACCEPT_MULTIPLE:
 			g_value_set_boolean( value, self->private->accept_multiple_files );
 			break;
 
-		case PROP_BASENAMES:
+		case PROP_PROFILE_BASENAMES:
 			list = na_utils_duplicate_string_list( self->private->basenames );
 			g_value_set_pointer( value, list );
 			break;
 
-		case PROP_ISDIR:
+		case PROP_PROFILE_ISDIR:
 			g_value_set_boolean( value, self->private->is_dir );
 			break;
 
-		case PROP_ISFILE:
+		case PROP_PROFILE_ISFILE:
 			g_value_set_boolean( value, self->private->is_file );
 			break;
 
-		case PROP_MATCHCASE:
+		case PROP_PROFILE_MATCHCASE:
 			g_value_set_boolean( value, self->private->match_case );
 			break;
 
-		case PROP_MIMETYPES:
+		case PROP_PROFILE_MIMETYPES:
 			list = na_utils_duplicate_string_list( self->private->mimetypes );
 			g_value_set_pointer( value, list );
 			break;
 
-		case PROP_SCHEMES:
+		case PROP_PROFILE_SCHEMES:
 			list = na_utils_duplicate_string_list( self->private->schemes );
 			g_value_set_pointer( value, list );
 			break;
@@ -340,7 +346,7 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 	NAActionProfile *self = NA_ACTION_PROFILE( object );
 
 	switch( property_id ){
-		case PROP_ACTION:
+		case PROP_PROFILE_ACTION:
 			self->private->action = g_value_get_pointer( value );
 			break;
 
@@ -349,48 +355,48 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 			self->private->name = g_value_dup_string( value );
 			break;
 
-		case PROP_LABEL:
+		case PROP_PROFILE_LABEL:
 			g_free( self->private->label );
 			self->private->label = g_value_dup_string( value );
 			break;
 
-		case PROP_PATH:
+		case PROP_PROFILE_PATH:
 			g_free( self->private->path );
 			self->private->path = g_value_dup_string( value );
 			break;
 
-		case PROP_PARAMETERS:
+		case PROP_PROFILE_PARAMETERS:
 			g_free( self->private->parameters );
 			self->private->parameters = g_value_dup_string( value );
 			break;
 
-		case PROP_ACCEPT_MULTIPLE:
+		case PROP_PROFILE_ACCEPT_MULTIPLE:
 			self->private->accept_multiple_files = g_value_get_boolean( value );
 			break;
 
-		case PROP_BASENAMES:
+		case PROP_PROFILE_BASENAMES:
 			na_utils_free_string_list( self->private->basenames );
 			self->private->basenames = na_utils_duplicate_string_list( g_value_get_pointer( value ));
 			break;
 
-		case PROP_ISDIR:
+		case PROP_PROFILE_ISDIR:
 			self->private->is_dir = g_value_get_boolean( value );
 			break;
 
-		case PROP_ISFILE:
+		case PROP_PROFILE_ISFILE:
 			self->private->is_file = g_value_get_boolean( value );
 			break;
 
-		case PROP_MATCHCASE:
+		case PROP_PROFILE_MATCHCASE:
 			self->private->match_case = g_value_get_boolean( value );
 			break;
 
-		case PROP_MIMETYPES:
+		case PROP_PROFILE_MIMETYPES:
 			na_utils_free_string_list( self->private->mimetypes );
 			self->private->mimetypes = na_utils_duplicate_string_list( g_value_get_pointer( value ));
 			break;
 
-		case PROP_SCHEMES:
+		case PROP_PROFILE_SCHEMES:
 			na_utils_free_string_list( self->private->schemes );
 			self->private->schemes = na_utils_duplicate_string_list( g_value_get_pointer( value ));
 			break;
@@ -460,7 +466,7 @@ na_action_profile_new( const NAObject *action, const gchar *name )
 	NAActionProfile *profile =
 		g_object_new(
 				NA_ACTION_PROFILE_TYPE,
-				PROP_ACTION_STR, action, PROP_PROFILE_NAME_STR, name, NULL );
+				PROP_PROFILE_ACTION_STR, action, PROP_PROFILE_NAME_STR, name, NULL );
 
 	return( profile );
 }
@@ -484,16 +490,16 @@ na_action_profile_copy( const NAActionProfile *profile )
 		na_action_profile_new( profile->private->action, profile->private->name );
 
 	g_object_set( G_OBJECT( new ),
-			PROP_LABEL_STR, profile->private->label,
-			PROP_PATH_STR, profile->private->path,
-			PROP_PARAMETERS_STR, profile->private->parameters,
-			PROP_ACCEPT_MULTIPLE_STR, profile->private->accept_multiple_files,
-			PROP_BASENAMES_STR, profile->private->basenames,
-			PROP_ISDIR_STR, profile->private->is_dir,
-			PROP_ISFILE_STR, profile->private->is_file,
-			PROP_MATCHCASE_STR, profile->private->match_case,
-			PROP_MIMETYPES_STR, profile->private->mimetypes,
-			PROP_SCHEMES_STR, profile->private->schemes,
+			PROP_PROFILE_LABEL_STR, profile->private->label,
+			PROP_PROFILE_PATH_STR, profile->private->path,
+			PROP_PROFILE_PARAMETERS_STR, profile->private->parameters,
+			PROP_PROFILE_ACCEPT_MULTIPLE_STR, profile->private->accept_multiple_files,
+			PROP_PROFILE_BASENAMES_STR, profile->private->basenames,
+			PROP_PROFILE_ISDIR_STR, profile->private->is_dir,
+			PROP_PROFILE_ISFILE_STR, profile->private->is_file,
+			PROP_PROFILE_MATCHCASE_STR, profile->private->match_case,
+			PROP_PROFILE_MIMETYPES_STR, profile->private->mimetypes,
+			PROP_PROFILE_SCHEMES_STR, profile->private->schemes,
 			NULL );
 
 	return( new );
@@ -584,7 +590,7 @@ do_get_label( const NAObject *profile )
 	g_assert( NA_IS_ACTION_PROFILE( profile ));
 
 	gchar *label;
-	g_object_get( G_OBJECT( profile ), PROP_LABEL_STR, &label, NULL );
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_LABEL_STR, &label, NULL );
 
 	return( label );
 }
@@ -618,7 +624,7 @@ na_action_profile_get_action( const NAActionProfile *profile )
 	g_assert( NA_IS_ACTION_PROFILE( profile ));
 
 	gpointer action;
-	g_object_get( G_OBJECT( profile ), PROP_ACTION_STR, &action, NULL );
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_ACTION_STR, &action, NULL );
 
 	return( NA_OBJECT( action ));
 }
@@ -637,7 +643,7 @@ na_action_profile_get_path( const NAActionProfile *profile )
 	g_assert( NA_IS_ACTION_PROFILE( profile ));
 
 	gchar *path;
-	g_object_get( G_OBJECT( profile ), PROP_PATH_STR, &path, NULL );
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_PATH_STR, &path, NULL );
 
 	return( path );
 }
@@ -656,11 +662,132 @@ na_action_profile_get_parameters( const NAActionProfile *profile )
 	g_assert( NA_IS_ACTION_PROFILE( profile ));
 
 	gchar *parameters;
-	g_object_get( G_OBJECT( profile ), PROP_PARAMETERS_STR, &parameters, NULL );
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_PARAMETERS_STR, &parameters, NULL );
 
 	return( parameters );
 }
 
+/**
+ * Returns the list of basenames this profile applies to.
+ *
+ * @profile: this NAActionProfile object.
+ *
+ * The returned GSList should be freed by the caller by calling
+ * na_utils_free_string_list.
+ */
+GSList *
+na_action_profile_get_basenames( const NAActionProfile *profile )
+{
+	g_assert( NA_IS_ACTION_PROFILE( profile ));
+
+	GSList *basenames;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_BASENAMES_STR, &basenames, NULL );
+
+	return( basenames );
+}
+
+/**
+ * Are specified basenames case sensitive ?
+ *
+ * @profile: this NAActionProfile object.
+ */
+gboolean
+na_action_profile_get_matchcase( const NAActionProfile *profile )
+{
+	g_assert( NA_IS_ACTION_PROFILE( profile ));
+
+	gboolean matchcase;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_MATCHCASE_STR, &matchcase, NULL );
+
+	return( matchcase );
+}
+
+/**
+ * Returns the list of mimetypes this profile applies to.
+ *
+ * @profile: this NAActionProfile object.
+ *
+ * The returned GSList should be freed by the caller by calling
+ * na_utils_free_string_list.
+ */
+GSList *
+na_action_profile_get_mimetypes( const NAActionProfile *profile )
+{
+	g_assert( NA_IS_ACTION_PROFILE( profile ));
+
+	GSList *mimetypes;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_MIMETYPES_STR, &mimetypes, NULL );
+
+	return( mimetypes );
+}
+
+/**
+ * Does this profile apply to files ?
+ *
+ * @profile: this NAActionProfile object.
+ */
+gboolean
+na_action_profile_get_is_file( const NAActionProfile *profile )
+{
+	g_assert( NA_IS_ACTION_PROFILE( profile ));
+
+	gboolean isfile;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_ISFILE_STR, &isfile, NULL );
+
+	return( isfile );
+}
+
+/**
+ * Does this profile apply to directories ?
+ *
+ * @profile: this NAActionProfile object.
+ */
+gboolean
+na_action_profile_get_is_dir( const NAActionProfile *profile )
+{
+	g_assert( NA_IS_ACTION_PROFILE( profile ));
+
+	gboolean isdir;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_ISDIR_STR, &isdir, NULL );
+
+	return( isdir );
+}
+
+/**
+ * Does this profile apply on a multiple selection ?
+ *
+ * @profile: this NAActionProfile object.
+ */
+gboolean
+na_action_profile_get_multiple( const NAActionProfile *profile )
+{
+	g_assert( NA_IS_ACTION_PROFILE( profile ));
+
+	gboolean multiple;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_ACCEPT_MULTIPLE_STR, &multiple, NULL );
+
+	return( multiple );
+}
+
+/**
+ * Returns the list of schemes this profile applies to.
+ *
+ * @profile: this NAActionProfile object.
+ *
+ * The returned GSList should be freed by the caller by calling
+ * na_utils_free_string_list.
+ */
+GSList *
+na_action_profile_get_schemes( const NAActionProfile *profile )
+{
+	g_assert( NA_IS_ACTION_PROFILE( profile ));
+
+	GSList *schemes;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_SCHEMES_STR, &schemes, NULL );
+
+	return( schemes );
+}
+
 static int
 validate_schemes( GSList* schemes2test, NautilusFileInfo* file )
 {
diff --git a/src/common/na-action-profile.h b/src/common/na-action-profile.h
index e21c2a1..53ce8a2 100644
--- a/src/common/na-action-profile.h
+++ b/src/common/na-action-profile.h
@@ -68,6 +68,23 @@ typedef struct {
 }
 	NAActionProfileClass;
 
+/* instance properties
+ * please note that property names must have the same spelling as the
+ * NactIIOProvider parameters
+ */
+#define PROP_PROFILE_ACTION_STR					"action"
+#define PROP_PROFILE_NAME_STR					"name"
+#define PROP_PROFILE_LABEL_STR					"desc-name"
+#define PROP_PROFILE_PATH_STR					"path"
+#define PROP_PROFILE_PARAMETERS_STR				"parameters"
+#define PROP_PROFILE_ACCEPT_MULTIPLE_STR		"accept-multiple-files"
+#define PROP_PROFILE_BASENAMES_STR				"basenames"
+#define PROP_PROFILE_ISDIR_STR					"isdir"
+#define PROP_PROFILE_ISFILE_STR					"isfile"
+#define PROP_PROFILE_MATCHCASE_STR				"matchcase"
+#define PROP_PROFILE_MIMETYPES_STR				"mimetypes"
+#define PROP_PROFILE_SCHEMES_STR				"schemes"
+
 GType            na_action_profile_get_type( void );
 
 NAActionProfile *na_action_profile_new( const NAObject *action, const gchar *name );
@@ -79,6 +96,13 @@ gchar           *na_action_profile_get_name( const NAActionProfile *profile );
 gchar           *na_action_profile_get_label( const NAActionProfile *profile );
 gchar           *na_action_profile_get_path( const NAActionProfile *profile );
 gchar           *na_action_profile_get_parameters( const NAActionProfile *profile );
+GSList          *na_action_profile_get_basenames( const NAActionProfile *profile );
+gboolean         na_action_profile_get_matchcase( const NAActionProfile *profile );
+GSList          *na_action_profile_get_mimetypes( const NAActionProfile *profile );
+gboolean         na_action_profile_get_is_dir( const NAActionProfile *profile );
+gboolean         na_action_profile_get_is_file( const NAActionProfile *profile );
+gboolean         na_action_profile_get_multiple( const NAActionProfile *profile );
+GSList          *na_action_profile_get_schemes( const NAActionProfile *profile );
 
 gboolean         na_action_profile_is_candidate( const NAActionProfile *profile, GList *files );
 gchar           *na_action_profile_parse_parameters( const NAActionProfile *profile, GList *files );
diff --git a/src/common/na-action.c b/src/common/na-action.c
index 02b72d4..df97fa4 100644
--- a/src/common/na-action.c
+++ b/src/common/na-action.c
@@ -61,25 +61,35 @@ struct NAActionPrivate {
 	 *  (thanks, Frederic ;-))
 	 */
 	GSList   *profiles;
+
+	/* dynamically set when reading the actions from the I/O storage
+	 * subsystem
+	 * defaults to FALSE unless a write has already returned an error
+	 */
+	gboolean  read_only;
 };
 
-/* private instance properties
+/* instance properties
  * please note that property names must have the same spelling as the
  * NactIIOProvider parameters
  */
 enum {
-	PROP_UUID = 1,
-	PROP_VERSION,
-	PROP_LABEL,
-	PROP_TOOLTIP,
-	PROP_ICON
+	PROP_ACTION_UUID = 1,
+	PROP_ACTION_VERSION,
+	PROP_ACTION_LABEL,
+	PROP_ACTION_TOOLTIP,
+	PROP_ACTION_ICON,
+	PROP_ACTION_READONLY
 };
 
-#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"
+#define PROP_ACTION_UUID_STR		"uuid"
+#define PROP_ACTION_VERSION_STR		"version"
+#define PROP_ACTION_LABEL_STR		"label"
+#define PROP_ACTION_TOOLTIP_STR		"tooltip"
+#define PROP_ACTION_ICON_STR		"icon"
+#define PROP_ACTION_READONLY_STR	"read-only"
+
+#define NA_ACTION_LATEST_VERSION	"2.0"
 
 static NAObjectClass *st_parent_class = NULL;
 
@@ -145,39 +155,46 @@ class_init( NAActionClass *klass )
 
 	/* the id of the object is marked as G_PARAM_CONSTRUCT_ONLY */
 	spec = g_param_spec_string(
-			PROP_UUID_STR,
-			PROP_UUID_STR,
+			PROP_ACTION_UUID_STR,
+			PROP_ACTION_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 );
+	g_object_class_install_property( object_class, PROP_ACTION_UUID, spec );
 
 	spec = g_param_spec_string(
-			PROP_VERSION_STR,
-			PROP_VERSION_STR,
+			PROP_ACTION_VERSION_STR,
+			PROP_ACTION_VERSION_STR,
 			"Version of the schema", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_VERSION, spec );
+	g_object_class_install_property( object_class, PROP_ACTION_VERSION, spec );
 
 	spec = g_param_spec_string(
-			PROP_LABEL_STR,
-			PROP_LABEL_STR,
+			PROP_ACTION_LABEL_STR,
+			PROP_ACTION_LABEL_STR,
 			"Context menu displayable label", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_LABEL, spec );
+	g_object_class_install_property( object_class, PROP_ACTION_LABEL, spec );
 
 	spec = g_param_spec_string(
-			PROP_TOOLTIP_STR,
-			PROP_TOOLTIP_STR,
+			PROP_ACTION_TOOLTIP_STR,
+			PROP_ACTION_TOOLTIP_STR,
 			"Context menu tooltip", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_TOOLTIP, spec );
+	g_object_class_install_property( object_class, PROP_ACTION_TOOLTIP, spec );
 
 	spec = g_param_spec_string(
-			PROP_ICON_STR,
-			PROP_ICON_STR,
+			PROP_ACTION_ICON_STR,
+			PROP_ACTION_ICON_STR,
 			"Context menu displayable icon", "",
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_ICON, spec );
+	g_object_class_install_property( object_class, PROP_ACTION_ICON, spec );
+
+	spec = g_param_spec_boolean(
+			PROP_ACTION_READONLY_STR,
+			PROP_ACTION_READONLY_STR,
+			"Is this action only readable", FALSE,
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_ACTION_READONLY, spec );
 
 	klass->private = g_new0( NAActionClassPrivate, 1 );
 
@@ -196,7 +213,17 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	NAAction* self = NA_ACTION( instance );
 
 	self->private = g_new0( NAActionPrivate, 1 );
+
 	self->private->dispose_has_run = FALSE;
+
+	/* initialize suitable default values, but for label which is
+	 * mandatory
+	 */
+	self->private->version = g_strdup( NA_ACTION_LATEST_VERSION );
+	self->private->label = NULL;
+	self->private->tooltip = NULL;
+	self->private->icon = NULL;
+	self->private->read_only = FALSE;
 }
 
 static void
@@ -206,26 +233,30 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 	NAAction *self = NA_ACTION( object );
 
 	switch( property_id ){
-		case PROP_UUID:
+		case PROP_ACTION_UUID:
 			g_value_set_string( value, self->private->uuid );
 			break;
 
-		case PROP_VERSION:
+		case PROP_ACTION_VERSION:
 			g_value_set_string( value, self->private->version );
 			break;
 
-		case PROP_LABEL:
+		case PROP_ACTION_LABEL:
 			g_value_set_string( value, self->private->label );
 			break;
 
-		case PROP_TOOLTIP:
+		case PROP_ACTION_TOOLTIP:
 			g_value_set_string( value, self->private->tooltip );
 			break;
 
-		case PROP_ICON:
+		case PROP_ACTION_ICON:
 			g_value_set_string( value, self->private->icon );
 			break;
 
+		case PROP_ACTION_READONLY:
+			g_value_set_boolean( value, self->private->read_only );
+			break;
+
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
 			break;
@@ -239,31 +270,35 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 	NAAction *self = NA_ACTION( object );
 
 	switch( property_id ){
-		case PROP_UUID:
+		case PROP_ACTION_UUID:
 			g_free( self->private->uuid );
 			self->private->uuid = g_value_dup_string( value );
 			break;
 
-		case PROP_VERSION:
+		case PROP_ACTION_VERSION:
 			g_free( self->private->version );
 			self->private->version = g_value_dup_string( value );
 			break;
 
-		case PROP_LABEL:
+		case PROP_ACTION_LABEL:
 			g_free( self->private->label );
 			self->private->label = g_value_dup_string( value );
 			break;
 
-		case PROP_TOOLTIP:
+		case PROP_ACTION_TOOLTIP:
 			g_free( self->private->tooltip );
 			self->private->tooltip = g_value_dup_string( value );
 			break;
 
-		case PROP_ICON:
+		case PROP_ACTION_ICON:
 			g_free( self->private->icon );
 			self->private->icon = g_value_dup_string( value );
 			break;
 
+		case PROP_ACTION_READONLY:
+			self->private->read_only = g_value_get_boolean( value );
+			break;
+
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
 			break;
@@ -322,7 +357,7 @@ instance_finalize( GObject *object )
 NAAction *
 na_action_new( const gchar *uuid )
 {
-	NAAction *action = g_object_new( NA_ACTION_TYPE, PROP_UUID_STR, uuid, NULL );
+	NAAction *action = g_object_new( NA_ACTION_TYPE, PROP_ACTION_UUID_STR, uuid, NULL );
 	return( action );
 }
 
@@ -343,17 +378,18 @@ na_action_duplicate( const NAAction *action )
 	g_assert( NA_IS_ACTION( action ));
 
 	gchar *uuid = do_get_id( NA_OBJECT( action ));
-	NAAction *duplicate = g_object_new( NA_ACTION_TYPE, PROP_UUID_STR, uuid, NULL );
+	NAAction *duplicate = g_object_new( NA_ACTION_TYPE, PROP_ACTION_UUID_STR, uuid, NULL );
 	g_free( uuid );
 
 	duplicate->private->version = g_strdup( action->private->version );
 	duplicate->private->label = g_strdup( action->private->label );
 	duplicate->private->tooltip = g_strdup( action->private->tooltip );
 	duplicate->private->icon = g_strdup( action->private->icon );
+	duplicate->private->read_only = action->private->read_only;
 
 	GSList *ip;
 	for( ip = action->private->profiles ; ip ; ip = ip->next ){
-
+		/* TODO: duplicate profile */
 	}
 
 	return( duplicate );
@@ -371,11 +407,12 @@ do_dump( const NAObject *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 );
-	g_debug( "%s:    icon='%s'", thisfn, self->private->icon );
+	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 );
+	g_debug( "%s:      icon='%s'", thisfn, self->private->icon );
+	g_debug( "%s: read-only='%s'", thisfn, self->private->read_only ? "True" : "False" );
 
 	/* dump profiles */
 	g_debug( "%s: %d profile(s) at %p", thisfn, na_action_get_profiles_count( self ), self->private->profiles );
@@ -391,7 +428,7 @@ do_get_id( const NAObject *action )
 	g_assert( NA_IS_ACTION( action ));
 
 	gchar *uuid;
-	g_object_get( G_OBJECT( action ), PROP_UUID_STR, &uuid, NULL );
+	g_object_get( G_OBJECT( action ), PROP_ACTION_UUID_STR, &uuid, NULL );
 
 	return( uuid );
 }
@@ -427,7 +464,7 @@ na_action_get_version( const NAAction *action )
 	g_assert( NA_IS_ACTION( action ));
 
 	gchar *version;
-	g_object_get( G_OBJECT( action ), PROP_VERSION_STR, &version, NULL );
+	g_object_get( G_OBJECT( action ), PROP_ACTION_VERSION_STR, &version, NULL );
 
 	return( version );
 }
@@ -438,7 +475,7 @@ do_get_label( const NAObject *action )
 	g_assert( NA_IS_ACTION( action ));
 
 	gchar *label;
-	g_object_get( G_OBJECT( action ), PROP_LABEL_STR, &label, NULL );
+	g_object_get( G_OBJECT( action ), PROP_ACTION_LABEL_STR, &label, NULL );
 
 	return( label );
 }
@@ -471,7 +508,7 @@ na_action_get_tooltip( const NAAction *action )
 	g_assert( NA_IS_ACTION( action ));
 
 	gchar *tooltip;
-	g_object_get( G_OBJECT( action ), PROP_TOOLTIP_STR, &tooltip, NULL );
+	g_object_get( G_OBJECT( action ), PROP_ACTION_TOOLTIP_STR, &tooltip, NULL );
 
 	return( tooltip );
 }
@@ -490,7 +527,7 @@ na_action_get_icon( const NAAction *action )
 	g_assert( NA_IS_ACTION( action ));
 
 	gchar *icon;
-	g_object_get( G_OBJECT( action ), PROP_ICON_STR, &icon, NULL );
+	g_object_get( G_OBJECT( action ), PROP_ACTION_ICON_STR, &icon, NULL );
 
 	return( icon );
 }
@@ -509,7 +546,7 @@ na_action_get_verified_icon_name( const NAAction *action )
 	g_assert( NA_IS_ACTION( action ));
 
 	gchar *icon_name;
-	g_object_get( G_OBJECT( action ), PROP_ICON_STR, &icon_name, NULL );
+	g_object_get( G_OBJECT( action ), PROP_ACTION_ICON_STR, &icon_name, NULL );
 
 	if( icon_name[0] == '/' ){
 		if( !g_file_test( icon_name, G_FILE_TEST_IS_REGULAR )){
@@ -525,6 +562,19 @@ na_action_get_verified_icon_name( const NAAction *action )
 }
 
 /**
+ * Is the specified action only readable ?
+ * Or, in other words, may this action be edited and then saved ?
+ *
+ * @action: an NAAction object.
+ */
+gboolean
+na_action_is_readonly( const NAAction *action )
+{
+	g_assert( NA_IS_ACTION( action ));
+	return( action->private->read_only );
+}
+
+/**
  * Set a new UUID for the action.
  *
  * @action: action whose UUID is to be set.
@@ -539,7 +589,7 @@ na_action_set_new_uuid( NAAction *action )
 	uuid_generate( uuid );
 	uuid_unparse_lower( uuid, uuid_str );
 
-	g_object_set( G_OBJECT( action ), PROP_UUID_STR, uuid_str, NULL );
+	g_object_set( G_OBJECT( action ), PROP_ACTION_UUID_STR, uuid_str, NULL );
 }
 
 /**
diff --git a/src/common/na-action.h b/src/common/na-action.h
index 7a5bdaa..c8eb992 100644
--- a/src/common/na-action.h
+++ b/src/common/na-action.h
@@ -67,6 +67,17 @@ typedef struct {
 }
 	NAActionClass;
 
+/* instance properties
+ * please note that property names must have the same spelling as the
+ * NactIIOProvider parameters
+ */
+#define PROP_ACTION_UUID_STR			"uuid"
+#define PROP_ACTION_VERSION_STR			"version"
+#define PROP_ACTION_LABEL_STR			"label"
+#define PROP_ACTION_TOOLTIP_STR			"tooltip"
+#define PROP_ACTION_ICON_STR			"icon"
+#define PROP_ACTION_READONLY_STR		"read-only"
+
 GType     na_action_get_type( void );
 
 NAAction *na_action_new( const gchar *uuid );
@@ -78,6 +89,7 @@ gchar    *na_action_get_label( const NAAction *action );
 gchar    *na_action_get_tooltip( const NAAction *action );
 gchar    *na_action_get_icon( const NAAction *action );
 gchar    *na_action_get_verified_icon_name( const NAAction *action );
+gboolean  na_action_is_readonly( const NAAction *action );
 
 void      na_action_set_new_uuid( NAAction *action );
 
diff --git a/src/common/na-gconf-keys.h b/src/common/na-gconf-keys.h
index 92703e5..b5d2d61 100644
--- a/src/common/na-gconf-keys.h
+++ b/src/common/na-gconf-keys.h
@@ -31,7 +31,25 @@
 #ifndef __NA_GCONF_KEYS_H__
 #define __NA_GCONF_KEYS_H__
 
-/* GConf general information */
+/* GConf general information
+ */
 #define NA_GCONF_CONFIG_PATH		NAUTILUS_ACTIONS_CONFIG_GCONF_BASEDIR "/configurations"
 
+/* GConf key names
+ */
+#define ACTION_VERSION_ENTRY			"version"
+#define ACTION_LABEL_ENTRY				"label"
+#define ACTION_TOOLTIP_ENTRY			"tooltip"
+#define ACTION_ICON_ENTRY				"icon"
+#define ACTION_PROFILE_LABEL_ENTRY		"desc-name"
+#define ACTION_PATH_ENTRY				"path"
+#define ACTION_PARAMETERS_ENTRY			"parameters"
+#define ACTION_BASENAMES_ENTRY			"basenames"
+#define ACTION_MATCHCASE_ENTRY			"matchcase"
+#define ACTION_MIMETYPES_ENTRY			"mimetypes"
+#define ACTION_ISFILE_ENTRY				"isfile"
+#define ACTION_ISDIR_ENTRY				"isdir"
+#define ACTION_MULTIPLE_ENTRY			"accept-multiple-files"
+#define ACTION_SCHEMES_ENTRY			"schemes"
+
 #endif /* __NA_GCONF_KEYS_H__ */
diff --git a/src/common/na-gconf.c b/src/common/na-gconf.c
index d899650..53c3011 100644
--- a/src/common/na-gconf.c
+++ b/src/common/na-gconf.c
@@ -72,29 +72,50 @@ enum {
 
 static GObjectClass *st_parent_class = NULL;
 
-static GType            register_type( void );
-static void             class_init( NAGConfClass *klass );
-static void             iio_provider_iface_init( NAIIOProviderInterface *iface );
-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 );
-
-static GSList          *do_read_actions( NAIIOProvider *provider );
-static void             load_action_properties( NAGConf *gconf, NAAction *action );
-static GSList          *load_profiles( NAGConf *gconf, NAAction *action );
-static void             load_profile_properties( NAGConf *gconf, NAActionProfile *profile );
-static GSList          *load_subdirs( const NAGConf *gconf, const gchar *path );
-static GSList          *load_keys_values( const NAGConf *gconf, const gchar *path );
-static void             free_keys_values( GSList *keys );
-static gchar           *path_to_key( const gchar *path );
-static void             set_item_properties( NAObject *object, GSList *properties );
+static GType          register_type( void );
+static void           class_init( NAGConfClass *klass );
+static void           iio_provider_iface_init( NAIIOProviderInterface *iface );
+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 );
+
+static GSList        *do_read_actions( NAIIOProvider *provider );
+static gboolean       load_action( NAGConf *gconf, NAAction *action, const gchar *uuid );
+/*static void           load_action_properties( NAGConf *gconf, NAAction *action );*/
+static GSList        *load_profiles( NAGConf *gconf, NAAction *action );
+static void           load_profile_properties( NAGConf *gconf, NAActionProfile *profile );
+static GSList        *load_subdirs( const NAGConf *gconf, const gchar *path );
+static GSList        *load_keys_values( const NAGConf *gconf, const gchar *path );
+static void           free_keys_values( GSList *entries );
+static gchar         *path_to_key( const gchar *path );
+static void           set_item_properties( NAObject *object, GSList *properties );
+static gboolean       set_action_properties( NAGConf *gconf, NAAction *action, GSList *properties );
+static void           load_v1_properties( NAAction *action, const gchar *version, GSList *properties );
+static gchar         *search_for_str( GSList *properties, const gchar *profile, const gchar *key );
+static gboolean       search_for_bool( GSList *properties, const gchar *profile, const gchar *key );
+static GSList        *search_for_list( GSList *properties, const gchar *profile, const gchar *key );
+static GSList        *keys_to_notify( GSList *entries );
 static NAPivotNotify *entry_to_notify( const GConfEntry *entry );
+static void           free_list_notify( GSList *list );
+static gboolean       remove_v1_keys( NAGConf *gconf, const NAAction *action, gchar **message );
+static gboolean       remove_key( NAGConf *gconf, const gchar *uuid, const gchar *key, gchar **message );
 
-static guint            install_gconf_watch( NAGConf *gconf );
-static void             remove_gconf_watch( NAGConf *gconf );
-static void             action_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data );
+static gboolean       do_is_writable( NAIIOProvider *provider );
+static gboolean       do_is_willing_to_write( NAIIOProvider *provider, const GObject *action );
+
+static guint          do_write_action( NAIIOProvider *provider, const GObject *action, gchar **message );
+static gboolean       write_v2_keys( NAGConf *gconf, const NAAction *action, gchar **message );
+static gboolean       write_str( NAGConf *gconf, const gchar *uuid, const gchar *key, gchar *value, gchar **message );
+static gboolean       write_str2( NAGConf *gconf, const gchar *uuid, const gchar *name, const gchar *key, gchar *value, gchar **message );
+static gboolean       write_key( NAGConf *gconf, const gchar *path, const gchar *value, gchar **message );
+static gboolean       write_bool( NAGConf *gconf, const gchar *uuid, const gchar *name, const gchar *key, gboolean value, gchar **message );
+static gboolean       write_list( NAGConf *gconf, const gchar *uuid, const gchar *name, const gchar *key, GSList *value, gchar **message );
+
+static guint          install_gconf_watch( NAGConf *gconf );
+static void           remove_gconf_watch( NAGConf *gconf );
+static void           action_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data );
 
 GType
 na_gconf_get_type( void )
@@ -168,6 +189,9 @@ iio_provider_iface_init( NAIIOProviderInterface *iface )
 	g_debug( "%s: iface=%p", thisfn, iface );
 
 	iface->read_actions = do_read_actions;
+	iface->is_writable = do_is_writable;
+	iface->is_willing_to_write = do_is_willing_to_write;
+	iface->write_action = do_write_action;
 }
 
 static void
@@ -271,6 +295,12 @@ na_gconf_new( const GObject *handler )
 /*
  * NAIIOProviderInterface implementation
  * load the list of actions and returns them as a GSList
+ *
+ * @provider: this NAGconf object, seen here as a I/O provider.
+ *
+ * Note that whatever be the version of the readen action, we convert
+ * it now to the latest available, possibly updating the GConf storage
+ * subsystem.
  */
 static GSList *
 do_read_actions( NAIIOProvider *provider )
@@ -285,7 +315,6 @@ do_read_actions( NAIIOProvider *provider )
 	GSList *items = NULL;
 	GSList *ip;
 	GSList *listpath = load_subdirs( self, NA_GCONF_CONFIG_PATH );
-	GSList *profiles;
 
 	for( ip = listpath ; ip ; ip = ip->next ){
 
@@ -293,13 +322,12 @@ do_read_actions( NAIIOProvider *provider )
 
 		NAAction *action = na_action_new( key );
 
-		load_action_properties( self, action );
-
-		profiles = load_profiles( self, action );
-		na_action_set_profiles( action, profiles );
-		na_action_free_profiles( profiles );
+		if( load_action( self, action, key )){
+			items = g_slist_prepend( items, action );
 
-		items = g_slist_prepend( items, action );
+		} else {
+			g_object_unref( action );
+		}
 
 		g_free( key );
 	}
@@ -311,12 +339,57 @@ do_read_actions( NAIIOProvider *provider )
 
 /*
  * load and set the properties of the specified action
+ * at least we must have a label, as all other entries can have
+ * suitable default values
+ *
+ * we have to deal with successive versions of action schema :
+ *
+ * - version = '1.0'
+ *   action+= uuid+label+tooltip+icon
+ *   action+= path+parameters+basenames+isdir+isfile+multiple+schemes
+ *
+ * - version > '1.0'
+ *   action+= matchcase+mimetypes
+ *
+ * - version = '2.0' which introduces the 'profile' notion
+ *   profile += name+label
  */
-static void
+static gboolean
+load_action( NAGConf *gconf, NAAction *action, const gchar *uuid )
+{
+	static const gchar *thisfn = "nacf_gconf_load_action";
+	g_debug( "%s: gconf=%p, action=%p, uuid=%s", thisfn, gconf, action, uuid );
+
+	g_assert( NA_IS_GCONF( gconf ));
+	g_assert( NA_IS_ACTION( action ));
+
+	gchar *path = g_strdup_printf( "%s/%s", NA_GCONF_CONFIG_PATH, uuid );
+
+	GSList *entries = load_keys_values( gconf, path );
+	GSList *properties = keys_to_notify( entries );
+	free_keys_values( entries );
+
+	gboolean ok = set_action_properties( gconf, action, properties );
+
+	if( !gconf_client_key_is_writable( gconf->private->gconf, path, NULL )){
+		g_debug( "%s: %s key is not writable", thisfn, path );
+		gboolean readonly = TRUE;
+		g_object_set( G_OBJECT( action ), PROP_ACTION_READONLY_STR, readonly, NULL );
+	}
+
+	free_list_notify( properties );
+	g_free( path );
+	return( ok );
+}
+
+/*
+ * load and set the properties of the specified action
+ */
+/*static void
 load_action_properties( NAGConf *gconf, NAAction *action )
 {
-	/*static const gchar *thisfn = "nacf_gconf_load_action_properties";
-	g_debug( "%s: gconf=%p, action=%p", thisfn, gconf, action );*/
+	static const gchar *thisfn = "nacf_gconf_load_action_properties";
+	g_debug( "%s: gconf=%p, action=%p", thisfn, gconf, action );
 
 	g_assert( NA_IS_GCONF( gconf ));
 	g_assert( NA_IS_ACTION( action ));
@@ -331,7 +404,7 @@ load_action_properties( NAGConf *gconf, NAAction *action )
 	free_keys_values( properties );
 	g_free( uuid );
 	g_free( path );
-}
+}*/
 
 /*
  * load the list of profiles for an action and returns them as a GSList
@@ -401,7 +474,7 @@ load_profile_properties( NAGConf *gconf, NAActionProfile *profile )
  * load the keys which are the subdirs of the given path
  * returns a list of keys as full path
  */
-GSList *
+static GSList *
 load_subdirs( const NAGConf *gconf, const gchar *path )
 {
 	static const gchar *thisfn = "na_gconf_load_subdirs";
@@ -418,10 +491,10 @@ load_subdirs( const NAGConf *gconf, const gchar *path )
 }
 
 /*
- * load all the key=value pairs of this key (specified as a full path)
+ * load all the key=value pairs of this key (specified as a full path),
+ * returning them as a list of GConfEntry.
  * The list is not recursive, it contains only the immediate children of
- * path.
- * To free the returned list, call free_key_values
+ * path. To free the returned list, call free_key_values.
  */
 static GSList *
 load_keys_values( const NAGConf *gconf, const gchar *path )
@@ -501,11 +574,188 @@ set_item_properties( NAObject *object, GSList *properties )
 }
 
 /*
+ * set the item properties into the action, dealing with successive
+ * versions
+ */
+static gboolean
+set_action_properties( NAGConf *gconf, NAAction *action, GSList *properties )
+{
+	/*static const gchar *thisfn = "na_gconf_set_action_properties";*/
+
+	/* the last action version we handle here */
+	static const gchar *last_version = "2.0";
+
+	gchar *label = search_for_str( properties, NULL, ACTION_LABEL_ENTRY );
+	if( !label ){
+		return( FALSE );
+	}
+
+	gchar *version = search_for_str( properties, NULL, ACTION_VERSION_ENTRY );
+	gchar *tooltip = search_for_str( properties, NULL, ACTION_TOOLTIP_ENTRY );
+	gchar *icon = search_for_str( properties, NULL, ACTION_ICON_ENTRY );
+
+	g_object_set( G_OBJECT( action ),
+			PROP_ACTION_VERSION_STR, last_version,
+			PROP_ACTION_LABEL_STR, label,
+			PROP_ACTION_TOOLTIP_STR, tooltip,
+			PROP_ACTION_ICON_STR, icon,
+			NULL );
+
+	g_free( icon );
+	g_free( tooltip );
+	g_free( label );
+
+	if( g_ascii_strcasecmp( version, "2.0" ) < 0 ){
+
+		load_v1_properties( action, version, properties );
+
+		gchar *uuid = na_action_get_uuid( action );
+		gchar *path = g_strdup_printf( "%s/%s", NA_GCONF_CONFIG_PATH, uuid );
+		if( gconf_client_key_is_writable( gconf->private->gconf, path, NULL )){
+			remove_v1_keys( gconf, action, NULL );
+		}
+		g_free( path );
+		g_free( uuid );
+
+	} else {
+
+		GSList *profiles = load_profiles( gconf, action );
+		na_action_set_profiles( action, profiles );
+		na_action_free_profiles( profiles );
+	}
+
+	g_free( version );
+	return( TRUE );
+}
+
+/*
+ * only handle one profile, which is already loaded
+ * action+= path+parameters+basenames+isdir+isfile+multiple+schemes
+ */
+static void
+load_v1_properties( NAAction *action, const gchar *version, GSList *properties )
+{
+	GSList *profiles = NULL;
+	NAActionProfile *profile = na_action_profile_new( NA_OBJECT( action ), "default" );
+
+	gchar *path = search_for_str( properties, NULL, ACTION_PATH_ENTRY );
+	gchar *parameters = search_for_str( properties, NULL, ACTION_PARAMETERS_ENTRY );
+	GSList *basenames = search_for_list( properties, NULL, ACTION_BASENAMES_ENTRY );
+	gboolean isdir = search_for_bool( properties, NULL, ACTION_ISDIR_ENTRY );
+	gboolean isfile = search_for_bool( properties, NULL, ACTION_ISFILE_ENTRY );
+	gboolean multiple = search_for_bool( properties, NULL, ACTION_MULTIPLE_ENTRY );
+	GSList *schemes = search_for_list( properties, NULL, ACTION_SCHEMES_ENTRY );
+
+	g_object_set( G_OBJECT( profile ),
+			PROP_PROFILE_PATH_STR, path,
+			PROP_PROFILE_PARAMETERS_STR, parameters,
+			PROP_PROFILE_BASENAMES_STR, basenames,
+			PROP_PROFILE_ISDIR_STR, isdir,
+			PROP_PROFILE_ISFILE_STR, isfile,
+			PROP_PROFILE_ACCEPT_MULTIPLE_STR, multiple,
+			PROP_PROFILE_SCHEMES_STR, schemes,
+			NULL );
+
+	g_free( path );
+	g_free( parameters );
+	na_utils_free_string_list( basenames );
+	na_utils_free_string_list( schemes );
+
+	if( g_ascii_strcasecmp( version, "1.0" ) > 0 ){
+
+		/* handle matchcase+mimetypes
+		 * note that default values for 1.0 version have been set
+		 * in na_action_profile_instance_init
+		 */
+		gboolean matchcase = search_for_bool( properties, "", ACTION_MATCHCASE_ENTRY );
+		GSList *mimetypes = search_for_list( properties, "", ACTION_MIMETYPES_ENTRY );
+
+		g_object_set( G_OBJECT( profile ),
+				PROP_PROFILE_MATCHCASE_STR, matchcase,
+				PROP_PROFILE_MIMETYPES_STR, mimetypes,
+				NULL );
+
+		na_utils_free_string_list( mimetypes );
+	}
+
+	profiles = g_slist_prepend( profiles, profile );
+	na_action_set_profiles( action, profiles );
+	na_action_free_profiles( profiles );
+}
+
+static gchar *
+search_for_str( GSList *properties, const gchar *profile, const gchar *key )
+{
+	GSList *ip;
+	for( ip = properties ; ip ; ip = ip->next ){
+		NAPivotNotify *npn = ( NAPivotNotify * ) ip->data;
+		if( npn->type == NA_PIVOT_STR &&
+		  ( !profile || !g_ascii_strcasecmp( profile, npn->profile )) &&
+		    !g_ascii_strcasecmp( key, npn->parm )){
+				return( g_strdup(( gchar * ) npn->data ));
+		}
+	}
+	return(( gchar * ) NULL );
+}
+
+static gboolean
+search_for_bool( GSList *properties, const gchar *profile, const gchar *key )
+{
+	GSList *ip;
+	for( ip = properties ; ip ; ip = ip->next ){
+		NAPivotNotify *npn = ( NAPivotNotify * ) ip->data;
+		if( npn->type == NA_PIVOT_BOOL &&
+		  ( !profile || !g_ascii_strcasecmp( profile, npn->profile )) &&
+			!g_ascii_strcasecmp( key, npn->parm )){
+				return(( gboolean ) npn->data );
+		}
+	}
+	return( FALSE );
+}
+
+static GSList *
+search_for_list( GSList *properties, const gchar *profile, const gchar *key )
+{
+	GSList *ip;
+	for( ip = properties ; ip ; ip = ip->next ){
+		NAPivotNotify *npn = ( NAPivotNotify * ) ip->data;
+		if( npn->type == NA_PIVOT_STRLIST &&
+		  ( !profile || !g_ascii_strcasecmp( profile, npn->profile )) &&
+			!g_ascii_strcasecmp( key, npn->parm )){
+				return( na_utils_duplicate_string_list(( GSList * ) npn->data ));
+		}
+	}
+	return(( GSList * ) NULL );
+}
+
+/*
+ * load all the key=value pairs of this key (specified as a full path),
+ * returning them as a list of GConfEntry.
+ * The list is not recursive, it contains only the immediate children of
+ * path. To free the returned list, call free_key_values.
+ */
+static GSList *
+keys_to_notify( GSList *entries )
+{
+	GSList *item;
+	GSList *properties = NULL;
+
+	for( item = entries ; item ; item = item->next ){
+		GConfEntry *entry = ( GConfEntry * ) item->data;
+		NAPivotNotify *npn = entry_to_notify( entry );
+		properties = g_slist_prepend( properties, npn );
+	}
+
+	return( properties );
+}
+
+/*
  * convert a GConfEntry to a structure suitable to notify NAPivot
  *
  * when created or modified, the entry can be of the forms :
  *  key/parm
  *  key/profile/parm with a not null value
+ *
  * but when removing an entry, it will be of the form :
  *  key
  *  key/parm
@@ -576,6 +826,199 @@ entry_to_notify( const GConfEntry *entry )
 	return( npn );
 }
 
+static void
+free_list_notify( GSList *list )
+{
+	GSList *il;
+	for( il = list ; il ; il = il->next ){
+		na_pivot_free_notify(( NAPivotNotify *) il->data );
+	}
+}
+
+static gboolean
+remove_v1_keys( NAGConf *gconf, const NAAction *action, gchar **message )
+{
+	gchar *uuid = na_action_get_uuid( action );
+
+	gboolean ret =
+		remove_key( gconf, uuid, ACTION_PATH_ENTRY, message ) &&
+		remove_key( gconf, uuid, ACTION_PARAMETERS_ENTRY, message ) &&
+		remove_key( gconf, uuid, ACTION_BASENAMES_ENTRY, message ) &&
+		remove_key( gconf, uuid, ACTION_MATCHCASE_ENTRY, message ) &&
+		remove_key( gconf, uuid, ACTION_MIMETYPES_ENTRY, message ) &&
+		remove_key( gconf, uuid, ACTION_ISFILE_ENTRY, message ) &&
+		remove_key( gconf, uuid, ACTION_ISDIR_ENTRY, message ) &&
+		remove_key( gconf, uuid, ACTION_MULTIPLE_ENTRY, message ) &&
+		remove_key( gconf, uuid, ACTION_SCHEMES_ENTRY, message );
+
+	g_free( uuid );
+	return( ret );
+}
+
+static gboolean
+remove_key( NAGConf *gconf, const gchar *uuid, const gchar *key, gchar **message )
+{
+	gboolean ret = TRUE;
+	GError *error = NULL;
+
+	gchar *path = g_strdup_printf( "%s/%s/%s", NA_GCONF_CONFIG_PATH, uuid, key );
+
+	if( !gconf_client_unset( gconf->private->gconf, path, &error )){
+		if( message ){
+			*message = g_strdup( error->message );
+		}
+		g_error_free( error );
+		ret = FALSE;
+	}
+
+	g_free( path );
+	return( ret );
+}
+
+static gboolean
+do_is_writable( NAIIOProvider *provider )
+{
+	return( TRUE );
+}
+
+static gboolean
+do_is_willing_to_write( NAIIOProvider *provider, const GObject *action )
+{
+	return( TRUE );
+}
+
+static guint
+do_write_action( NAIIOProvider *provider, const GObject *obj_action, gchar **message )
+{
+	static const gchar *thisfn = "nacf_gconf_do_write_action";
+	g_debug( "%s: provider=%p, action=%p, message=%p", thisfn, provider, obj_action, message );
+
+	g_assert( NA_IS_IIO_PROVIDER( provider ));
+	g_assert( NA_IS_GCONF( provider ));
+	NAGConf *self = NA_GCONF( provider );
+
+	message = NULL;
+
+	g_assert( NA_IS_ACTION( obj_action ));
+	NAAction *action = NA_ACTION( obj_action );
+
+	if( !write_v2_keys( self, action, message )){
+		return( NA_IIO_PROVIDER_WRITE_ERROR );
+	}
+
+	return( NA_IIO_PROVIDER_WRITE_OK );
+}
+
+static gboolean
+write_v2_keys( NAGConf *gconf, const NAAction *action, gchar **message )
+{
+	gchar *uuid = na_action_get_uuid( action );
+
+	gboolean ret =
+		write_str( gconf, uuid, ACTION_VERSION_ENTRY, na_action_get_version( action ), message ) &&
+		write_str( gconf, uuid, ACTION_LABEL_ENTRY, na_action_get_label( action ), message ) &&
+		write_str( gconf, uuid, ACTION_TOOLTIP_ENTRY, na_action_get_tooltip( action ), message ) &&
+		write_str( gconf, uuid, ACTION_ICON_ENTRY, na_action_get_icon( action ), message );
+
+	GSList *ip;
+	GSList *profiles = na_action_get_profiles( action );
+
+	for( ip = profiles ; ip && ret ; ip = ip->next ){
+
+		NAActionProfile *profile = NA_ACTION_PROFILE( ip->data );
+		gchar *name = na_action_profile_get_name( profile );
+
+		ret =
+			write_str2( gconf, uuid, name, ACTION_PROFILE_LABEL_ENTRY, na_action_profile_get_label( profile ), message ) &&
+			write_str2( gconf, uuid, name, ACTION_PATH_ENTRY, na_action_profile_get_path( profile ), message ) &&
+			write_str2( gconf, uuid, name, ACTION_PARAMETERS_ENTRY, na_action_profile_get_parameters( profile ), message ) &&
+			write_list( gconf, uuid, name, ACTION_BASENAMES_ENTRY, na_action_profile_get_basenames( profile ), message ) &&
+			write_bool( gconf, uuid, name, ACTION_MATCHCASE_ENTRY, na_action_profile_get_matchcase( profile ), message ) &&
+			write_list( gconf, uuid, name, ACTION_MIMETYPES_ENTRY, na_action_profile_get_mimetypes( profile ), message ) &&
+			write_bool( gconf, uuid, name, ACTION_ISFILE_ENTRY, na_action_profile_get_is_file( profile ), message ) &&
+			write_bool( gconf, uuid, name, ACTION_ISDIR_ENTRY, na_action_profile_get_is_dir( profile ), message ) &&
+			write_bool( gconf, uuid, name, ACTION_MULTIPLE_ENTRY, na_action_profile_get_multiple( profile ), message ) &&
+			write_list( gconf, uuid, name, ACTION_SCHEMES_ENTRY, na_action_profile_get_schemes( profile ), message );
+
+		g_free( name );
+	}
+
+	g_free( uuid );
+	return( ret );
+}
+
+static gboolean
+write_str( NAGConf *gconf, const gchar *uuid, const gchar *key, gchar *value, gchar **message )
+{
+	gchar *path = g_strdup_printf( "%s/%s/%s", NA_GCONF_CONFIG_PATH, uuid, key );
+	gboolean ret = write_key( gconf, path, value, message );
+	g_free( value );
+	g_free( path );
+	return( ret );
+}
+
+static gboolean
+write_str2( NAGConf *gconf, const gchar *uuid, const gchar *name, const gchar *key, gchar *value, gchar **message )
+{
+	gchar *path = g_strdup_printf( "%s/%s/%s/%s", NA_GCONF_CONFIG_PATH, uuid, name, key );
+	gboolean ret = write_key( gconf, path, value, message );
+	g_free( value );
+	g_free( path );
+	return( ret );
+}
+
+static gboolean
+write_key( NAGConf *gconf, const gchar *path, const gchar *value, gchar **message )
+{
+	gboolean ret = TRUE;
+	GError *error = NULL;
+
+	if( !gconf_client_set_string( gconf->private->gconf, path, value, &error )){
+		*message = g_strdup( error->message );
+		g_error_free( error );
+		ret = FALSE;
+	}
+
+	return( ret );
+}
+
+static gboolean
+write_bool( NAGConf *gconf, const gchar *uuid, const gchar *name, const gchar *key, gboolean value, gchar **message )
+{
+	gboolean ret = TRUE;
+	GError *error = NULL;
+
+	gchar *path = g_strdup_printf( "%s/%s/%s/%s", NA_GCONF_CONFIG_PATH, uuid, name, key );
+
+	if( !gconf_client_set_bool( gconf->private->gconf, path, value, &error )){
+		*message = g_strdup( error->message );
+		g_error_free( error );
+		ret = FALSE;
+	}
+
+	g_free( path );
+	return( ret );
+}
+
+static gboolean
+write_list( NAGConf *gconf, const gchar *uuid, const gchar *name, const gchar *key, GSList *value, gchar **message )
+{
+	gboolean ret = TRUE;
+	GError *error = NULL;
+
+	gchar *path = g_strdup_printf( "%s/%s/%s/%s", NA_GCONF_CONFIG_PATH, uuid, name, key );
+
+	if( !gconf_client_set_list( gconf->private->gconf, path, GCONF_VALUE_STRING, value, &error )){
+		*message = g_strdup( error->message );
+		g_error_free( error );
+		ret = FALSE;
+	}
+
+	na_utils_free_string_list( value );
+	g_free( path );
+	return( ret );
+}
+
 /*
  * note that we need the NAPivot object in action_changed_cb handler
  * but it is initialized as a construction property, and this watch is
diff --git a/src/common/na-iio-provider.c b/src/common/na-iio-provider.c
index 19e53ff..05664a0 100644
--- a/src/common/na-iio-provider.c
+++ b/src/common/na-iio-provider.c
@@ -44,9 +44,12 @@
 struct NAIIOProviderInterfacePrivate {
 };
 
-static GType register_type( void );
-static void  interface_base_init( NAIIOProviderInterface *klass );
-static void  interface_base_finalize( NAIIOProviderInterface *klass );
+static GType    register_type( void );
+static void     interface_base_init( NAIIOProviderInterface *klass );
+static void     interface_base_finalize( NAIIOProviderInterface *klass );
+
+static gboolean do_is_writable( NAIIOProvider *instance );
+static gboolean do_is_willing_to_write( NAIIOProvider *instance, const GObject *action );
 
 /**
  * Registers the GType of this interface.
@@ -100,6 +103,9 @@ interface_base_init( NAIIOProviderInterface *klass )
 		klass->private = g_new0( NAIIOProviderInterfacePrivate, 1 );
 
 		klass->read_actions = NULL;
+		klass->is_writable = do_is_writable;
+		klass->is_willing_to_write = do_is_willing_to_write;
+		klass->write_action = NULL;
 
 		initialized = TRUE;
 	}
@@ -147,7 +153,6 @@ na_iio_provider_read_actions( const GObject *object )
 	for( ip = providers ; ip ; ip = ip->next ){
 
 		instance = NA_IIO_PROVIDER( ip->data );
-
 		if( NA_IIO_PROVIDER_GET_INTERFACE( instance )->read_actions ){
 
 			list = NA_IIO_PROVIDER_GET_INTERFACE( instance )->read_actions( instance );
@@ -182,7 +187,7 @@ na_iio_provider_read_actions( const GObject *object )
  *
  * Returns TRUE if the write is successfull, FALSE else.
  */
-gboolean
+guint
 na_iio_provider_write_action( const GObject *obj_pivot, const GObject *obj_action, gchar **message )
 {
 	static const gchar *thisfn = "na_iio_provider_write_action";
@@ -193,7 +198,7 @@ na_iio_provider_write_action( const GObject *obj_pivot, const GObject *obj_actio
 
 	g_assert( NA_IS_ACTION( obj_action ));
 
-	gboolean ret = TRUE;
+	guint ret = NA_IIO_PROVIDER_NOT_WRITABLE;
 	GSList *ip;
 	NAIIOProvider *instance;
 
@@ -202,13 +207,26 @@ na_iio_provider_write_action( const GObject *obj_pivot, const GObject *obj_actio
 	for( ip = providers ; ip ; ip = ip->next ){
 
 		instance = NA_IIO_PROVIDER( ip->data );
-
-		/* TODO: write the action
 		if( NA_IIO_PROVIDER_GET_INTERFACE( instance )->write_action ){
-			list = NA_IIO_PROVIDER_GET_INTERFACE( instance )->load_actions( instance );
-			actions = g_slist_concat( actions, list );
-		}*/
+
+			ret = NA_IIO_PROVIDER_GET_INTERFACE( instance )->write_action( instance, obj_action, message );
+			if( ret == NA_IIO_PROVIDER_WRITE_OK || ret == NA_IIO_PROVIDER_WRITE_ERROR ){
+				break;
+			}
+		}
 	}
 
 	return( ret );
 }
+
+static gboolean
+do_is_writable( NAIIOProvider *instance )
+{
+	return( FALSE );
+}
+
+static gboolean
+do_is_willing_to_write( NAIIOProvider *instance, const GObject *action )
+{
+	return( FALSE );
+}
diff --git a/src/common/na-iio-provider.h b/src/common/na-iio-provider.h
index 86c6175..fd9bcd1 100644
--- a/src/common/na-iio-provider.h
+++ b/src/common/na-iio-provider.h
@@ -60,8 +60,10 @@ typedef struct {
 	NAIIOProviderInterfacePrivate *private;
 
 	/* i/o api */
-	GSList * ( *read_actions )( NAIIOProvider *instance );
-	gboolean ( *write_action )( NAIIOProvider *instance, const GObject *action, gchar **message );
+	GSList * ( *read_actions )       ( NAIIOProvider *instance );
+	gboolean ( *is_writable )        ( NAIIOProvider *instance );
+	gboolean ( *is_willing_to_write )( NAIIOProvider *instance, const GObject *action );
+	guint    ( *write_action )       ( NAIIOProvider *instance, const GObject *action, gchar **message );
 }
 	NAIIOProviderInterface;
 
@@ -69,7 +71,16 @@ GType    na_iio_provider_get_type( void );
 
 GSList  *na_iio_provider_read_actions( const GObject *pivot );
 
-gboolean na_iio_provider_write_action( const GObject *pivot, const GObject *action, gchar **message );
+guint    na_iio_provider_write_action( const GObject *pivot, const GObject *action, gchar **message );
+
+/* return code of write_action function
+ */
+enum {
+	NA_IIO_PROVIDER_WRITE_OK = 0,
+	NA_IIO_PROVIDER_NOT_WRITABLE,
+	NA_IIO_PROVIDER_NOT_WILLING_TO_WRITE,
+	NA_IIO_PROVIDER_WRITE_ERROR
+};
 
 G_END_DECLS
 
diff --git a/src/plugin/nautilus-actions.c b/src/plugin/nautilus-actions.c
index f26f639..9bca418 100644
--- a/src/plugin/nautilus-actions.c
+++ b/src/plugin/nautilus-actions.c
@@ -278,7 +278,7 @@ static GList *
 get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files )
 {
 	static const gchar *thisfn = "nautilus_actions_get_file_items";
-	g_debug( "%s provider=%p, window=%p, files=%p, count=%d", thisfn, provider, window, files, g_list_length( files ));
+	g_debug( "%s: provider=%p, window=%p, files=%p, count=%d", thisfn, provider, window, files, g_list_length( files ));
 
 	GList *items = NULL;
 	GSList* profiles;



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