[nautilus-actions] Refactoring: update menu bar management



commit a7ffd68df7a1712ff511691d7692a1f71e88b183
Author: Pierre Wieser <pwieser trychlos org>
Date:   Wed Feb 17 18:34:23 2010 +0100

    Refactoring: update menu bar management

 ChangeLog                     |   18 +++++
 src/api/na-object-action.h    |    9 ++-
 src/api/na-object-api.h       |   14 ++++
 src/api/na-object-id.h        |   22 ++++++
 src/api/na-object-item.h      |    7 ++-
 src/api/na-object-profile.h   |    4 +
 src/api/na-object.h           |    7 +-
 src/core/na-object-action.c   |   51 +++++++++++++
 src/core/na-object-id.c       |  159 +++++++++++++++++++++++++++++++++++++++--
 src/core/na-object-item.c     |  143 +++++++++++++++++++++++++++++++++++--
 src/core/na-object-profile.c  |   26 +++++++
 src/core/na-object.c          |   80 +++++++++++++++------
 src/core/na-pivot.c           |   16 ++++
 src/core/na-pivot.h           |    3 +-
 src/core/na-updater.c         |   61 ++++++++++++++++
 src/core/na-updater.h         |   10 ++-
 src/nact/nact-export-format.c |   10 ++--
 src/nact/nact-main-menubar.c  |   83 +++++++++++-----------
 18 files changed, 634 insertions(+), 89 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3546691..d3985ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2009-02-17 Pierre Wieser <pwieser trychlos org>
 
+	* src/api/na-object-action.h:
+	* src/api/na-object-api.h:
+	* src/api/na-object-id.h:
+	* src/api/na-object-item.h:
+	* src/api/na-object-profile.h:
+	* src/api/na-object.h:
+	* src/core/na-object-action.c:
+	* src/core/na-object-id.c:
+	* src/core/na-object-item.c:
+	* src/core/na-object-profile.c:
+	* src/core/na-object.c:
+	* src/core/na-pivot.c:
+	* src/core/na-pivot.h:
+	* src/core/na-updater.c:
+	* src/core/na-updater.h:
+	* src/nact/nact-export-format.c:
+	* src/nact/nact-main-menubar.c: Update menu bar.
+
 	* src/nact/nact-iprefs.c: Update NactIPrefs interface.
 
 	* src/api/na-core-utils.h:
diff --git a/src/api/na-object-action.h b/src/api/na-object-action.h
index ec4fe59..d3db7ad 100644
--- a/src/api/na-object-action.h
+++ b/src/api/na-object-action.h
@@ -28,8 +28,8 @@
  *   ... and many others (see AUTHORS)
  */
 
-#ifndef __NAUTILUS_OBJECT_ACTIONS_API_NA_OBJECT_ACTION_H__
-#define __NAUTILUS_OBJECT_ACTIONS_API_NA_OBJECT_ACTION_H__
+#ifndef __NAUTILUS_ACTIONS_API_NA_OBJECT_ACTION_H__
+#define __NAUTILUS_ACTIONS_API_NA_OBJECT_ACTION_H__
 
 /**
  * SECTION: na_object_action
@@ -73,15 +73,16 @@ typedef struct {
 }
 	NAObjectActionClass;
 
-GType           na_object_action_get_type( void );
+GType na_object_action_get_type( void );
 
 NAObjectAction *na_object_action_new( void );
 NAObjectAction *na_object_action_new_with_profile( void );
 
+gchar          *na_object_action_get_new_profile_name( const NAObjectAction *action );
 void            na_object_action_attach_profile( NAObjectAction *action, NAObjectProfile *profile );
 
 gboolean        na_object_action_is_candidate( const NAObjectAction *action, gint target );
 
 G_END_DECLS
 
-#endif /* __NAUTILUS_OBJECT_ACTIONS_API_NA_OBJECT_ACTION_H__ */
+#endif /* __NAUTILUS_ACTIONS_API_NA_OBJECT_ACTION_H__ */
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index d5ec136..d38dfbc 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -62,6 +62,8 @@ G_BEGIN_DECLS
 
 #define na_object_set_origin( obj, origin )				na_iduplicable_set_origin( NA_IDUPLICABLE( obj ), ( NAIDuplicable * )( origin ))
 
+#define na_object_reset_origin( obj, origin )			na_object_object_reset_origin( NA_OBJECT( obj ), ( NAObject * )( origin ))
+
 /* NAObject
  */
 #define na_object_dump( obj )							na_object_object_dump( NA_OBJECT( obj ))
@@ -84,6 +86,11 @@ G_BEGIN_DECLS
 #define na_object_sort_alpha_asc( a, b )				na_object_id_sort_alpha_asc( NA_OBJECT_ID( a ), NA_OBJECT_ID( b ))
 #define na_object_sort_alpha_desc( a, b )				na_object_id_sort_alpha_desc( NA_OBJECT_ID( a ), NA_OBJECT_ID( b ))
 
+#define na_object_prepare_for_paste( obj, relabel, renumber, action ) \
+														na_object_id_prepare_for_paste( NA_OBJECT_ID( obj ), ( relabel ), ( renumber ), ( NAObjectId * )( action ))
+#define na_object_set_copy_of_label( obj )				na_object_id_set_copy_of_label( NA_OBJECT_ID( obj ))
+#define na_object_set_new_id( obj, parent )				na_object_id_set_new_id( NA_OBJECT_ID( obj ), ( NAObjectId * )( parent ))
+
 /* NAObjectItem
  */
 #define na_object_get_tooltip( obj )					(( gchar * ) na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLTIP ))
@@ -105,7 +112,11 @@ G_BEGIN_DECLS
 #define na_object_set_provider_data( obj, data )		na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_PROVIDER_DATA, ( const void * )( data ))
 
 #define na_object_get_item( obj, id )					na_object_item_get_item( NA_OBJECT_ITEM( obj ),( const gchar * )( id ))
+#define na_object_get_position( obj, child )			na_object_item_get_position( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ))
 #define na_object_append_item( obj, child )				na_object_item_append_item( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ))
+#define na_object_insert_at( obj, child, pos )			na_object_item_insert_at( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ), ( pos ))
+#define na_object_remove_item( obj, child )				na_object_item_remove_item( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ))
+
 #define na_object_build_items_slist( obj )				na_object_item_build_items_slist( NA_OBJECT_ITEM( obj ))
 #define na_object_get_items_count( obj )				na_object_item_get_items_count( NA_OBJECT_ITEM( obj ))
 #define na_object_count_items( list, cm, ca, cp, brec )	na_object_item_count_items( list, ( cm ), ( ca ), ( cp ), ( brec ))
@@ -119,6 +130,7 @@ G_BEGIN_DECLS
 #define na_object_is_target_toolbar( obj )				(( gboolean ) GPOINTER_TO_UINT( na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_TARGET_TOOLBAR )))
 #define na_object_get_toolbar_label( obj )				(( gchar * ) na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLBAR_LABEL ))
 #define na_object_is_toolbar_same_label( obj )			(( gboolean ) GPOINTER_TO_UINT( na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLBAR_SAME_LABEL )))
+#define na_object_get_last_allocated( obj )				(( guint ) GPOINTER_TO_UINT( na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_LAST_ALLOCATED )))
 
 #define na_object_set_version( obj, version )			na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_VERSION, ( const void * )( version ))
 #define na_object_set_target_selection( obj, target )	na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_TARGET_SELECTION, ( const void * ) GUINT_TO_POINTER( target ))
@@ -126,7 +138,9 @@ G_BEGIN_DECLS
 #define na_object_set_target_toolbar( obj, target )		na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_TARGET_TOOLBAR, ( const void * ) GUINT_TO_POINTER( target ))
 #define na_object_set_toolbar_label( obj, label )		na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLBAR_LABEL, ( const void * )( label ))
 #define na_object_set_toolbar_same_label( obj, same )	na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLBAR_SAME_LABEL, ( const void * ) GUINT_TO_POINTER( same ))
+#define na_object_set_last_allocated( obj, last )		na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_LAST_ALLOCATED, ( const void * ) GUINT_TO_POINTER( last ))
 
+#define na_object_reset_last_allocated( obj )			na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_LAST_ALLOCATED, ( const void * ) GUINT_TO_POINTER( 0 ))
 #define na_object_attach_profile( obj, profile )		na_object_action_attach_profile( NA_OBJECT_ACTION( obj ), NA_OBJECT_PROFILE( profile ))
 
 /* NAObjectProfile
diff --git a/src/api/na-object-id.h b/src/api/na-object-id.h
index 1817e05..ca596c3 100644
--- a/src/api/na-object-id.h
+++ b/src/api/na-object-id.h
@@ -65,6 +65,24 @@ typedef struct NAObjectIdClassPrivate NAObjectIdClassPrivate;
 typedef struct {
 	NAObjectClass           parent;
 	NAObjectIdClassPrivate *private;
+
+	/**
+	 * new_id:
+	 * @object: a #NAObjectId object.
+	 * @new_parent: possibly the new #NAObjectId parent, or NULL.
+	 * If not NULL, this should actually be a #NAObjectItem.
+	 *
+	 * Returns: a new id suitable for this @object.
+	 *
+	 * If @object is a #NAObjectProfile, then @new_parent must be a
+	 * not null #NAObjectAction. This function ensures that the new
+	 * profile name does not already exist in the given @new_parent.
+	 *
+	 * This is a pure virtual function which should be implemented by
+	 * the actual class. Actually, we asks for the most-derived class
+	 * which implements this function.
+	 */
+	gchar * ( *new_id )( const NAObjectId *object, const NAObjectId *new_parent );
 }
 	NAObjectIdClass;
 
@@ -73,6 +91,10 @@ GType  na_object_id_get_type( void );
 gint   na_object_id_sort_alpha_asc ( const NAObjectId *a, const NAObjectId *b );
 gint   na_object_id_sort_alpha_desc( const NAObjectId *a, const NAObjectId *b );
 
+void   na_object_id_prepare_for_paste( NAObjectId *object, gboolean relabel, gboolean renumber, NAObjectId *action );
+void   na_object_id_set_copy_of_label( NAObjectId *object );
+void   na_object_id_set_new_id       ( NAObjectId *object, const NAObjectId *new_parent );
+
 G_END_DECLS
 
 #endif /* __NAUTILUS_ACTIONS_API_NA_OBJECT_ID_H__ */
diff --git a/src/api/na-object-item.h b/src/api/na-object-item.h
index 9e4c30c..df8386a 100644
--- a/src/api/na-object-item.h
+++ b/src/api/na-object-item.h
@@ -80,8 +80,11 @@ 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 );
-void        na_object_item_append_item( NAObjectItem *object, const NAObjectId *item );
+NAObjectId *na_object_item_get_item    ( const NAObjectItem *item, const gchar *id );
+gint        na_object_item_get_position( const NAObjectItem *item, const NAObjectId *child );
+void        na_object_item_append_item ( NAObjectItem *object, const NAObjectId *item );
+void        na_object_item_insert_at   ( NAObjectItem *object, const NAObjectId *item, gint pos );
+void        na_object_item_remove_item ( NAObjectItem *object, const NAObjectId *item );
 
 GSList     *na_object_item_build_items_slist( const NAObjectItem *item );
 
diff --git a/src/api/na-object-profile.h b/src/api/na-object-profile.h
index c7a9e75..fe2e656 100644
--- a/src/api/na-object-profile.h
+++ b/src/api/na-object-profile.h
@@ -67,6 +67,10 @@ typedef struct {
 }
 	NAObjectProfileClass;
 
+/* default prefix for profile name
+ */
+#define NA_PROFILE_DEFAULT_PREFIX		"profile-"
+
 GType            na_object_profile_get_type( void );
 
 NAObjectProfile *na_object_profile_new( void );
diff --git a/src/api/na-object.h b/src/api/na-object.h
index de77be8..e52ab73 100644
--- a/src/api/na-object.h
+++ b/src/api/na-object.h
@@ -138,6 +138,8 @@ GType     na_object_object_get_type( void );
 void      na_object_object_check_status   ( const NAObject *object );
 gboolean  na_object_object_check_status_up( const NAObject *object );
 
+void      na_object_object_reset_origin   ( NAObject *object, const NAObject *origin );
+
 NAObject *na_object_object_ref  ( NAObject *object );
 void      na_object_object_unref( NAObject *object );
 
@@ -145,9 +147,8 @@ 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 );
 
-#if 0
-GList *na_object_object_get_hierarchy( const NAObject *object );
-#endif
+GList    *na_object_object_get_hierarchy( const NAObject *object );
+void      na_object_free_hierarchy( GList *hierarchy );
 
 G_END_DECLS
 
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index ed0792a..96c1ba8 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -344,6 +344,57 @@ na_object_action_new_with_profile( void )
 }
 
 /**
+ * na_object_action_get_new_profile_name:
+ * @action: the #NAObjectAction object which will receive a new profile.
+ *
+ * Returns a name suitable as a new profile name.
+ *
+ * The search is made by iterating over the standard profile name
+ * prefix : basically, we increment a counter until finding a name
+ * which is not yet allocated. The provided name is so only suitable
+ * for the specified @action.
+ *
+ * Returns: a newly allocated profile name, which should be g_free() by
+ * the caller.
+ *
+ * When inserting a list of profiles in the action, we iter first for
+ * new names, before actually do the insertion. We so keep the last
+ * allocated name to avoid to allocate the same one twice.
+ */
+gchar *
+na_object_action_get_new_profile_name( const NAObjectAction *action )
+{
+	int i;
+	gboolean ok = FALSE;
+	gchar *candidate = NULL;
+	guint last_allocated;
+
+	g_return_val_if_fail( NA_IS_OBJECT_ACTION( action ), NULL );
+
+	if( !action->private->dispose_has_run ){
+
+		last_allocated = na_object_get_last_allocated( action );
+		for( i = last_allocated + 1 ; !ok ; ++i ){
+
+			g_free( candidate );
+			candidate = g_strdup_printf( "%s%d", NA_PROFILE_DEFAULT_PREFIX, i );
+
+			if( !na_object_get_item( action, candidate )){
+				ok = TRUE;
+				na_object_set_last_allocated( action, i );
+			}
+		}
+
+		if( !ok ){
+			g_free( candidate );
+			candidate = NULL;
+		}
+	}
+
+	return( candidate );
+}
+
+/**
  * na_object_action_attach_profile:
  * @action: the #NAObjectAction action to which the profile will be attached.
  * @profile: the #NAObjectProfile profile to be attached to @action.
diff --git a/src/core/na-object-id.c b/src/core/na-object-id.c
index f45d6bc..f12c176 100644
--- a/src/core/na-object-id.c
+++ b/src/core/na-object-id.c
@@ -32,6 +32,8 @@
 #include <config.h>
 #endif
 
+#include <glib/gi18n.h>
+
 #include <api/na-object-api.h>
 
 /* private class data
@@ -52,11 +54,13 @@ struct NAObjectIdPrivate {
 
 static NAObjectClass *st_parent_class = NULL;
 
-static GType register_type( void );
-static void  class_init( NAObjectIdClass *klass );
-static void  instance_init( GTypeInstance *instance, gpointer klass );
-static void  instance_dispose( GObject *object );
-static void  instance_finalize( GObject *object );
+static GType  register_type( void );
+static void   class_init( NAObjectIdClass *klass );
+static void   instance_init( GTypeInstance *instance, gpointer klass );
+static void   instance_dispose( GObject *object );
+static void   instance_finalize( GObject *object );
+
+static gchar *v_new_id( const NAObjectId *object, const NAObjectId *new_parent );
 
 GType
 na_object_id_get_type( void )
@@ -116,6 +120,8 @@ class_init( NAObjectIdClass *klass )
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = NULL;
 
+	klass->new_id = NULL;
+
 	klass->private = g_new0( NAObjectIdClassPrivate, 1 );
 }
 
@@ -223,3 +229,146 @@ na_object_id_sort_alpha_desc( const NAObjectId *a, const NAObjectId *b )
 {
 	return( -1 * na_object_id_sort_alpha_asc( a, b ));
 }
+
+/**
+ * na_object_id_prepare_for_paste:
+ * @object: the #NAObjectId object to be pasted.
+ * @relabel: whether this object should be relabeled when pasted.
+ * @relabel: whether this item should be renumbered ?
+ * @action: if @object is a #NAObjectProfile, the parent #NAObjectAction.
+ *
+ * Prepares @object to be pasted.
+ *
+ * If a #NAObjectProfile, then @object is attached to the specified
+ * #NAObjectAction @action. The identifier is always renumbered to be
+ * suitable with the already existing profiles.
+ *
+ * If a #NAObjectAction or a #NAObjectMenu, a new UUID is allocated if
+ * and only if @relabel is %TRUE.
+ *
+ * Actual relabeling takes place if @relabel is %TRUE, depending of the
+ * user preferences.
+ */
+void
+na_object_id_prepare_for_paste( NAObjectId *object, gboolean relabel, gboolean renumber, NAObjectId *action )
+{
+	static const gchar *thisfn = "na_object_id_prepare_for_paste";
+	GList *subitems, *it;
+
+	g_debug( "%s: object=%p, relabel=%s, renumber=%s, action=%p",
+			thisfn, ( void * ) object, relabel ? "True":"False", renumber ? "True":"False", ( void * ) action );
+	g_return_if_fail( NA_IS_OBJECT_ID( object ));
+	g_return_if_fail( !action || NA_IS_OBJECT_ACTION( action ));
+
+	if( !object->private->dispose_has_run ){
+
+		if( NA_IS_OBJECT_PROFILE( object )){
+			na_object_set_parent( object, action );
+			na_object_set_new_id( object, action );
+			if( renumber && relabel ){
+				na_object_set_copy_of_label( object );
+			}
+
+		} else {
+			if( renumber ){
+				na_object_set_new_id( object, NULL );
+				if( relabel ){
+					na_object_set_copy_of_label( object );
+				}
+				na_object_set_provider( object, NULL );
+				na_object_set_readonly( object, FALSE );
+			}
+			if( NA_IS_OBJECT_MENU( object )){
+				subitems = na_object_get_items( object );
+				for( it = subitems ; it ; it = it->next ){
+					na_object_prepare_for_paste( it->data, relabel, renumber, NULL );
+				}
+			}
+		}
+	}
+}
+
+/**
+ * na_object_id_set_copy_of_label:
+ * @object: the #NAObjectId object whose label is to be changed.
+ *
+ * Sets the 'Copy of' label.
+ */
+void
+na_object_id_set_copy_of_label( NAObjectId *object )
+{
+	gchar *label, *new_label;
+
+	g_return_if_fail( NA_IS_OBJECT_ID( object ));
+
+	if( !object->private->dispose_has_run ){
+
+		label = na_object_get_label( object );
+
+		/* i18n: copied items have a label as 'Copy of original label' */
+		new_label = g_strdup_printf( _( "Copy of %s" ), label );
+
+		na_object_set_label( object, new_label );
+
+		g_free( new_label );
+		g_free( label );
+	}
+}
+
+/**
+ * na_object_id_set_new_id:
+ * @object: the #NAObjectId object whose internal identifiant is to be
+ * set.
+ * @new_parent: if @object is a #NAObjectProfile, then @new_parent
+ * should be set to the #NAObjectActio new parent. Else, it would not
+ * be possible to allocate a new profile id compatible with already
+ * existing ones.
+ *
+ * Request a new id to the derived class, and set it.
+ */
+void
+na_object_id_set_new_id( NAObjectId *object, const NAObjectId *new_parent )
+{
+	gchar *id;
+
+	g_return_if_fail( NA_IS_OBJECT_ID( object ));
+	g_return_if_fail( !new_parent || NA_IS_OBJECT_ID( new_parent ));
+
+	if( !object->private->dispose_has_run ){
+
+		id = v_new_id( object, new_parent );
+
+		if( id ){
+			na_object_set_id( object, id );
+			g_free( id );
+		}
+	}
+}
+
+static gchar *
+v_new_id( const NAObjectId *object, const NAObjectId *new_parent )
+{
+	gchar *new_id;
+	GList *hierarchy, *ih;
+	gboolean found;
+
+	found = FALSE;
+	new_id = NULL;
+	hierarchy = g_list_reverse( na_object_get_hierarchy( NA_OBJECT( object )));
+	/*g_debug( "na_object_id_most_derived_id: object=%p (%s)",
+					( void * ) object, G_OBJECT_TYPE_NAME( object ));*/
+
+	for( ih = hierarchy ; ih && !found ; ih = ih->next ){
+		if( NA_OBJECT_ID_CLASS( ih->data )->new_id ){
+			new_id = NA_OBJECT_ID_CLASS( ih->data )->new_id( object, new_parent );
+			found = TRUE;
+		}
+		if( G_OBJECT_CLASS_TYPE( ih->data ) == NA_OBJECT_ID_TYPE ){
+			break;
+		}
+	}
+
+	na_object_free_hierarchy( hierarchy );
+
+	return( new_id );
+}
diff --git a/src/core/na-object-item.c b/src/core/na-object-item.c
index 99e2896..cc34752 100644
--- a/src/core/na-object-item.c
+++ b/src/core/na-object-item.c
@@ -33,6 +33,7 @@
 #endif
 
 #include <string.h>
+#include <uuid/uuid.h>
 
 #include <api/na-object-api.h>
 
@@ -59,11 +60,13 @@ struct NAObjectItemPrivate {
 
 static NAObjectIdClass *st_parent_class = NULL;
 
-static GType register_type( void );
-static void  class_init( NAObjectItemClass *klass );
-static void  instance_init( GTypeInstance *instance, gpointer klass );
-static void  instance_dispose( GObject *object );
-static void  instance_finalize( GObject *object );
+static GType  register_type( void );
+static void   class_init( NAObjectItemClass *klass );
+static void   instance_init( GTypeInstance *instance, gpointer klass );
+static void   instance_dispose( GObject *object );
+static void   instance_finalize( GObject *object );
+
+static gchar *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
 
 GType
 na_object_item_get_type( void )
@@ -108,6 +111,7 @@ class_init( NAObjectItemClass *klass )
 	static const gchar *thisfn = "na_object_item_class_init";
 	GObjectClass *object_class;
 	NAObjectClass *naobject_class;
+	NAObjectIdClass *naobjectid_class;
 
 	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
 
@@ -123,6 +127,9 @@ class_init( NAObjectItemClass *klass )
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = NULL;
 
+	naobjectid_class = NA_OBJECT_ID_CLASS( klass );
+	naobjectid_class->new_id = object_id_new_id;
+
 	klass->private = g_new0( NAObjectItemClassPrivate, 1 );
 }
 
@@ -182,6 +189,39 @@ instance_finalize( GObject *object )
 	}
 }
 
+/*
+ * 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
+ * check this
+ */
+static gchar *
+object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent )
+{
+	GList *childs, *it;
+	uuid_t uuid;
+	gchar uuid_str[64];
+	gchar *new_uuid = NULL;
+
+	g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), NULL );
+
+	if( !NA_OBJECT_ITEM( item )->private->dispose_has_run ){
+
+		/* recurse into NAObjectItems childs
+		 * i.e., if a menu, recurse into embedded actions
+		 */
+		childs = na_object_get_items( item );
+		for( it = childs ; it ; it = it->next ){
+			na_object_set_new_id( it->data, new_parent );
+		}
+
+		uuid_generate( uuid );
+		uuid_unparse_lower( uuid, uuid_str );
+		new_uuid = g_strdup( uuid_str );
+	}
+
+	return( new_uuid );
+}
+
 /**
  * na_object_item_copy:
  * @item: the target #NAObjectItem instance.
@@ -354,6 +394,36 @@ na_object_item_get_item( const NAObjectItem *item, const gchar *id )
 }
 
 /**
+ * na_object_item_get_position:
+ * @object: this #NAObjectItem object.
+ * @child: a #NAObjectId-derived child.
+ *
+ * Returns: the position of @child in the subitems list of @object,
+ * starting from zero, or -1 if not found.
+ */
+gint
+na_object_item_get_position( const NAObjectItem *object, const NAObjectId *child )
+{
+	gint pos = -1;
+	GList *childs;
+
+	g_return_val_if_fail( NA_IS_OBJECT_ITEM( object ), pos );
+	g_return_val_if_fail( NA_IS_OBJECT_ID( child ), pos );
+
+	if( !child ){
+		return( pos );
+	}
+
+	if( !object->private->dispose_has_run ){
+
+		childs = na_object_get_items( object );
+		pos = g_list_index( childs, ( gconstpointer ) child );
+	}
+
+	return( pos );
+}
+
+/**
  * na_object_item_append_item:
  * @item: the #NAObjectItem to which add the subitem.
  * @child: a #NAObjectId to be added to list of subitems.
@@ -385,6 +455,69 @@ na_object_item_append_item( NAObjectItem *item, const NAObjectId *child )
 }
 
 /**
+ * na_object_item_insert_at:
+ * @item: the #NAObjectItem in which add the subitem.
+ * @object: a #NAObjectId-derived to be inserted in the list of subitems.
+ * @pos: the position at which the @object child should be inserted.
+ *
+ * Inserts a new @object in the list of subitems of @item.
+ *
+ * Doesn't modify the reference count on @object.
+ */
+void
+na_object_item_insert_at( NAObjectItem *item, const NAObjectId *object, gint pos )
+{
+	GList *childs, *it;
+	gint i;
+
+	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
+	g_return_if_fail( NA_IS_OBJECT_ID( object ));
+
+	if( !item->private->dispose_has_run ){
+
+		childs = na_object_get_items( item );
+		if( pos == -1 || pos >= g_list_length( childs )){
+			na_object_append_item( item, object );
+
+		} else {
+			i = 0;
+			for( it = childs ; it && i <= pos ; it = it->next ){
+				if( i == pos ){
+					childs = g_list_insert_before( childs, it, ( gpointer ) object );
+				}
+				i += 1;
+			}
+			na_object_set_items( item, childs );
+		}
+	}
+}
+
+/**
+ * na_object_item_remove_item:
+ * @item: the #NAObjectItem from which the subitem must be removed.
+ * @object: a #NAObjectId-derived to be removed from the list of subitems.
+ *
+ * Removes an @object from the list of subitems of @item.
+ *
+ * Doesn't modify the reference count on @object.
+ */
+void
+na_object_item_remove_item( NAObjectItem *item, const NAObjectId *object )
+{
+	GList *childs;
+
+	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
+	g_return_if_fail( NA_IS_OBJECT_ID( object ));
+
+	if( !item->private->dispose_has_run ){
+
+		childs = na_object_get_items( item );
+		childs = g_list_remove( childs, ( gconstpointer ) object );
+		na_object_set_items( item, childs );
+	}
+}
+
+/**
  * na_object_item_build_items_slist:
  * @item: this #NAObjectItem object.
  *
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 5fc8d88..cec0619 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -82,6 +82,8 @@ static gchar   *idata_factory_get_default( const NAIDataFactory *instance, const
 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 gchar   *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
+
 static gboolean is_target_background_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
 static gboolean is_target_toolbar_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
 static gboolean is_current_folder_inside( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
@@ -149,6 +151,7 @@ class_init( NAObjectProfileClass *klass )
 	static const gchar *thisfn = "na_object_profile_class_init";
 	GObjectClass *object_class;
 	NAObjectClass *naobject_class;
+	NAObjectIdClass *naobjectid_class;
 
 	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
 
@@ -166,6 +169,9 @@ class_init( NAObjectProfileClass *klass )
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = NULL;
 
+	naobjectid_class = NA_OBJECT_ID_CLASS( klass );
+	naobjectid_class->new_id = object_id_new_id;
+
 	klass->private = g_new0( NAObjectProfileClassPrivate, 1 );
 
 	na_data_factory_properties( object_class );
@@ -314,6 +320,26 @@ idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer,
 
 }
 
+/*
+ * new_parent is specifically set to be able to allocate a new id for
+ * the current profile into the target parent
+ */
+static gchar *
+object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent )
+{
+	gchar *id = NULL;
+
+	g_return_val_if_fail( NA_IS_OBJECT_PROFILE( item ), NULL );
+	g_return_val_if_fail( new_parent && NA_IS_OBJECT_ACTION( new_parent ), NULL );
+
+	if( !NA_OBJECT_PROFILE( item )->private->dispose_has_run ){
+
+		id = na_object_action_get_new_profile_name( NA_OBJECT_ACTION( new_parent ));
+	}
+
+	return( id );
+}
+
 /**
  * na_object_profile_new:
  *
diff --git a/src/core/na-object.c b/src/core/na-object.c
index 7dd0478..8704141 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -545,38 +545,44 @@ dump_tree( GList *tree, gint level )
 }
 
 /**
- * na_object_get_hierarchy:
+ * na_object_object_reset_origin:
+ * @object: a #NAObject-derived object.
+ * @origin: must be a duplication of @object.
  *
- * Returns the class hierarchy,
- * from the topmost base class, to the most-derived one.
+ * Recursively reset origin of @object and its childs to @origin and
+ * its childs), so that @origin appear as the actual origin of @object.
  *
- * The returned list should be released with g_list_free() by the caller.
+ * The origin of @origin itself is set to NULL.
+ *
+ * This only works if @origin has just been duplicated from @object,
+ * and thus we do not have to check if childs lists are equal.
  */
-#if 0
-GList *
-na_object_object_get_hierarchy( const NAObject *object )
+void
+na_object_object_reset_origin( NAObject *object, const NAObject *origin )
 {
-	GList *hierarchy = NULL;
-	GObjectClass *class;
-
-	g_return_val_if_fail( NA_IS_OBJECT( object ), NULL );
-
-	if( !object->private->dispose_has_run ){
+	GList *origin_childs, *iorig;
+	GList *object_childs, *iobj;
+	NAObject *orig_object;
 
-		class = G_OBJECT_GET_CLASS( object );
+	g_return_if_fail( NA_IS_OBJECT( origin ));
+	g_return_if_fail( NA_IS_OBJECT( object ));
 
-		while( G_OBJECT_CLASS_TYPE( class ) != NA_OBJECT_TYPE ){
+	if( !object->private->dispose_has_run && !origin->private->dispose_has_run ){
 
-			hierarchy = g_list_prepend( hierarchy, class );
-			class = g_type_class_peek_parent( class );
+		origin_childs = na_object_get_items( origin );
+		object_childs = na_object_get_items( object );
+		for( iorig = origin_childs, iobj = object_childs ; iorig && iobj ; iorig = iorig->next, iobj = iobj->next ){
+			orig_object = ( NAObject * ) na_object_get_origin( iorig->data );
+			g_return_if_fail( orig_object == iobj->data );
+			na_object_reset_origin( iobj->data, iorig->data );
 		}
 
-		hierarchy = g_list_prepend( hierarchy, class );
+		orig_object = ( NAObject * ) na_object_get_origin( origin );
+		g_return_if_fail( orig_object == object );
+		na_iduplicable_set_origin( NA_IDUPLICABLE( object ), NA_IDUPLICABLE( origin ));
+		na_iduplicable_set_origin( NA_IDUPLICABLE( origin ), NULL );
 	}
-
-	return( hierarchy );
 }
-#endif
 
 /**
  * na_object_object_ref:
@@ -693,3 +699,35 @@ build_class_hierarchy( const NAObject *object )
 
 	return( hierarchy );
 }
+
+/**
+ * na_object_object_get_hierarchy:
+ *
+ * Returns the class hierarchy,
+ * from the topmost base class, to the most-derived one.
+ */
+GList *
+na_object_object_get_hierarchy( const NAObject *object )
+{
+	GList *hierarchy;
+
+	g_return_val_if_fail( NA_IS_OBJECT( object ), NULL );
+
+	hierarchy = NULL;
+
+	if( !object->private->dispose_has_run ){
+
+		hierarchy = build_class_hierarchy( object );
+	}
+
+	return( hierarchy );
+}
+
+/**
+ * na_object_free_hierarchy:
+ */
+void
+na_object_free_hierarchy( GList *hierarchy )
+{
+	g_list_free( hierarchy );
+}
diff --git a/src/core/na-pivot.c b/src/core/na-pivot.c
index ce4c171..aad33ba 100644
--- a/src/core/na-pivot.c
+++ b/src/core/na-pivot.c
@@ -87,6 +87,7 @@ struct NAPivotPrivate {
  */
 enum {
 	NAPIVOT_PROP_LOADABLE_SET_ID = 1,
+	NAPIVOT_PROP_TREE_ID,
 };
 
 static GObjectClass *st_parent_class = NULL;
@@ -191,6 +192,13 @@ class_init( NAPivotClass *klass )
 			"Nature of population to be loaded", 0, UINT_MAX, 0,
 			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, NAPIVOT_PROP_LOADABLE_SET_ID, spec );
+
+	spec = g_param_spec_pointer(
+			NAPIVOT_PROP_TREE,
+			"Items tree",
+			"Hierarchical tree of items",
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, NAPIVOT_PROP_TREE_ID, spec );
 }
 
 static void
@@ -254,6 +262,10 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 				g_value_set_uint( value, self->private->loadable_set );
 				break;
 
+			case NAPIVOT_PROP_TREE_ID:
+				g_value_set_pointer( value, self->private->tree );
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
 				break;
@@ -276,6 +288,10 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 				self->private->loadable_set = g_value_get_uint( value );
 				break;
 
+			case NAPIVOT_PROP_TREE_ID:
+				self->private->tree = g_value_get_pointer( value );
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
 				break;
diff --git a/src/core/na-pivot.h b/src/core/na-pivot.h
index 7f044b1..a7dbccb 100644
--- a/src/core/na-pivot.h
+++ b/src/core/na-pivot.h
@@ -116,9 +116,10 @@ typedef enum {
 }
 	NAPivotLoadableSet;
 
-/* these properties must be set at construction time
+/* properties
  */
 #define NAPIVOT_PROP_LOADABLE_SET		"na-pivot-prop-loadable-set"
+#define NAPIVOT_PROP_TREE				"na-pivot-prop-tree"
 
 NAPivot      *na_pivot_new( NAPivotLoadableSet loadable );
 void          na_pivot_dump( const NAPivot *pivot );
diff --git a/src/core/na-updater.c b/src/core/na-updater.c
index 7698e3f..feb934a 100644
--- a/src/core/na-updater.c
+++ b/src/core/na-updater.c
@@ -188,6 +188,67 @@ na_updater_new( NAPivotLoadableSet loadable )
 }
 
 /**
+ * na_updater_add_item:
+ * @updater: this #NAUpdater instance.
+ * @item: the #NAObjectItem to be added to the list.
+ *
+ * Adds a new item to the list.
+ *
+ * We take the provided pointer. The provided @item should so not
+ * be g_object_unref() by the caller.
+ */
+void
+na_updater_add_item( NAUpdater *updater, const NAObjectItem *item )
+{
+	GList *tree;
+
+	g_return_if_fail( NA_IS_UPDATER( updater ));
+	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
+
+	if( !updater->private->dispose_has_run ){
+
+		g_object_get( G_OBJECT( updater ), NAPIVOT_PROP_TREE, &tree, NULL );
+		tree = g_list_append( tree, ( gpointer ) item );
+		g_object_set( G_OBJECT( updater ), NAPIVOT_PROP_TREE, &tree, NULL );
+	}
+}
+
+/**
+ * na_updater_remove_item:
+ * @updater: this #NAPivot instance.
+ * @item: the #NAObjectItem to be removed from the list.
+ *
+ * Removes a #NAObjectItem from the hierarchical tree.
+ *
+ * Note that #NAUpdater also g_object_unref() the removed #NAObjectItem.
+ *
+ * Last, note that the @item may have been already deleted, when its
+ * parents has itself been removed from @updater.
+ */
+void
+na_updater_remove_item( NAUpdater *updater, NAObject *item )
+{
+	GList *tree;
+
+	g_debug( "na_updater_remove_item: updater=%p, item=%p (%s)",
+			( void * ) updater,
+			( void * ) item, G_IS_OBJECT( item ) ? G_OBJECT_TYPE_NAME( item ) : "(null)" );
+
+	g_return_if_fail( NA_IS_PIVOT( updater ));
+
+	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 )){
+			na_object_unref( item );
+		}
+	}
+}
+
+/**
  * na_updater_is_item_writable:
  * @updater: this #NAUpdater object.
  * @item: the #NAObjectItem to be written.
diff --git a/src/core/na-updater.h b/src/core/na-updater.h
index bed690b..de2926e 100644
--- a/src/core/na-updater.h
+++ b/src/core/na-updater.h
@@ -71,9 +71,15 @@ GType      na_updater_get_type( void );
 
 NAUpdater *na_updater_new( NAPivotLoadableSet loadable );
 
-gboolean   na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item, gint *reason );
+/* update the tree in memory
+ */
+void       na_updater_add_item   ( NAUpdater *updater, const NAObjectItem *item );
+void       na_updater_remove_item( NAUpdater *updater, NAObject *item );
 
-guint      na_updater_write_item( const NAUpdater *updater, NAObjectItem *item, GSList **messages );
+/* read from / write to the physical storage subsystem
+ */
+gboolean   na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item, gint *reason );
+guint      na_updater_write_item      ( const NAUpdater *updater, NAObjectItem *item, GSList **messages );
 
 G_END_DECLS
 
diff --git a/src/nact/nact-export-format.c b/src/nact/nact-export-format.c
index e05b2b8..d73daac 100755
--- a/src/nact/nact-export-format.c
+++ b/src/nact/nact-export-format.c
@@ -102,7 +102,7 @@ draw_in_vbox( const NAExportFormat *format, GtkWidget *container, guint mode )
 	gchar *description;
 	GtkHBox *hbox1, *hbox2;
 	GtkRadioButton *button;
-	guint indicator_size;
+	guint size, spacing;
 	GtkLabel *radio_label;
 	gchar *markup, *label;
 	GtkLabel *desc_label;
@@ -151,13 +151,13 @@ draw_in_vbox( const NAExportFormat *format, GtkWidget *container, guint mode )
 	switch( mode ){
 
 		case EXPORT_FORMAT_DISPLAY_ASSISTANT:
-			/* TODO: get radio button indicator size */
-			/*g_object_get( G_OBJECT( GTK_CHECK_BUTTON( button )), "indicator-size", &indicator_size, NULL );*/
-			indicator_size = 17;
+			gtk_widget_style_get( GTK_WIDGET( button ), "indicator-size", &size, NULL );
+			gtk_widget_style_get( GTK_WIDGET( button ), "indicator-spacing", &spacing, NULL );
+			size += 2*spacing;
 			hbox2 = GTK_HBOX( gtk_hbox_new( TRUE, 0 ));
 			gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox2 ), FALSE, TRUE, 0 );
 			desc_label = GTK_LABEL( gtk_label_new( description ));
-			g_object_set( G_OBJECT( desc_label ), "xpad", indicator_size, NULL );
+			g_object_set( G_OBJECT( desc_label ), "xpad", size, NULL );
 			gtk_box_pack_start( GTK_BOX( hbox2 ), GTK_WIDGET( desc_label ), TRUE, TRUE, 4 );
 			break;
 	}
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index 78cda20..ca51e70 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -36,9 +36,10 @@
 
 #include <api/na-object-api.h>
 
-#include <runtime/na-iabout.h>
-#include <runtime/na-iprefs.h>
-#include <runtime/na-ipivot-consumer.h>
+#include <core/na-iabout.h>
+#include <core/na-iprefs.h>
+#include <core/na-ipivot-consumer.h>
+#include <core/na-io-provider.h>
 
 #include "nact-application.h"
 #include "nact-assistant-export.h"
@@ -116,7 +117,7 @@ static void     on_new_menu_activated( GtkAction *action, NactMainWindow *window
 static void     on_new_action_activated( GtkAction *action, NactMainWindow *window );
 static void     on_new_profile_activated( GtkAction *action, NactMainWindow *window );
 static void     on_save_activated( GtkAction *action, NactMainWindow *window );
-static void     save_item( NactMainWindow *window, NAPivot *pivot, NAObjectItem *item );
+static void     save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item );
 static void     on_quit_activated( GtkAction *action, NactMainWindow *window );
 
 static void     on_cut_activated( GtkAction *action, NactMainWindow *window );
@@ -596,7 +597,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_main_menubar_on_update_sensitivities";
 	NactApplication *application;
-	NAPivot *pivot;
+	NAUpdater *updater;
 	gboolean is_level_zero_writable;
 	gboolean has_writable_providers;
 	gboolean has_modified_items;
@@ -624,8 +625,8 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
 
 	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	pivot = nact_application_get_pivot( application );
-	is_level_zero_writable = na_pivot_is_level_zero_writable( pivot );
+	updater = nact_application_get_updater( application );
+	is_level_zero_writable = na_pivot_is_level_zero_writable( NA_PIVOT( updater ));
 
 	has_writable_providers = nact_window_has_writable_providers( NACT_WINDOW( window ));
 	g_debug( "%s: has_writable_providers=%s", thisfn, has_writable_providers ? "True":"False" );
@@ -638,7 +639,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 			? ( NAObject * ) na_object_get_parent( selected_items->data )
 			: NULL;
 	is_first_parent_writable = first_parent
-			? na_pivot_is_item_writable( pivot, NA_OBJECT_ITEM( first_parent ), NULL )
+			? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( first_parent ), NULL )
 			: is_level_zero_writable;
 
 	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
@@ -688,7 +689,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 	enable_item( window, "NewProfileItem",
 			new_profile_enabled &&
 			selected_action != NULL &&
-			na_pivot_is_item_writable( pivot, NA_OBJECT_ITEM( selected_action ), NULL ));
+			nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( selected_action ), NULL ));
 
 	/* save enabled if at least one item has been modified
 	 * or level-zero has been resorted and is writable
@@ -707,7 +708,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 	for( is = selected_items ; is ; is = is->next ){
 		parent_item = ( NAObject * ) na_object_get_parent( is->data );
 		if( parent_item ){
-			if( !na_pivot_is_item_writable( pivot, NA_OBJECT_ITEM( parent_item ), NULL )){
+			if( !na_updater_is_item_writable( updater, NA_OBJECT_ITEM( parent_item ), NULL )){
 				are_parents_writable = FALSE;
 				break;
 			}
@@ -745,7 +746,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 							? na_object_get_parent( selected_items->data )
 							: selected_items->data );
 			paste_enabled &= NA_IS_OBJECT_ACTION( selected_action );
-			paste_enabled &= na_pivot_is_item_writable( pivot, NA_OBJECT_ITEM( selected_action ), NULL );
+			paste_enabled &= na_updater_is_item_writable( updater, NA_OBJECT_ITEM( selected_action ), NULL );
 		}
 	} else {
 		paste_enabled &= has_writable_providers;
@@ -755,7 +756,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 			if( paste_enabled ){
 				parent_item = ( NAObject * ) na_object_get_parent( selected_item );
 				paste_enabled &= parent_item
-						? na_pivot_is_item_writable( pivot, NA_OBJECT_ITEM( parent_item ), NULL )
+						? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( parent_item ), NULL )
 						: is_level_zero_writable;
 			}
 		} else {
@@ -782,7 +783,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 		if( paste_enabled ){
 			selected_action = NA_OBJECT( selected_items->data );
 			paste_enabled &= NA_IS_OBJECT_ACTION( selected_action );
-			paste_enabled &= na_pivot_is_item_writable( pivot, NA_OBJECT_ITEM( selected_action ), NULL );
+			paste_enabled &= nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( selected_action ), NULL );
 		}
 	} else {
 		paste_enabled &= has_writable_providers;
@@ -792,7 +793,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 			if( paste_enabled ){
 				parent_item = ( NAObject * ) na_object_get_parent( selected_item );
 				paste_enabled &= parent_item
-						? na_pivot_is_item_writable( pivot, NA_OBJECT_ITEM( parent_item ), NULL )
+						? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( parent_item ), NULL )
 						: is_level_zero_writable;
 			}
 		} else {
@@ -833,7 +834,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 
 	/* about always enabled */
 
-	na_object_free_items_list( selected_items );
+	na_object_unref_items( selected_items );
 }
 
 static void
@@ -849,7 +850,7 @@ on_new_menu_activated( GtkAction *gtk_action, NactMainWindow *window )
 	na_object_check_status( menu );
 	items = g_list_prepend( NULL, menu );
 	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-	na_object_free_items_list( items );
+	na_object_unref_items( items );
 }
 
 static void
@@ -865,7 +866,7 @@ on_new_action_activated( GtkAction *gtk_action, NactMainWindow *window )
 	na_object_check_status( action );
 	items = g_list_prepend( NULL, action );
 	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-	na_object_free_items_list( items );
+	na_object_unref_items( items );
 }
 
 static void
@@ -894,7 +895,7 @@ on_new_profile_activated( GtkAction *gtk_action, NactMainWindow *window )
 	items = g_list_prepend( NULL, profile );
 	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
 
-	na_object_free_items_list( items );
+	na_object_unref_items( items );
 	g_free( name );
 }
 
@@ -924,7 +925,7 @@ nact_main_menubar_save_items( NactMainWindow *window )
 	static const gchar *thisfn = "nact_main_menubar_save_items";
 	GList *items, *it;
 	NactApplication *application;
-	NAPivot *pivot;
+	NAUpdater *updater;
 	MenubarIndicatorsStruct *mis;
 
 	g_debug( "%s: window=%p", thisfn, ( void * ) window );
@@ -939,9 +940,9 @@ nact_main_menubar_save_items( NactMainWindow *window )
 	 * and reset the corresponding modification flag
 	 */
 	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	pivot = nact_application_get_pivot( application );
+	updater = nact_application_get_updater( application );
 	items = nact_iactions_list_bis_get_items( NACT_IACTIONS_LIST( window ));
-	na_pivot_write_level_zero( pivot, items );
+	na_pivot_write_level_zero( NA_PIVOT( updater ), items );
 
 	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
 	mis->level_zero_order_changed = FALSE;
@@ -952,7 +953,7 @@ nact_main_menubar_save_items( NactMainWindow *window )
 	 * recursively each and every modified item
 	 */
 	for( it = items ; it ; it = it->next ){
-		save_item( window, pivot, NA_OBJECT_ITEM( it->data ));
+		save_item( window, updater, NA_OBJECT_ITEM( it->data ));
 		na_object_check_status( it->data );
 	}
 	g_list_free( items );
@@ -970,7 +971,7 @@ nact_main_menubar_save_items( NactMainWindow *window )
  *   for save their subitems
  */
 static void
-save_item( NactMainWindow *window, NAPivot *pivot, NAObjectItem *item )
+save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item )
 {
 	NAObjectItem *origin;
 	NAObjectItem *dup_pivot;
@@ -981,13 +982,13 @@ save_item( NactMainWindow *window, NAPivot *pivot, NAObjectItem *item )
 	NAIOProvider *provider_after;
 
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-	g_return_if_fail( NA_IS_PIVOT( pivot ));
+	g_return_if_fail( NA_IS_UPDATER( updater ));
 	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
 
 	if( NA_IS_OBJECT_MENU( item )){
-		subitems = na_object_get_items_list( item );
+		subitems = na_object_get_items( item );
 		for( it = subitems ; it ; it = it->next ){
-			save_item( window, pivot, NA_OBJECT_ITEM( it->data ));
+			save_item( window, updater, NA_OBJECT_ITEM( it->data ));
 		}
 	}
 
@@ -997,7 +998,7 @@ save_item( NactMainWindow *window, NAPivot *pivot, NAObjectItem *item )
 		nact_window_save_item( NACT_WINDOW( window ), item )){
 
 			if( NA_IS_OBJECT_ACTION( item )){
-				na_object_action_reset_last_allocated( NA_OBJECT_ACTION( item ));
+				na_object_reset_last_allocated( item );
 			}
 
 			/* do not use NA_OBJECT_ITEM macro as this may return a
@@ -1013,7 +1014,7 @@ save_item( NactMainWindow *window, NAPivot *pivot, NAObjectItem *item )
 					pos = na_object_get_position( parent, origin );
 					na_object_remove_item( parent, origin );
 				} else {
-					na_pivot_remove_item( pivot, NA_OBJECT( origin ));
+					na_updater_remove_item( updater, NA_OBJECT( origin ));
 				}
 			}
 
@@ -1027,7 +1028,7 @@ save_item( NactMainWindow *window, NAPivot *pivot, NAObjectItem *item )
 					na_object_insert_at( parent, dup_pivot, pos );
 				}
 			} else {
-				na_pivot_add_item( pivot, dup_pivot );
+				na_updater_add_item( updater, dup_pivot );
 			}
 
 			nact_iactions_list_bis_removed_modified( NACT_IACTIONS_LIST( window ), item );
@@ -1110,7 +1111,7 @@ on_copy_activated( GtkAction *gtk_action, NactMainWindow *window )
 	clipboard = nact_main_window_get_clipboard( window );
 	nact_clipboard_primary_set( clipboard, items, CLIPBOARD_MODE_COPY );
 	update_clipboard_counters( window );
-	na_object_free_items_list( items );
+	na_object_unref_items( items );
 
 	g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
 }
@@ -1138,7 +1139,7 @@ on_paste_activated( GtkAction *gtk_action, NactMainWindow *window )
 	items = prepare_for_paste( window );
 	if( items ){
 		nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-		na_object_free_items_list( items );
+		na_object_unref_items( items );
 	}
 }
 
@@ -1165,7 +1166,7 @@ on_paste_into_activated( GtkAction *gtk_action, NactMainWindow *window )
 	items = prepare_for_paste( window );
 	if( items ){
 		nact_iactions_list_bis_insert_into( NACT_IACTIONS_LIST( window ), items );
-		na_object_free_items_list( items );
+		na_object_unref_items( items );
 	}
 }
 
@@ -1179,10 +1180,10 @@ prepare_for_paste( NactMainWindow *window )
 	gboolean relabel;
 	gboolean renumber;
 	NactApplication *application;
-	NAPivot *pivot;
+	NAUpdater *updater;
 
 	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	pivot = nact_application_get_pivot( application );
+	updater = nact_application_get_updater( application );
 
 	clipboard = nact_main_window_get_clipboard( window );
 	items = nact_clipboard_primary_get( clipboard, &renumber );
@@ -1199,7 +1200,7 @@ prepare_for_paste( NactMainWindow *window )
 			}
 		}
 
-		relabel = nact_main_menubar_is_pasted_object_relabeled( NA_OBJECT( it->data ), pivot );
+		relabel = nact_main_menubar_is_pasted_object_relabeled( NA_OBJECT( it->data ), NA_PIVOT( updater ));
 		na_object_prepare_for_paste( it->data, relabel, renumber, action );
 		na_object_check_status( it->data );
 	}
@@ -1223,7 +1224,7 @@ on_duplicate_activated( GtkAction *gtk_action, NactMainWindow *window )
 {
 	static const gchar *thisfn = "nact_main_menubar_on_duplicate_activated";
 	NactApplication *application;
-	NAPivot *pivot;
+	NAUpdater *updater;
 	NAObjectAction *action;
 	GList *items, *it;
 	GList *dup;
@@ -1235,7 +1236,7 @@ on_duplicate_activated( GtkAction *gtk_action, NactMainWindow *window )
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
 
 	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	pivot = nact_application_get_pivot( application );
+	updater = nact_application_get_updater( application );
 
 	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
 	for( it = items ; it ; it = it->next ){
@@ -1249,16 +1250,16 @@ on_duplicate_activated( GtkAction *gtk_action, NactMainWindow *window )
 			action = NA_OBJECT_ACTION( na_object_get_parent( it->data ));
 		}
 
-		relabel = nact_main_menubar_is_pasted_object_relabeled( obj, pivot );
+		relabel = nact_main_menubar_is_pasted_object_relabeled( obj, NA_PIVOT( updater ));
 		na_object_prepare_for_paste( obj, relabel, TRUE, action );
 		na_object_set_origin( obj, NULL );
 		na_object_check_status( obj );
 		dup = g_list_prepend( NULL, obj );
 		nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), dup, it->data );
-		na_object_free_items_list( dup );
+		na_object_unref_items( dup );
 	}
 
-	na_object_free_items_list( items );
+	na_object_unref_items( items );
 }
 
 /*
@@ -1400,7 +1401,7 @@ on_dump_selection_activated( GtkAction *action, NactMainWindow *window )
 		na_object_dump( it->data );
 	}
 
-	na_object_free_items_list( items );
+	na_object_unref_items( items );
 }
 
 static void



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