[nautilus-actions: 2/3] Various fixes



commit 34be635a64aaff8212be96395b1e6e873ab9c665
Author: Pierre Wieser <pwieser trychlos org>
Date:   Sun Feb 28 21:50:21 2010 +0100

    Various fixes
    
    Review all the copy machinery, introducing a 'recursive' flag for actions.
    Fix the update of the NAPivot tree when removing an item.
    Fix the writing of the data to I/O Gconf provider.

 ChangeLog                          |   60 +++++++++++++++++++++
 TODO                               |    2 +
 src/api/na-ifactory-object.h       |    7 +--
 src/api/na-object-api.h            |    1 +
 src/api/na-object-item.h           |    1 -
 src/api/na-object.h                |    5 ++-
 src/core/na-factory-object.c       |   22 ++++++--
 src/core/na-iduplicable.c          |   16 ++++--
 src/core/na-object-action.c        |   56 +++++++-------------
 src/core/na-object-item-factory.c  |    6 +-
 src/core/na-object-item.c          |  102 +++++++++++++++++++++---------------
 src/core/na-object-menu.c          |   52 ++++++------------
 src/core/na-object-profile.c       |   44 ++++++---------
 src/core/na-object.c               |   92 ++++++++++++++++++++++----------
 src/core/na-pivot.c                |    1 +
 src/core/na-updater.c              |   12 ++--
 src/io-gconf/nagp-gconf-provider.c |    2 +-
 src/io-gconf/nagp-reader.c         |    4 +-
 src/io-gconf/nagp-writer.c         |   38 +++++++++++++
 src/io-gconf/nagp-writer.h         |    8 ++-
 src/nact/nact-iaction-tab.c        |   25 +--------
 src/nact/nact-iactions-list-bis.c  |    4 +-
 src/nact/nact-iactions-list.h      |    2 +-
 src/nact/nact-icommand-tab.c       |    9 ---
 src/nact/nact-iconditions-tab.c    |    6 --
 src/nact/nact-main-menubar.c       |   13 ++---
 src/nact/nact-window.c             |    3 -
 27 files changed, 342 insertions(+), 251 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 136e09c..da1dfe4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,63 @@
+2009-02-28 Pierre Wieser <pwieser trychlos org>
+
+	* src/api/na-ifactory-object.h:
+	* src/core/na-object-item-factory.c:
+	* src/nact/nact-iactions-list-bis.c:
+	* src/nact/nact-iactions-list.h:
+	Fix minor typo.
+
+	* src/api/na-object-api.h:
+	New na_object_copy macro (evaluates as na_object_object_copy).
+
+	* src/api/na-object-item.h (na_object_item_copy): Removed function.
+
+	* src/api/na-object.h:
+	* src/core/na-object.c:.
+	(copy): Add 'recursive' flag.
+	(iduplicable_copy): Use na_object_copy() macro.
+	(na_object_object_copy): New function.
+
+	* src/core/na-factory-object.c (na_factory_object_copy):
+	No more delete all NADataBoxed, but update those who already exist.
+	(write_data_iter): Fix return code.
+
+	* src/core/na-iduplicable.c (na_iduplicable_duplicate):
+	Review the rationale, and ensure that the function is recursive.
+
+	* src/core/na-object-action.c
+	* src/core/na-object-item.c:
+	* src/core/na-object-menu.c:
+	* src/core/na-object-profile.c:
+	(instance_constructed): Removed function.
+	(ifactory_object_copy): Removed function.
+	(object_copy): New function, implementation of NAObject::copy.
+
+	* src/core/na-pivot.c (instance_dispose): Add debug message.
+
+	* src/core/na-updater.c (na_updater_remove_item):
+	Only update tree if object has no parent.
+
+	* src/io-gconf/nagp-gconf-provider.c
+	(ifactory_provider_iface_init): Address nagp_writer_write_start().
+
+	* src/io-gconf/nagp-reader.c (nagp_reader_read_data): Comment debug message.
+
+	* src/io-gconf/nagp-writer.c:
+	* src/io-gconf/nagp-writer.h (nagp_writer_write_start): New function.
+	Write the type of the NAObjectItem.
+
+	* src/nact/nact-iaction-tab.c (on_tab_updatable_selection_changed):
+	* src/nact/nact-icommand-tab.c (on_tab_updatable_selection_changed):
+	* src/nact/nact-iconditions-tab.c (on_tab_updatable_selection_changed):
+	As objects have defaults, no more test for null string.
+
+	* src/nact/nact-main-menubar.c
+	(nact_main_menubar_save_items): Dump after check status.
+	(save_item): Use new na_object_copy() macro.
+
+	* src/nact/nact-window.c (nact_window_save_item):
+	Remove superfluous dumps.
+
 2009-02-27 Pierre Wieser <pwieser trychlos org>
 
 	* src/core/na-iduplicable.c (na_iduplicable_check_status):
diff --git a/TODO b/TODO
index 598e3a2..6395fbd 100644
--- a/TODO
+++ b/TODO
@@ -165,3 +165,5 @@
 - segfaults on reload
 
 - check adding/removing profile on desktop/gconf/xml import/export
+
+- shouldn't be able to copy an action into an action !
diff --git a/src/api/na-ifactory-object.h b/src/api/na-ifactory-object.h
index bcbd250..0527400 100644
--- a/src/api/na-ifactory-object.h
+++ b/src/api/na-ifactory-object.h
@@ -89,10 +89,9 @@ typedef struct {
 	 * @instance: the target #NAIFactoryObject instance.
 	 * @source: the source #NAIFactoryObject instance.
 	 *
-	 * This function is triggered when copying one instance to another,
-	 * after all copyable elementary dats have been copied themselves.
-	 * The target @instance may take advantage of this call to do some
-	 * particular copy tasks.
+	 * This function is triggered after having copied @source to
+	 * @instance target. This later may take advantage of this call
+	 * to do some particular copy tasks.
 	 */
 	void          ( *copy )       ( NAIFactoryObject *instance, const NAIFactoryObject *source );
 
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index 135c589..a75df71 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -66,6 +66,7 @@ G_BEGIN_DECLS
 
 /* NAObject
  */
+#define na_object_copy( tgt, src, rec )					na_object_object_copy( NA_OBJECT( tgt ), NA_OBJECT( src ), ( rec ))
 #define na_object_dump( obj )							na_object_object_dump( NA_OBJECT( obj ))
 #define na_object_dump_norec( obj )						na_object_object_dump_norec( NA_OBJECT( obj ))
 #define na_object_dump_tree( tree )						na_object_object_dump_tree( tree )
diff --git a/src/api/na-object-item.h b/src/api/na-object-item.h
index 99ab3fa..9f73191 100644
--- a/src/api/na-object-item.h
+++ b/src/api/na-object-item.h
@@ -77,7 +77,6 @@ enum {
 
 GType       na_object_item_get_type( void );
 
-void        na_object_item_copy     ( NAObjectItem *item, const NAObjectItem *source );
 gboolean    na_object_item_are_equal( const NAObjectItem *a, const NAObjectItem *b );
 
 NAObjectId *na_object_item_get_item    ( const NAObjectItem *item, const gchar *id );
diff --git a/src/api/na-object.h b/src/api/na-object.h
index 95b7d6c..36cfd5c 100644
--- a/src/api/na-object.h
+++ b/src/api/na-object.h
@@ -81,6 +81,7 @@ typedef struct {
 	 * copy:
 	 * @target: the #NAObject-derived object which will receive data.
 	 * @source: the #NAObject-derived object which will provide data.
+	 * @recursive: whether children should be recursively copied.
 	 *
 	 * Copies data and properties from @source to @target.
 	 *
@@ -90,7 +91,7 @@ typedef struct {
 	 * base class up to the most-derived one. Each class has so only to
 	 * take care of dumping its own data.
 	 */
-	void     ( *copy )     ( NAObject *target, const NAObject *source );
+	void     ( *copy )     ( NAObject *target, const NAObject *source, gboolean recursive );
 
 	/**
 	 * are_equal:
@@ -143,6 +144,8 @@ void      na_object_object_reset_origin   ( NAObject *object, const NAObject *or
 NAObject *na_object_object_ref  ( NAObject *object );
 void      na_object_object_unref( NAObject *object );
 
+void      na_object_object_copy      ( NAObject *target, const NAObject *source, gboolean recursive );
+
 void      na_object_object_dump      ( const NAObject *object );
 void      na_object_object_dump_norec( const NAObject *object );
 void      na_object_object_dump_tree ( GList *tree );
diff --git a/src/core/na-factory-object.c b/src/core/na-factory-object.c
index 0dafe06..6b71572 100644
--- a/src/core/na-factory-object.c
+++ b/src/core/na-factory-object.c
@@ -265,6 +265,8 @@ na_factory_object_set_defaults( NAIFactoryObject *object )
 
 	if( ifactory_object_initialized && !ifactory_object_finalized ){
 
+		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
 		groups = v_get_groups( object );
 		if( !groups ){
 			g_warning( "%s: no NADataGroup found for %s", thisfn, G_OBJECT_TYPE_NAME( object ));
@@ -349,9 +351,16 @@ na_factory_object_move_boxed( NAIFactoryObject *target, const NAIFactoryObject *
 void
 na_factory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source )
 {
+	static const gchar *thisfn = "na_factory_object_copy";
 	GList *src_list, *isrc;
 
-	free_data_boxed_list( target );
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( target ));
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( source ));
+
+	g_debug( "%s: target=%p (%s), source=%p (%s)",
+			thisfn,
+			( void * ) target, G_OBJECT_TYPE_NAME( target ),
+			( void * ) source, G_OBJECT_TYPE_NAME( source ));
 
 	src_list = g_object_get_data( G_OBJECT( source ), NA_IFACTORY_OBJECT_PROP_DATA );
 
@@ -359,11 +368,14 @@ na_factory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source
 
 		NADataBoxed *src_boxed = NA_DATA_BOXED( isrc->data );
 		NADataDef *def = na_data_boxed_get_data_def( src_boxed );
-		if( def->copyable ){
 
-			NADataBoxed *tgt_boxed = na_data_boxed_new( def );
+		if( def->copyable ){
+			NADataBoxed *tgt_boxed = data_boxed_from_name( target, def->name );
+			if( !tgt_boxed ){
+				tgt_boxed = na_data_boxed_new( def );
+				attach_boxed_to_object( target, tgt_boxed );
+			}
 			na_data_boxed_set_from_boxed( tgt_boxed, src_boxed );
-			attach_boxed_to_object( target, tgt_boxed );
 		}
 	}
 
@@ -681,7 +693,7 @@ write_data_iter( const NAIFactoryObject *object, NADataBoxed *boxed, NafoWriteIt
 	}
 
 	/* iter while code is ok */
-	return( iter->code == NA_IIO_PROVIDER_CODE_OK );
+	return( iter->code != NA_IIO_PROVIDER_CODE_OK );
 }
 
 /**
diff --git a/src/core/na-iduplicable.c b/src/core/na-iduplicable.c
index c8a0b5a..f186c00 100644
--- a/src/core/na-iduplicable.c
+++ b/src/core/na-iduplicable.c
@@ -234,13 +234,17 @@ na_iduplicable_dump( const NAIDuplicable *object )
  * na_iduplicable_duplicate:
  * @object: the #NAIDuplicable object to be duplicated.
  *
- * Exactly duplicates a #NAIDuplicable-implemented object.
- * Properties %NA_IDUPLICABLE_PROP_ORIGIN, %PROP_IDUPLICABLE_ISMODIFIED
- * and %PROP_IDUPLICABLE_ISVALID are initialized to their default
- * values.
+ * Exactly duplicates a #NAIDuplicable-implemented object, including
+ * modification and validity status which are copied from @object to
+ * the duplicated one.
  *
- * As %PROP_IDUPLICABLE_ISVALID property is set to %TRUE without any
- * further check, this suppose that only valid objects are duplicated.
+ * Though this function is not recursive by itself, it is widely supposed
+ * everywhere in the program that recursivity is provided but #NAObject
+ * implementation.
+ *
+ * +------------------------------------------------------------------------------+
+ * | na_object_duplicate (aka na_iduplicable_duplicate) is definitively recursive |
+ * +------------------------------------------------------------------------------+
  *
  * Returns: a new #NAIDuplicable.
  */
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 04d2b27..3ff3b20 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -71,18 +71,17 @@ static NAObjectItemClass *st_parent_class = NULL;
 static GType        register_type( void );
 static void         class_init( NAObjectActionClass *klass );
 static void         instance_init( GTypeInstance *instance, gpointer klass );
-static void         instance_constructed( GObject *object );
 static void         instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
 static void         instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
 static void         instance_dispose( GObject *object );
 static void         instance_finalize( GObject *object );
 
+static void         object_copy( NAObject *target, const NAObject *source, gboolean recursive );
 static gboolean     object_is_valid( const NAObject *object );
 
 static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
 static guint        ifactory_object_get_version( const NAIFactoryObject *instance );
 static NADataGroup *ifactory_object_get_groups( const NAIFactoryObject *instance );
-static void         ifactory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source );
 static gboolean     ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
 static gboolean     ifactory_object_is_valid( const NAIFactoryObject *object );
 static void         ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
@@ -138,10 +137,6 @@ register_type( void )
 
 	g_type_add_interface_static( type, NA_IFACTORY_OBJECT_TYPE, &ifactory_object_iface_info );
 
-#if 0
-	na_factory_object_register_type( type, action_id_groups );
-#endif
-
 	return( type );
 }
 
@@ -157,7 +152,6 @@ class_init( NAObjectActionClass *klass )
 	st_parent_class = g_type_class_peek_parent( klass );
 
 	object_class = G_OBJECT_CLASS( klass );
-	object_class->constructed = instance_constructed;
 	object_class->set_property = instance_set_property;
 	object_class->get_property = instance_get_property;
 	object_class->dispose = instance_dispose;
@@ -165,7 +159,7 @@ class_init( NAObjectActionClass *klass )
 
 	naobject_class = NA_OBJECT_CLASS( klass );
 	naobject_class->dump = NULL;
-	naobject_class->copy = NULL;
+	naobject_class->copy = object_copy;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = object_is_valid;
 
@@ -191,27 +185,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 }
 
 static void
-instance_constructed( GObject *object )
-{
-	static const gchar *thisfn = "na_object_action_instance_constructed";
-	NAObjectAction *self;
-
-	g_debug( "%s: object=%p", thisfn, ( void * ) object );
-	g_return_if_fail( NA_IS_OBJECT_ACTION( object ));
-	self = NA_OBJECT_ACTION( object );
-
-	if( !self->private->dispose_has_run ){
-
-		na_factory_object_set_defaults( NA_IFACTORY_OBJECT( object ));
-
-		/* chain up to the parent class */
-		if( G_OBJECT_CLASS( st_parent_class )->constructed ){
-			G_OBJECT_CLASS( st_parent_class )->constructed( object );
-		}
-	}
-}
-
-static void
 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
 {
 	g_return_if_fail( NA_IS_OBJECT_ACTION( object ));
@@ -278,6 +251,19 @@ instance_finalize( GObject *object )
 	}
 }
 
+static void
+object_copy( NAObject *target, const NAObject *source, gboolean recursive )
+{
+	g_return_if_fail( NA_IS_OBJECT_ACTION( target ));
+	g_return_if_fail( NA_IS_OBJECT_ACTION( source ));
+
+	if( !NA_OBJECT_ACTION( target )->private->dispose_has_run &&
+		!NA_OBJECT_ACTION( source )->private->dispose_has_run ){
+
+		na_factory_object_copy( NA_IFACTORY_OBJECT( target ), NA_IFACTORY_OBJECT( source ));
+	}
+}
+
 static gboolean
 object_is_valid( const NAObject *object )
 {
@@ -295,7 +281,7 @@ ifactory_object_iface_init( NAIFactoryObjectInterface *iface )
 
 	iface->get_version = ifactory_object_get_version;
 	iface->get_groups = ifactory_object_get_groups;
-	iface->copy = ifactory_object_copy;
+	iface->copy = NULL;
 	iface->are_equal = ifactory_object_are_equal;
 	iface->is_valid = ifactory_object_is_valid;
 	iface->read_start = NULL;
@@ -316,12 +302,6 @@ ifactory_object_get_groups( const NAIFactoryObject *instance )
 	return( action_data_groups );
 }
 
-static void
-ifactory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source )
-{
-	na_object_item_copy( NA_OBJECT_ITEM( target ), NA_OBJECT_ITEM( source ));
-}
-
 static gboolean
 ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b )
 {
@@ -365,6 +345,8 @@ ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider
 	} else {
 		g_object_unref( parms.profile );
 	}
+
+	na_factory_object_set_defaults( instance );
 }
 
 static guint
@@ -511,7 +493,6 @@ na_object_action_new_with_profile( void )
 	NAObjectProfile *profile;
 
 	action = na_object_action_new();
-
 	profile = na_object_profile_new();
 	na_object_action_attach_profile( action, profile );
 
@@ -536,6 +517,7 @@ na_object_action_new_with_defaults( void )
 	na_object_set_new_id( action, NULL );
 	na_object_set_label( action, NEW_NAUTILUS_ACTION );
 	na_object_set_toolbar_label( action, NEW_NAUTILUS_ACTION );
+	na_factory_object_set_defaults( NA_IFACTORY_OBJECT( action ));
 
 	profile = na_object_profile_new_with_defaults();
 	na_object_action_attach_profile( action, profile );
diff --git a/src/core/na-object-item-factory.c b/src/core/na-object-item-factory.c
index aac705b..0f7deb3 100644
--- a/src/core/na-object-item-factory.c
+++ b/src/core/na-object-item-factory.c
@@ -100,9 +100,9 @@ NADataDef data_def_item [] = {
 				NAFD_TYPE_POINTER,
 				NULL,
 				FALSE,			/* not copyable */
-				FALSE,			/*     comparable */
-				FALSE,
-				FALSE,
+				FALSE,			/* not comparable */
+				FALSE,			/* not mandatory */
+				FALSE,			/* not localized */
 				NULL,
 				FALSE },
 
diff --git a/src/core/na-object-item.c b/src/core/na-object-item.c
index d76db0c..9738d60 100644
--- a/src/core/na-object-item.c
+++ b/src/core/na-object-item.c
@@ -67,8 +67,11 @@ static void   instance_init( GTypeInstance *instance, gpointer klass );
 static void   instance_dispose( GObject *object );
 static void   instance_finalize( GObject *object );
 
+static void   object_copy( NAObject*target, const NAObject *source, gboolean recursive );
+
 static gchar *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
 
+static void   copy_children( NAObjectItem *target, const NAObjectItem *source );
 static void   rebuild_children_slist( NAObjectItem *item );
 
 GType
@@ -126,7 +129,7 @@ class_init( NAObjectItemClass *klass )
 
 	naobject_class = NA_OBJECT_CLASS( klass );
 	naobject_class->dump = NULL;
-	naobject_class->copy = NULL;
+	naobject_class->copy = object_copy;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = NULL;
 
@@ -197,6 +200,21 @@ instance_finalize( GObject *object )
 	}
 }
 
+static void
+object_copy( NAObject *target, const NAObject *source, gboolean recursive )
+{
+	g_return_if_fail( NA_IS_OBJECT_ITEM( target ));
+	g_return_if_fail( NA_IS_OBJECT_ITEM( source ));
+
+	if( !NA_OBJECT_ITEM( target )->private->dispose_has_run &&
+		!NA_OBJECT_ITEM( source )->private->dispose_has_run ){
+
+		if( recursive ){
+			copy_children( NA_OBJECT_ITEM( target ), NA_OBJECT_ITEM( source ));
+		}
+	}
+}
+
 /*
  * new_parent is not relevant when allocating a new UUID for an action
  * or a menu ; it may safely be left as NULL though there is no gain to
@@ -231,47 +249,6 @@ object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent )
 }
 
 /**
- * na_object_item_copy:
- * @item: the target #NAObjectItem instance.
- * @source: the source #NAObjectItem instance.
- * @recursive: whether the children should be recursively copied.
- *
- * Copies data from @source to @item.
- *
- * This function participates to the #na_iduplicable_duplicate() stack,
- * and is triggered after all copyable elementary data (in #NAIFactoryObject
- * sense) have already been copied themselves.
- */
-void
-na_object_item_copy( NAObjectItem *item, const NAObjectItem *source )
-{
-	static const gchar *thisfn = "na_object_item_copy";
-	GList *tgt_children, *src_children, *ic;
-	NAObject *dup;
-
-	tgt_children = na_object_get_items( item );
-	g_debug( "%s: tgt_children=%p (count=%d)", thisfn, ( void * ) tgt_children, g_list_length( tgt_children ));
-	if( tgt_children ){
-
-		g_warning( "%s: target %s has already %d children",
-				thisfn, G_OBJECT_TYPE_NAME( item ), g_list_length( tgt_children ));
-		na_object_unref_items( tgt_children );
-		tgt_children = NULL;
-	}
-
-	src_children = na_object_get_items( source );
-	for( ic = src_children ; ic ; ic = ic->next ){
-
-		dup = ( NAObject * ) na_object_duplicate( ic->data );
-		na_object_set_parent( dup, item );
-		tgt_children = g_list_prepend( tgt_children, dup );
-	}
-
-	tgt_children = g_list_reverse( tgt_children );
-	na_object_set_items( item, tgt_children );
-}
-
-/**
  * na_object_item_are_equal:
  * @a: the first (original) #NAObjectItem instance.
  * @b: the second #NAObjectItem instance.
@@ -316,6 +293,14 @@ na_object_item_are_equal( const NAObjectItem *a, const NAObjectItem *b )
 			if( !equal ){
 				g_debug( "%s: %p (%s) not equal as g_list_length not equal",
 						thisfn, ( void * ) b, G_OBJECT_TYPE_NAME( b ));
+				g_debug( "a=%p children_count=%u", ( void * ) a, g_list_length( a_children ));
+				for( it = a_children ; it ; it = it->next ){
+					g_debug( "a_child=%p", ( void * ) it->data );
+				}
+				g_debug( "b=%p children_count=%u", ( void * ) b, g_list_length( b_children ));
+				for( it = b_children ; it ; it = it->next ){
+					g_debug( "b_child=%p", ( void * ) it->data );
+				}
 			}
 		}
 
@@ -576,7 +561,12 @@ na_object_item_remove_item( NAObjectItem *item, const NAObjectId *object )
 	if( !item->private->dispose_has_run ){
 
 		children = na_object_get_items( item );
+
 		if( children ){
+			g_debug( "na_object_item_remove_item: removing %p (%s) from %p (%s)",
+					( void * ) object, G_OBJECT_TYPE_NAME( object ),
+					( void * ) item, G_OBJECT_TYPE_NAME( item ));
+
 			children = g_list_remove( children, ( gconstpointer ) object );
 			na_object_set_items( item, children );
 		}
@@ -698,6 +688,33 @@ na_object_item_factory_write_start( NAObjectItem *item )
 }
 
 static void
+copy_children( NAObjectItem *target, const NAObjectItem *source )
+{
+	static const gchar *thisfn = "na_object_item_copy_children";
+	GList *tgt_children, *src_children, *ic;
+	NAObject *dup;
+
+	tgt_children = na_object_get_items( target );
+	g_debug( "%s: tgt_children=%p (count=%d)", thisfn, ( void * ) tgt_children, g_list_length( tgt_children ));
+
+	if( tgt_children ){
+		na_object_unref_items( tgt_children );
+		tgt_children = NULL;
+	}
+
+	src_children = na_object_get_items( source );
+	for( ic = src_children ; ic ; ic = ic->next ){
+
+		dup = ( NAObject * ) na_object_duplicate( ic->data );
+		na_object_set_parent( dup, target );
+		tgt_children = g_list_prepend( tgt_children, dup );
+	}
+
+	tgt_children = g_list_reverse( tgt_children );
+	na_object_set_items( target, tgt_children );
+}
+
+static void
 rebuild_children_slist( NAObjectItem *item )
 {
 	GSList *slist;
@@ -718,7 +735,6 @@ rebuild_children_slist( NAObjectItem *item )
 
 		na_object_set_items_slist( item, slist );
 
-		na_core_utils_slist_dump( slist );
 		na_core_utils_slist_free( slist );
 	}
 }
diff --git a/src/core/na-object-menu.c b/src/core/na-object-menu.c
index 3c5fd07..2f8f689 100644
--- a/src/core/na-object-menu.c
+++ b/src/core/na-object-menu.c
@@ -64,18 +64,17 @@ static NAObjectItemClass *st_parent_class = NULL;
 static GType        register_type( void );
 static void         class_init( NAObjectMenuClass *klass );
 static void         instance_init( GTypeInstance *instance, gpointer klass );
-static void         instance_constructed( GObject *object );
 static void         instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
 static void         instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
 static void         instance_dispose( GObject *object );
 static void         instance_finalize( GObject *object );
 
+static void         object_copy( NAObject *target, const NAObject *source, gboolean recursive );
 static gboolean     object_is_valid( const NAObject *object );
 
 static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
 static guint        ifactory_object_get_version( const NAIFactoryObject *instance );
 static NADataGroup *ifactory_object_get_groups( const NAIFactoryObject *instance );
-static void         ifactory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source );
 static gboolean     ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b );
 static gboolean     ifactory_object_is_valid( const NAIFactoryObject *object );
 static void         ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
@@ -143,7 +142,6 @@ class_init( NAObjectMenuClass *klass )
 	st_parent_class = g_type_class_peek_parent( klass );
 
 	object_class = G_OBJECT_CLASS( klass );
-	object_class->constructed = instance_constructed;
 	object_class->set_property = instance_set_property;
 	object_class->get_property = instance_get_property;
 	object_class->dispose = instance_dispose;
@@ -151,7 +149,7 @@ class_init( NAObjectMenuClass *klass )
 
 	naobject_class = NA_OBJECT_CLASS( klass );
 	naobject_class->dump = NULL;
-	naobject_class->copy = NULL;
+	naobject_class->copy = object_copy;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = object_is_valid;
 
@@ -177,27 +175,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 }
 
 static void
-instance_constructed( GObject *object )
-{
-	static const gchar *thisfn = "na_object_menu_instance_constructed";
-	NAObjectMenu *self;
-
-	g_debug( "%s: object=%p", thisfn, ( void * ) object );
-	g_return_if_fail( NA_IS_OBJECT_MENU( object ));
-	self = NA_OBJECT_MENU( object );
-
-	if( !self->private->dispose_has_run ){
-
-		na_factory_object_set_defaults( NA_IFACTORY_OBJECT( object ));
-
-		/* chain up to the parent class */
-		if( G_OBJECT_CLASS( st_parent_class )->constructed ){
-			G_OBJECT_CLASS( st_parent_class )->constructed( object );
-		}
-	}
-}
-
-static void
 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
 {
 	g_return_if_fail( NA_IS_OBJECT_MENU( object ));
@@ -264,6 +241,19 @@ instance_finalize( GObject *object )
 	}
 }
 
+static void
+object_copy( NAObject *target, const NAObject *source, gboolean recursive )
+{
+	g_return_if_fail( NA_IS_OBJECT_MENU( target ));
+	g_return_if_fail( NA_IS_OBJECT_MENU( source ));
+
+	if( !NA_OBJECT_MENU( target )->private->dispose_has_run &&
+		!NA_OBJECT_MENU( source )->private->dispose_has_run ){
+
+		na_factory_object_copy( NA_IFACTORY_OBJECT( target ), NA_IFACTORY_OBJECT( source ));
+	}
+}
+
 static gboolean
 object_is_valid( const NAObject *object )
 {
@@ -281,7 +271,7 @@ ifactory_object_iface_init( NAIFactoryObjectInterface *iface )
 
 	iface->get_version = ifactory_object_get_version;
 	iface->get_groups = ifactory_object_get_groups;
-	iface->copy = ifactory_object_copy;
+	iface->copy = NULL;
 	iface->are_equal = ifactory_object_are_equal;
 	iface->is_valid = ifactory_object_is_valid;
 	iface->read_start = NULL;
@@ -302,12 +292,6 @@ ifactory_object_get_groups( const NAIFactoryObject *instance )
 	return( menu_data_groups );
 }
 
-static void
-ifactory_object_copy( NAIFactoryObject *target, const NAIFactoryObject *source )
-{
-	na_object_item_copy( NA_OBJECT_ITEM( target ), NA_OBJECT_ITEM( source ));
-}
-
 static gboolean
 ifactory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b )
 {
@@ -325,7 +309,7 @@ ifactory_object_is_valid( const NAIFactoryObject *object )
 static void
 ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
 {
-
+	na_factory_object_set_defaults( instance );
 }
 
 static guint
@@ -422,9 +406,9 @@ NAObjectMenu *
 na_object_menu_new_with_defaults( void )
 {
 	NAObjectMenu *menu = na_object_menu_new();
-
 	na_object_set_new_id( menu, NULL );
 	na_object_set_label( menu, NEW_NAUTILUS_MENU );
+	na_factory_object_set_defaults( NA_IFACTORY_OBJECT( menu ));
 
 	return( menu );
 }
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 089d71e..18a9c86 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -68,12 +68,12 @@ static NAObjectIdClass *st_parent_class = NULL;
 static GType        register_type( void );
 static void         class_init( NAObjectProfileClass *klass );
 static void         instance_init( GTypeInstance *instance, gpointer klass );
-static void         instance_constructed( GObject *object );
 static void         instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
 static void         instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
 static void         instance_dispose( GObject *object );
 static void         instance_finalize( GObject *object );
 
+static void         object_copy( NAObject *target, const NAObject *source, gboolean recursive );
 static gboolean     object_is_valid( const NAObject *object );
 
 static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
@@ -165,7 +165,6 @@ class_init( NAObjectProfileClass *klass )
 	st_parent_class = g_type_class_peek_parent( klass );
 
 	object_class = G_OBJECT_CLASS( klass );
-	object_class->constructed = instance_constructed;
 	object_class->set_property = instance_set_property;
 	object_class->get_property = instance_get_property;
 	object_class->dispose = instance_dispose;
@@ -173,7 +172,7 @@ class_init( NAObjectProfileClass *klass )
 
 	naobject_class = NA_OBJECT_CLASS( klass );
 	naobject_class->dump = NULL;
-	naobject_class->copy = NULL;
+	naobject_class->copy = object_copy;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = object_is_valid;
 
@@ -204,27 +203,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 }
 
 static void
-instance_constructed( GObject *object )
-{
-	static const gchar *thisfn = "na_object_profile_instance_constructed";
-	NAObjectProfile *self;
-
-	g_debug( "%s: object=%p", thisfn, ( void * ) object );
-	g_return_if_fail( NA_IS_OBJECT_PROFILE( object ));
-	self = NA_OBJECT_PROFILE( object );
-
-	if( !self->private->dispose_has_run ){
-
-		na_factory_object_set_defaults( NA_IFACTORY_OBJECT( object ));
-
-		/* chain up to the parent class */
-		if( G_OBJECT_CLASS( st_parent_class )->constructed ){
-			G_OBJECT_CLASS( st_parent_class )->constructed( object );
-		}
-	}
-}
-
-static void
 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
 {
 	g_return_if_fail( NA_IS_OBJECT_PROFILE( object ));
@@ -291,6 +269,19 @@ instance_finalize( GObject *object )
 	}
 }
 
+static void
+object_copy( NAObject *target, const NAObject *source, gboolean recursive )
+{
+	g_return_if_fail( NA_IS_OBJECT_PROFILE( target ));
+	g_return_if_fail( NA_IS_OBJECT_PROFILE( source ));
+
+	if( !NA_OBJECT_PROFILE( target )->private->dispose_has_run &&
+		!NA_OBJECT_PROFILE( source )->private->dispose_has_run ){
+
+		na_factory_object_copy( NA_IFACTORY_OBJECT( target ), NA_IFACTORY_OBJECT( source ));
+	}
+}
+
 static gboolean
 object_is_valid( const NAObject *object )
 {
@@ -345,7 +336,7 @@ ifactory_object_is_valid( const NAIFactoryObject *object )
 static void
 ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
 {
-
+	na_factory_object_set_defaults( instance );
 }
 
 static guint
@@ -552,9 +543,10 @@ NAObjectProfile *
 na_object_profile_new_with_defaults( void )
 {
 	NAObjectProfile *profile = na_object_profile_new();
-
 	na_object_set_id( profile, "profile-zero" );
+	/* i18n: label for the default profile */
 	na_object_set_label( profile, _( "Default profile" ));
+	na_factory_object_set_defaults( NA_IFACTORY_OBJECT( profile ));
 
 	return( profile );
 }
diff --git a/src/core/na-object.c b/src/core/na-object.c
index df49bdb..19a99a0 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -48,7 +48,7 @@ struct NAObjectPrivate {
 	gboolean   dispose_has_run;
 };
 
-/* a structure to iter on the class hierarchy
+/* while iterating on the class hierarchy for are_equal() and is_valid()
  */
 typedef struct {
 	NAObject *object;
@@ -56,6 +56,14 @@ typedef struct {
 }
 	HierarchyIter;
 
+/* while iterating on the class hierarchy for object_copy()
+ */
+typedef struct {
+	NAObject *target;
+	gboolean  recursive;
+}
+	CopyIter;
+
 typedef gboolean ( *HierarchyIterFunc )( GObjectClass *class, const NAObject *object, void *user_data );
 
 static GObjectClass *st_parent_class   = NULL;
@@ -70,13 +78,13 @@ static void           object_dump( const NAObject *object );
 
 static void           iduplicable_iface_init( NAIDuplicableInterface *iface );
 static void           iduplicable_copy( NAIDuplicable *target, const NAIDuplicable *source );
-static gboolean       iduplicable_copy_iter( GObjectClass *class, const NAObject *target, NAObject *source );
 static gboolean       iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b );
 static gboolean       iduplicable_are_equal_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str );
 static gboolean       iduplicable_is_valid( const NAIDuplicable *object );
 static gboolean       iduplicable_is_valid_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str );
 
 static void           push_modified_status_up( const NAObject *object, gboolean is_modified );
+static gboolean       object_copy_iter( GObjectClass *class, const NAObject *source, CopyIter *data );
 static gboolean       dump_class_hierarchy_iter( GObjectClass *class, const NAObject *object, void *user_data );
 static void           dump_tree( GList *tree, gint level );
 static void           iter_on_class_hierarchy( const NAObject *object, HierarchyIterFunc pfn, void *user_data );
@@ -132,6 +140,7 @@ class_init( NAObjectClass *klass )
 {
 	static const gchar *thisfn = "na_object_class_init";
 	GObjectClass *object_class;
+	NAObjectClass *naobject_class;
 
 	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
 
@@ -141,6 +150,12 @@ class_init( NAObjectClass *klass )
 	object_class->dispose = instance_dispose;
 	object_class->finalize = instance_finalize;
 
+	naobject_class = NA_OBJECT_CLASS( klass );
+	naobject_class->dump = NULL;
+	naobject_class->copy = NULL;
+	naobject_class->are_equal = NULL;
+	naobject_class->is_valid = NULL;
+
 	klass->private = g_new0( NAObjectClassPrivate, 1 );
 
 	klass->dump = object_dump;
@@ -235,35 +250,14 @@ iduplicable_iface_init( NAIDuplicableInterface *iface )
 	iface->is_valid = iduplicable_is_valid;
 }
 
+/*
+ * implementation of na_iduplicable::copy interface virtual function
+ * it recursively copies @source to @target
+ */
 static void
 iduplicable_copy( NAIDuplicable *target, const NAIDuplicable *source )
 {
-	g_return_if_fail( NA_IS_OBJECT( target ));
-	g_return_if_fail( NA_IS_OBJECT( source ));
-
-	if( !NA_OBJECT( source )->private->dispose_has_run &&
-		!NA_OBJECT( target )->private->dispose_has_run ){
-
-		if( NA_IS_IFACTORY_OBJECT( source )){
-			na_factory_object_copy( NA_IFACTORY_OBJECT( target ), NA_IFACTORY_OBJECT( source ));
-
-		} else {
-			iter_on_class_hierarchy( NA_OBJECT( source ),
-					( HierarchyIterFunc ) &iduplicable_copy_iter, ( void * ) target );
-		}
-	}
-}
-
-static gboolean
-iduplicable_copy_iter( GObjectClass *class, const NAObject *source, NAObject *target )
-{
-	gboolean stop = FALSE;
-
-	if( NA_OBJECT_CLASS( class )->copy ){
-		NA_OBJECT_CLASS( class )->copy( target, source );
-	}
-
-	return( stop );
+	na_object_copy( NA_OBJECT( target ), NA_OBJECT( source ), TRUE );
 }
 
 static gboolean
@@ -476,6 +470,48 @@ push_modified_status_up( const NAObject *object, gboolean is_modified )
 }
 
 /**
+ * na_object_object_copy:
+ * @target: the target #NAObject-derived object.
+ * @source: the source #NAObject-derived object.
+ * @recursive: whether the copy should be recursive.
+ *
+ * Copies @source to @target.
+ */
+void
+na_object_object_copy( NAObject *target, const NAObject *source, gboolean recursive )
+{
+	CopyIter *data;
+
+	g_return_if_fail( NA_IS_OBJECT( target ));
+	g_return_if_fail( NA_IS_OBJECT( source ));
+
+	if( !NA_OBJECT( source )->private->dispose_has_run &&
+		!NA_OBJECT( target )->private->dispose_has_run ){
+
+		data = g_new0( CopyIter, 1 );
+		data->target = target;
+		data->recursive = recursive;
+
+		iter_on_class_hierarchy( NA_OBJECT( source ),
+					( HierarchyIterFunc ) object_copy_iter, ( void * ) data );
+
+		g_free( data );
+	}
+}
+
+static gboolean
+object_copy_iter( GObjectClass *class, const NAObject *source, CopyIter *data )
+{
+	gboolean stop = FALSE;
+
+	if( NA_OBJECT_CLASS( class )->copy ){
+		NA_OBJECT_CLASS( class )->copy( data->target, source, data->recursive );
+	}
+
+	return( stop );
+}
+
+/**
  * na_object_object_dump:
  * @object: the #NAObject-derived object to be dumped.
  *
diff --git a/src/core/na-pivot.c b/src/core/na-pivot.c
index 240fe2b..05535e4 100644
--- a/src/core/na-pivot.c
+++ b/src/core/na-pivot.c
@@ -312,6 +312,7 @@ instance_dispose( GObject *object )
 		self->private->consumers = NULL;
 
 		/* release item tree */
+		g_debug( "%s: tree=%p, count=%u", thisfn, ( void * ) self->private->tree, g_list_length( self->private->tree ));
 		na_object_unref_items( self->private->tree );
 		self->private->tree = NULL;
 
diff --git a/src/core/na-updater.c b/src/core/na-updater.c
index f21e21a..6033d31 100644
--- a/src/core/na-updater.c
+++ b/src/core/na-updater.c
@@ -247,13 +247,13 @@ na_updater_remove_item( NAUpdater *updater, NAObject *item )
 
 	if( !updater->private->dispose_has_run ){
 
-		g_object_get( G_OBJECT( updater ), NAPIVOT_PROP_TREE, &tree, NULL );
-		tree = g_list_remove( tree, ( gconstpointer ) item );
-		g_object_set( G_OBJECT( updater ), NAPIVOT_PROP_TREE, &tree, NULL );
-
-		if( G_IS_OBJECT( item )){
-			g_object_unref( item );
+		if( !na_object_get_parent( item )){
+			g_object_get( G_OBJECT( updater ), NAPIVOT_PROP_TREE, &tree, NULL );
+			tree = g_list_remove( tree, ( gconstpointer ) item );
+			g_object_set( G_OBJECT( updater ), NAPIVOT_PROP_TREE, tree, NULL );
 		}
+
+		g_object_unref( item );
 	}
 }
 
diff --git a/src/io-gconf/nagp-gconf-provider.c b/src/io-gconf/nagp-gconf-provider.c
index 2cf6832..e4796d5 100644
--- a/src/io-gconf/nagp-gconf-provider.c
+++ b/src/io-gconf/nagp-gconf-provider.c
@@ -245,7 +245,7 @@ ifactory_provider_iface_init( NAIFactoryProviderInterface *iface )
 	iface->read_start = NULL;
 	iface->read_data = nagp_reader_read_data;
 	iface->read_done = nagp_reader_read_done;
-	iface->write_start = NULL;
+	iface->write_start = nagp_writer_write_start;
 	iface->write_data = nagp_writer_write_data;
 	iface->write_done = nagp_writer_write_done;
 }
diff --git a/src/io-gconf/nagp-reader.c b/src/io-gconf/nagp-reader.c
index ddcedc4..31b37e0 100644
--- a/src/io-gconf/nagp-reader.c
+++ b/src/io-gconf/nagp-reader.c
@@ -175,11 +175,11 @@ nagp_reader_read_data( const NAIFactoryProvider *provider, void *reader_data, co
 	g_return_val_if_fail( NA_IS_IFACTORY_PROVIDER( provider ), NULL );
 	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
 
-	g_debug( "%s: reader_data=%p, object=%p (%s), data=%s",
+	/*g_debug( "%s: reader_data=%p, object=%p (%s), data=%s",
 			thisfn,
 			( void * ) reader_data,
 			( void * ) object, G_OBJECT_TYPE_NAME( object ),
-			def->name );
+			def->name );*/
 
 	if( !def->gconf_entry || !strlen( def->gconf_entry )){
 		g_warning( "%s: GConf entry is not set for NADataDef %s", thisfn, def->name );
diff --git a/src/io-gconf/nagp-writer.c b/src/io-gconf/nagp-writer.c
index acf42bc..f260c47 100644
--- a/src/io-gconf/nagp-writer.c
+++ b/src/io-gconf/nagp-writer.c
@@ -327,6 +327,44 @@ nagp_iio_provider_delete_item( const NAIIOProvider *provider, const NAObjectItem
 }
 
 guint
+nagp_writer_write_start( const NAIFactoryProvider *writer, void *writer_data,
+							const NAIFactoryObject *object, GSList **messages  )
+{
+	guint code;
+	gchar *id, *parent_path, *path;
+	gchar *msg;
+
+	code = NA_IIO_PROVIDER_CODE_OK;
+
+	if( NA_IS_OBJECT_ITEM( object )){
+		g_return_val_if_fail(
+				(( WriterData * ) writer_data )->parent_id == NULL,
+				NA_IIO_PROVIDER_CODE_PROGRAM_ERROR );
+
+		id = na_object_get_id( object );
+		parent_path = gconf_concat_dir_and_key( NAGP_CONFIGURATIONS_PATH, id );
+		path = gconf_concat_dir_and_key( parent_path, NAGP_ENTRY_TYPE );
+
+		msg = NULL;
+		na_gconf_utils_write_string(
+				NAGP_GCONF_PROVIDER( writer )->private->gconf,
+				path,
+				NA_IS_OBJECT_ACTION( object ) ? NAGP_VALUE_TYPE_ACTION : NAGP_VALUE_TYPE_MENU,
+				&msg );
+		if( msg ){
+			*messages = g_slist_append( *messages, msg );
+			code = NA_IIO_PROVIDER_CODE_WRITE_ERROR;
+		}
+
+		g_free( path );
+		g_free( parent_path );
+		g_free( id );
+	}
+
+	return( code );
+}
+
+guint
 nagp_writer_write_data( const NAIFactoryProvider *provider, void *writer_data,
 									const NAIFactoryObject *object, const NADataBoxed *boxed,
 									GSList **messages )
diff --git a/src/io-gconf/nagp-writer.h b/src/io-gconf/nagp-writer.h
index b62030d..1c96436 100644
--- a/src/io-gconf/nagp-writer.h
+++ b/src/io-gconf/nagp-writer.h
@@ -48,11 +48,15 @@ guint    nagp_iio_provider_delete_item( const NAIIOProvider *provider, const NAO
 
 /* NAIFactoryProvider interface
  */
-guint    nagp_writer_write_data( const NAIFactoryProvider *provider, void *writer_data,
+guint    nagp_writer_write_start( const NAIFactoryProvider *writer, void *writer_data,
+									const NAIFactoryObject *object,
+									GSList **messages  );
+
+guint    nagp_writer_write_data ( const NAIFactoryProvider *provider, void *writer_data,
 									const NAIFactoryObject *object, const NADataBoxed *boxed,
 									GSList **messages );
 
-guint    nagp_writer_write_done( const NAIFactoryProvider *writer, void *writer_data,
+guint    nagp_writer_write_done ( const NAIFactoryProvider *writer, void *writer_data,
 									const NAIFactoryObject *object,
 									GSList **messages  );
 
diff --git a/src/nact/nact-iaction-tab.c b/src/nact/nact-iaction-tab.c
index 34be660..07dc834 100644
--- a/src/nact/nact-iaction-tab.c
+++ b/src/nact/nact-iaction-tab.c
@@ -462,9 +462,6 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 		enable_label = ( item && ( NA_IS_OBJECT_MENU( item ) || target_selection || target_background ));
 		label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionMenuLabelEntry" );
 		label = item ? na_object_get_label( item ) : g_strdup( "" );
-		if( !label ){
-			label = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( label_widget ), label );
 		if( item ){
 			check_for_label( instance, GTK_ENTRY( label_widget ), label );
@@ -486,9 +483,6 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 
 		label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionIconLabelEntry" );
 		label = item && NA_IS_OBJECT_ACTION( item ) ? na_object_get_toolbar_label( NA_OBJECT_ACTION( item )) : g_strdup( "" );
-		if( !label ){
-			label = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( label_widget ), label );
 		g_free( label );
 		toolbar_label_set_sensitive( instance, item );
@@ -496,9 +490,6 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 
 		tooltip_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionTooltipEntry" );
 		tooltip = item ? na_object_get_tooltip( item ) : g_strdup( "" );
-		if( !tooltip ){
-			tooltip = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( tooltip_widget ), tooltip );
 		g_free( tooltip );
 		gtk_widget_set_sensitive( tooltip_widget, item != NULL );
@@ -506,9 +497,6 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 
 		icon_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionIconComboBoxEntry" );
 		icon = item ? na_object_get_icon( item ) : g_strdup( "" );
-		if( !icon ){
-			icon = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( GTK_BIN( icon_widget )->child ), icon );
 		g_free( icon );
 		gtk_widget_set_sensitive( icon_widget, item != NULL );
@@ -547,9 +535,6 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 
 		label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionItemID" );
 		label = item ? na_object_get_id( item ) : g_strdup( "" );
-		if( !label ){
-			label = g_strdup( "" );
-		}
 		gtk_label_set_text( GTK_LABEL( label_widget ), label );
 		g_free( label );
 		gtk_widget_set_sensitive( label_widget, item != NULL );
@@ -686,7 +671,6 @@ on_label_changed( GtkEntry *entry, NactIActionTab *instance )
 {
 	NAObjectItem *edited;
 	const gchar *label;
-	gboolean target_toolbar;
 	gboolean toolbar_same_label;
 
 	g_object_get(
@@ -700,12 +684,9 @@ on_label_changed( GtkEntry *entry, NactIActionTab *instance )
 		check_for_label( instance, entry, label );
 
 		if( NA_IS_OBJECT_ACTION( edited )){
-			target_toolbar = na_object_is_target_toolbar( NA_OBJECT_ACTION( edited ));
-			if( target_toolbar ){
-				toolbar_same_label = na_object_is_toolbar_same_label( NA_OBJECT_ACTION( edited ));
-				if( toolbar_same_label ){
-					na_object_set_toolbar_label( NA_OBJECT_ACTION( edited ), label );
-				}
+			toolbar_same_label = na_object_is_toolbar_same_label( NA_OBJECT_ACTION( edited ));
+			if( toolbar_same_label ){
+				na_object_set_toolbar_label( NA_OBJECT_ACTION( edited ), label );
 			}
 		}
 
diff --git a/src/nact/nact-iactions-list-bis.c b/src/nact/nact-iactions-list-bis.c
index c0e7d71..b2a237c 100644
--- a/src/nact/nact-iactions-list-bis.c
+++ b/src/nact/nact-iactions-list-bis.c
@@ -581,13 +581,13 @@ nact_iactions_list_bis_list_modified_items( NactIActionsList *instance )
 }
 
 /**
- * nact_iactions_list_bis_removed_modified:
+ * nact_iactions_list_bis_remove_modified:
  * @instance: this #NactIActionsList instance.
  *
  * Removes the saved item from the modified items list.
  */
 void
-nact_iactions_list_bis_removed_modified( NactIActionsList *instance, const NAObjectItem *item )
+nact_iactions_list_bis_remove_modified( NactIActionsList *instance, const NAObjectItem *item )
 {
 	IActionsListInstanceData *ialid;
 
diff --git a/src/nact/nact-iactions-list.h b/src/nact/nact-iactions-list.h
index 4a7bbae..8abc64b 100644
--- a/src/nact/nact-iactions-list.h
+++ b/src/nact/nact-iactions-list.h
@@ -148,7 +148,7 @@ void      nact_iactions_list_bis_insert_at_path( NactIActionsList *instance, GLi
 void      nact_iactions_list_bis_insert_items( NactIActionsList *instance, GList *items, NAObject *sibling );
 void      nact_iactions_list_bis_insert_into( NactIActionsList *instance, GList *items );
 void      nact_iactions_list_bis_list_modified_items( NactIActionsList *instance );
-void      nact_iactions_list_bis_removed_modified( NactIActionsList *instance, const NAObjectItem *item );
+void      nact_iactions_list_bis_remove_modified( NactIActionsList *instance, const NAObjectItem *item );
 void      nact_iactions_list_bis_select_first_row( NactIActionsList *instance );
 void      nact_iactions_list_bis_select_row_at_path( NactIActionsList *instance, GtkTreeView *treeview, GtkTreeModel *model, GtkTreePath *path );
 void      nact_iactions_list_bis_toggle_collapse( NactIActionsList *instance );
diff --git a/src/nact/nact-icommand-tab.c b/src/nact/nact-icommand-tab.c
index e5adc38..d942fec 100644
--- a/src/nact/nact-icommand-tab.c
+++ b/src/nact/nact-icommand-tab.c
@@ -340,9 +340,6 @@ on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_select
 
 		label_entry = get_label_entry( instance );
 		label = profile ? na_object_get_label( profile ) : g_strdup( "" );
-		if( !label ){
-			label = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( label_entry ), label );
 		check_for_label( instance, GTK_ENTRY( label_entry ), label );
 		g_free( label );
@@ -351,9 +348,6 @@ on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_select
 
 		path_entry = get_path_entry( instance );
 		path = profile ? na_object_get_path( profile ) : g_strdup( "" );
-		if( !path ){
-			path = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( path_entry ), path );
 		g_free( path );
 		gtk_widget_set_sensitive( path_entry, profile != NULL );
@@ -365,9 +359,6 @@ on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_select
 
 		parameters_entry = get_parameters_entry( instance );
 		parameters = profile ? na_object_get_parameters( profile ) : g_strdup( "" );
-		if( !parameters ){
-			parameters = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( parameters_entry ), parameters );
 		g_free( parameters );
 		gtk_widget_set_sensitive( parameters_entry, profile != NULL );
diff --git a/src/nact/nact-iconditions-tab.c b/src/nact/nact-iconditions-tab.c
index 3ef7d49..c8c0936 100644
--- a/src/nact/nact-iconditions-tab.c
+++ b/src/nact/nact-iconditions-tab.c
@@ -332,9 +332,6 @@ on_tab_updatable_selection_changed( NactIConditionsTab *instance, gint count_sel
 		basenames_widget = get_basenames_entry( instance );
 		basenames = profile ? na_object_get_basenames( profile ) : NULL;
 		basenames_text = profile ? na_core_utils_slist_to_text( basenames ) : g_strdup( "" );
-		if( !basenames_text ){
-			basenames_text = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( basenames_widget ), basenames_text );
 		g_free( basenames_text );
 		na_core_utils_slist_free( basenames );
@@ -350,9 +347,6 @@ on_tab_updatable_selection_changed( NactIConditionsTab *instance, gint count_sel
 		mimetypes_widget = get_mimetypes_entry( instance );
 		mimetypes = profile ? na_object_get_mimetypes( profile ) : NULL;
 		mimetypes_text = profile ? na_core_utils_slist_to_text( mimetypes ) : g_strdup( "" );
-		if( !mimetypes_text ){
-			mimetypes_text = g_strdup( "" );
-		}
 		gtk_entry_set_text( GTK_ENTRY( mimetypes_widget ), mimetypes_text );
 		g_free( mimetypes_text );
 		na_core_utils_slist_free( mimetypes );
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index 0e69c24..85cc527 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -952,12 +952,13 @@ nact_main_menubar_save_items( NactMainWindow *window )
 
 	/* recursively save the modified items
 	 * check is useless here if item was not modified, but not very costly
-	 * above all, it is cheaper to check the status here, than to check
+	 * above all, it is less costly to check the status here, than to check
 	 * recursively each and every modified item
 	 */
 	for( it = items ; it ; it = it->next ){
 		save_item( window, updater, NA_OBJECT_ITEM( it->data ));
 		na_object_check_status( it->data );
+		na_object_dump( it->data );
 	}
 	g_list_free( items );
 
@@ -1010,13 +1011,7 @@ save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item )
 			g_debug( "%s: origin=%p", thisfn, ( void * ) origin );
 
 			if( origin ){
-				if( NA_IS_OBJECT_ACTION( item )){
-					subitems = na_object_get_items( origin );
-					na_object_unref_items( subitems );
-				}
-
-				na_factory_object_copy(
-						NA_IFACTORY_OBJECT( origin ), NA_IFACTORY_OBJECT( item ));
+				na_object_copy( origin, item, NA_IS_OBJECT_ACTION( item ));
 
 			} else {
 				dup_pivot = NA_OBJECT_ITEM( na_object_duplicate( item ));
@@ -1060,7 +1055,7 @@ save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item )
 			}
 #endif
 
-			nact_iactions_list_bis_removed_modified( NACT_IACTIONS_LIST( window ), item );
+			nact_iactions_list_bis_remove_modified( NACT_IACTIONS_LIST( window ), item );
 
 			provider_after = na_object_get_provider( item );
 			if( provider_after != provider_before ){
diff --git a/src/nact/nact-window.c b/src/nact/nact-window.c
index 9cac039..e231860 100644
--- a/src/nact/nact-window.c
+++ b/src/nact/nact-window.c
@@ -337,12 +337,9 @@ nact_window_save_item( NactWindow *window, NAObjectItem *item )
 		application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
 		updater = nact_application_get_updater( application );
 
-		na_object_dump( item );
-
 		ret = na_updater_write_item( updater, item, &messages );
 
 		g_debug( "nact_window_save_item: ret=%d", ret );
-		na_object_dump( item );
 
 		if( messages ){
 			base_window_error_dlg(



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