[nautilus-actions] Restore validity checks



commit a792e413bb1ae321245d1d497c6dc1f8ba8279b4
Author: Pierre Wieser <pwieser trychlos org>
Date:   Thu Feb 18 01:35:17 2010 +0100

    Restore validity checks

 ChangeLog                              |   32 +++++++
 po/POTFILES.in                         |    3 +-
 src/api/na-core-utils.h                |    3 +-
 src/api/na-idata-factory-str.h         |    3 +
 src/api/na-idata-factory.h             |   11 +++
 src/api/na-iduplicable.h               |    5 -
 src/core/na-core-utils.c               |   84 ++++++++++++------
 src/core/na-data-element.c             |  106 +++++++++++------------
 src/core/na-data-element.h             |    3 +-
 src/core/na-data-factory.c             |   49 +++++++++++
 src/core/na-data-factory.h             |    1 +
 src/core/na-idata-factory.c            |    5 +
 src/core/na-iduplicable.c              |  148 --------------------------------
 src/core/na-io-provider.c              |   26 ++++--
 src/core/na-iprefs.c                   |    2 +-
 src/core/na-object-action-enum.c       |   19 +++--
 src/core/na-object-action.c            |   73 ++++++++++++++++
 src/core/na-object-id-enum.c           |    5 +-
 src/core/na-object-item-enum.c         |   17 +++-
 src/core/na-object-menu.c              |   53 +++++++++++-
 src/core/na-object-priv.h              |   46 ----------
 src/core/na-object-profile-enum.c      |   28 ++++--
 src/core/na-object-profile.c           |  136 +++++++++++++++++++++++++++++
 src/core/na-object.c                   |   20 +++--
 src/io-desktop/nadp-desktop-provider.c |    5 +-
 src/io-gconf/nagp-reader.c             |    2 +-
 src/nact/nact-iconditions-tab.c        |    1 -
 src/nact/nact-main-statusbar.c         |    2 -
 src/nact/nact-preferences-editor.c     |    2 -
 src/test/test-parse-uris.c             |    3 +-
 src/utils/nautilus-actions-run.c       |    4 +-
 31 files changed, 558 insertions(+), 339 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 087fd9b..b427c4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,37 @@
 2009-02-17 Pierre Wieser <pwieser trychlos org>
 
+	* po/POTFILES.in:
+	* src/test/test-parse-uris.c:
+	* src/nact/nact-preferences-editor.c:
+	* src/nact/nact-main-statusbar.c:
+	* src/nact/nact-iconditions-tab.c: Update list of translatable files.
+
+	* src/api/na-core-utils.h:
+	* src/api/na-idata-factory-str.h:
+	* src/api/na-idata-factory.h:
+	* src/api/na-iduplicable.h:
+	* src/core/na-core-utils.c:
+	* src/core/na-data-element.c:
+	* src/core/na-data-element.h:
+	* src/core/na-data-factory.c:
+	* src/core/na-data-factory.h:
+	* src/core/na-idata-factory.c:
+	* src/core/na-iduplicable.c:
+	* src/core/na-io-provider.c:
+	* src/core/na-iprefs.c:
+	* src/core/na-object-action-enum.c:
+	* src/core/na-object-action.c:
+	* src/core/na-object-id-enum.c:
+	* src/core/na-object-item-enum.c:
+	* src/core/na-object-menu.c:
+	* src/core/na-object-profile-enum.c:
+	* src/core/na-object-profile.c:
+	* src/core/na-object.c:
+	* src/io-desktop/nadp-desktop-provider.c:
+	* src/io-gconf/nagp-reader.c: Add is_valid() functions.
+
+	* src/utils/nautilus-actions-run.c: Restore production loadable set.
+
 	* src/api/na-idata-factory.h:
 	* src/api/na-iio-factory.h:
 	* src/core/na-data-factory.c:
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 99b9e3d..0a8febe 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -36,7 +36,6 @@ src/nact/nact-tree-model-dnd.c
 src/nact/nact-window.c
 src/nact/nautilus-actions-config-tool.ui
 src/plugin-menu/nautilus-actions.c
-src/test/test-parse-uris.c
 src/utils/nautilus-actions-new.c
 src/utils/nautilus-actions-run.c
-src/utils/nautilus-actions-schemas.c
\ No newline at end of file
+src/utils/nautilus-actions-schemas.c
diff --git a/src/api/na-core-utils.h b/src/api/na-core-utils.h
index 8b081a7..0ba7e40 100644
--- a/src/api/na-core-utils.h
+++ b/src/api/na-core-utils.h
@@ -47,8 +47,9 @@ gboolean na_core_utils_boolean_from_string( const gchar *string );
 
 /* string manipulation
  */
-gchar   *na_core_utils_str_remove_suffix( const gchar *string, const gchar *suffix );
 gchar   *na_core_utils_str_add_prefix( const gchar *prefix, const gchar *str );
+gchar   *na_core_utils_str_get_first_word( const gchar *string );
+gchar   *na_core_utils_str_remove_suffix( const gchar *string, const gchar *suffix );
 
 /* some functions to get or set GSList list of strings
  */
diff --git a/src/api/na-idata-factory-str.h b/src/api/na-idata-factory-str.h
index 03a85ec..aba1c68 100644
--- a/src/api/na-idata-factory-str.h
+++ b/src/api/na-idata-factory-str.h
@@ -103,6 +103,9 @@ typedef struct {
 
 	gboolean comparable;				/* whether this data should be compared when we
 										 * are testing two objects for equality */
+
+	gboolean mandatory;					/* whether this data must be not null and not empty
+										 * when we are testing for validity of an object */
 }
 	NadfIdType;
 
diff --git a/src/api/na-idata-factory.h b/src/api/na-idata-factory.h
index 57fb72a..54a2bdf 100644
--- a/src/api/na-idata-factory.h
+++ b/src/api/na-idata-factory.h
@@ -115,6 +115,17 @@ typedef struct {
 	gboolean ( *are_equal )  ( const NAIDataFactory *a, const NAIDataFactory *b );
 
 	/**
+	 * is_valid:
+	 * @object: the #NAIDataFactory instance whose validity is to be checked.
+	 *
+	 * Returns: %TRUE if @object is valid.
+	 *
+	 * This function is triggered after all elementary data comparisons
+	 * have been sucessfully made.
+	 */
+	gboolean ( *is_valid )   ( const NAIDataFactory *object );
+
+	/**
 	 * read_start:
 	 * @instance: this #NAIDataFactory instance.
 	 * @reader: the instance which has provided read services.
diff --git a/src/api/na-iduplicable.h b/src/api/na-iduplicable.h
index f1f2891..f37d4b1 100644
--- a/src/api/na-iduplicable.h
+++ b/src/api/na-iduplicable.h
@@ -143,11 +143,6 @@ void           na_iduplicable_set_origin  ( NAIDuplicable *object, const NAIDupl
 
 void           na_iduplicable_register_consumer( GObject *consumer );
 
-#if 0
-void           na_iduplicable_init        ( NAIDuplicable *object );
-void           na_iduplicable_reset_status( NAIDuplicable *object );
-#endif
-
 G_END_DECLS
 
 #endif /* __NAUTILUS_ACTIONS_API_NA_IDUPLICABLE_H__ */
diff --git a/src/core/na-core-utils.c b/src/core/na-core-utils.c
index f8a5b33..68f7e19 100644
--- a/src/core/na-core-utils.c
+++ b/src/core/na-core-utils.c
@@ -58,33 +58,6 @@ na_core_utils_boolean_from_string( const gchar *string )
 }
 
 /**
- * na_core_utils_str_remove_suffix:
- * @string: source string.
- * @suffix: suffix to be removed from @string.
- *
- * Returns: a newly allocated string, which is a copy of the source @string,
- * minus the removed @suffix if present. If @strings doesn't terminate with
- * @suffix, then the returned string is equal to source @string.
- *
- * The returned string should be g_free() by the caller.
- */
-gchar *
-na_core_utils_str_remove_suffix( const gchar *string, const gchar *suffix )
-{
-	gchar *removed;
-	gchar *ptr;
-
-	removed = g_strdup( string );
-
-	if( g_str_has_suffix( string, suffix )){
-		ptr = g_strrstr( removed, suffix );
-		ptr[0] = '\0';
-	}
-
-	return( removed );
-}
-
-/**
  * na_core_utils_str_add_prefix:
  * @prefix: the prefix to be prepended.
  * @str: a multiline string.
@@ -112,6 +85,63 @@ na_core_utils_str_add_prefix( const gchar *prefix, const gchar *str )
 }
 
 /**
+ * na_core_utils_str_get_first_word:
+ * @string: a space-separated string.
+ *
+ * Returns: the first word of @string, as a newly allocated string which
+ * should be g_free() by the caller.
+ */
+gchar *
+na_core_utils_str_get_first_word( const gchar *string )
+{
+	gchar **splitted, **iter;
+	gchar *word, *tmp;
+
+	splitted = g_strsplit( string, " ", 0 );
+	iter = splitted;
+	word = NULL;
+
+	while( *iter ){
+		tmp = g_strstrip( *iter );
+		if( g_utf8_strlen( tmp, -1 )){
+			word = g_strdup( tmp );
+			break;
+		}
+		iter++;
+	}
+
+	g_strfreev( splitted );
+	return( word );
+}
+
+/**
+ * na_core_utils_str_remove_suffix:
+ * @string: source string.
+ * @suffix: suffix to be removed from @string.
+ *
+ * Returns: a newly allocated string, which is a copy of the source @string,
+ * minus the removed @suffix if present. If @strings doesn't terminate with
+ * @suffix, then the returned string is equal to source @string.
+ *
+ * The returned string should be g_free() by the caller.
+ */
+gchar *
+na_core_utils_str_remove_suffix( const gchar *string, const gchar *suffix )
+{
+	gchar *removed;
+	gchar *ptr;
+
+	removed = g_strdup( string );
+
+	if( g_str_has_suffix( string, suffix )){
+		ptr = g_strrstr( removed, suffix );
+		ptr[0] = '\0';
+	}
+
+	return( removed );
+}
+
+/**
  * na_core_utils_slist_duplicate:
  * @source_slist: the #GSList to be duplicated.
  *
diff --git a/src/core/na-data-element.c b/src/core/na-data-element.c
index 4c0a325..607e5b6 100644
--- a/src/core/na-data-element.c
+++ b/src/core/na-data-element.c
@@ -303,33 +303,6 @@ na_data_element_set( NADataElement *element, const NADataElement *value )
 	}
 }
 
-#if 0
-/**
- * na_data_element_set_from_boolean:
- * @element: the #NADataElement whose value is to be set.
- * @value: the boolean to be set.
- *
- * Set the boolean, if @element is of type NADF_TYPE_BOOLEAN.
- */
-void
-na_data_element_set_from_boolean( NADataElement *element, gboolean value )
-{
-	static const gchar *thisfn = "na_data_element_set_from_boolean";
-
-	g_return_if_fail( NA_IS_DATA_ELEMENT( element ));
-
-	if( !element->private->dispose_has_run ){
-
-		if( element->private->type == NADF_TYPE_BOOLEAN ){
-			element->private->u.boolean = value;
-
-		} else {
-			g_warning( "%s: element is of type %d", thisfn, element->private->type );
-		}
-	}
-}
-#endif
-
 /**
  * na_data_element_set_from_string:
  * @element: the #NADataElement whose value is to be set.
@@ -379,34 +352,6 @@ na_data_element_set_from_string( NADataElement *element, const gchar *value )
 	}
 }
 
-#if 0
-/**
- * na_data_element_set_from_slist:
- * @element: the #NADataElement whose value is to be set.
- * @value: the string list to be set.
- *
- * Set the string list, if @element is of type NADF_TYPE_STRING_LIST.
- */
-void
-na_data_element_set_from_slist( NADataElement *element, GSList *value )
-{
-	static const gchar *thisfn = "na_data_element_set_from_slist";
-
-	g_return_if_fail( NA_IS_DATA_ELEMENT( element ));
-
-	if( !element->private->dispose_has_run ){
-
-		if( element->private->type == NADF_TYPE_STRING_LIST ){
-			na_core_utils_slist_free( element->private->u.slist );
-			element->private->u.slist = na_core_utils_slist_duplicate( value );
-
-		} else {
-			g_warning( "%s: element is of type=%d", thisfn, element->private->type );
-		}
-	}
-}
-#endif
-
 /**
  * na_data_element_set_from_value:
  * @element: the #NADataElement whose value is to be set.
@@ -659,3 +604,54 @@ na_data_element_are_equal( const NADataElement *a, const NADataElement *b )
 
 	return( are_equal );
 }
+
+/**
+ * na_data_element_is_valid:
+ * @object: the #NADataElement object whose validity is to be checked.
+ *
+ * Returns: %TRUE if the element is valid, %FALSE else.
+ */
+gboolean
+na_data_element_is_valid( const NADataElement *object )
+{
+	static const gchar *thisfn = "na_data_element_is_valid";
+	gboolean is_valid;
+
+	g_return_val_if_fail( NA_IS_DATA_ELEMENT( object ), FALSE );
+
+	is_valid = FALSE;
+
+	if( !object->private->dispose_has_run ){
+
+		is_valid = TRUE;
+
+		switch( object->private->type ){
+
+			case NADF_TYPE_STRING:
+			case NADF_TYPE_LOCALE_STRING:
+				is_valid = object->private->u.string && strlen( object->private->u.string ) > 0;
+				break;
+
+			case NADF_TYPE_STRING_LIST:
+				is_valid = object->private->u.slist && g_slist_length( object->private->u.slist ) > 0;
+				break;
+
+			case NADF_TYPE_BOOLEAN:
+				break;
+
+			case NADF_TYPE_POINTER:
+				is_valid = ( object->private->u.pointer != NULL );
+				break;
+
+			case NADF_TYPE_UINT:
+				is_valid = ( object->private->u.uint > 0 );
+				break;
+
+			default:
+				g_warning( "%s: unmanaged type=%d", thisfn, object->private->type );
+				is_valid = FALSE;
+		}
+	}
+
+	return( is_valid );
+}
diff --git a/src/core/na-data-element.h b/src/core/na-data-element.h
index 125ae4e..dfe0ed9 100644
--- a/src/core/na-data-element.h
+++ b/src/core/na-data-element.h
@@ -74,9 +74,7 @@ NADataElement *na_data_element_new( guint type );
 void           na_data_element_dump( const NADataElement *element, const gchar *name );
 
 void           na_data_element_set             ( NADataElement *element, const NADataElement *value );
-/*void           na_data_element_set_from_boolean( NADataElement *element, gboolean value );*/
 void           na_data_element_set_from_string ( NADataElement *element, const gchar *value );
-/*void           na_data_element_set_from_slist  ( NADataElement *element, GSList *value );*/
 void           na_data_element_set_from_value  ( NADataElement *element, const GValue *value );
 void           na_data_element_set_from_void   ( NADataElement *element, const void *value );
 
@@ -84,6 +82,7 @@ void          *na_data_element_get             ( const NADataElement *element );
 void           na_data_element_set_to_value    ( const NADataElement *element, GValue *value );
 
 gboolean       na_data_element_are_equal       ( const NADataElement *a, const NADataElement *b );
+gboolean       na_data_element_is_valid        ( const NADataElement *element );
 
 G_END_DECLS
 
diff --git a/src/core/na-data-factory.c b/src/core/na-data-factory.c
index c72d553..4521edd 100644
--- a/src/core/na-data-factory.c
+++ b/src/core/na-data-factory.c
@@ -80,6 +80,7 @@ static gboolean       data_factory_init_iter( const NadfIdType *iddef, NAIDataFa
 static gchar         *v_get_default( const NAIDataFactory *object, const NadfIdType *iddef );
 static void           v_copy( NAIDataFactory *target, const NAIDataFactory *source );
 static gboolean       v_are_equal( const NAIDataFactory *a, const NAIDataFactory *b );
+static gboolean       v_is_valid( const NAIDataFactory *object );
 static void           data_factory_read_data( NAIDataFactory *serializable, const NAIIOFactory *reader, void *reader_data, NadfIdGroup *groups, GSList **messages );
 static gboolean       data_factory_read_data_iter( NadfIdType *iddef, NadfRWIter *iter );
 static void           v_read_start( NAIDataFactory *serializable, const NAIIOFactory *reader, void *reader_data, GSList **messages );
@@ -363,6 +364,54 @@ v_are_equal( const NAIDataFactory *a, const NAIDataFactory *b )
 }
 
 /**
+ * na_data_factory_is_valid:
+ * @object: the #NAIDataFactory instance whose validity is to be checked.
+ *
+ * Returns: %TRUE if @object is valid, %FALSE else.
+ */
+gboolean
+na_data_factory_is_valid( const NAIDataFactory *object )
+{
+	gboolean is_valid;
+	GList *list_values, *iv;
+	NadfDataValue *a_data;
+
+	g_return_val_if_fail( NA_IS_IDATA_FACTORY( object ), FALSE );
+
+	list_values = g_object_get_data( G_OBJECT( object ), NA_IDATA_FACTORY_PROP_DATA );
+	is_valid = TRUE;
+
+	for( iv = list_values ; iv && is_valid ; iv = iv->next ){
+
+		a_data = ( NadfDataValue * ) iv->data;
+		if( a_data->iddef->mandatory ){
+
+			is_valid = na_data_element_is_valid( a_data->element );
+		}
+	}
+
+	if( is_valid ){
+		is_valid = v_is_valid( object );
+	}
+
+	return( is_valid );
+}
+
+static gboolean
+v_is_valid( const NAIDataFactory *object )
+{
+	gboolean is_valid;
+
+	is_valid = TRUE;
+
+	if( NA_IDATA_FACTORY_GET_INTERFACE( object )->is_valid ){
+		is_valid = NA_IDATA_FACTORY_GET_INTERFACE( object )->is_valid( object );
+	}
+
+	return( is_valid );
+}
+
+/**
  * na_data_factory_dump:
  * @object: this #NAIDataFactory instance.
  *
diff --git a/src/core/na-data-factory.h b/src/core/na-data-factory.h
index 93312a2..6f4cfe6 100644
--- a/src/core/na-data-factory.h
+++ b/src/core/na-data-factory.h
@@ -47,6 +47,7 @@ NAIDataFactory *na_data_factory_new       ( GType type );
 void            na_data_factory_init      ( NAIDataFactory *object );
 void            na_data_factory_copy      ( NAIDataFactory *target, const NAIDataFactory *source );
 gboolean        na_data_factory_are_equal ( const NAIDataFactory *a, const NAIDataFactory *b );
+gboolean        na_data_factory_is_valid  ( const NAIDataFactory *object );
 void            na_data_factory_dump      ( const NAIDataFactory *object );
 void            na_data_factory_finalize  ( NAIDataFactory *object );
 
diff --git a/src/core/na-idata-factory.c b/src/core/na-idata-factory.c
index 29f4e58..79b3685 100644
--- a/src/core/na-idata-factory.c
+++ b/src/core/na-idata-factory.c
@@ -106,7 +106,12 @@ interface_base_init( NAIDataFactoryInterface *klass )
 
 		klass->get_version = idata_factory_get_version;
 		klass->get_default = NULL;
+		klass->copy = NULL;
+		klass->are_equal = NULL;
+		klass->is_valid = NULL;
+		klass->read_start = NULL;
 		klass->read_done = NULL;
+		klass->write_start = NULL;
 		klass->write_done = NULL;
 
 		idata_factory_initialized = TRUE;
diff --git a/src/core/na-iduplicable.c b/src/core/na-iduplicable.c
index e516c0b..42ce9ef 100644
--- a/src/core/na-iduplicable.c
+++ b/src/core/na-iduplicable.c
@@ -74,18 +74,6 @@ static gboolean       v_is_valid( const NAIDuplicable *object );
 
 static DuplicableStr *get_duplicable_str( const NAIDuplicable *object );
 
-#if 0
-static NAIDuplicable *v_new( const NAIDuplicable *object );
-
-static gboolean       get_modified( const NAIDuplicable *object );
-static NAIDuplicable *get_origin( const NAIDuplicable *object );
-static gboolean       get_valid( const NAIDuplicable *object );
-static gboolean       set_modified( const NAIDuplicable *object, gboolean is_modified );
-static void           set_origin( const NAIDuplicable *object, const NAIDuplicable *origin );
-static gboolean       set_valid( const NAIDuplicable *object, gboolean is_valid );
-
-#endif
-
 static void           status_changed_handler( NAIDuplicable *instance, gpointer user_data );
 static void           propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpointer user_data );
 static void           release_signal_consumers( GList *consumers );
@@ -187,42 +175,6 @@ interface_base_finalize( NAIDuplicableInterface *klass )
 	}
 }
 
-#if 0
-/**
- * na_iduplicable_init:
- * @object: the #NAIDuplicable object to be initialized.
- *
- * Initializes the properties of a IDuplicable object.
- *
- * This function should be called by the implementation when creating
- * the object, e.g. from instance_init().
- */
-void
-na_iduplicable_init( NAIDuplicable *object )
-{
-	DuplicableStr *str;
-
-	g_return_if_fail( NA_IS_IDUPLICABLE( object ));
-
-	if( st_initialized && !st_finalized ){
-
-		str = g_new0( DuplicableStr, 1 );
-
-		str->origin = NULL;
-		str->modified = FALSE;
-		str->valid = TRUE;
-
-		str->status_changed_handler_id = g_signal_connect(
-				G_OBJECT( object ),
-				NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
-				G_CALLBACK( status_changed_handler ),
-				object );
-
-		g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_DATA_DUPLICABLE, str );
-	}
-}
- #endif
-
 /**
  * na_iduplicable_dispose:
  * @object: the #NAIDuplicable object to be initialized.
@@ -529,106 +481,6 @@ na_iduplicable_register_consumer( GObject *consumer )
 	}
 }
 
-#if 0
-/**
- * na_iduplicable_reset_status:
- * @object: the #NAIDuplicable object whose status is to be reset.
- *
- * Reset validity and modification status of the object.
- */
-void
-na_iduplicable_reset_status( NAIDuplicable *object )
-{
-	g_return_if_fail( st_initialized && !st_finalized );
-	g_return_if_fail( NA_IS_IDUPLICABLE( object ));
-
-	set_valid( object, TRUE );
-	set_modified( object, FALSE );
-}
-
-static NAIDuplicable *
-v_new( const NAIDuplicable *object )
-{
-	if( NA_IDUPLICABLE_GET_INTERFACE( object )->new ){
-		return( NA_IDUPLICABLE_GET_INTERFACE( object )->new( object ));
-	}
-
-	return( NULL );
-}
-
-static gboolean
-get_modified( const NAIDuplicable *object )
-{
-	return(( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_MODIFIED )));
-}
-
-/*
- * do not use here NA_IDUPLICABLE macro as it may return a (valid) NULL
- * value
- */
-static NAIDuplicable *
-get_origin( const NAIDuplicable *object )
-{
-	/*return( NA_IDUPLICABLE( g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_ORIGIN )));*/
-	return(( NAIDuplicable * ) g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_ORIGIN ));
-}
-
-static gboolean
-get_valid( const NAIDuplicable *object )
-{
-	return(( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_VALID )));
-}
-
-/*
- * I'd wish simulate the behavior of GObject property which is able to
- * send a message each time a property is changed ; but these data are
- * not properties of NAObject
- */
-static gboolean
-set_modified( const NAIDuplicable *object, gboolean is_modified )
-{
-	gboolean was_modified;
-
-	was_modified = get_modified( object );
-
-	if( was_modified != is_modified ){
-		g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_MODIFIED, GUINT_TO_POINTER( is_modified ));
-
-#if NA_IDUPLICABLE_EDITION_STATUS_DEBUG
-		g_debug( "na_iduplicable_set_modified: object=%p (%s) modified=%s",
-				( void * ) object, G_OBJECT_TYPE_NAME( object ), is_modified ? "True":"False" );
-#endif
-	}
-
-	return( was_modified );
-}
-
-static void
-set_origin( const NAIDuplicable *object, const NAIDuplicable *origin )
-{
-	g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_ORIGIN, ( gpointer ) origin );
-}
-
-static gboolean
-set_valid( const NAIDuplicable *object, gboolean is_valid )
-{
-	gboolean was_valid;
-
-	was_valid = get_valid( object );
-
-	if( was_valid != is_valid ){
-		g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_VALID, GUINT_TO_POINTER( is_valid ));
-
-#if NA_IDUPLICABLE_EDITION_STATUS_DEBUG
-		g_debug( "na_iduplicable_set_valid: object=%p (%s) valid=%s",
-				( void * ) object, G_OBJECT_TYPE_NAME( object ), is_valid ? "True":"False" );
-#endif
-	}
-
-	return( was_valid );
-}
-#endif
-
 static void
 status_changed_handler( NAIDuplicable *instance, gpointer user_data )
 {
diff --git a/src/core/na-io-provider.c b/src/core/na-io-provider.c
index 341676a..ccbd0f2 100644
--- a/src/core/na-io-provider.c
+++ b/src/core/na-io-provider.c
@@ -41,7 +41,6 @@
 #include <api/na-gconf-utils.h>
 
 #include "na-io-provider.h"
-#include "na-updater.h"
 
 /* private class data
  */
@@ -82,7 +81,7 @@ static void   instance_finalize( GObject *object );
 static void   setup_io_providers( const NAPivot *pivot, GSList *priority );
 static GList *allocate_ordered_providers( GSList *priority );
 static GList *merge_available_io_providers( const NAPivot *pivot, GList *ordered_providers );
-static void   io_provider_set_provider( const NAPivot *pivot, NAIOProvider *provider, NAIIOProvider *instance );
+static void   io_provider_set_provider( NAIOProvider *provider, NAIIOProvider *instance, const NAPivot *pivot );
 static GList *add_io_providers_from_prefs( const NAPivot *pivot, GList *runtime_providers );
 
 static void   dump( const NAIOProvider *provider );
@@ -323,6 +322,10 @@ na_io_provider_get_providers_list( const NAPivot *pivot )
 	if( !st_io_providers ){
 
 		order = na_iprefs_read_string_list( NA_IPREFS( pivot ), IO_PROVIDER_KEY_ORDER, NULL );
+
+		g_debug( "na_io_provider_get_providers_list: dumping providers order" );
+		na_core_utils_slist_dump( order );
+
 		setup_io_providers( pivot, order );
 		na_core_utils_slist_free( order );
 	}
@@ -368,11 +371,12 @@ allocate_ordered_providers( GSList *priority )
 	providers = NULL;
 
 	for( ip = priority ; ip ; ip = ip->next ){
+
 		provider = g_object_new( NA_IO_PROVIDER_TYPE, IO_PROVIDER_PROP_ID, ( const gchar * ) ip->data, NULL );
-		providers = g_list_append( providers, provider );
+		providers = g_list_prepend( providers, provider );
 	}
 
-	return( providers );
+	return( g_list_reverse( providers ));
 }
 
 /*
@@ -396,6 +400,7 @@ merge_available_io_providers( const NAPivot *pivot, GList *ordered )
 		id = NULL;
 		if( NA_IIO_PROVIDER_GET_INTERFACE( NA_IIO_PROVIDER( im->data ))->get_id ){
 			id = NA_IIO_PROVIDER_GET_INTERFACE( NA_IIO_PROVIDER( im->data ))->get_id( NA_IIO_PROVIDER( im->data ));
+
 		} else {
 			g_warning( "%s: NAIIOProvider %p doesn't support get_id() interface", thisfn, ( void * ) im->data );
 		}
@@ -406,11 +411,16 @@ merge_available_io_providers( const NAPivot *pivot, GList *ordered )
 			provider = na_io_provider_find_provider_by_id( merged, id );
 			if( !provider ){
 
+				g_debug( "%s: no provider already allocated in ordered list for id=%s", thisfn, id );
 				provider = g_object_new( NA_IO_PROVIDER_TYPE, IO_PROVIDER_PROP_ID, id, NULL );
 				merged = g_list_append( merged, provider );
+
+			} else {
+				g_debug( "%s: found NAIOProvider=%p (NAIIOProvider=%p) for id=%s",
+						thisfn, ( void * ) provider, ( void * ) im->data, id );
 			}
 
-			io_provider_set_provider( pivot, provider, NA_IIO_PROVIDER( im->data ));
+			io_provider_set_provider( provider, NA_IIO_PROVIDER( im->data ), pivot );
 
 			g_free( id );
 		}
@@ -422,7 +432,7 @@ merge_available_io_providers( const NAPivot *pivot, GList *ordered )
 }
 
 static void
-io_provider_set_provider( const NAPivot *pivot, NAIOProvider *provider, NAIIOProvider *instance )
+io_provider_set_provider( NAIOProvider *provider, NAIIOProvider *instance, const NAPivot *pivot )
 {
 	static const gchar *thisfn = "na_io_provider_set_provider";
 
@@ -734,9 +744,7 @@ build_hierarchy( GList **tree, GSList *level_zero, gboolean list_if_empty )
 		for( ilevel = level_zero ; ilevel ; ilevel = ilevel->next ){
 			g_debug( "%s: uuid=%s", thisfn, ( gchar * ) ilevel->data );
 			it = g_list_find_custom( *tree, ilevel->data, ( GCompareFunc ) search_item );
-			g_debug( "un" );
 			if( it ){
-				g_debug( "deux" );
 				hierarchy = g_list_append( hierarchy, it->data );
 
 				g_debug( "%s: uuid=%s: %s (%p) appended to hierarchy %p",
@@ -778,10 +786,8 @@ search_item( const NAObject *obj, const gchar *uuid )
 
 	if( NA_IS_OBJECT_ITEM( obj )){
 		obj_id = na_object_get_id( obj );
-		g_debug( "objid=%s", obj_id );
 		ret = strcmp( obj_id, uuid );
 		g_free( obj_id );
-		g_debug( "ret=%d", ret );
 	}
 
 	return( ret );
diff --git a/src/core/na-iprefs.c b/src/core/na-iprefs.c
index 2599e61..4eda8b9 100644
--- a/src/core/na-iprefs.c
+++ b/src/core/na-iprefs.c
@@ -105,7 +105,7 @@ interface_base_init( NAIPrefsInterface *klass )
 {
 	static const gchar *thisfn = "na_iprefs_interface_base_init";
 
-	if( st_initialized && !st_initialized ){
+	if( !st_initialized ){
 
 		g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
 
diff --git a/src/core/na-object-action-enum.c b/src/core/na-object-action-enum.c
index f07ff95..fb79ad7 100644
--- a/src/core/na-object-action-enum.c
+++ b/src/core/na-object-action-enum.c
@@ -48,7 +48,8 @@ static NadfIdType action_iddef [] = {
 				NADF_TYPE_STRING,
 				"2.0",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_TARGET_SELECTION,
 				"na-object-target-selection",
@@ -58,7 +59,8 @@ static NadfIdType action_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"TRUE",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_TARGET_BACKGROUND,
 				"na-object-target-background",
@@ -68,7 +70,8 @@ static NadfIdType action_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"FALSE",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_TARGET_TOOLBAR,
 				"na-object-target-toolbar",
@@ -80,7 +83,8 @@ static NadfIdType action_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"FALSE",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_TOOLBAR_LABEL,
 				"na-object-toolbar-label",
@@ -91,7 +95,8 @@ static NadfIdType action_iddef [] = {
 				NADF_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_TOOLBAR_SAME_LABEL,
 				"na-object-toolbar-same-label",
@@ -101,7 +106,8 @@ static NadfIdType action_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"true",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_LAST_ALLOCATED,
 				"na-object-last-allocated",
@@ -112,6 +118,7 @@ static NadfIdType action_iddef [] = {
 				NADF_TYPE_UINT,
 				"0",
 				TRUE,
+				FALSE,
 				FALSE },
 
 	{ 0, NULL, FALSE, NULL, NULL, 0, NULL, FALSE, FALSE },
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 5a90438..107add8 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -71,9 +71,13 @@ static guint    idata_factory_get_version( const NAIDataFactory *instance );
 static gchar   *idata_factory_get_default( const NAIDataFactory *instance, const NadfIdType *iddef );
 static void     idata_factory_copy( NAIDataFactory *target, const NAIDataFactory *source );
 static gboolean idata_factory_are_equal( const NAIDataFactory *a, const NAIDataFactory *b );
+static gboolean idata_factory_is_valid( const NAIDataFactory *object );
 static void     idata_factory_read_done( NAIDataFactory *instance, const NAIIOFactory *reader, void *reader_data, GSList **messages );
 static void     idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer, void *writer_data, GSList **messages );
 
+static gboolean is_valid_label( const NAObjectAction *action );
+static gboolean is_valid_toolbar_label( const NAObjectAction *action );
+
 GType
 na_object_action_get_type( void )
 {
@@ -248,6 +252,7 @@ idata_factory_iface_init( NAIDataFactoryInterface *iface )
 	iface->get_default = idata_factory_get_default;
 	iface->copy = idata_factory_copy;
 	iface->are_equal = idata_factory_are_equal;
+	iface->is_valid = idata_factory_is_valid;
 	iface->read_start = NULL;
 	iface->read_done = idata_factory_read_done;
 	iface->write_start = NULL;
@@ -290,6 +295,48 @@ idata_factory_are_equal( const NAIDataFactory *a, const NAIDataFactory *b )
 	return( na_object_item_are_equal( NA_OBJECT_ITEM( a ), NA_OBJECT_ITEM( b )));
 }
 
+static gboolean
+idata_factory_is_valid( const NAIDataFactory *action )
+{
+	gboolean is_valid;
+	GList *profiles, *ip;
+	gint valid_profiles;
+
+	g_return_val_if_fail( NA_IS_OBJECT_ACTION( action ), FALSE );
+
+	is_valid = FALSE;
+
+	if( !NA_OBJECT_ACTION( action )->private->dispose_has_run ){
+
+		is_valid = TRUE;
+
+		if( is_valid ){
+			if( na_object_is_target_toolbar( action )){
+				is_valid = is_valid_toolbar_label( NA_OBJECT_ACTION( action ));
+			}
+		}
+
+		if( is_valid ){
+			if( na_object_is_target_selection( action ) || na_object_is_target_background( action )){
+				is_valid = is_valid_label( NA_OBJECT_ACTION( action ));
+			}
+		}
+
+		if( is_valid ){
+			valid_profiles = 0;
+			profiles = na_object_get_items( action );
+			for( ip = profiles ; ip && !valid_profiles ; ip = ip->next ){
+				if( na_object_is_valid( ip->data )){
+					valid_profiles += 1;
+				}
+			}
+			is_valid = ( valid_profiles > 0 );
+		}
+	}
+
+	return( is_valid );
+}
+
 static void
 idata_factory_read_done( NAIDataFactory *instance, const NAIIOFactory *reader, void *reader_data, GSList **messages )
 {
@@ -304,6 +351,32 @@ idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer,
 
 }
 
+static gboolean
+is_valid_label( const NAObjectAction *action )
+{
+	gboolean is_valid;
+	gchar *label;
+
+	label = na_object_get_label( action );
+	is_valid = ( label && g_utf8_strlen( label, -1 ) > 0 );
+	g_free( label );
+
+	return( is_valid );
+}
+
+static gboolean
+is_valid_toolbar_label( const NAObjectAction *action )
+{
+	gboolean is_valid;
+	gchar *label;
+
+	label = na_object_get_toolbar_label( action );
+	is_valid = ( label && g_utf8_strlen( label, -1 ) > 0 );
+	g_free( label );
+
+	return( is_valid );
+}
+
 /**
  * na_object_action_new:
  *
diff --git a/src/core/na-object-id-enum.c b/src/core/na-object-id-enum.c
index cefe991..187171f 100644
--- a/src/core/na-object-id-enum.c
+++ b/src/core/na-object-id-enum.c
@@ -47,6 +47,7 @@ NadfIdType id_iddef [] = {
 				NADF_TYPE_STRING,
 				NULL,
 				TRUE,
+				TRUE,
 				TRUE },
 
 	{ NADF_DATA_LABEL,
@@ -58,7 +59,8 @@ NadfIdType id_iddef [] = {
 				NADF_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_PARENT,
 				"na-object-parent",
@@ -68,6 +70,7 @@ NadfIdType id_iddef [] = {
 				NADF_TYPE_POINTER,
 				NULL,
 				FALSE,
+				FALSE,
 				FALSE },
 
 	{ 0, NULL, FALSE, NULL, NULL, 0, NULL, FALSE, FALSE },
diff --git a/src/core/na-object-item-enum.c b/src/core/na-object-item-enum.c
index bf59ce6..29c82dc 100644
--- a/src/core/na-object-item-enum.c
+++ b/src/core/na-object-item-enum.c
@@ -45,7 +45,8 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_ICON,
 				"na-object-icon",
@@ -56,7 +57,8 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_DESCRIPTION,
 				"na-object-description",
@@ -67,7 +69,8 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_LOCALE_STRING,
 				"",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_SUBITEMS,
 				"na-object-subitems",
@@ -77,6 +80,7 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_POINTER,
 				NULL,
 				FALSE,
+				FALSE,
 				FALSE },
 
 	{ NADF_DATA_SUBITEMS_SLIST,
@@ -88,6 +92,7 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_STRING_LIST,
 				"",
 				FALSE,
+				FALSE,
 				FALSE },
 
 	{ NADF_DATA_ENABLED,
@@ -100,7 +105,8 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"TRUE",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_READONLY,
 				"na-object-readonly",
@@ -115,6 +121,7 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"FALSE",
 				TRUE,
+				FALSE,
 				FALSE },
 
 	{ NADF_DATA_PROVIDER,
@@ -125,6 +132,7 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_POINTER,
 				NULL,
 				TRUE,
+				FALSE,
 				FALSE },
 
 	{ NADF_DATA_PROVIDER_DATA,
@@ -135,6 +143,7 @@ NadfIdType item_iddef [] = {
 				NADF_TYPE_POINTER,
 				NULL,
 				TRUE,
+				FALSE,
 				FALSE },
 
 	{ 0, NULL, FALSE, NULL, NULL, 0, NULL, FALSE, FALSE },
diff --git a/src/core/na-object-menu.c b/src/core/na-object-menu.c
index 5306795..7fb0637 100644
--- a/src/core/na-object-menu.c
+++ b/src/core/na-object-menu.c
@@ -35,7 +35,7 @@
 #include <glib/gi18n.h>
 
 #include <api/na-idata-factory.h>
-#include <api/na-object-menu.h>
+#include <api/na-object-api.h>
 
 #include "na-io-factory.h"
 #include "na-data-factory.h"
@@ -72,9 +72,12 @@ static guint    idata_factory_get_version( const NAIDataFactory *instance );
 static gchar   *idata_factory_get_default( const NAIDataFactory *instance, const NadfIdType *iddef );
 static void     idata_factory_copy( NAIDataFactory *target, const NAIDataFactory *source );
 static gboolean idata_factory_are_equal( const NAIDataFactory *a, const NAIDataFactory *b );
+static gboolean idata_factory_is_valid( const NAIDataFactory *object );
 static void     idata_factory_read_done( NAIDataFactory *instance, const NAIIOFactory *reader, void *reader_data, GSList **messages );
 static void     idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer, void *writer_data, GSList **messages );
 
+static gboolean is_valid_label( const NAObjectMenu *menu );
+
 GType
 na_object_menu_get_type( void )
 {
@@ -249,6 +252,7 @@ idata_factory_iface_init( NAIDataFactoryInterface *iface )
 	iface->get_default = idata_factory_get_default;
 	iface->copy = idata_factory_copy;
 	iface->are_equal = idata_factory_are_equal;
+	iface->is_valid = idata_factory_is_valid;
 	iface->read_start = NULL;
 	iface->read_done = idata_factory_read_done;
 	iface->write_start = NULL;
@@ -290,6 +294,40 @@ idata_factory_are_equal( const NAIDataFactory *a, const NAIDataFactory *b )
 	return( na_object_item_are_equal( NA_OBJECT_ITEM( a ), NA_OBJECT_ITEM( b )));
 }
 
+static gboolean
+idata_factory_is_valid( const NAIDataFactory *menu )
+{
+	gboolean is_valid;
+	gint valid_subitems;
+	GList *subitems, *ip;
+
+	g_return_val_if_fail( NA_IS_OBJECT_MENU( menu ), FALSE );
+
+	is_valid = FALSE;
+
+	if( !NA_OBJECT_MENU( menu )->private->dispose_has_run ){
+
+		is_valid = TRUE;
+
+		if( is_valid ){
+			is_valid = is_valid_label( NA_OBJECT_MENU( menu ));
+		}
+
+		if( is_valid ){
+			valid_subitems = 0;
+			subitems = na_object_get_items( menu );
+			for( ip = subitems ; ip && !valid_subitems ; ip = ip->next ){
+				if( na_object_is_valid( ip->data )){
+					valid_subitems += 1;
+				}
+			}
+			is_valid = ( valid_subitems > 0 );
+		}
+	}
+
+	return( is_valid );
+}
+
 static void
 idata_factory_read_done( NAIDataFactory *instance, const NAIIOFactory *reader, void *reader_data, GSList **messages )
 {
@@ -302,6 +340,19 @@ idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer,
 
 }
 
+static gboolean
+is_valid_label( const NAObjectMenu *menu )
+{
+	gboolean is_valid;
+	gchar *label;
+
+	label = na_object_get_label( menu );
+	is_valid = ( label && g_utf8_strlen( label, -1 ) > 0 );
+	g_free( label );
+
+	return( is_valid );
+}
+
 /**
  * na_object_menu_new:
  *
diff --git a/src/core/na-object-profile-enum.c b/src/core/na-object-profile-enum.c
index d905500..18f1405 100644
--- a/src/core/na-object-profile-enum.c
+++ b/src/core/na-object-profile-enum.c
@@ -47,6 +47,7 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_STRING,
 				"",
 				TRUE,
+				TRUE,
 				TRUE },
 
 	{ NADF_DATA_PARAMETERS,
@@ -57,7 +58,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_STRING,
 				"",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_BASENAMES,
 				"na-object-basenames",
@@ -68,7 +70,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_STRING_LIST,
 				"*",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_MATCHCASE,
 				"na-object-matchcase",
@@ -79,7 +82,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"TRUE",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_MIMETYPES,
 				"na-object-mimetypes",
@@ -90,7 +94,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_STRING_LIST,
 				"*",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_ISFILE,
 				"na-object-isfile",
@@ -101,7 +106,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"TRUE",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_ISDIR,
 				"na-object-isdir",
@@ -112,7 +118,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"FALSE",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_MULTIPLE,
 				"na-object-multiple",
@@ -123,7 +130,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_BOOLEAN,
 				"FALSE",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_SCHEMES,
 				"na-object-schemes",
@@ -134,7 +142,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_STRING_LIST,
 				"file",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ NADF_DATA_FOLDERS,
 				"na-object-folders",
@@ -145,7 +154,8 @@ static NadfIdType profile_iddef [] = {
 				NADF_TYPE_STRING_LIST,
 				"/",
 				TRUE,
-				TRUE },
+				TRUE,
+				FALSE },
 
 	{ 0, NULL, FALSE, NULL, NULL, 0, NULL, FALSE, FALSE },
 };
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 75ddcd9..90df5d6 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -79,8 +79,15 @@ static void     instance_finalize( GObject *object );
 static void     idata_factory_iface_init( NAIDataFactoryInterface *iface );
 static guint    idata_factory_get_version( const NAIDataFactory *instance );
 static gchar   *idata_factory_get_default( const NAIDataFactory *instance, const NadfIdType *iddef );
+static gboolean idata_factory_is_valid( const NAIDataFactory *object );
 static void     idata_factory_read_done( NAIDataFactory *instance, const NAIIOFactory *reader, void *reader_data, GSList **messages );
 static void     idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer, void *writer_data, GSList **messages );
+static gboolean is_valid_path_parameters( const NAObjectProfile *profile );
+static gboolean is_valid_basenames( const NAObjectProfile *profile );
+static gboolean is_valid_mimetypes( const NAObjectProfile *profile );
+static gboolean is_valid_isfiledir( const NAObjectProfile *profile );
+static gboolean is_valid_schemes( const NAObjectProfile *profile );
+static gboolean is_valid_folders( const NAObjectProfile *profile );
 
 static gchar   *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
 
@@ -277,6 +284,7 @@ idata_factory_iface_init( NAIDataFactoryInterface *iface )
 	iface->get_default = idata_factory_get_default;
 	iface->copy = NULL;
 	iface->are_equal = NULL;
+	iface->is_valid = idata_factory_is_valid;
 	iface->read_start = NULL;
 	iface->read_done = idata_factory_read_done;
 	iface->write_start = NULL;
@@ -310,6 +318,42 @@ idata_factory_get_default( const NAIDataFactory *instance, const NadfIdType *idd
 	return( value );
 }
 
+static gboolean
+idata_factory_is_valid( const NAIDataFactory *profile )
+{
+	gboolean is_valid;
+	NAObjectItem *parent;
+
+	g_return_val_if_fail( NA_IS_OBJECT_PROFILE( profile ), FALSE );
+
+	is_valid = FALSE;
+
+	if( !NA_OBJECT_PROFILE( profile )->private->dispose_has_run ){
+
+		is_valid = TRUE;
+		parent = na_object_get_parent( profile );
+
+		if( is_valid && na_object_is_target_background( parent )){
+			is_valid =
+					is_valid_path_parameters( NA_OBJECT_PROFILE( profile )) &&
+					is_valid_folders( NA_OBJECT_PROFILE( profile ));
+		}
+
+		if( is_valid ){
+			if( na_object_is_target_selection( parent ) || na_object_is_target_toolbar( parent )){
+				is_valid =
+					is_valid_path_parameters( NA_OBJECT_PROFILE( profile )) &&
+					is_valid_basenames( NA_OBJECT_PROFILE( profile )) &&
+					is_valid_mimetypes( NA_OBJECT_PROFILE( profile )) &&
+					is_valid_isfiledir( NA_OBJECT_PROFILE( profile )) &&
+					is_valid_schemes( NA_OBJECT_PROFILE( profile ));
+			}
+		}
+	}
+
+	return( is_valid );
+}
+
 static void
 idata_factory_read_done( NAIDataFactory *instance, const NAIIOFactory *reader, void *reader_data, GSList **messages )
 {
@@ -322,6 +366,98 @@ idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer,
 
 }
 
+static gboolean
+is_valid_path_parameters( const NAObjectProfile *profile )
+{
+	gboolean valid;
+	gchar *path, *parameters;
+	gchar *command, *exe;
+
+	path = na_object_get_path( profile );
+	parameters = na_object_get_parameters( profile );
+
+	command = g_strdup_printf( "%s %s", path, parameters );
+	exe = na_core_utils_str_get_first_word( command );
+
+	valid =
+		g_file_test( exe, G_FILE_TEST_EXISTS ) &&
+		g_file_test( exe, G_FILE_TEST_IS_EXECUTABLE ) &&
+		!g_file_test( exe, G_FILE_TEST_IS_DIR );
+
+	g_free( exe );
+	g_free( command );
+	g_free( parameters );
+	g_free( path );
+
+	return( valid );
+}
+
+static gboolean
+is_valid_basenames( const NAObjectProfile *profile )
+{
+	gboolean valid;
+	GSList *basenames;
+
+	basenames = na_object_get_basenames( profile );
+	valid = basenames && g_slist_length( basenames ) > 0;
+	na_core_utils_slist_free( basenames );
+
+	return( valid );
+}
+
+static gboolean
+is_valid_mimetypes( const NAObjectProfile *profile )
+{
+	gboolean valid;
+	GSList *mimetypes;
+
+	mimetypes = na_object_get_mimetypes( profile );
+	valid = mimetypes && g_slist_length( mimetypes ) > 0;
+	na_core_utils_slist_free( mimetypes );
+
+	return( valid );
+}
+
+static gboolean
+is_valid_isfiledir( const NAObjectProfile *profile )
+{
+	gboolean valid;
+	gboolean isfile, isdir;
+
+	isfile = na_object_is_file( profile );
+	isdir = na_object_is_dir( profile );
+
+	valid = isfile || isdir;
+
+	return( valid );
+}
+
+static gboolean
+is_valid_schemes( const NAObjectProfile *profile )
+{
+	gboolean valid;
+	GSList *schemes;
+
+	schemes = na_object_get_schemes( profile );
+	valid = schemes && g_slist_length( schemes ) > 0;
+	na_core_utils_slist_free( schemes );
+
+	return( valid );
+}
+
+static gboolean
+is_valid_folders( const NAObjectProfile *profile )
+{
+	gboolean valid;
+	GSList *folders;
+
+	folders = na_object_get_folders( profile );
+	valid = folders && g_slist_length( folders ) > 0;
+	na_core_utils_slist_free( folders );
+
+	return( valid );
+}
+
 /*
  * new_parent is specifically set to be able to allocate a new id for
  * the current profile into the target parent
diff --git a/src/core/na-object.c b/src/core/na-object.c
index 8704141..25390f5 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -295,18 +295,23 @@ iduplicable_are_equal_iter( GObjectClass *class, const NAObject *a, HierarchyIte
 static gboolean
 iduplicable_is_valid( const NAIDuplicable *object )
 {
-	gboolean is_valid = FALSE;
+	gboolean is_valid;
 	HierarchyIter *str;
 
-	if( !NA_OBJECT( object )->private->dispose_has_run ){
-
-		str = g_new0( HierarchyIter, 1 );
+	is_valid = FALSE;
 
-		iter_on_class_hierarchy( NA_OBJECT( object ), ( HierarchyIterFunc ) &iduplicable_is_valid_iter, str );
+	if( !NA_OBJECT( object )->private->dispose_has_run ){
 
-		is_valid = str->result;
+		if( NA_IS_IDATA_FACTORY( object )){
+			na_data_factory_is_valid( NA_IDATA_FACTORY( object ));
 
-		g_free( str );
+		} else {
+			str = g_new0( HierarchyIter, 1 );
+			str->result = TRUE;
+			iter_on_class_hierarchy( NA_OBJECT( object ), ( HierarchyIterFunc ) &iduplicable_is_valid_iter, str );
+			is_valid = str->result;
+			g_free( str );
+		}
 	}
 
 	return( is_valid );
@@ -318,6 +323,7 @@ iduplicable_is_valid_iter( GObjectClass *class, const NAObject *a, HierarchyIter
 	gboolean stop = FALSE;
 
 	if( NA_OBJECT_CLASS( class )->is_valid ){
+
 		str->result = NA_OBJECT_CLASS( class )->is_valid( a );
 		stop = !str->result;
 	}
diff --git a/src/io-desktop/nadp-desktop-provider.c b/src/io-desktop/nadp-desktop-provider.c
index 9f3a173..40cb1f9 100644
--- a/src/io-desktop/nadp-desktop-provider.c
+++ b/src/io-desktop/nadp-desktop-provider.c
@@ -247,7 +247,6 @@ static void
 iio_factory_read_start( const NAIIOFactory *reader, void *reader_data, NAIDataFactory *serializable, GSList **messages )
 {
 	static const gchar *thisfn = "nadp_desktop_provider_iio_factory_read_start";
-	/*NAObjectProfile *profile;*/
 
 	g_debug( "%s: reader=%p (%s), reader_data=%p, serializable=%p (%s), messages=%p",
 			thisfn,
@@ -312,14 +311,14 @@ iio_factory_read_value( const NAIIOFactory *reader, void *reader_data, const Nad
 					g_value_init( value, G_TYPE_STRING );
 					str_value = nadp_desktop_file_get_locale_string( nrd->ndf, group, key, iddef->default_value );
 					g_value_set_string( value, str_value );
-					g_free( str_value );
+					/*g_free( str_value );*/
 					break;
 
 				case NADF_TYPE_STRING:
 					g_value_init( value, G_TYPE_STRING );
 					str_value = nadp_desktop_file_get_string( nrd->ndf, group, key, iddef->default_value );
 					g_value_set_string( value, str_value );
-					g_free( str_value );
+					/*g_free( str_value );*/
 					break;
 
 				case NADF_TYPE_BOOLEAN:
diff --git a/src/io-gconf/nagp-reader.c b/src/io-gconf/nagp-reader.c
index 73477b1..902338c 100644
--- a/src/io-gconf/nagp-reader.c
+++ b/src/io-gconf/nagp-reader.c
@@ -189,7 +189,7 @@ read_item_action( NagpGConfProvider *provider, const gchar *path, NAObjectAction
 		for( ip = order ; ip ; ip = ip->next ){
 			profile_path = gconf_concat_dir_and_key( path, ( gchar * ) ip->data );
 			read_item_action_profile( provider, action, profile_path );
-			list_profiles = na_core_utils_slist_remove_utf8( list_profiles, profile_path );
+			list_profiles = na_core_utils_slist_remove_ascii( list_profiles, profile_path );
 			g_free( profile_path );
 		}
 
diff --git a/src/nact/nact-iconditions-tab.c b/src/nact/nact-iconditions-tab.c
index 4ee0d84..c8c0936 100644
--- a/src/nact/nact-iconditions-tab.c
+++ b/src/nact/nact-iconditions-tab.c
@@ -32,7 +32,6 @@
 #include <config.h>
 #endif
 
-#include <glib/gi18n.h>
 #include <string.h>
 
 #include <api/na-core-utils.h>
diff --git a/src/nact/nact-main-statusbar.c b/src/nact/nact-main-statusbar.c
index 8e5af08..87e40b2 100644
--- a/src/nact/nact-main-statusbar.c
+++ b/src/nact/nact-main-statusbar.c
@@ -32,8 +32,6 @@
 #include <config.h>
 #endif
 
-#include <glib/gi18n.h>
-
 #include <core/na-io-provider.h>
 
 #include "nact-gtk-utils.h"
diff --git a/src/nact/nact-preferences-editor.c b/src/nact/nact-preferences-editor.c
index 281bb0b..7df5939 100644
--- a/src/nact/nact-preferences-editor.c
+++ b/src/nact/nact-preferences-editor.c
@@ -32,8 +32,6 @@
 #include <config.h>
 #endif
 
-#include <glib/gi18n.h>
-
 #include "nact-application.h"
 #include "nact-iprefs.h"
 #include "nact-export-format.h"
diff --git a/src/test/test-parse-uris.c b/src/test/test-parse-uris.c
index fe6bcea..6d32f0d 100644
--- a/src/test/test-parse-uris.c
+++ b/src/test/test-parse-uris.c
@@ -34,7 +34,6 @@
 
 #include <glib-object.h>
 #include <glib/gprintf.h>
-#include <glib/gi18n.h>
 #include <stdlib.h>
 
 #include <core/na-gnome-vfs-uri.h>
@@ -54,7 +53,7 @@ main( int argc, char** argv )
 	int i;
 
 	g_type_init();
-	g_printf( _( "URIs parsing test.\n\n" ));
+	g_printf( "URIs parsing test.\n\n" );
 
 	for( i = 0 ; uris[i] ; ++i ){
 		NAGnomeVFSURI *vfs = g_new0( NAGnomeVFSURI, 1 );
diff --git a/src/utils/nautilus-actions-run.c b/src/utils/nautilus-actions-run.c
index 33c75b5..1731021 100644
--- a/src/utils/nautilus-actions-run.c
+++ b/src/utils/nautilus-actions-run.c
@@ -213,9 +213,7 @@ get_action( const gchar *id )
 
 	action = NULL;
 
-	/*pivot = na_pivot_new( !PIVOT_LOAD_DISABLED & !PIVOT_LOAD_INVALID );*/
-	pivot = na_pivot_new( PIVOT_LOAD_ALL );
-
+	pivot = na_pivot_new( !PIVOT_LOAD_DISABLED & !PIVOT_LOAD_INVALID );
 	na_pivot_load_items( pivot );
 
 	action = ( NAObjectAction * ) na_pivot_get_item( pivot, id );



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