[nautilus-actions] NactTreeIEditable: inserting new items



commit dd7f51ef0e0af5a5f1c8ea0eb5bf56782fd9273e
Author: Pierre Wieser <pwieser trychlos org>
Date:   Fri Feb 4 22:41:06 2011 +0100

    NactTreeIEditable: inserting new items

 src/api/na-iduplicable.h          |    2 +-
 src/core/na-factory-object.c      |   19 +-
 src/core/na-iduplicable.c         |   59 +-
 src/core/na-object-profile.c      |    7 +-
 src/core/na-object.c              |   21 +-
 src/nact/nact-assistant-import.c  |   11 +-
 src/nact/nact-clipboard.c         |    2 +-
 src/nact/nact-iaction-tab.c       |   15 +-
 src/nact/nact-ibasenames-tab.c    |   13 +-
 src/nact/nact-icapabilities-tab.c |   13 +-
 src/nact/nact-icommand-tab.c      |   17 +-
 src/nact/nact-ienvironment-tab.c  |   16 +-
 src/nact/nact-iexecution-tab.c    |   11 +-
 src/nact/nact-ifolders-tab.c      |   13 +-
 src/nact/nact-imimetypes-tab.c    |   13 +-
 src/nact/nact-iproperties-tab.c   |   10 +-
 src/nact/nact-ischemes-tab.c      |   13 +-
 src/nact/nact-main-window.c       |   59 ++-
 src/nact/nact-main-window.h       |    3 +-
 src/nact/nact-menubar.c           |  142 ++--
 src/nact/nact-tree-ieditable.c    | 1425 ++++++++++++++++---------------------
 src/nact/nact-tree-ieditable.h    |   20 +-
 src/nact/nact-tree-model-dnd.c    |   16 +-
 src/nact/nact-tree-model.c        |  479 ++++++-------
 src/nact/nact-tree-model.h        |   26 +-
 src/nact/nact-tree-view.c         |  222 +++++--
 src/nact/nact-tree-view.h         |    3 +
 27 files changed, 1271 insertions(+), 1379 deletions(-)
---
diff --git a/src/api/na-iduplicable.h b/src/api/na-iduplicable.h
index 70db6d7..61b5d47 100644
--- a/src/api/na-iduplicable.h
+++ b/src/api/na-iduplicable.h
@@ -184,7 +184,7 @@ typedef struct {
 }
 	NAIDuplicableInterface;
 
-#define NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED	"status-changed"
+#define NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED	"iduplicable-status-changed"
 
 GType          na_iduplicable_get_type( void );
 
diff --git a/src/core/na-factory-object.c b/src/core/na-factory-object.c
index cc8ac09..79d0b7f 100644
--- a/src/core/na-factory-object.c
+++ b/src/core/na-factory-object.c
@@ -493,12 +493,15 @@ na_factory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *
 gboolean
 na_factory_object_is_valid( const NAIFactoryObject *object )
 {
+	static const gchar *thisfn = "na_factory_object_is_valid";
 	gboolean is_valid;
 	NADataGroup *groups;
 	GList *list, *iv;
 
 	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), FALSE );
 
+	g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
 	list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
 	is_valid = TRUE;
 
@@ -855,15 +858,11 @@ na_factory_object_set_from_void( NAIFactoryObject *object, const gchar *name, co
 static NADataGroup *
 v_get_groups( const NAIFactoryObject *object )
 {
-	NADataGroup *groups;
-
-	groups = NULL;
-
 	if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_groups ){
-		groups = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_groups( object );
+		return( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_groups( object ));
 	}
 
-	return( groups );
+	return( NULL );
 }
 
 static void
@@ -891,15 +890,11 @@ v_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b )
 static gboolean
 v_is_valid( const NAIFactoryObject *object )
 {
-	gboolean is_valid;
-
-	is_valid = TRUE;
-
 	if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid ){
-		is_valid = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid( object );
+		return( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid( object ));
 	}
 
-	return( is_valid );
+	return( FALSE );
 }
 
 static void
diff --git a/src/core/na-iduplicable.c b/src/core/na-iduplicable.c
index 66906e0..ef30b75 100644
--- a/src/core/na-iduplicable.c
+++ b/src/core/na-iduplicable.c
@@ -46,7 +46,6 @@ typedef struct {
 	NAIDuplicable *origin;
 	gboolean       modified;
 	gboolean       valid;
-	gulong         status_changed_handler_id;
 }
 	DuplicableStr;
 
@@ -74,8 +73,8 @@ static gboolean       v_is_valid( const NAIDuplicable *object );
 
 static DuplicableStr *get_duplicable_str( const NAIDuplicable *object );
 
-static void           status_changed_handler( NAIDuplicable *instance, gpointer user_data );
-static void           propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpointer user_data );
+static void           on_status_changed_class_handler( NAIDuplicable *instance );
+static void           propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal );
 static void           release_signal_consumers( GList *consumers );
 
 GType
@@ -139,18 +138,25 @@ interface_base_init( NAIDuplicableInterface *klass )
 		 *
 		 * This signal is emitted by #NAIDuplicable when the modification
 		 * or the validity status of an object has been modified.
+		 *
+		 * The default class handler propagates the signal to registered
+		 * consumers.
+		 *
+		 * Signal args: None
+		 *
+		 * Handler prototype:
+		 * void ( *handler )( NAIDuplicable *duplicable, gpointer user_data );
 		 */
-		st_signals[ STATUS_CHANGED ] = g_signal_new(
+		st_signals[ STATUS_CHANGED ] = g_signal_new_class_handler(
 				NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
 				G_TYPE_OBJECT,
 				G_SIGNAL_RUN_LAST,
-				0,						/* no default handler */
+				G_CALLBACK( on_status_changed_class_handler ),
 				NULL,
 				NULL,
-				g_cclosure_marshal_VOID__POINTER,
+				g_cclosure_marshal_VOID__VOID,
 				G_TYPE_NONE,
-				1,
-				G_TYPE_POINTER );
+				0 );
 
 		st_interface = klass;
 
@@ -194,10 +200,6 @@ na_iduplicable_dispose( const NAIDuplicable *object )
 
 		str = get_duplicable_str( object );
 
-		if( g_signal_handler_is_connected(( gpointer ) object, str->status_changed_handler_id )){
-			g_signal_handler_disconnect(( gpointer ) object, str->status_changed_handler_id );
-		}
-
 		g_free( str );
 	}
 }
@@ -331,7 +333,7 @@ na_iduplicable_check_status( const NAIDuplicable *object )
 		changed = FALSE;
 
 		if( str->origin ){
-			g_debug( "%s: origin=%p (%s)", thisfn, ( void * ) str->origin, G_OBJECT_TYPE_NAME( str->origin ));
+			g_debug( "%s: vs. origin=%p (%s)", thisfn, ( void * ) str->origin, G_OBJECT_TYPE_NAME( str->origin ));
 			g_return_if_fail( NA_IS_IDUPLICABLE( str->origin ));
 			str->modified = !v_are_equal( str->origin, object );
 
@@ -362,7 +364,7 @@ na_iduplicable_check_status( const NAIDuplicable *object )
 		}
 
 		if( changed ){
-			g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED, object );
+			g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED );
 		}
 
 #if 0
@@ -509,7 +511,7 @@ na_iduplicable_set_modified( NAIDuplicable *object, gboolean modified )
 
 		if( str->modified != modified ){
 			str->modified = modified;
-			g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED, object );
+			g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED );
 		}
 	}
 }
@@ -565,20 +567,18 @@ na_iduplicable_register_consumer( GObject *consumer )
 }
 
 static void
-status_changed_handler( NAIDuplicable *instance, gpointer user_data )
+on_status_changed_class_handler( NAIDuplicable *instance )
 {
-	/*g_debug( "na_iduplicable_propagate_modified_changed: instance=%p (%s), user_data=%p (%s)",
-			( void * ) instance, G_OBJECT_TYPE_NAME( instance ),
-			( void * ) user_data, G_OBJECT_TYPE_NAME( user_data ));*/
+	/*
+	static const gchar *thisfn = "na_iduplicable_on_status_changed_class_handler";
+	g_debug( "%s: instance=%p (%s)", thisfn,  ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
+	*/
 
-	propagate_signal_to_consumers( NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED, instance, user_data );
+	propagate_signal_to_consumers( instance, NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED );
 }
 
-/*
- * note that propagating the signal to consumers re-triggers
- */
 static void
-propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpointer user_data )
+propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal )
 {
 	static const gchar *thisfn = "na_iduplicable_propagate_signals_to_consumers";
 	GList *ic;
@@ -586,11 +586,10 @@ propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpo
 	g_return_if_fail( st_interface );
 
 	if( st_initialized && !st_finalized ){
-
-		g_debug( "%s: signal=%s, instance=%p, user_data=%p", thisfn, signal, ( void * ) instance, ( void * ) user_data );
+		g_debug( "%s: instance=%p, signal=%s", thisfn, ( void * ) instance, signal );
 
 		for( ic = st_interface->private->consumers ; ic ; ic = ic->next ){
-			g_signal_emit_by_name( ic->data, signal, user_data );
+			g_signal_emit_by_name( ic->data, signal );
 		}
 	}
 }
@@ -615,12 +614,6 @@ get_duplicable_str( const NAIDuplicable *object )
 		str->modified = FALSE;
 		str->valid = TRUE;
 
-		str->status_changed_handler_id = g_signal_connect(
-				G_OBJECT( object ),
-				NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
-				G_CALLBACK( status_changed_handler ),
-				( gpointer ) object );
-
 		g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_DATA_DUPLICABLE, str );
 	}
 
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 618f775..53518d2 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -321,13 +321,12 @@ ifactory_object_get_groups( const NAIFactoryObject *instance )
 static gboolean
 ifactory_object_is_valid( const NAIFactoryObject *object )
 {
-	static const gchar *thisfn = "na_object_profile_ifactory_object_is_valid: object";
-
-	g_debug( "%s: object=%p (%s)",
-			thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+	static const gchar *thisfn = "na_object_profile_ifactory_object_is_valid";
 
 	g_return_val_if_fail( NA_IS_OBJECT_PROFILE( object ), FALSE );
 
+	g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
 	return( profile_is_valid( NA_OBJECT_PROFILE( object )));
 }
 
diff --git a/src/core/na-object.c b/src/core/na-object.c
index ee29d07..dfe7a8e 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -266,6 +266,7 @@ iduplicable_copy( NAIDuplicable *target, const NAIDuplicable *source )
 static gboolean
 iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b )
 {
+	static const gchar *thisfn = "na_object_iduplicable_are_equal";
 	gboolean are_equal;
 	HierarchyIter *str;
 
@@ -277,6 +278,8 @@ iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b )
 	if( !NA_OBJECT( a )->private->dispose_has_run &&
 		!NA_OBJECT( b )->private->dispose_has_run ){
 
+		g_debug( "%s: a=%p (%s), b=%p", thisfn, ( void * ) a, G_OBJECT_TYPE_NAME( a ), ( void * ) b );
+
 		if( NA_IS_IFACTORY_OBJECT( a )){
 			are_equal = na_factory_object_are_equal( NA_IFACTORY_OBJECT( a ), NA_IFACTORY_OBJECT( b ));
 
@@ -316,14 +319,12 @@ iduplicable_is_valid( const NAIDuplicable *object )
 	gboolean is_valid;
 	HierarchyIter *str;
 
-	g_debug( "%s: object=%p (%s)",
-			thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
-
 	g_return_val_if_fail( NA_IS_OBJECT( object ), FALSE );
 
 	is_valid = FALSE;
 
 	if( !NA_OBJECT( object )->private->dispose_has_run ){
+		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
 
 		if( NA_IS_IFACTORY_OBJECT( object )){
 			is_valid = na_factory_object_is_valid( NA_IFACTORY_OBJECT( object ));
@@ -374,7 +375,7 @@ iduplicable_is_valid_iter( GObjectClass *class, const NAObject *a, HierarchyIter
  *      +- valid_status = v_is_valid( object )             -> interface <structfield>NAObjectClass::is_valid</structfield>
  *
  * Note that the recursivity is managed here, so that we can be sure
- * that edition status of childs is actually checked before those of
+ * that edition status of children is actually checked before those of
  * the parent.
  *
  * Since: 2.30
@@ -383,22 +384,14 @@ void
 na_object_object_check_status( const NAObject *object )
 {
 	static const gchar *thisfn = "na_object_object_check_status";
-	GList *children, *ic;
 
 	g_return_if_fail( NA_IS_OBJECT( object ));
 
 	if( !object->private->dispose_has_run ){
-
-		g_debug( "%s: object=%p (%s)",
-				thisfn,
-				( void * ) object, G_OBJECT_TYPE_NAME( object ));
+		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
 
 		if( NA_IS_OBJECT_ITEM( object )){
-			children = na_object_get_items( object );
-
-			for( ic = children ; ic ; ic = ic->next ){
-				na_object_check_status( ic->data );
-			}
+			g_list_foreach( na_object_get_items( object ), ( GFunc ) na_object_object_check_status, NULL );
 		}
 
 		na_iduplicable_check_status( NA_IDUPLICABLE( object ));
diff --git a/src/nact/nact-assistant-import.c b/src/nact/nact-assistant-import.c
index c8318fc..70bb083 100644
--- a/src/nact/nact-assistant-import.c
+++ b/src/nact/nact-assistant-import.c
@@ -44,6 +44,7 @@
 #include "nact-application.h"
 #include "nact-assistant-import.h"
 #include "nact-main-window.h"
+#include "nact-tree-ieditable.h"
 
 /* Import Assistant
  *
@@ -639,6 +640,7 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
 	NAImporterResult *result;
 	NactApplication *application;
 	NAUpdater *updater;
+	NactTreeView *items_view;
 
 	g_return_if_fail( NACT_IS_ASSISTANT_IMPORT( wnd ));
 
@@ -676,11 +678,14 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
 
 	/* then insert the list
 	 * assuring that actions will be inserted in the same order as uris
+	 *
+	 * the tree view (and its underlying tree store) takes a new reference
+	 * on the inserted objects; the pointers so remain valid even after
+	 * having released the imported_items list
 	 */
 	imported_items = g_list_reverse( imported_items );
-#if 0
-	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( main_window ), imported_items, NULL );
-#endif
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( main_window ));
+	nact_tree_ieditable_insert_items( NACT_TREE_IEDITABLE( items_view ), imported_items, NULL );
 	na_object_free_items( imported_items );
 }
 
diff --git a/src/nact/nact-clipboard.c b/src/nact/nact-clipboard.c
index 2324db5..5832d59 100644
--- a/src/nact/nact-clipboard.c
+++ b/src/nact/nact-clipboard.c
@@ -525,7 +525,7 @@ export_rows( NactClipboard *clipboard, GList *rows, const gchar *dest_folder )
 		if( path ){
 			gtk_tree_model_get_iter( model, &iter, path );
 			gtk_tree_path_free( path );
-			gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+			gtk_tree_model_get( model, &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
 			buffer = export_row_object( clipboard, object, dest_folder, &exported, first );
 			if( buffer && strlen( buffer )){
 				data = g_string_append( data, buffer );
diff --git a/src/nact/nact-iaction-tab.c b/src/nact/nact-iaction-tab.c
index 5a93388..62b6fe7 100644
--- a/src/nact/nact-iaction-tab.c
+++ b/src/nact/nact-iaction-tab.c
@@ -67,7 +67,7 @@ static void          interface_base_init( NactIActionTabInterface *klass );
 static void          interface_base_finalize( NactIActionTabInterface *klass );
 
 static void          on_tree_view_content_changed( NactIActionTab *instance, NactTreeView *view, NAObject *object, gpointer user_data );
-static void          on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selected );
+static void          on_main_selection_changed( NactIActionTab *instance, GList *selected_items, gpointer user_data );
 
 static void          on_target_selection_toggled( GtkToggleButton *button, NactIActionTab *instance );
 static void          on_target_location_toggled( GtkToggleButton *button, NactIActionTab *instance );
@@ -217,11 +217,8 @@ nact_iaction_tab_runtime_init_toplevel( NactIActionTab *instance )
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
-				G_CALLBACK( on_tab_updatable_selection_changed ));
+		base_window_signal_connect( BASE_WINDOW( instance ),
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		base_window_signal_connect( BASE_WINDOW( instance ),
 				G_OBJECT( instance ), TREE_SIGNAL_CONTENT_CHANGED, G_CALLBACK( on_tree_view_content_changed ));
@@ -364,9 +361,10 @@ on_tree_view_content_changed( NactIActionTab *instance, NactTreeView *view, NAOb
 }
 
 static void
-on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selected )
+on_main_selection_changed( NactIActionTab *instance, GList *selected_items, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_iaction_tab_on_tab_updatable_selection_changed";
+	static const gchar *thisfn = "nact_iaction_tab_on_main_selection_changed";
+	guint count_selected;
 	gboolean enable_tab;
 	NAObjectItem *item;
 	gboolean editable;
@@ -383,6 +381,7 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 
 	if( st_initialized && !st_finalized ){
 
+		count_selected = g_list_length( selected_items );
 		g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
 
 		enable_tab = ( count_selected == 1 );
diff --git a/src/nact/nact-ibasenames-tab.c b/src/nact/nact-ibasenames-tab.c
index b45c1c2..c966b30 100644
--- a/src/nact/nact-ibasenames-tab.c
+++ b/src/nact/nact-ibasenames-tab.c
@@ -57,7 +57,7 @@ static GType   register_type( void );
 static void    interface_base_init( NactIBasenamesTabInterface *klass );
 static void    interface_base_finalize( NactIBasenamesTabInterface *klass );
 
-static void    on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected );
+static void    on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data );
 
 static void    on_matchcase_toggled( GtkToggleButton *button, BaseWindow *window );
 static GSList *get_basenames( void *context );
@@ -186,11 +186,8 @@ nact_ibasenames_tab_runtime_init_toplevel( NactIBasenamesTab *instance )
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
-				G_CALLBACK( on_tab_updatable_selection_changed ));
+		base_window_signal_connect( BASE_WINDOW( instance ),
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		button = base_window_get_widget( BASE_WINDOW( instance ), "BasenamesMatchcaseButton" );
 		base_window_signal_connect(
@@ -238,8 +235,9 @@ nact_ibasenames_tab_dispose( NactIBasenamesTab *instance )
 }
 
 static void
-on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected )
+on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data )
 {
+	guint count_selected;
 	NAIContext *context;
 	gboolean editable;
 	GtkToggleButton *matchcase_button;
@@ -247,6 +245,7 @@ on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected )
 
 	if( st_initialized && !st_finalized ){
 
+		count_selected = g_list_length( selected_items );
 		context = nact_main_tab_get_context( NACT_MAIN_WINDOW( window ), &editable );
 
 		st_on_selection_change = TRUE;
diff --git a/src/nact/nact-icapabilities-tab.c b/src/nact/nact-icapabilities-tab.c
index 5126004..58fb475 100644
--- a/src/nact/nact-icapabilities-tab.c
+++ b/src/nact/nact-icapabilities-tab.c
@@ -57,7 +57,7 @@ static GType   register_type( void );
 static void    interface_base_init( NactICapabilitiesTabInterface *klass );
 static void    interface_base_finalize( NactICapabilitiesTabInterface *klass );
 
-static void    on_tab_updatable_selection_changed( NactICapabilitiesTab *instance, gint count_selected );
+static void    on_main_selection_changed( NactICapabilitiesTab *instance, GList *selected_items, gpointer user_data );
 
 static void    on_add_clicked( GtkButton *button, BaseWindow *window );
 static GSList *get_capabilities( NAIContext *context );
@@ -172,11 +172,8 @@ nact_icapabilities_tab_runtime_init_toplevel( NactICapabilitiesTab *instance )
 
 		nact_match_list_init_view( BASE_WINDOW( instance ), ITAB_NAME );
 
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
-				G_CALLBACK( on_tab_updatable_selection_changed ));
+		base_window_signal_connect( BASE_WINDOW( instance ),
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 	}
 }
 
@@ -209,9 +206,9 @@ nact_icapabilities_tab_dispose( NactICapabilitiesTab *instance )
 }
 
 static void
-on_tab_updatable_selection_changed( NactICapabilitiesTab *instance, gint count_selected )
+on_main_selection_changed( NactICapabilitiesTab *instance, GList *selected_items, gpointer user_data )
 {
-	nact_match_list_on_selection_changed( BASE_WINDOW( instance ), ITAB_NAME, count_selected );
+	nact_match_list_on_selection_changed( BASE_WINDOW( instance ), ITAB_NAME, g_list_length( selected_items ));
 }
 
 static void
diff --git a/src/nact/nact-icommand-tab.c b/src/nact/nact-icommand-tab.c
index b3feee7..0c52c18 100644
--- a/src/nact/nact-icommand-tab.c
+++ b/src/nact/nact-icommand-tab.c
@@ -71,7 +71,7 @@ static void       interface_base_init( NactICommandTabInterface *klass );
 static void       interface_base_finalize( NactICommandTabInterface *klass );
 
 static void       on_tree_view_content_changed( NactICommandTab *instance, NactTreeView *view, NAObject *object, gpointer user_data );
-static void       on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_selected );
+static void       on_main_selection_changed( NactICommandTab *instance, GList *selected_items, gpointer user_data );
 
 static GtkWidget *get_label_entry( NactICommandTab *instance );
 static GtkButton *get_legend_button( NactICommandTab *instance );
@@ -261,11 +261,8 @@ nact_icommand_tab_runtime_init_toplevel( NactICommandTab *instance )
 				"clicked",
 				G_CALLBACK( on_wdir_browse ));
 
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
-				G_CALLBACK( on_tab_updatable_selection_changed ));
+		base_window_signal_connect( BASE_WINDOW( instance ),
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		base_window_signal_connect( BASE_WINDOW( instance ),
 				G_OBJECT( instance ), TREE_SIGNAL_CONTENT_CHANGED, G_CALLBACK( on_tree_view_content_changed ));
@@ -337,9 +334,9 @@ on_tree_view_content_changed( NactICommandTab *instance, NactTreeView *view, NAO
 }
 
 static void
-on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_selected )
+on_main_selection_changed( NactICommandTab *instance, GList *selected_items, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_icommand_tab_on_tab_updatable_selection_changed";
+	static const gchar *thisfn = "nact_icommand_tab_on_main_selection_changed";
 	NAObjectProfile *profile;
 	gboolean editable;
 	gboolean enable_tab;
@@ -351,8 +348,8 @@ on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_select
 	g_return_if_fail( NACT_IS_ICOMMAND_TAB( instance ));
 
 	if( st_initialized && !st_finalized ){
-
-		g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
+		g_debug( "%s: instance=%p, selected_items=%p (count=%d)",
+				thisfn, ( void * ) instance, ( void * ) selected_items, g_list_length( selected_items ));
 
 		g_object_get(
 				G_OBJECT( instance ),
diff --git a/src/nact/nact-ienvironment-tab.c b/src/nact/nact-ienvironment-tab.c
index fa8de68..69e79d0 100644
--- a/src/nact/nact-ienvironment-tab.c
+++ b/src/nact/nact-ienvironment-tab.c
@@ -106,7 +106,7 @@ static GType    register_type( void );
 static void     interface_base_init( NactIEnvironmentTabInterface *klass );
 static void     interface_base_finalize( NactIEnvironmentTabInterface *klass );
 
-static void     on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_selected );
+static void     on_main_selection_changed( NactIEnvironmentTab *instance, GList *selected_items, gpointer user_data );
 
 static void     on_selcount_ope_changed( GtkComboBox *combo, NactIEnvironmentTab *instance );
 static void     on_selcount_int_changed( GtkEntry *entry, NactIEnvironmentTab *instance );
@@ -245,11 +245,8 @@ nact_ienvironment_tab_runtime_init_toplevel( NactIEnvironmentTab *instance )
 	if( st_initialized && !st_finalized ){
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
-				G_CALLBACK( on_tab_updatable_selection_changed ));
+		base_window_signal_connect( BASE_WINDOW( instance ),
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		base_window_signal_connect_by_name( BASE_WINDOW( instance ),
 				"SelectionCountSigneCombobox", "changed", G_CALLBACK( on_selcount_ope_changed ));
@@ -342,9 +339,9 @@ nact_ienvironment_tab_dispose( NactIEnvironmentTab *instance )
 }
 
 static void
-on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_selected )
+on_main_selection_changed( NactIEnvironmentTab *instance, GList *selected_items, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_ienvironment_tab_on_tab_updatable_selection_changed";
+	static const gchar *thisfn = "nact_ienvironment_tab_on_main_selection_changed";
 	NAIContext *context;
 	gboolean editable;
 	gboolean enable_tab;
@@ -361,7 +358,8 @@ on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_se
 	g_return_if_fail( NACT_IS_IENVIRONMENT_TAB( instance ));
 
 	if( st_initialized && !st_finalized ){
-		g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
+		g_debug( "%s: instance=%p, selected_items=%p (count=%d)",
+				thisfn, ( void * ) instance, ( void * ) selected_items, g_list_length( selected_items ));
 
 		context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), &editable );
 
diff --git a/src/nact/nact-iexecution-tab.c b/src/nact/nact-iexecution-tab.c
index 15b9fd9..7fa0064 100644
--- a/src/nact/nact-iexecution-tab.c
+++ b/src/nact/nact-iexecution-tab.c
@@ -54,7 +54,7 @@ static GType    register_type( void );
 static void     interface_base_init( NactIExecutionTabInterface *klass );
 static void     interface_base_finalize( NactIExecutionTabInterface *klass );
 
-static void     on_tab_updatable_selection_changed( NactIExecutionTab *instance, gint count_selected );
+static void     on_main_selection_changed( NactIExecutionTab *instance, GList *selected_items, gpointer user_data );
 
 static void     on_normal_mode_toggled( GtkToggleButton *togglebutton, NactIExecutionTab *instance );
 static void     on_terminal_mode_toggled( GtkToggleButton *togglebutton, NactIExecutionTab *instance );
@@ -168,7 +168,7 @@ nact_iexecution_tab_runtime_init_toplevel( NactIExecutionTab *instance )
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
 		base_window_signal_connect( BASE_WINDOW( instance ),
-				G_OBJECT( instance ), MAIN_WINDOW_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tab_updatable_selection_changed ));
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		base_window_signal_connect_by_name( BASE_WINDOW( instance ),
 				"ExecutionModeNormal", "toggled", G_CALLBACK( on_normal_mode_toggled ));
@@ -224,9 +224,9 @@ nact_iexecution_tab_dispose( NactIExecutionTab *instance )
 }
 
 static void
-on_tab_updatable_selection_changed( NactIExecutionTab *instance, gint count_selected )
+on_main_selection_changed( NactIExecutionTab *instance, GList *selected_items, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_iexecution_tab_on_tab_updatable_selection_changed";
+	static const gchar *thisfn = "nact_iexecution_tab_on_main_selection_changed";
 	NAObjectProfile *profile;
 	gboolean editable;
 	gboolean enable_tab;
@@ -240,7 +240,8 @@ on_tab_updatable_selection_changed( NactIExecutionTab *instance, gint count_sele
 	g_return_if_fail( NACT_IS_IEXECUTION_TAB( instance ));
 
 	if( st_initialized && !st_finalized ){
-		g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
+		g_debug( "%s: instance=%p, selected_items=%p (count=%d)",
+				thisfn, ( void * ) instance, ( void * ) selected_items, g_list_length( selected_items ));
 
 		g_object_get(
 				G_OBJECT( instance ),
diff --git a/src/nact/nact-ifolders-tab.c b/src/nact/nact-ifolders-tab.c
index 17d180d..b3b9129 100644
--- a/src/nact/nact-ifolders-tab.c
+++ b/src/nact/nact-ifolders-tab.c
@@ -62,7 +62,7 @@ static GType   register_type( void );
 static void    interface_base_init( NactIFoldersTabInterface *klass );
 static void    interface_base_finalize( NactIFoldersTabInterface *klass );
 
-static void    on_tab_updatable_selection_changed( NactIFoldersTab *instance, gint count_selected );
+static void    on_main_selection_changed( NactIFoldersTab *instance, GList *selected_items, gpointer user_data );
 
 static void    on_browse_folder_clicked( GtkButton *button, BaseWindow *window );
 static GSList *get_folders( void *context );
@@ -178,11 +178,8 @@ nact_ifolders_tab_runtime_init_toplevel( NactIFoldersTab *instance )
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
-				G_CALLBACK( on_tab_updatable_selection_changed ));
+		base_window_signal_connect( BASE_WINDOW( instance ),
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		nact_match_list_init_view( BASE_WINDOW( instance ), ITAB_NAME );
 
@@ -224,12 +221,14 @@ nact_ifolders_tab_dispose( NactIFoldersTab *instance )
 }
 
 static void
-on_tab_updatable_selection_changed( NactIFoldersTab *instance, gint count_selected )
+on_main_selection_changed( NactIFoldersTab *instance, GList *selected_items, gpointer user_data )
 {
+	guint count_selected;
 	NAIContext *context;
 	gboolean editable;
 	GtkWidget *button;
 
+	count_selected = g_list_length( selected_items );
 	nact_match_list_on_selection_changed( BASE_WINDOW( instance ), ITAB_NAME, count_selected );
 
 	context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), &editable );
diff --git a/src/nact/nact-imimetypes-tab.c b/src/nact/nact-imimetypes-tab.c
index aa0bbba..f29ea31 100644
--- a/src/nact/nact-imimetypes-tab.c
+++ b/src/nact/nact-imimetypes-tab.c
@@ -55,7 +55,7 @@ static GType   register_type( void );
 static void    interface_base_init( NactIMimetypesTabInterface *klass );
 static void    interface_base_finalize( NactIMimetypesTabInterface *klass );
 
-static void    on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected );
+static void    on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data );
 
 static GSList *get_mimetypes( void *context );
 static void    set_mimetypes( void *context, GSList *filters );
@@ -182,11 +182,8 @@ nact_imimetypes_tab_runtime_init_toplevel( NactIMimetypesTab *instance )
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
-				G_CALLBACK( on_tab_updatable_selection_changed ));
+		base_window_signal_connect( BASE_WINDOW( instance ),
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		nact_match_list_init_view( BASE_WINDOW( instance ), ITAB_NAME );
 	}
@@ -227,9 +224,9 @@ nact_imimetypes_tab_dispose( NactIMimetypesTab *instance )
 }
 
 static void
-on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected )
+on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data )
 {
-	nact_match_list_on_selection_changed( window, ITAB_NAME, count_selected );
+	nact_match_list_on_selection_changed( window, ITAB_NAME, g_list_length( selected_items ));
 }
 
 static GSList *
diff --git a/src/nact/nact-iproperties-tab.c b/src/nact/nact-iproperties-tab.c
index 385f244..3a37dbe 100644
--- a/src/nact/nact-iproperties-tab.c
+++ b/src/nact/nact-iproperties-tab.c
@@ -61,7 +61,7 @@ static GType      register_type( void );
 static void       interface_base_init( NactIPropertiesTabInterface *klass );
 static void       interface_base_finalize( NactIPropertiesTabInterface *klass );
 
-static void       on_tab_updatable_selection_changed( NactIPropertiesTab *instance, gint count_selected );
+static void       on_main_selection_changed( NactIPropertiesTab *instance, GList *selected_items, gpointer user_data );
 static void       on_tab_updatable_provider_changed( NactIPropertiesTab *instance, NAObjectItem *item );
 
 static GtkButton *get_enabled_button( NactIPropertiesTab *instance );
@@ -165,7 +165,7 @@ nact_iproperties_tab_runtime_init_toplevel( NactIPropertiesTab *instance )
 		g_debug( "%s: instance=%p (%s)", thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
 
 		base_window_signal_connect( BASE_WINDOW( instance ),
-				G_OBJECT( instance ), MAIN_WINDOW_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tab_updatable_selection_changed ));
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		base_window_signal_connect( BASE_WINDOW( instance ),
 				G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED, G_CALLBACK( on_tab_updatable_provider_changed ));
@@ -219,9 +219,10 @@ nact_iproperties_tab_dispose( NactIPropertiesTab *instance )
 }
 
 static void
-on_tab_updatable_selection_changed( NactIPropertiesTab *instance, gint count_selected )
+on_main_selection_changed( NactIPropertiesTab *instance, GList *selected_items, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_iproperties_tab_on_tab_updatable_selection_changed";
+	static const gchar *thisfn = "nact_iproperties_tab_on_main_selection_changed";
+	guint count_selected;
 	NAObjectItem *item;
 	gboolean editable;
 	gboolean enable_tab;
@@ -238,6 +239,7 @@ on_tab_updatable_selection_changed( NactIPropertiesTab *instance, gint count_sel
 	g_return_if_fail( NACT_IS_IPROPERTIES_TAB( instance ));
 
 	if( st_initialized && !st_finalized ){
+		count_selected = g_list_length( selected_items );
 		g_debug( "%s: instance=%p (%s), count_selected=%d",
 				thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), count_selected );
 
diff --git a/src/nact/nact-ischemes-tab.c b/src/nact/nact-ischemes-tab.c
index 85aab62..b716677 100644
--- a/src/nact/nact-ischemes-tab.c
+++ b/src/nact/nact-ischemes-tab.c
@@ -58,7 +58,7 @@ static GType   register_type( void );
 static void    interface_base_init( NactISchemesTabInterface *klass );
 static void    interface_base_finalize( NactISchemesTabInterface *klass );
 
-static void    on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected );
+static void    on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data );
 
 static void    on_add_from_defaults( GtkButton *button, BaseWindow *window );
 static GSList *get_schemes( void *context );
@@ -174,11 +174,8 @@ nact_ischemes_tab_runtime_init_toplevel( NactISchemesTab *instance )
 
 		g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
-				G_CALLBACK( on_tab_updatable_selection_changed ));
+		base_window_signal_connect( BASE_WINDOW( instance ),
+				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		nact_match_list_init_view( BASE_WINDOW( instance ), ITAB_NAME );
 
@@ -218,13 +215,13 @@ nact_ischemes_tab_dispose( NactISchemesTab *instance )
 }
 
 static void
-on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected )
+on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data )
 {
 	NAIContext *context;
 	gboolean editable;
 	GtkWidget *button;
 
-	nact_match_list_on_selection_changed( window, ITAB_NAME, count_selected );
+	nact_match_list_on_selection_changed( window, ITAB_NAME, g_list_length( selected_items ));
 
 	context = nact_main_tab_get_context( NACT_MAIN_WINDOW( window ), &editable );
 	button = base_window_get_widget( window, "AddFromDefaultButton" );
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index e6d1fb6..8bd6bc4 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -133,6 +133,7 @@ enum {
 	PROVIDER_CHANGED,
 	ITEM_UPDATED,
 	ORDER_CHANGED,
+	SELECTION_CHANGED,
 	LAST_SIGNAL
 };
 
@@ -169,6 +170,7 @@ static void     on_base_all_widgets_showed( NactMainWindow *window, gpointer use
 
 static void     on_tree_view_modified_count_changed( NactMainWindow *window, NactTreeView *view, guint count, gpointer user_data );
 static void     on_tree_view_selection_changed( NactMainWindow *window, NactTreeView *view, GList *selected_items, gpointer user_data );
+static void     on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items );
 static void     raz_selection_properties( NactMainWindow *window );
 static void     setup_current_selection( NactMainWindow *window, NAObjectId *selected_row );
 static void     setup_dialog_title( NactMainWindow *window );
@@ -430,6 +432,35 @@ class_init( NactMainWindowClass *klass )
 			G_TYPE_NONE,
 			1,
 			G_TYPE_POINTER );
+
+	/**
+	 * NactMainWindow::main-selection-changed:
+	 *
+	 * This signal is emitted on the window parent each time the selection
+	 * has changed in the treeview, after having set the current item/profile/
+	 * context properties.
+	 *
+	 * This way, we are sure that notebook edition tabs which required to
+	 * have a current item/profile/context will have it, whenever they have
+	 * connected to the 'selection-changed' signal.
+	 *
+	 * Signal args:
+	 * - a #GList of currently selected #NAObjectItems.
+	 *
+	 * Handler prototype:
+	 * void ( *handler )( BaseWindow *window, GList *selected, gpointer user_data );
+	 */
+	st_signals[ SELECTION_CHANGED ] = g_signal_new_class_handler(
+			MAIN_SIGNAL_SELECTION_CHANGED,
+			G_TYPE_OBJECT,
+			G_SIGNAL_RUN_CLEANUP,
+			G_CALLBACK( on_selection_changed_cleanup_handler ),
+			NULL,
+			NULL,
+			g_cclosure_marshal_VOID__POINTER,
+			G_TYPE_NONE,
+			1,
+			G_TYPE_POINTER );
 }
 
 static void
@@ -623,6 +654,10 @@ instance_constructed( GObject *window )
 	if( !self->private->dispose_has_run ){
 		g_debug( "%s: window=%p (%s)", thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ));
 
+		/* first connect to BaseWindow signals
+		 * so that convenience objects instanciated later will have this same signal
+		 * triggered after the one of NactMainWindow
+		 */
 		base_window_signal_connect( BASE_WINDOW( window ),
 				G_OBJECT( window ), BASE_SIGNAL_INITIALIZE_GTK, G_CALLBACK( on_base_initialize_gtk_toplevel ));
 
@@ -646,6 +681,9 @@ instance_constructed( GObject *window )
 		self->private->items_view = nact_tree_view_new( BASE_WINDOW( window ), "ActionsList", TREE_MODE_EDITION );
 
 		base_window_signal_connect( BASE_WINDOW( window ),
+				G_OBJECT( window ), TREE_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tree_view_selection_changed ));
+
+		base_window_signal_connect( BASE_WINDOW( window ),
 				G_OBJECT( window ), TREE_SIGNAL_MODIFIED_COUNT_CHANGED, G_CALLBACK( on_tree_view_modified_count_changed ));
 
 		/* create the menubar
@@ -807,9 +845,6 @@ on_base_initialize_base_window( NactMainWindow *window, gpointer user_data )
 			gtk_paned_set_position( GTK_PANED( pane ), pos );
 		}
 
-		base_window_signal_connect( BASE_WINDOW( window ),
-				G_OBJECT( window ), TREE_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tree_view_selection_changed ));
-
 		nact_iaction_tab_runtime_init_toplevel( NACT_IACTION_TAB( window ));
 		nact_icommand_tab_runtime_init_toplevel( NACT_ICOMMAND_TAB( window ));
 		nact_ibasenames_tab_runtime_init_toplevel( NACT_IBASENAMES_TAB( window ));
@@ -991,9 +1026,27 @@ on_tree_view_selection_changed( NactMainWindow *window, NactTreeView *view, GLis
 		}
 
 		setup_dialog_title( window );
+
+		g_signal_emit_by_name( G_OBJECT( window ),
+				MAIN_SIGNAL_SELECTION_CHANGED, na_object_copyref_items( selected_items ));
 	}
 }
 
+/*
+ * cleanup handler for our MAIN_SIGNAL_SELECTION_CHANGED signal
+ */
+static void
+on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items )
+{
+	static const gchar *thisfn = "nact_mainw_window_on_selection_changed_cleanup_handler";
+
+	g_debug( "%s: window=%p, selected_items=%p (count=%u)",
+			thisfn, ( void * ) window,
+			( void * ) selected_items, g_list_length( selected_items ));
+
+	na_object_free_items( selected_items );
+}
+
 static void
 raz_selection_properties( NactMainWindow *window )
 {
diff --git a/src/nact/nact-main-window.h b/src/nact/nact-main-window.h
index 96d5beb..ede30df 100644
--- a/src/nact/nact-main-window.h
+++ b/src/nact/nact-main-window.h
@@ -80,7 +80,8 @@ typedef struct {
 }
 	NactMainWindowClass;
 
-#define MAIN_WINDOW_SIGNAL_SELECTION_CHANGED			"main-window-selection-changed"
+#define MAIN_SIGNAL_SELECTION_CHANGED					"main-selection-changed"
+
 #define MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED		"main-window-level-zero-order-changed"
 
 GType           nact_main_window_get_type( void );
diff --git a/src/nact/nact-menubar.c b/src/nact/nact-menubar.c
index 6ab8070..ce4f94b 100644
--- a/src/nact/nact-menubar.c
+++ b/src/nact/nact-menubar.c
@@ -351,6 +351,10 @@ instance_dispose( GObject *object )
 		g_object_unref( self->private->action_group );
 		g_object_unref( self->private->ui_manager );
 
+		if( self->private->selected_items ){
+			self->private->selected_items = na_object_free_items( self->private->selected_items );
+		}
+
 		/* chain up to the parent class */
 		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
 			G_OBJECT_CLASS( st_parent_class )->dispose( object );
@@ -716,6 +720,9 @@ on_tree_view_focus_out( BaseWindow *window, NactTreeView *view, gpointer user_da
 
 /*
  * when the selection changes in the tree view, see what is selected
+ *
+ * It happens that this function is triggered after all tabs have already
+ * dealt with the MAIN_SIGNAL_SELECTION_CHANGED signal
  */
 static void
 on_tree_view_selection_changed( BaseWindow *window, NactTreeView *view, GList *selected, gpointer user_data )
@@ -727,95 +734,104 @@ on_tree_view_selection_changed( BaseWindow *window, NactTreeView *view, GList *s
 
 	BAR_WINDOW_VOID( window );
 
-	g_debug( "%s: selected=%p (count=%d)", thisfn, ( void * ) selected, g_list_length( selected ));
+	g_debug( "%s: selected_items=%p (count=%d)", thisfn, ( void * ) selected, g_list_length( selected ));
 
 	bar->private->count_selected = g_list_length( selected );
+
 	if( bar->private->selected_items ){
 		bar->private->selected_items = na_object_free_items( bar->private->selected_items );
 	}
 	bar->private->selected_items = na_object_copyref_items( selected );
 
+	/* check if the parent of the first selected item is writable
+	 * (File: New menu/New action)
+	 * (Edit: Paste menu or action)
+	 */
+	first = NULL;
 	if( selected ){
-		/* check if the parent of the first selected item is writable
-		 * (File: New menu/New action)
-		 * (Edit: Paste menu or action)
-		 */
 		first = ( NAObject *) selected->data;
-		if( first ){
-			if( NA_IS_OBJECT_PROFILE( first )){
-				first = NA_OBJECT( na_object_get_parent( first ));
-			}
-			first = ( NAObject * ) na_object_get_parent( first );
-			bar->private->is_parent_writable = first ? na_object_is_finally_writable( first, NULL ) : bar->private->is_level_zero_writable;
+		if( NA_IS_OBJECT_PROFILE( first )){
+			first = NA_OBJECT( na_object_get_parent( first ));
 		}
-		/* check is only an action is selected, or only profile(s) of a same action
-		 * (File: New profile)
-		 * (Edit: Paste a profile)
-		 */
-		bar->private->enable_new_profile = TRUE;
-		selected_action = NULL;
-		for( is = selected ; is ; is = is->next ){
+		first = ( NAObject * ) na_object_get_parent( first );
+	}
+	if( first ){
+		bar->private->is_parent_writable = na_object_is_finally_writable( first, NULL );
+	} else {
+		bar->private->is_parent_writable = bar->private->is_level_zero_writable;
+	}
+
+	/* check is only an action is selected, or only profile(s) of a same action
+	 * (File: New profile)
+	 * (Edit: Paste a profile)
+	 */
+	bar->private->enable_new_profile = TRUE;
+	selected_action = NULL;
+	for( is = selected ; is ; is = is->next ){
+
+		if( NA_IS_OBJECT_MENU( is->data )){
+			bar->private->enable_new_profile = FALSE;
+			break;
 
-			if( NA_IS_OBJECT_MENU( is->data )){
+		} else if( NA_IS_OBJECT_ACTION( is->data )){
+			if( !selected_action ){
+				selected_action = NA_OBJECT( is->data );
+			} else {
 				bar->private->enable_new_profile = FALSE;
 				break;
+			}
 
-			} else if( NA_IS_OBJECT_ACTION( is->data )){
-				if( !selected_action ){
-					selected_action = NA_OBJECT( is->data );
-				} else {
-					bar->private->enable_new_profile = FALSE;
-					break;
-				}
-
-			} else if( NA_IS_OBJECT_PROFILE( is->data )){
-				first = NA_OBJECT( na_object_get_parent( is->data ));
-				if( !selected_action ){
-					selected_action = first;
-				} else if( selected_action != first ){
-					bar->private->enable_new_profile = FALSE;
-					break;
-				}
+		} else if( NA_IS_OBJECT_PROFILE( is->data )){
+			first = NA_OBJECT( na_object_get_parent( is->data ));
+			if( !selected_action ){
+				selected_action = first;
+			} else if( selected_action != first ){
+				bar->private->enable_new_profile = FALSE;
+				break;
 			}
 		}
-		if( !selected_action ){
-			bar->private->enable_new_profile = FALSE;
-		} else {
-			bar->private->is_action_writable = na_object_is_finally_writable( selected_action, NULL );
+	}
+	if( selected_action ){
+		bar->private->is_action_writable = na_object_is_finally_writable( selected_action, NULL );
+	} else {
+		bar->private->enable_new_profile = FALSE;
+	}
+
+	/* check that selection is not empty and that each selected item is writable
+	 * and that all parents are writable
+	 * if some selection is at level zero, then it must be writable
+	 * (Edit: Cut/Delete)
+	 */
+	bar->private->are_parents_writable = TRUE;
+	for( is = selected ; is ; is = is->next ){
+		gchar *label = na_object_get_label( is->data );
+		gboolean writable = na_object_is_finally_writable( is->data, NULL );
+		g_debug( "%s: label=%s, writable=%s", thisfn, label, writable ? "True":"False" );
+		if( !na_object_is_finally_writable( is->data, NULL )){
+			bar->private->are_parents_writable = FALSE;
+			break;
 		}
-		/* check that selection is not empty and that each selected item is writable
-		 * and that all parents are writable
-		 * if some selection is at level zero, then it must be writable
-		 * (Edit: Cut/Delete)
-		 */
-		bar->private->are_parents_writable = TRUE;
-		for( is = selected ; is ; is = is->next ){
-			gchar *label = na_object_get_label( is->data );
-			gboolean writable = na_object_is_finally_writable( is->data, NULL );
-			g_debug( "%s: label=%s, writable=%s", thisfn, label, writable ? "True":"False" );
-			if( !na_object_is_finally_writable( is->data, NULL )){
-				bar->private->are_parents_writable = FALSE;
-				break;
-			}
-			first = ( NAObject * ) na_object_get_parent( is->data );
-			if( first ){
-				if( !na_object_is_finally_writable( first, NULL )){
-					bar->private->are_parents_writable = FALSE;
-					break;
-				}
-			} else if( !bar->private->is_level_zero_writable ){
+		first = ( NAObject * ) na_object_get_parent( is->data );
+		if( first ){
+			if( !na_object_is_finally_writable( first, NULL )){
 				bar->private->are_parents_writable = FALSE;
 				break;
 			}
+		} else if( !bar->private->is_level_zero_writable ){
+			bar->private->are_parents_writable = FALSE;
+			break;
 		}
 	}
 
 	bar->private->selected_menus = 0;
 	bar->private->selected_actions = 0;
 	bar->private->selected_profiles = 0;
-	na_object_item_count_items( selected, &bar->private->selected_menus, &bar->private->selected_actions, &bar->private->selected_profiles, FALSE );
-	g_debug( "nact_menubar_on_iactions_list_selection_changed: menus=%d, actions=%d, profiles=%d",
-			bar->private->selected_menus, bar->private->selected_actions, bar->private->selected_profiles );
+	if( selected ){
+		na_object_item_count_items( selected, &bar->private->selected_menus, &bar->private->selected_actions, &bar->private->selected_profiles, FALSE );
+		g_debug( "%s: selected_menus=%d, selected_actions=%d, selected_profiles=%d",
+				thisfn,
+				bar->private->selected_menus, bar->private->selected_actions, bar->private->selected_profiles );
+	}
 
 	g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
 }
diff --git a/src/nact/nact-tree-ieditable.c b/src/nact/nact-tree-ieditable.c
index e7a1a3c..b858680 100644
--- a/src/nact/nact-tree-ieditable.c
+++ b/src/nact/nact-tree-ieditable.c
@@ -32,7 +32,10 @@
 #include <config.h>
 #endif
 
+#include <api/na-object-api.h>
+
 #include "nact-tree-ieditable.h"
+#include "nact-tree-model.h"
 
 /* private interface data
  */
@@ -43,7 +46,8 @@ struct _NactTreeIEditableInterfacePrivate {
 /* data attached to the NactTreeView
  */
 typedef struct {
-	guint nb_modified;
+	GtkTreeView *treeview;
+	guint        count_modified;
 }
 	IEditableData;
 
@@ -56,7 +60,12 @@ static GType          register_type( void );
 static void           interface_base_init( NactTreeIEditableInterface *klass );
 static void           interface_base_finalize( NactTreeIEditableInterface *klass );
 
+static void           do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTreePath *insert_path, GList **list_parents );
+static NAObject      *do_insert_into_first( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTreePath *insert_path, GtkTreePath **new_path );
+static GtkTreePath   *get_selection_first_path( GtkTreeView *treeview );
 static IEditableData *get_instance_data( NactTreeIEditable *view );
+static void           increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items );
+static void           increment_counters_modified( NAObject *object, IEditableData *ied );
 
 GType
 nact_tree_ieditable_get_type( void )
@@ -124,1088 +133,846 @@ interface_base_finalize( NactTreeIEditableInterface *klass )
 }
 
 /**
- * nact_tree_ieditable_view_constructed:
- * @view: the #NactTreeView which implements this interface.
- * @window: the #BaseWindow which embeds the @view.
+ * nact_tree_ieditable_initialize:
+ * @instance: the #NactTreeView which implements this interface.
+ * @treeview: the embedded #GtkTreeView tree view.
+ * @window: the #BaseWindow which embeds the @instance.
  *
  * Initialize the interface, mainly connecting to signals of interest.
  */
 void
-nact_tree_ieditable_on_view_constructed( NactTreeView *view, BaseWindow *window )
+nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treeview, BaseWindow *window )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_on_view_constructed";
+	static const gchar *thisfn = "nact_tree_ieditable_initialize";
 	IEditableData *ied;
 
-	g_debug( "%s: view=%p, window=%p", thisfn, ( void * ) view, ( void * ) window );
+	g_debug( "%s: instance=%p, window=%p", thisfn, ( void * ) instance, ( void * ) window );
 
-	ied = get_instance_data( NACT_TREE_IEDITABLE( view ));
+	ied = get_instance_data( instance );
+	ied->treeview = treeview;
 }
 
-static IEditableData *
-get_instance_data( NactTreeIEditable *view )
+/**
+ * nact_tree_ieditable_insert_at_path:
+ * @instance: this #NactTreeIEditable instance.
+ * @items: a list of items to be inserted (e.g. from a paste).
+ * @path: insertion path.
+ *
+ * Inserts the provided @items list in the treeview.
+ *
+ * This function takes care of repositionning a new selection if
+ * possible, and refilter the display model.
+ */
+void
+nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, GtkTreePath *insert_path )
 {
+	static const gchar *thisfn = "nact_tree_ieditable_insert_at_path";
 	IEditableData *ied;
+	GtkTreeModel *model;
+	GList *parents;
 
-	ied = ( IEditableData * ) g_object_get_data( G_OBJECT( view ), VIEW_DATA_IEDITABLE );
-
-	if( !ied ){
-		ied = g_new0( IEditableData, 1 );
-		g_object_set_data( G_OBJECT( view ), VIEW_DATA_IEDITABLE, ied );
-	}
-
-	return( ied );
-}
-
-#if 0
-/* when iterating through a selection
- */
-typedef struct {
-	gboolean has_menu_or_action;
-}
-	SelectionIter;
-
-/* signals
- */
-enum {
-	LIST_COUNT_UPDATED,
-	SELECTION_CHANGED,
-	FOCUS_IN,
-	FOCUS_OUT,
-	COLUMN_EDITED,
-	STATUS_CHANGED,
-	LAST_SIGNAL
-};
+	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
 
-static gint     st_signals[ LAST_SIGNAL ] = { 0 };
-
-static void     free_items_callback( NactTreeIEditable *instance, GList *items );
-static void     free_column_edited_callback( NactTreeIEditable *instance, NAObject *object, gchar *text, gint column );
-
-static gboolean are_profiles_displayed( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid );
-static void     display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeIEditable *instance );
-static gboolean filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, NactTreeIEditable *instance );
-static gboolean filter_selection_is_homogeneous( GtkTreeSelection *selection, NAObject *object );
-static void     filter_selection_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, SelectionIter *str );
-static gboolean filter_selection_has_menu_or_action( GtkTreeSelection *selection );
-static gboolean filter_selection_is_implicitely_selected( NAObject *object );
-static void     filter_selection_set_implicitely_selected_childs( NAObject *object, gboolean select );
-static gboolean have_dnd_mode( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid );
-static gboolean have_filter_selection_mode( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid );
-static void     inline_edition( NactTreeIEditable *instance );
-static gboolean is_iduplicable_proxy( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid );
-static gboolean on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactTreeIEditable *instance );
-static void     on_edition_status_changed( NactTreeIEditable *instance, NAIDuplicable *object );
-static gboolean on_focus_in( GtkWidget *widget, GdkEventFocus *event, NactTreeIEditable *instance );
-static gboolean on_focus_out( GtkWidget *widget, GdkEventFocus *event, NactTreeIEditable *instance );
-static gboolean on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactTreeIEditable *instance );
-static void     on_label_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, NactTreeIEditable *instance );
-static void     on_tab_updatable_item_updated( NactTreeIEditable *instance, NAObject *object, gboolean force_display );
-static void     open_popup( NactTreeIEditable *instance, GdkEventButton *event );
+	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+		g_debug( "%s: instance=%p, items=%p (count=%d)",
+			thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ));
 
-static void
-free_items_callback( NactTreeIEditable *instance, GList *items )
-{
-	g_debug( "nact_tree_ieditable_free_items_callback: selection=%p (%d items)",
-			( void * ) items, g_list_length( items ));
+		ied = get_instance_data( instance );
+		model = gtk_tree_view_get_model( ied->treeview );
+		g_return_if_fail( NACT_IS_TREE_MODEL( model ));
 
-	na_object_free_items( items );
-}
+		do_insert_items( ied->treeview, model, items, insert_path, &parents );
 
-static void
-free_column_edited_callback( NactTreeIEditable *instance, NAObject *object, gchar *text, gint column )
-{
-	static const gchar *thisfn = "nact_tree_ieditable_free_column_edited_callback";
+		g_list_foreach( parents, ( GFunc ) na_object_object_check_status, NULL );
+		g_list_free( parents );
 
-	g_debug( "%s: instance=%p, object=%p (%s), text=%s, column=%d",
-			thisfn, ( void * ) instance, ( void * ) object, G_OBJECT_TYPE_NAME( object ), text, column );
+		increment_counters( instance, ied, items );
 
-	g_free( text );
+		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
+		nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), insert_path );
+	}
 }
 
 /**
- * nact_tree_ieditable_initial_load_toplevel:
- * @instance: this #NactTreeIEditable *instance.
+ * nact_tree_ieditable_insert_items:
+ * @instance: this #NactTreeIEditable instance.
+ * @items: a list of items to be inserted (e.g. from a paste).
+ * @sibling: the #NAObject besides which the insertion should occurs;
+ *  this is mainly used for inserting duplicated items besides each of
+ *  original ones; may be %NULL.
+ *
+ * Inserts the provided @items list just before the @sibling object,
+ * or at the current position in the treeview if @sibling is %NULL.
  *
- * Allocates and initializes the ActionsList widget.
+ * The provided @items list is supposed to be homogeneous, i.e. referes
+ * to only profiles, or only actions or menus.
  *
- * GtkTreeView is created with NactTreeModel model
- * NactTreeModel
- *   implements EggTreeMultiDragSourceIface
- *   is derived from GtkTreeModelFilter
- *     GtkTreeModelFilter is built on top of GtkTreeStore
+ * If the @items list contains profiles, they can only be inserted
+ * into an action, or before another profile.
  *
- * Please note that management mode for the list should have been set
- * before calling this function.
+ * If new item is a #NAObjectMenu or a #NAObjectAction, it will be inserted
+ * before the current action or menu.
+ *
+ * This function takes care of repositionning a new selection (if possible)
+ * on the lastly inserted item, and to refresh the display.
  */
 void
-nact_tree_ieditable_initial_load_toplevel( NactTreeIEditable *instance )
+nact_tree_ieditable_insert_items( NactTreeIEditable *instance, GList *items, NAObject *sibling )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_initial_load_toplevel";
-	GtkWidget *label;
-	GtkTreeView *treeview;
-	GtkTreeViewColumn *column;
-	GtkCellRenderer *renderer;
-	TreeIEditableInstanceData *ialid;
+	static const gchar *thisfn = "nact_tree_ieditable_insert_items";
+	IEditableData *ied;
+	GtkTreeModel *model;
+	GtkTreePath *insert_path;
+	NAObject *object, *parent;
 
-	g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
 	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
 
 	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+		g_debug( "%s: instance=%p, items=%p (count=%d), sibling=%p",
+				thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ), ( void * ) sibling );
+
+		insert_path = NULL;
+		ied = get_instance_data( instance );
+		model = gtk_tree_view_get_model( ied->treeview );
+		g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+
+		if( sibling ){
+			insert_path = nact_tree_model_object_to_path( NACT_TREE_MODEL( model ), sibling );
+
+		} else {
+			insert_path = get_selection_first_path( ied->treeview );
+			object = nact_tree_model_object_at_path( NACT_TREE_MODEL( model ), insert_path );
+			g_debug( "%s: current object at insertion path is %p", thisfn, ( void * ) object );
+
+			/* as a particular case, insert a new profile _into_ current action
+			 */
+			if( NA_IS_OBJECT_ACTION( object ) && NA_IS_OBJECT_PROFILE( items->data )){
+				nact_tree_ieditable_insert_items_into( instance, items );
+				gtk_tree_path_free( insert_path );
+				return;
+			}
+
+			/* insert a new NAObjectItem before current NAObjectItem
+			 */
+			if( NA_IS_OBJECT_PROFILE( object ) && NA_IS_OBJECT_ITEM( items->data )){
+				parent = ( NAObject * ) na_object_get_parent( object );
+				gtk_tree_path_free( insert_path );
+				insert_path = nact_tree_model_object_to_path( NACT_TREE_MODEL( model ), parent );
+			}
+		}
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-		ialid->selection_changed_allowed = FALSE;
-
-		/* associates the ActionsList to the label */
-		label = base_window_get_widget( BASE_WINDOW( instance ), "ActionsListLabel" );
-		gtk_label_set_mnemonic_widget( GTK_LABEL( label ), GTK_WIDGET( treeview ));
-
-		nact_tree_model_initial_load( BASE_WINDOW( instance ), treeview );
-		gtk_tree_view_set_enable_tree_lines( treeview, TRUE );
-
-		/* create visible columns on the tree view
-		 */
-		/* icon: no header */
-		column = gtk_tree_view_column_new_with_attributes(
-				"icon",
-				gtk_cell_renderer_pixbuf_new(),
-				"pixbuf", TREE_IEDITABLE_ICON_COLUMN,
-				NULL );
-		gtk_tree_view_append_column( treeview, column );
-
-		renderer = gtk_cell_renderer_text_new();
-		column = gtk_tree_view_column_new_with_attributes(
-				"label",
-				renderer,
-				"text", TREE_IEDITABLE_LABEL_COLUMN,
-				NULL );
-		gtk_tree_view_column_set_sort_column_id( column, TREE_IEDITABLE_LABEL_COLUMN );
-		gtk_tree_view_column_set_cell_data_func(
-				column, renderer, ( GtkTreeCellDataFunc ) display_label, instance, NULL );
-		gtk_tree_view_append_column( treeview, column );
+		nact_tree_ieditable_insert_at_path( instance, items, insert_path );
+		gtk_tree_path_free( insert_path );
 	}
 }
 
 /**
- * nact_tree_ieditable_runtime_init_toplevel:
- * @window: this #NactTreeIEditable *instance.
- * @items: list of #NAObject actions and menus as provided by #NAPivot.
+ * nact_tree_ieditable_insert_items_into:
+ * @instance: this #NactTreeIEditable instance.
+ * @items: a list of items to be inserted (e.g. from a paste).
  *
- * Allocates and initializes the ActionsList widget.
+ * Inserts the provided @items list as first children of the current item.
+ *
+ * The provided @items list is supposed to be homogeneous, i.e. referes
+ * to only profiles, or only actions or menus.
+ *
+ * If the @items list contains only profiles, they can only be inserted
+ * into an action, and the profiles will eventually be renumbered.
+ *
+ * If new item is a #NAObjectMenu or a #NAObjectAction, it will be inserted
+ * as first children of the current menu.
+ *
+ * This function takes care of repositionning a new selection as the
+ * last inserted item, and refilter the display model.
  */
 void
-nact_tree_ieditable_runtime_init_toplevel( NactTreeIEditable *instance, GList *items )
+nact_tree_ieditable_insert_items_into( NactTreeIEditable *instance, GList *items )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_runtime_init_toplevel";
-	GtkTreeView *treeview;
-	NactTreeModel *model;
-	gboolean have_dnd;
-	gboolean have_filter_selection;
-	gboolean is_proxy;
-	GtkTreeSelection *selection;
-	TreeIEditableInstanceData *ialid;
-	GtkTreeViewColumn *column;
-	GList *renderers;
+	static const gchar *thisfn = "nact_tree_ieditable_insert_items_into";
+	IEditableData *ied;
+	GtkTreeModel *model;
+	GtkTreePath *insert_path;
+	GtkTreePath *new_path;
+	NAObject *parent;
 
-	g_debug( "%s: instance=%p, items=%p (%d items)",
-			thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ));
 	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
 
 	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+		g_debug( "%s: instance=%p, items=%p (count=%d)",
+			thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ));
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
+		insert_path = NULL;
+		ied = get_instance_data( instance );
+		model = gtk_tree_view_get_model( ied->treeview );
+		insert_path = get_selection_first_path( ied->treeview );
 
-		ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-		ialid->selection_changed_allowed = FALSE;
-		have_dnd = have_dnd_mode( instance, ialid );
-		have_filter_selection = have_filter_selection_mode( instance, ialid );
+		increment_counters( instance, ied, items );
 
-		if( have_filter_selection ){
-			selection = gtk_tree_view_get_selection( treeview );
-			gtk_tree_selection_set_select_function( selection, ( GtkTreeSelectionFunc ) filter_selection, instance, NULL );
-		}
+		parent = do_insert_into_first( ied->treeview, model, items, insert_path, &new_path );
 
-		nact_tree_model_runtime_init( model, have_dnd );
-
-		/* set up selection control */
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( gtk_tree_view_get_selection( treeview )),
-				"changed",
-				G_CALLBACK( nact_tree_ieditable_on_treeview_selection_changed ));
-
-		/* catch press 'Enter' */
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( treeview ),
-				"key-press-event",
-				G_CALLBACK( on_key_pressed_event ));
-
-		/* catch double-click */
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( treeview ),
-				"button-press-event",
-				G_CALLBACK( on_button_press_event ));
-
-		/* updates the treeview display when an item is modified */
-		ialid->tab_updated_handler = base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( instance ),
-				TAB_UPDATABLE_SIGNAL_ITEM_UPDATED,
-				G_CALLBACK( on_tab_updatable_item_updated ));
-
-		/* enable/disable edit menu item accelerators depending of
-		 * which widget has the focus */
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( treeview ),
-				"focus-in-event",
-				G_CALLBACK( on_focus_in ));
-
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( treeview ),
-				"focus-out-event",
-				G_CALLBACK( on_focus_out ));
-
-		/* label edition: inform the corresponding tab */
-		column = gtk_tree_view_get_column( treeview, TREE_IEDITABLE_LABEL_COLUMN );
-		renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
-		base_window_signal_connect(
-				BASE_WINDOW( instance ),
-				G_OBJECT( renderers->data ),
-				"edited",
-				G_CALLBACK( on_label_edited ));
-
-		/* records NactTreeIEditable as a proxy for edition status
-		 * modification */
-		is_proxy = is_iduplicable_proxy( instance, ialid );
-		if( is_proxy ){
-			na_iduplicable_register_consumer( G_OBJECT( instance ));
-
-			base_window_signal_connect(
-					BASE_WINDOW( instance ),
-					G_OBJECT( instance ),
-					NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
-					G_CALLBACK( on_edition_status_changed ));
-		}
+		na_object_check_status( parent );
 
-		/* fill the model after having connected the signals
-		 * so that callbacks are triggered at last
-		 */
-		nact_tree_ieditable_fill( instance, items );
+		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
+		nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), new_path );
 
-		/* force the treeview to have the focus at start
-		 */
-		gtk_widget_grab_focus( GTK_WIDGET( treeview ));
+		gtk_tree_path_free( new_path );
+		gtk_tree_path_free( insert_path );
 	}
 }
 
-/**
- * nact_tree_ieditable_all_widgets_showed:
- * @window: this #NactTreeIEditable *instance.
- */
-void
-nact_tree_ieditable_all_widgets_showed( NactTreeIEditable *instance )
+static void
+do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTreePath *insert_path, GList **list_parents )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_all_widgets_showed";
-	gboolean profiles_are_displayed;
-	TreeIEditableInstanceData *ialid;
+	static const gchar *thisfn = "nact_tree_ieditable_do_insert_items";
+	GList *reversed;
+	GList *it;
+	GList *subitems;
+	NAObject *obj_parent;
+	gpointer updatable;
+	GtkTreePath *inserted_path;
 
-	g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+	obj_parent = NULL;
+	if( list_parents ){
+		*list_parents = NULL;
+	}
 
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+	reversed = g_list_reverse( g_list_copy( items ));
+
+	for( it = reversed ; it ; it = it->next ){
+		inserted_path = nact_tree_model_insert( NACT_TREE_MODEL( model ), NA_OBJECT( it->data ), insert_path, &obj_parent );
+
+		g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
+				( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ), G_OBJECT( it->data )->ref_count );
 
-		ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-		profiles_are_displayed = are_profiles_displayed( instance, ialid );
+		if( list_parents ){
+			updatable = obj_parent ? obj_parent : it->data;
+			if( !g_list_find( *list_parents, updatable )){
+				*list_parents = g_list_prepend( *list_parents, updatable );
+			}
+		}
 
-		if( profiles_are_displayed ){
-			nact_tree_ieditable_priv_send_list_count_updated_signal( instance, ialid );
+		/* recursively insert subitems
+		 */
+		if( NA_IS_OBJECT_ITEM( it->data ) && na_object_get_items_count( it->data )){
+			subitems = na_object_get_items( it->data );
+			do_insert_into_first( treeview, model, subitems, inserted_path, NULL );
 		}
 
-		nact_tree_ieditable_bis_select_first_row( instance );
+		gtk_tree_path_free( inserted_path );
 	}
+
+	g_list_free( reversed );
 }
 
-/**
- * nact_tree_ieditable_dispose:
- * @window: this #NactTreeIEditable *instance.
- */
-void
-nact_tree_ieditable_dispose( NactTreeIEditable *instance )
+static NAObject *
+do_insert_into_first( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTreePath *insert_path, GtkTreePath **new_path )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_dispose";
-	GtkTreeView *treeview;
-	NactTreeModel *model;
-	TreeIEditableInstanceData *ialid;
+	static const gchar *thisfn = "nact_tree_ieditable_do_insert_into_first";
+	GList *copy;
+	GList *last;
+	NAObject *parent;
+	gchar *insert_path_str;
+	GtkTreePath *inserted_path;
+	GList *subitems;
 
-	g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+	insert_path_str = gtk_tree_path_to_string( insert_path );
+	g_debug( "%s: treeview=%p, model=%p, items=%p (count=%d), insert_path=%p (%s), new_path=%p",
+			thisfn,
+			( void * ) treeview, ( void * ) model, ( void * ) items, g_list_length( items ),
+			( void * ) insert_path, insert_path_str, ( void * ) new_path );
+	g_free( insert_path_str );
 
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+	parent = NULL;
+	copy = g_list_copy( items );
+	last = g_list_last( copy );
+	copy = g_list_remove_link( copy, last );
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
+	inserted_path = nact_tree_model_insert_into( NACT_TREE_MODEL( model ), NA_OBJECT( last->data ), insert_path, &parent );
+	gtk_tree_view_expand_to_path( treeview, inserted_path );
 
-		ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-		g_list_free( ialid->modified_items );
-		ialid->modified_items = NULL;
+	/* recursively insert subitems
+	 */
+	if( NA_IS_OBJECT_ITEM( last->data ) && na_object_get_items_count( last->data )){
+		subitems = na_object_get_items( last->data );
+		do_insert_into_first( treeview, model, subitems, inserted_path, NULL );
+	}
 
-		ialid->selection_changed_allowed = FALSE;
-		nact_tree_model_dispose( model );
+	do_insert_items( treeview, model, copy, inserted_path, NULL );
 
-		g_free( ialid );
+	if( new_path ){
+		*new_path = gtk_tree_path_copy( inserted_path );
 	}
+
+	g_list_free( copy );
+	gtk_tree_path_free( inserted_path );
+
+	return( parent );
 }
 
-/**
- * nact_tree_ieditable_brief_tree_dump:
- * @instance: this #NactTreeIEditable implementation.
- *
- * Brief dump of the tree store content.
- */
-void
-nact_tree_ieditable_brief_tree_dump( NactTreeIEditable *instance )
+static GtkTreePath *
+get_selection_first_path( GtkTreeView *treeview )
 {
-	GtkTreeView *treeview;
-	NactTreeModel *model;
+	GtkTreeSelection *selection;
+	GList *selected;
+	GtkTreePath *path;
 
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+	path = NULL;
+	selection = gtk_tree_view_get_selection( treeview );
+	selected = gtk_tree_selection_get_selected_rows( selection, NULL );
 
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+	if( selected ){
+		path = gtk_tree_path_copy(( GtkTreePath * ) selected->data );
+
+	} else {
+		path = gtk_tree_path_new_from_string( "0" );
+	}
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
-		nact_tree_model_dump( model );
+	g_list_foreach( selected, ( GFunc ) gtk_tree_path_free, NULL );
+	g_list_free( selected );
+
+	return( path );
+}
+
+static IEditableData *
+get_instance_data( NactTreeIEditable *view )
+{
+	IEditableData *ied;
+
+	ied = ( IEditableData * ) g_object_get_data( G_OBJECT( view ), VIEW_DATA_IEDITABLE );
+
+	if( !ied ){
+		ied = g_new0( IEditableData, 1 );
+		g_object_set_data( G_OBJECT( view ), VIEW_DATA_IEDITABLE, ied );
 	}
+
+	return( ied );
 }
 
-/**
- * nact_tree_ieditable_collapse_all:
- * @instance: this #NactTreeIEditable implementation.
- *
- * Collapse all the tree hierarchy.
- */
-void
-nact_tree_ieditable_collapse_all( NactTreeIEditable *instance )
+static void
+increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_collapse_all";
-	GtkTreeView *treeview;
+	static const gchar *thisfn = "nact_tre_ieditablet_increment_counters";
+	guint modified_prev;
+	gint menus, actions, profiles;
+	BaseWindow *window;
 
-	g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+	g_debug( "%s: view=%p, ied=%p, items=%p (count=%d)",
+			thisfn, ( void * ) view, ( void * ) ied, ( void * ) items, items ? g_list_length( items ) : 0 );
 
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+	menus = 0;
+	actions = 0;
+	profiles = 0;
+	na_object_item_count_items( items, &menus, &actions, &profiles, TRUE );
+	window = nact_tree_view_get_window( NACT_TREE_VIEW( view ));
+	g_signal_emit_by_name( G_OBJECT( window ), TREE_SIGNAL_COUNT_CHANGED, view, FALSE, menus, actions, profiles );
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		gtk_tree_view_collapse_all( treeview );
+	modified_prev = ied->count_modified;
+	g_list_foreach( items, ( GFunc ) increment_counters_modified, ied );
+	if( ied->count_modified != modified_prev ){
+		g_signal_emit_by_name( G_OBJECT( window ), TREE_SIGNAL_MODIFIED_COUNT_CHANGED, view, ied->count_modified );
 	}
 }
 
+static void
+increment_counters_modified( NAObject *object, IEditableData *ied )
+{
+	if( NA_IS_OBJECT_ITEM( object )){
+		if( !na_object_get_provider( object )){
+			ied->count_modified += 1;
+		}
+	}
+}
+
+#if 0
+
+/* iter on selection prototype
+ */
+typedef gboolean ( *FnIterOnSelection )( NactIActionsList *, GtkTreeView *, GtkTreeModel *, GtkTreeIter *, NAObject *, gpointer );
+
 /**
- * nact_tree_ieditable_display_order_change:
- * @instance: this #NactTreeIEditable implementation.
- * @order_mode: the new order mode.
+ * nact_iactions_list_bis_clear_selection:
+ * @instance: this instance of the #NactIActionsList interface.
+ * @treeview: the #GtkTreeView.
  *
- * Setup the new order mode.
+ * Clears the current selection.
  */
 void
-nact_tree_ieditable_display_order_change( NactTreeIEditable *instance, gint order_mode )
+nact_iactions_list_bis_clear_selection( NactIActionsList *instance, GtkTreeView *treeview )
 {
-	GtkTreeView *treeview;
-	NactTreeModel *model;
-
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+	GtkTreeSelection *selection;
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
-		nact_tree_model_display_order_change( model, order_mode );
-	}
+	selection = gtk_tree_view_get_selection( treeview );
+	gtk_tree_selection_unselect_all( selection );
 }
 
 /**
- * nact_tree_ieditable_expand_all:
- * @instance: this #NactTreeIEditable implementation.
+ * nact_iactions_list_bis_collapse_to_parent:
+ * @instance: this instance of the #NactIActionsList interface.
  *
- * Expand all the tree hierarchy.
+ * On left arrow, if we are on a first child, then collapse and go to
+ * the parent.
  */
 void
-nact_tree_ieditable_expand_all( NactTreeIEditable *instance )
+nact_iactions_list_bis_collapse_to_parent( NactIActionsList *instance )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_expand_all";
+	static const gchar *thisfn = "nact_iactions_list_bis_collapse_to_parent";
+	IActionsListInstanceData *ialid;
 	GtkTreeView *treeview;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GList *listrows;
+	GtkTreePath *path;
+	gint *indices;
+	GtkTreePath *parent_path;
 
 	g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+	g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
 
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+	ialid = nact_iactions_list_priv_get_instance_data( instance );
+	if( ialid->management_mode == IACTIONS_LIST_MANAGEMENT_MODE_EDITION ){
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		gtk_tree_view_expand_all( treeview );
+		treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+		selection = gtk_tree_view_get_selection( treeview );
+		listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+		if( g_list_length( listrows ) == 1 ){
+
+			path = ( GtkTreePath * ) listrows->data;
+			/*g_debug( "%s: path_depth=%d", thisfn, gtk_tree_path_get_depth( path ));*/
+			if( gtk_tree_path_get_depth( path ) > 1 ){
+
+				indices = gtk_tree_path_get_indices( path );
+				if( indices[ gtk_tree_path_get_depth( path )-1 ] == 0 ){
+
+					parent_path = gtk_tree_path_copy( path );
+					gtk_tree_path_up( parent_path );
+					nact_iactions_list_bis_select_row_at_path( instance, treeview, model, parent_path );
+					gtk_tree_view_collapse_row( treeview, parent_path );
+					gtk_tree_path_free( parent_path );
+				}
+			}
+		}
+
+		g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+		g_list_free( listrows );
 	}
 }
 
 /**
- * nact_tree_ieditable_fill:
- * @instance: this #NactTreeIEditable instance.
+ * nact_iactions_list_bis_delete:
+ * @window: this #NactIActionsList instance.
+ * @list: list of #NAObject to be deleted.
  *
- * Fill the listbox with the provided list of items.
+ * Deletes the specified list from the underlying tree store.
  *
- * Menus are expanded, profiles are not.
- * The selection is reset to the first line of the tree, if there is one.
+ * This function takes care of repositionning a new selection if
+ * possible, and refilter the display model.
  */
 void
-nact_tree_ieditable_fill( NactTreeIEditable *instance, GList *items )
+nact_iactions_list_bis_delete( NactIActionsList *instance, GList *items, gboolean select_at_end )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_fill";
+	static const gchar *thisfn = "nact_iactions_list_bis_delete";
 	GtkTreeView *treeview;
-	NactTreeModel *model;
-	gboolean profiles_are_displayed;
-	TreeIEditableInstanceData *ialid;
-
-	g_debug( "%s: instance=%p, items=%p", thisfn, ( void * ) instance, ( void * ) items );
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+	GtkTreeModel *model;
+	GtkTreePath *path = NULL;
+	GList *it;
+	IActionsListInstanceData *ialid;
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
+	g_debug( "%s: instance=%p, items=%p (count=%d), select_at_end=%s",
+			thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ), select_at_end ? "True":"False" );
+	g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
 
-		nact_tree_ieditable_bis_clear_selection( instance, treeview );
+	if( st_iactions_list_initialized && !st_iactions_list_finalized ){
 
-		ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-		profiles_are_displayed = are_profiles_displayed( instance, ialid );
-		g_debug( "%s: profiles_are_displayed:%s", thisfn, profiles_are_displayed ? "True":"False" );
+		treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+		model = gtk_tree_view_get_model( treeview );
 
+		ialid = nact_iactions_list_priv_get_instance_data( instance );
 		ialid->selection_changed_allowed = FALSE;
-		nact_tree_model_fill( model, items, profiles_are_displayed );
-		ialid->selection_changed_allowed = TRUE;
-
-		g_list_free( ialid->modified_items );
-		ialid->modified_items = NULL;
-
-		g_signal_emit_by_name(
-				instance,
-				MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED,
-				GINT_TO_POINTER( FALSE ));
-
-		ialid->menus = 0;
-		ialid->actions = 0;
-		ialid->profiles = 0;
-
-		if( profiles_are_displayed ){
-			na_object_item_count_items( items, &ialid->menus, &ialid->actions, &ialid->profiles, TRUE );
-			nact_tree_ieditable_priv_send_list_count_updated_signal( instance, ialid );
-		}
-	}
-}
-
-/**
- * nact_tree_ieditable_get_management_mode:
- * @instance: this #NactTreeIEditable instance.
- *
- * Returns: the current management mode of the list.
- */
-gint
-nact_tree_ieditable_get_management_mode( NactTreeIEditable *instance )
-{
-	gint mode = 0;
-	TreeIEditableInstanceData *ialid;
 
-	g_return_val_if_fail( NACT_IS_TREE_IEDITABLE( instance ), 0 );
+		decrement_counters( instance, ialid, items );
 
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+		for( it = items ; it ; it = it->next ){
+			if( path ){
+				gtk_tree_path_free( path );
+			}
 
-		ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-		mode = ialid->management_mode;
-	}
+			path = nact_tree_model_remove( NACT_TREE_MODEL( model ), NA_OBJECT( it->data ));
 
-	return( mode );
-}
+			ialid->modified_items = nact_iactions_list_remove_rec( ialid->modified_items, NA_OBJECT( it->data ));
 
-/**
- * nact_tree_ieditable_has_modified_items:
- * @window: this #NactTreeIEditable instance.
- *
- * Returns: %TRUE if at least there is one modified item in the list.
- */
-gboolean
-nact_tree_ieditable_has_modified_items( NactTreeIEditable *instance )
-{
-	gboolean has_modified = FALSE;
-	/*GtkTreeView *treeview;
-	NactTreeModel *model;*/
-	TreeIEditableInstanceData *ialid;
-
-	g_return_val_if_fail( NACT_IS_TREE_IEDITABLE( instance ), FALSE );
+			g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
+					( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ), G_OBJECT( it->data )->ref_count );
+		}
 
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
 
-		ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-		has_modified = ( g_list_length( ialid->modified_items ) > 0 );
+		ialid->selection_changed_allowed = TRUE;
 
-		/*treeview = get_actions_list_treeview( instance );
-		model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
-		nact_tree_model_iter( model, ( FnIterOnStore ) has_modified_iter, &has_modified );*/
+		if( path ){
+			if( select_at_end ){
+				nact_iactions_list_bis_select_row_at_path( instance, treeview, model, path );
+			}
+			gtk_tree_path_free( path );
+		}
 	}
-
-	return( has_modified );
 }
 
 /**
- * nact_tree_ieditable_on_treeview_selection_changed:
- * @selection: current selection.
- * @instance: this instance of the #NactTreeIEditable interface.
+ * nact_iactions_list_bis_expand_to_first_child:
+ * @instance: this #NactIActionsList interface.
  *
- * This is our handler for "changed" signal emitted by the treeview.
- * The handler is inhibited while filling the list (usually only at
- * runtime init), and while deleting a selection.
+ * On right arrow, expand the parent if it has childs, and select the
+ * first child.
  */
 void
-nact_tree_ieditable_on_treeview_selection_changed( GtkTreeSelection *selection, NactTreeIEditable *instance )
+nact_iactions_list_bis_expand_to_first_child( NactIActionsList *instance )
 {
-	GList *selected_items;
-	TreeIEditableInstanceData *ialid;
-
-	ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-	if( ialid->selection_changed_allowed ){
+	static const gchar *thisfn = "nact_iactions_list_bis_expand_to_first_child";
+	IActionsListInstanceData *ialid;
+	GtkTreeView *treeview;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GList *listrows;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	GtkTreePath *child_path;
 
-		g_debug( "nact_tree_ieditable_on_treeview_selection_changed" );
-		g_signal_handler_block( instance, ialid->tab_updated_handler );
+	g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
+	g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
 
-		selected_items = nact_tree_ieditable_bis_get_selected_items( instance );
-		g_debug( "nact_tree_ieditable_on_treeview_selection_changed: selection=%p (%d items)", ( void * ) selected_items, g_list_length( selected_items ));
-		g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_SELECTION_CHANGED, selected_items );
+	ialid = nact_iactions_list_priv_get_instance_data( instance );
+	if( ialid->management_mode == IACTIONS_LIST_MANAGEMENT_MODE_EDITION ){
+		treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+		selection = gtk_tree_view_get_selection( treeview );
+		listrows = gtk_tree_selection_get_selected_rows( selection, &model );
 
-		g_signal_handler_unblock( instance, ialid->tab_updated_handler );
+		if( g_list_length( listrows ) == 1 ){
+			path = ( GtkTreePath * ) listrows->data;
+			gtk_tree_model_get_iter( model, &iter, path );
+			if( gtk_tree_model_iter_has_child( model, &iter )){
+				child_path = gtk_tree_path_copy( path );
+				gtk_tree_path_append_index( child_path, 0 );
+				gtk_tree_view_expand_row( treeview, child_path, FALSE );
+				nact_iactions_list_bis_select_row_at_path( instance, treeview, model, child_path );
+				gtk_tree_path_free( child_path );
+			}
+		}
 
-		/* selection list is freed in cleanup handler for the signal */
+		g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+		g_list_free( listrows );
 	}
 }
 
 /**
- * nact_tree_ieditable_remove_rec:
- * @list: list of modified objects.
- * @object: the object to be removed from the list.
- *
- * When removing from modified list an object which is no more modified,
- * then all subitems of the object have also to be removed
+ * nact_iactions_list_bis_get_selected_items:
+ * @window: this #NactIActionsList instance.
  *
- * Returns: the updated list.
- */
-GList *
-nact_tree_ieditable_remove_rec( GList *list, NAObject *object )
-{
-	GList *subitems, *it;
-
-	if( NA_IS_OBJECT_ITEM( object )){
-		subitems = na_object_get_items( object );
-		for( it = subitems ; it ; it = it->next ){
-			list = nact_tree_ieditable_remove_rec( list, it->data );
-		}
-	}
-
-	list = g_list_remove( list, object );
-
-	return( list );
-}
-
-/**
- * nact_tree_ieditable_set_management_mode:
- * @instance: this #NactTreeIEditable instance.
- * @mode: management mode.
+ * Returns: the currently selected rows as a list of #NAObjects.
  *
- * Set the management mode for this @instance.
+ * We acquire here a new reference on objects corresponding to actually
+ * selected rows, and their childs.
  *
- * For the two known modes (edition mode, export mode), we also allow
- * multiple selection in the list.
+ * The caller may safely call na_object_free_items() on the
+ * returned list.
  */
-void
-nact_tree_ieditable_set_management_mode( NactTreeIEditable *instance, gint mode )
+GList *
+nact_iactions_list_bis_get_selected_items( NactIActionsList *instance )
 {
+	GList *items = NULL;
 	GtkTreeView *treeview;
 	GtkTreeSelection *selection;
-	gboolean multiple;
-	TreeIEditableInstanceData *ialid;
-
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-
-	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GList *it, *listrows;
+	NAObject *object;
+	GtkTreePath *path;
 
-		ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-		ialid->management_mode = mode;
+	g_return_val_if_fail( NACT_IS_IACTIONS_LIST( instance ), NULL );
 
-		multiple = ( mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION ||
-						mode == TREE_IEDITABLE_MANAGEMENT_MODE_EXPORT );
+	if( st_iactions_list_initialized && !st_iactions_list_finalized ){
 
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
+		treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
 		selection = gtk_tree_view_get_selection( treeview );
-		gtk_tree_selection_set_mode( selection, multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE );
-	}
-}
+		listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+
+		for( it = listrows ; it ; it = it->next ){
+			path = ( GtkTreePath * ) it->data;
+			gtk_tree_model_get_iter( model, &iter, path );
+			gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+			g_debug( "nact_iactions_list_get_selected_items: object=%p", ( void * ) object );
+			items = g_list_prepend( items, na_object_ref( object ));
+			g_object_unref( object );
+		}
 
-static gboolean
-are_profiles_displayed( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid )
-{
-	gboolean display;
+		g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+		g_list_free( listrows );
 
-	display = ( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION );
+		items = g_list_reverse( items );
+	}
 
-	return( display );
+	return( items );
 }
 
-/*
- * item modified: italic
- * item not saveable (invalid): red
+/**
+ * nact_iactions_list_bis_list_modified_items:
+ * @instance: this #NactIActionsList instance.
+ *
+ * Dumps the modified items list.
  */
-static void
-display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeIEditable *instance )
+void
+nact_iactions_list_bis_list_modified_items( NactIActionsList *instance )
 {
-	NAObject *object;
-	gchar *label;
-	gboolean modified = FALSE;
-	gboolean valid = TRUE;
-	TreeIEditableInstanceData *ialid;
-	NAObjectItem *item;
-#if 0
-	gboolean writable_item;
-	NactApplication *application;
-	NAUpdater *updater;
-#endif
+	static const gchar *thisfn = "nact_iactions_list_bis_list_modified_items";
+	IActionsListInstanceData *ialid;
+	GList *it;
 
-	gtk_tree_model_get( model, iter, TREE_IEDITABLE_NAOBJECT_COLUMN, &object, -1 );
-	g_object_unref( object );
-	g_return_if_fail( NA_IS_OBJECT( object ));
-
-	ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-	label = na_object_get_label( object );
-	g_object_set( cell, "style-set", FALSE, NULL );
-	g_object_set( cell, "foreground-set", FALSE, NULL );
-	/*g_debug( "nact_tree_ieditable_display_label: %s %s", G_OBJECT_TYPE_NAME( object ), label );*/
+	g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
+	g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
 
-	if( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION ){
+	if( st_iactions_list_initialized && !st_iactions_list_finalized ){
 
-		modified = na_object_is_modified( object );
-		valid = na_object_is_valid( object );
-		item = NA_IS_OBJECT_PROFILE( object ) ? na_object_get_parent( object ) : NA_OBJECT_ITEM( object );
+		ialid = nact_iactions_list_priv_get_instance_data( instance );
 
-		if( modified ){
-			g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
+		g_debug( "%s: raw list", thisfn );
+		for( it = ialid->modified_items ; it ; it = it->next ){
+			g_debug( "%s: %p (%s)", thisfn, ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ));
 		}
 
-		if( !valid ){
-			g_object_set( cell, "foreground", "Red", "foreground-set", TRUE, NULL );
+		g_debug( "%s: detailed list", thisfn );
+		for( it = ialid->modified_items ; it ; it = it->next ){
+			na_object_dump( it->data );
 		}
-
-#if 0
-		application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( instance )));
-		updater = nact_application_get_updater( application );
-		writable_item = na_updater_is_item_writable( updater, item, NULL );
-		g_object_set( cell, "editable", writable_item, NULL );
-#endif
 	}
-
-	g_object_set( cell, "text", label, NULL );
-	g_free( label );
 }
 
-/*
- * rationale: it is very difficult to copy anything in the clipboard,
- * and to hope that this will be easily copyable anywhere after.
- * We know how to insert profiles, or how to insert actions or menus,
- * but not how nor where to insert e.g. a mix selection.
- *
- * So a selection must first be homogeneous, i.e. it only contains
- * explicitely selected profiles _or_ menus or actions (and their childs).
+/**
+ * nact_iactions_list_bis_remove_modified:
+ * @instance: this #NactIActionsList instance.
  *
- * To simplify the selection management while letting the user actually
- * select almost anything, we are doing following assumptions:
- * - when the user selects one row, all childs are also automatically
- *   selected ; visible childs are setup so that they are known as
- *   'indirectly' selected
- * - when a row is set as 'indirectly' selected, user cannot select
- *   nor unselect it (sort of readonly or mandatory implied selection)
- *   while the parent stays itself selected
+ * Removes the saved item from the modified items list.
  */
-static gboolean
-filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, NactTreeIEditable *instance )
+void
+nact_iactions_list_bis_remove_modified( NactIActionsList *instance, const NAObjectItem *item )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_filter_selection";
-	GList *selected_paths;
-	GtkTreeIter iter;
-	NAObject *object;
+	IActionsListInstanceData *ialid;
 
-	gtk_tree_model_get_iter( model, &iter, path );
-	gtk_tree_model_get( model, &iter, TREE_IEDITABLE_NAOBJECT_COLUMN, &object, -1 );
-	g_return_val_if_fail( object, FALSE );
-	g_return_val_if_fail( NA_IS_OBJECT_ID( object ), FALSE );
-	g_object_unref( object );
+	g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
 
-	/* if there is not yet any selection, then anything is allowed
-	 */
-	selected_paths = gtk_tree_selection_get_selected_rows( selection, NULL );
-	if( !selected_paths || !g_list_length( selected_paths )){
-		/*g_debug( "%s: current selection is empty: allowing this one", thisfn );*/
-		filter_selection_set_implicitely_selected_childs( object, !path_currently_selected );
-		return( TRUE );
-	}
-
-	/* if the object at the row is already 'implicitely' selected, i.e.
-	 * selected because of the selection of one of its parents, then
-	 * nothing is allowed
-	 */
-	if( filter_selection_is_implicitely_selected( object )){
-		g_debug( "%s: implicitely selected item: selection not allowed", thisfn );
-		return( FALSE );
-	}
+	if( st_iactions_list_initialized && !st_iactions_list_finalized ){
 
-	/* object at the row is not 'implicitely' selected: we may so select
-	 * or unselect it while the selection stays homogeneous
-	 * (rather we set its childs to the corresponding implied status)
-	 */
-	if( path_currently_selected ||
-		filter_selection_is_homogeneous( selection, object )){
+		ialid = nact_iactions_list_priv_get_instance_data( instance );
+		ialid->modified_items = g_list_remove( ialid->modified_items, item );
 
-			filter_selection_set_implicitely_selected_childs( object, !path_currently_selected );
+		if( g_list_length( ialid->modified_items ) == 0 ){
+			g_list_free( ialid->modified_items );
+			ialid->modified_items = NULL;
+		}
 	}
-	return( TRUE );
 }
 
-/*
- * does the selection stay homogeneous when adding this object ?
+/**
+ * nact_iactions_list_bis_toggle_collapse:
+ * @instance: this #NactIActionsList interface.
+ *
+ * Toggle or collapse the current subtree.
  */
-static gboolean
-filter_selection_is_homogeneous( GtkTreeSelection *selection, NAObject *object )
+void
+nact_iactions_list_bis_toggle_collapse( NactIActionsList *instance )
 {
-	gboolean homogeneous;
+	int toggle = TOGGLE_UNDEFINED;
 
-	if( filter_selection_has_menu_or_action( selection )){
-		homogeneous = !NA_IS_OBJECT_PROFILE( object );
-	} else {
-		homogeneous = NA_IS_OBJECT_PROFILE( object );
-	}
-
-	return( homogeneous );
+	iter_on_selection( instance, ( FnIterOnSelection ) toggle_collapse_iter, &toggle );
 }
 
-static gboolean
-filter_selection_has_menu_or_action( GtkTreeSelection *selection )
+/**
+ * nact_iactions_list_bis_toggle_collapse_object:
+ * @instance: the current instance of the #NactIActionsList interface.
+ * @item: the item to be toggled/collapsed.
+ *
+ * Collapse / expand if actions has more than one profile.
+ */
+void
+nact_iactions_list_bis_toggle_collapse_object( NactIActionsList *instance, const NAObject *item )
 {
-	gboolean has_menu_or_action;
-	SelectionIter *str;
+	static const gchar *thisfn = "nact_iactions_list_bis_toggle_collapse";
+	GtkTreeView *treeview;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean iterok, stop;
+	NAObject *iter_object;
 
-	has_menu_or_action = FALSE;
-	str = g_new0( SelectionIter, 1 );
-	str->has_menu_or_action = has_menu_or_action;
-	gtk_tree_selection_selected_foreach( selection, ( GtkTreeSelectionForeachFunc ) filter_selection_iter, str );
-	has_menu_or_action = str->has_menu_or_action;
-	g_free( str );
+	g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
+	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
 
-	return( has_menu_or_action );
-}
+	if( st_iactions_list_initialized && !st_iactions_list_finalized ){
 
-static void
-filter_selection_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, SelectionIter *str )
-{
-	NAObject *object;
+		treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+		model = gtk_tree_view_get_model( treeview );
+		iterok = gtk_tree_model_get_iter_first( model, &iter );
+		stop = FALSE;
 
-	gtk_tree_model_get( model, iter, TREE_IEDITABLE_NAOBJECT_COLUMN, &object, -1 );
+		while( iterok && !stop ){
 
-	if( NA_IS_OBJECT_ITEM( object )){
-		str->has_menu_or_action = TRUE;
-	}
+			gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &iter_object, -1 );
+			if( iter_object == item ){
 
-	g_object_unref( object );
-}
+				if( na_object_get_items_count( item ) > 1 ){
 
-static gboolean
-filter_selection_is_implicitely_selected( NAObject *object )
-{
-	gboolean selected;
+					GtkTreePath *path = gtk_tree_model_get_path( model, &iter );
 
-	selected = ( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( object), "nact-implicit-selection" ));
+					if( gtk_tree_view_row_expanded( GTK_TREE_VIEW( treeview ), path )){
+						gtk_tree_view_collapse_row( GTK_TREE_VIEW( treeview ), path );
+						g_debug( "%s: action=%p collapsed", thisfn, ( void * ) item );
 
-	return( selected );
-}
+					} else {
+						gtk_tree_view_expand_row( GTK_TREE_VIEW( treeview ), path, TRUE );
+						g_debug( "%s: action=%p expanded", thisfn, ( void * ) item );
+					}
 
-/*
- * the object is being selected (resp. unselected)
- * recursively set the 'implicit selection' flag for all its childs
- */
-static void
-filter_selection_set_implicitely_selected_childs( NAObject *object, gboolean select )
-{
-	GList *childs, *ic;
+					gtk_tree_path_free( path );
+				}
+				stop = TRUE;
+			}
 
-	if( NA_IS_OBJECT_ITEM( object )){
-		childs = na_object_get_items( object );
-		for( ic = childs ; ic ; ic = ic->next ){
-			g_object_set_data( G_OBJECT( ic->data ), "nact-implicit-selection", GUINT_TO_POINTER(( guint ) select ));
-			filter_selection_set_implicitely_selected_childs( NA_OBJECT( ic->data ), select );
+			g_object_unref( iter_object );
+			iterok = gtk_tree_model_iter_next( model, &iter );
 		}
 	}
 }
 
-static gboolean
-have_dnd_mode( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid )
+static void
+decrement_counters( NactIActionsList *instance, IActionsListInstanceData *ialid, GList *items )
 {
-	gboolean have_dnd;
+	static const gchar *thisfn = "nact_iactions_list_decrement_counters";
+	gint menus, actions, profiles;
 
-	have_dnd = ( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION );
+	g_debug( "%s: instance=%p, ialid=%p, items=%p",
+			thisfn, ( void * ) instance, ( void * ) ialid, ( void * ) items );
 
-	return( have_dnd );
-}
+	menus = 0;
+	actions = 0;
+	profiles = 0;
+	na_object_item_count_items( items, &menus, &actions, &profiles, TRUE );
 
-static gboolean
-have_filter_selection_mode( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid )
-{
-	gboolean have_filter;
-
-	have_filter = ( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION );
+	ialid->menus -= menus;
+	ialid->actions -= actions;
+	ialid->profiles -= profiles;
 
-	return( have_filter );
+	nact_iactions_list_priv_send_list_count_updated_signal( instance, ialid );
 }
 
 /*
- * triggered by 'F2' key
- * only in edition mode
+ * when expanding a selected row which has childs
  */
 static void
-inline_edition( NactTreeIEditable *instance )
+extend_selection_to_childs( NactIActionsList *instance, GtkTreeView *treeview, GtkTreeModel *model, GtkTreeIter *parent )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_inline_edition";
-	TreeIEditableInstanceData *ialid;
-	GtkTreeView *treeview;
 	GtkTreeSelection *selection;
-	GList *listrows;
-	GtkTreePath *path;
-	GtkTreeViewColumn *column;
-
-	g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-
-	ialid = nact_tree_ieditable_priv_get_instance_data( instance );
-	if( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION ){
-
-		ialid->selection_changed_allowed = FALSE;
-
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		selection = gtk_tree_view_get_selection( treeview );
-		listrows = gtk_tree_selection_get_selected_rows( selection, NULL );
-
-		if( g_list_length( listrows ) == 1 ){
-			path = ( GtkTreePath * ) listrows->data;
-			column = gtk_tree_view_get_column( treeview, TREE_IEDITABLE_LABEL_COLUMN );
-			gtk_tree_view_set_cursor( treeview, path, column, TRUE );
-		}
-
-		g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
-		g_list_free( listrows );
-
-		ialid->selection_changed_allowed = TRUE;
-	}
-}
-
-static gboolean
-is_iduplicable_proxy( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid )
-{
-	gboolean is_proxy;
-
-	is_proxy = ( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION );
-	g_debug( "nact_tree_ieditable_is_iduplicable_proxy: is_proxy=%s", is_proxy ? "True":"False" );
-
-	return( is_proxy );
-}
-
-static gboolean
-on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactTreeIEditable *instance )
-{
-	/*static const gchar *thisfn = "nact_tree_ieditable_v_on_button_pres_event";
-	g_debug( "%s: widget=%p, event=%p, user_data=%p", thisfn, widget, event, user_data );*/
+	GtkTreeIter iter;
+	gboolean ok;
 
-	gboolean stop = FALSE;
+	selection = gtk_tree_view_get_selection( treeview );
 
-	/* double-click of left button */
-	if( event->type == GDK_2BUTTON_PRESS && event->button == 1 ){
-		nact_tree_ieditable_bis_toggle_collapse( instance );
-		stop = TRUE;
-	}
+	ok = gtk_tree_model_iter_children( model, &iter, parent );
 
-	/* single click on right button */
-	if( event->type == GDK_BUTTON_PRESS && event->button == 3 ){
-		open_popup( instance, event );
-		stop = TRUE;
+	while( ok ){
+		GtkTreePath *path = gtk_tree_model_get_path( model, &iter );
+		gtk_tree_selection_select_path( selection, path );
+		gtk_tree_path_free( path );
+		ok = gtk_tree_model_iter_next( model, &iter );
 	}
-
-	return( stop );
 }
 
 static void
-on_edition_status_changed( NactTreeIEditable *instance, NAIDuplicable *object )
+iter_on_selection( NactIActionsList *instance, FnIterOnSelection fn_iter, gpointer user_data )
 {
 	GtkTreeView *treeview;
-	NactTreeModel *model;
-	TreeIEditableInstanceData *ialid;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GList *listrows, *ipath;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	NAObject *object;
+	gboolean stop = FALSE;
 
-	ialid = nact_tree_ieditable_priv_get_instance_data( instance );
+	treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+	selection = gtk_tree_view_get_selection( treeview );
+	listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+	listrows = g_list_reverse( listrows );
 
-	g_debug( "nact_tree_ieditable_on_edition_status_changed: instance=%p, object=%p (%s)",
-			( void * ) instance,
-			( void * ) object, G_OBJECT_TYPE_NAME( object ));
+	for( ipath = listrows ; !stop && ipath ; ipath = ipath->next ){
 
-	g_return_if_fail( NA_IS_OBJECT( object ));
+		path = ( GtkTreePath * ) ipath->data;
+		gtk_tree_model_get_iter( model, &iter, path );
+		gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
 
-	treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-	model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
-	nact_tree_model_display( model, NA_OBJECT( object ));
+		stop = fn_iter( instance, treeview, model, &iter, object, user_data );
 
-	if( na_object_is_modified( object )){
-		if( !g_list_find( ialid->modified_items, object )){
-			ialid->modified_items = g_list_prepend( ialid->modified_items, object );
-		}
-	} else {
-		ialid->modified_items = nact_tree_ieditable_remove_rec( ialid->modified_items, NA_OBJECT( object ));
+		g_object_unref( object );
 	}
 
-	/* do not send status-changed signal while filling the tree
-	 */
-	if( ialid->selection_changed_allowed ){
-		g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_STATUS_CHANGED, NULL );
-	}
+	g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+	g_list_free( listrows );
 }
 
-/*
- * focus is monitored to avoid an accelerator being pressed while on a tab
- * triggers an unwaited operation on the list
- * e.g. when editing an entry field on the tab, pressing Del should _not_
- * delete current row in the list !
- */
 static gboolean
-on_focus_in( GtkWidget *widget, GdkEventFocus *event, NactTreeIEditable *instance )
+toggle_collapse_iter( NactIActionsList *instance,
+						GtkTreeView *treeview,
+						GtkTreeModel *model,
+						GtkTreeIter *iter,
+						NAObject *object,
+						gpointer user_data )
 {
-	/*static const gchar *thisfn = "nact_tree_ieditable_on_focus_in";*/
-	gboolean stop = FALSE;
-
-	/*g_debug( "%s: widget=%p, event=%p, instance=%p", thisfn, ( void * ) widget, ( void * ) event, ( void * ) instance );*/
-	g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_FOCUS_IN, instance );
-
-	return( stop );
-}
+	guint count;
+	guint *toggle;
 
-static gboolean
-on_focus_out( GtkWidget *widget, GdkEventFocus *event, NactTreeIEditable *instance )
-{
-	/*static const gchar *thisfn = "nact_tree_ieditable_on_focus_out";*/
-	gboolean stop = FALSE;
+	toggle = ( guint * ) user_data;
 
-	/*g_debug( "%s: widget=%p, event=%p, instance=%p", thisfn, ( void * ) widget, ( void * ) event, ( void * ) instance );*/
-	g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_FOCUS_OUT, instance );
+	if( NA_IS_OBJECT_ITEM( object )){
 
-	return( stop );
-}
+		GtkTreePath *path = gtk_tree_model_get_path( model, iter );
 
-static gboolean
-on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactTreeIEditable *instance )
-{
-	/*static const gchar *thisfn = "nact_tree_ieditable_v_on_key_pressed_event";
-	g_debug( "%s: widget=%p, event=%p, user_data=%p", thisfn, widget, event, user_data );*/
-	gboolean stop = FALSE;
+		if( NA_IS_OBJECT_ITEM( object )){
+			count = na_object_get_items_count( object );
 
-	if( event->keyval == NACT_KEY_Return || event->keyval == NACT_KEY_KP_Enter ){
-		nact_tree_ieditable_bis_toggle_collapse( instance );
-		stop = TRUE;
-	}
+			if(( count > 1 && NA_IS_OBJECT_ACTION( object )) ||
+				( count > 0 && NA_IS_OBJECT_MENU( object ))){
 
-	if( event->keyval == NACT_KEY_F2 ){
-		inline_edition( instance );
-		stop = TRUE;
-	}
+				toggle_collapse_row( treeview, path, toggle );
+			}
+		}
 
-	if( event->keyval == NACT_KEY_Right ){
-		nact_tree_ieditable_bis_expand_to_first_child( instance );
-		stop = TRUE;
-	}
+		gtk_tree_path_free( path );
 
-	if( event->keyval == NACT_KEY_Left ){
-		nact_tree_ieditable_bis_collapse_to_parent( instance );
-		stop = TRUE;
+		/* do not extend selection */
+		if( *toggle == TOGGLE_EXPAND && FALSE ){
+			extend_selection_to_childs( instance, treeview, model, iter );
+		}
 	}
 
-	return( stop );
-}
-
-/*
- * path: path of the edited row, as a string
- * text: new text
- *
- * - inform tabs so that they can update their fields
- *   data = object_at_row + new_label
- *   this will trigger set the object content, and other updates
- */
-static void
-on_label_edited( GtkCellRendererText *renderer, const gchar *path_str, const gchar *text, NactTreeIEditable *instance )
-{
-	GtkTreeView *treeview;
-	NactTreeModel *model;
-	NAObject *object;
-	GtkTreePath *path;
-	gchar *new_text;
-
-	treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-	model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
-	path = gtk_tree_path_new_from_string( path_str );
-	object = nact_tree_model_object_at_path( model, path );
-	new_text = g_strdup( text );
-
-	g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_COLUMN_EDITED, object, new_text, TREE_IEDITABLE_LABEL_COLUMN );
+	/* do not stop iteration */
+	return( FALSE );
 }
 
 /*
- * an item has been updated in one of the tabs
- * update the treeview to reflects its new edition status
+ * toggle mode can be undefined, collapse or expand
+ * it is set on the first row
  */
 static void
-on_tab_updatable_item_updated( NactTreeIEditable *instance, NAObject *object, gboolean force_display )
+toggle_collapse_row( GtkTreeView *treeview, GtkTreePath *path, guint *toggle )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_on_tab_updatable_item_updated";
-	GtkTreeView *treeview;
-	GtkTreeModel *model;
-
-	g_debug( "%s: instance=%p, object=%p (%s), force_display=%s", thisfn,
-			( void * ) instance, ( void * ) object, G_OBJECT_TYPE_NAME( object ),
-			force_display ? "True":"False" );
-	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-	g_return_if_fail( NA_IS_OBJECT( object ));
-	g_return_if_fail( NA_IS_IDUPLICABLE( object ));
-
-	if( object ){
-		treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-		model = gtk_tree_view_get_model( treeview );
-		if( !na_object_check_status_up( object ) && force_display ){
-			on_edition_status_changed( instance, NA_IDUPLICABLE( object ));
-		}
+	if( *toggle == TOGGLE_UNDEFINED ){
+		*toggle = gtk_tree_view_row_expanded( treeview, path ) ? TOGGLE_COLLAPSE : TOGGLE_EXPAND;
 	}
-}
 
-static void
-open_popup( NactTreeIEditable *instance, GdkEventButton *event )
-{
-	GtkTreeView *treeview;
-	GtkTreeModel *model;
-	GtkTreePath *path;
-
-	treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-
-	if( gtk_tree_view_get_path_at_pos( treeview, event->x, event->y, &path, NULL, NULL, NULL )){
-		model = gtk_tree_view_get_model( treeview );
-		nact_tree_ieditable_bis_select_row_at_path( instance, treeview, model, path );
-		gtk_tree_path_free( path );
-		nact_menubar_open_popup( BASE_WINDOW( instance ), event );
+	if( *toggle == TOGGLE_COLLAPSE ){
+		if( gtk_tree_view_row_expanded( treeview, path )){
+			gtk_tree_view_collapse_row( treeview, path );
+		}
+	} else {
+		if( !gtk_tree_view_row_expanded( treeview, path )){
+			gtk_tree_view_expand_row( treeview, path, TRUE );
+		}
 	}
 }
 #endif
diff --git a/src/nact/nact-tree-ieditable.h b/src/nact/nact-tree-ieditable.h
index 066f61e..0c63a23 100644
--- a/src/nact/nact-tree-ieditable.h
+++ b/src/nact/nact-tree-ieditable.h
@@ -47,7 +47,9 @@
  * The modified count is fully recomputed after a save.
  */
 
-#include "nact-tree-view.h"
+#include <api/na-object.h>
+
+#include "base-window.h"
 
 G_BEGIN_DECLS
 
@@ -68,16 +70,13 @@ typedef struct {
 
 GType nact_tree_ieditable_get_type( void );
 
-void  nact_tree_ieditable_on_view_constructed( NactTreeView *view, BaseWindow *window );
+void  nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treeview, BaseWindow *window );
+
+void  nact_tree_ieditable_insert_at_path   ( NactTreeIEditable *instance, GList *items, GtkTreePath *path );
+void  nact_tree_ieditable_insert_items     ( NactTreeIEditable *instance, GList *items, NAObject *sibling );
+void  nact_tree_ieditable_insert_items_into( NactTreeIEditable *instance, GList *items );
 
 #if 0
-/* signals
- */
-#define TREE_IEDITABLE_SIGNAL_LIST_COUNT_UPDATED			"nact-iactions-list-count-updated"
-#define TREE_IEDITABLE_SIGNAL_FOCUS_IN					"nact-iactions-list-focus-in"
-#define TREE_IEDITABLE_SIGNAL_FOCUS_OUT					"nact-iactions-list-focus-out"
-#define TREE_IEDITABLE_SIGNAL_COLUMN_EDITED				"nact-iactions-list-column-edited"
-#define TREE_IEDITABLE_SIGNAL_STATUS_CHANGED				"nact-iactions-list-status-changed"
 
 void      nact_tree_ieditable_initial_load_toplevel( NactTreeIEditable *instance );
 void      nact_tree_ieditable_runtime_init_toplevel( NactTreeIEditable *instance, GList *actions );
@@ -102,9 +101,6 @@ void      nact_tree_ieditable_bis_expand_to_first_child( NactTreeIEditable *inst
 NAObject *nact_tree_ieditable_bis_get_item( NactTreeIEditable *instance, const gchar *id );
 GList    *nact_tree_ieditable_bis_get_items( NactTreeIEditable *instance );
 GList    *nact_tree_ieditable_bis_get_selected_items( NactTreeIEditable *instance );
-void      nact_tree_ieditable_bis_insert_at_path( NactTreeIEditable *instance, GList *items, GtkTreePath *path );
-void      nact_tree_ieditable_bis_insert_items( NactTreeIEditable *instance, GList *items, NAObject *sibling );
-void      nact_tree_ieditable_bis_insert_into( NactTreeIEditable *instance, GList *items );
 void      nact_tree_ieditable_bis_list_modified_items( NactTreeIEditable *instance );
 void      nact_tree_ieditable_bis_remove_modified( NactTreeIEditable *instance, const NAObjectItem *item );
 void      nact_tree_ieditable_bis_select_first_row( NactTreeIEditable *instance );
diff --git a/src/nact/nact-tree-model-dnd.c b/src/nact/nact-tree-model-dnd.c
index 95e80d7..09fdf91 100644
--- a/src/nact/nact-tree-model-dnd.c
+++ b/src/nact/nact-tree-model-dnd.c
@@ -49,6 +49,7 @@
 #include "nact-main-window.h"
 #include "nact-tree-model.h"
 #include "nact-tree-model-priv.h"
+#include "nact-tree-ieditable.h"
 
 /*
  * call once egg_tree_multi_drag_add_drag_support( treeview ) at init time (before gtk_main)
@@ -455,7 +456,7 @@ nact_tree_model_dnd_imulti_drag_source_row_draggable( EggTreeMultiDragSource *dr
 
 			path = gtk_tree_row_reference_get_path(( GtkTreeRowReference * ) it->data );
 			gtk_tree_model_get_iter( store, &iter, path );
-			gtk_tree_model_get( store, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+			gtk_tree_model_get( store, &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
 
 			if( NA_IS_OBJECT_PROFILE( object )){
 				model->private->drag_has_profiles = TRUE;
@@ -610,7 +611,7 @@ drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selecti
 		path = gtk_tree_row_reference_get_path(( GtkTreeRowReference * ) it->data );
 		if( path ){
 			if( gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path )){
-				gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &current, -1 );
+				gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, TREE_COLUMN_NAOBJECT, &current, -1 );
 				g_object_unref( current );
 
 				if( copy_data ){
@@ -732,7 +733,7 @@ is_drop_possible_before_iter( NactTreeModel *model, GtkTreeIter *iter, NactMainW
 	drop_ok = FALSE;
 	*parent = NULL;
 
-	gtk_tree_model_get( GTK_TREE_MODEL( model ), iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+	gtk_tree_model_get( GTK_TREE_MODEL( model ), iter, TREE_COLUMN_NAOBJECT, &object, -1 );
 	g_object_unref( object );
 	g_debug( "%s: current object at dest is %s", thisfn, G_OBJECT_TYPE_NAME( object ));
 
@@ -777,7 +778,7 @@ is_drop_possible_into_dest( NactTreeModel *model, GtkTreePath *dest, NactMainWin
 
 	if( gtk_tree_path_up( path )){
 		if( gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path )){
-			gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+			gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
 			g_object_unref( object );
 			g_debug( "%s: current object at parent dest is %s", thisfn, G_OBJECT_TYPE_NAME( object ));
 
@@ -872,6 +873,7 @@ drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selec
 	GSList *im;
 	GList *imported;
 	const gchar *selection_data_data;
+	NactTreeView *view;
 
 	gchar *dest_str = gtk_tree_path_to_string( dest );
 	g_debug( "%s: model=%p, dest=%p (%s), selection_data=%p",
@@ -959,10 +961,8 @@ drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selec
 		drop_done = TRUE;
 	}
 
-#if 0
-	nact_iactions_list_bis_insert_at_path( NACT_IACTIONS_LIST( main_window ), imported, dest );
-	nact_tree_model_dump( model );
-#endif
+	view = nact_main_window_get_items_view( main_window );
+	nact_tree_ieditable_insert_at_path( NACT_TREE_IEDITABLE( view ), imported, dest );
 
 	na_object_free_items( imported );
 	na_core_utils_slist_free( parms.uris );
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 57b69a2..bc80646 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -50,15 +50,9 @@ struct _NactTreeModelClassPrivate {
 	void *empty;						/* so that gcc -pedantic is happy */
 };
 
-/* search for an object, setting the iter if found
+/* iter on tree store
  */
-typedef struct {
-	GtkTreeModel   *store;
-	const NAObject *object;
-	gboolean        found;
-	GtkTreeIter    *iter;
-}
-	ntmSearchStruct;
+typedef gboolean ( *FnIterOnStore )( const NactTreeModel *, GtkTreeStore *, GtkTreePath *, NAObject *, gpointer );
 
 /* getting the list of items
  * - mode is the indicator of the wished content
@@ -70,7 +64,7 @@ typedef struct {
 }
 	ntmGetItems;
 
-/* when iterating while searching for an object
+/* when iterating while searching for an object by id
  * setting the iter if found
  */
 typedef struct {
@@ -78,6 +72,16 @@ typedef struct {
 	NAObject    *object;
 	GtkTreeIter *iter;
 }
+	ntmFindId;
+
+/* when iterating while searching for an object by its address
+ * setting the iter if found
+ */
+typedef struct {
+	const NAObject *object;
+	GtkTreeIter    *iter;
+	GtkTreePath    *path;
+}
 	ntmFindObject;
 
 /* dump the content of the tree
@@ -106,27 +110,26 @@ static void           instance_dispose( GObject *model );
 static void           instance_finalize( GObject *model );
 
 static void           on_initialize_model( BaseWindow *window, gpointer user_data );
-static void           dump( NactTreeModel *model );
 
 static void           append_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *parent, GtkTreeIter *iter, const NAObject *object );
 static void           display_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *iter, const NAObject *object );
 #if 0
+static void           dump( NactTreeModel *model );
 static gboolean       dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpStruct *ntm );
 #endif
 static void           fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, GtkTreeIter *parent );
 static gboolean       filter_visible( GtkTreeModel *store, GtkTreeIter *iter, NactTreeModel *model );
-static gboolean       find_item_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFindObject *nfo );
-static gboolean       get_items_iter( const NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmGetItems *ngi );
+static gboolean       find_item_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindId *nfo );
+static gboolean       find_object_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindObject *nfo );
+static gboolean       get_items_iter( const NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmGetItems *ngi );
 static void           iter_on_store( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *parent, FnIterOnStore fn, gpointer user_data );
 static gboolean       iter_on_store_item( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *iter, FnIterOnStore fn, gpointer user_data );
 static void           remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *object );
 static gboolean       remove_items( GtkTreeStore *store, GtkTreeIter *iter );
-static gboolean       search_for_object( NactTreeModel *model, GtkTreeModel *store, const NAObject *object, GtkTreeIter *iter );
-static gboolean       search_for_object_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmSearchStruct *ntm );
+/*static gboolean       search_for_object( NactTreeModel *model, GtkTreeModel *store, const NAObject *object, GtkTreeIter *iter );
+static gboolean       search_for_object_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFindObject *ntm );*/
 static gint           sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data );
 
-static void           on_finalizing_window( NactTreeModel *model, GObject *window );
-
 GType
 nact_tree_model_get_type( void )
 {
@@ -296,11 +299,10 @@ instance_finalize( GObject *object )
  * @treeview: the #GtkTreeView widget.
  * @mode: management mode.
  *
- * Returns: a newly created NactTreeModel object, which will take
- * care itself of its destroy by attaching a weak reference to the
- * @window.
+ * Returns: a newly created NactTreeModel object.
  *
- * The returned reference is owned by the #GtkTreeView.
+ * The returned reference is owned by the #GtkTreeView, which will automatically
+ * take care of g_object_unref() its tree model when destroyint its widget.
  */
 NactTreeModel *
 nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mode )
@@ -348,8 +350,6 @@ nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mod
 
 	g_object_set_data( G_OBJECT( window ), WINDOW_DATA_TREE_MODEL, model );
 
-	g_object_weak_ref( G_OBJECT( window ), ( GWeakNotify ) on_finalizing_window, model );
-
 	/* attach the model to the tree view
 	 */
 	gtk_tree_view_set_model( treeview, GTK_TREE_MODEL( model ));
@@ -412,22 +412,7 @@ on_initialize_model( BaseWindow *window, gpointer user_data )
 	}
 }
 
-/*
- * dump:
- * @model: this #NactTreeModel instance.
- *
- * Briefly dumps the content of the tree.
- */
-static void
-dump( NactTreeModel *model )
-{
-	GList *items;
-
-	items = nact_tree_model_get_items( model, TREE_LIST_ALL );
-	na_object_dump_tree( items );
-	na_object_free_items( items );
-}
-
+#if 0
 /**
  * nact_tree_model_display:
  * @model: this #NactTreeModel instance.
@@ -464,6 +449,7 @@ nact_tree_model_display( NactTreeModel *model, NAObject *object )
 		/*gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));*/
 	}
 }
+#endif
 
 /**
  * nact_tree_model_display_order_change:
@@ -488,41 +474,27 @@ nact_tree_model_display_order_change( NactTreeModel *model, gint order_mode )
 
 			case IPREFS_ORDER_ALPHA_ASCENDING:
 
-				gtk_tree_sortable_set_sort_column_id(
-						GTK_TREE_SORTABLE( store ),
-						IACTIONS_LIST_LABEL_COLUMN,
-						GTK_SORT_ASCENDING );
-
-				gtk_tree_sortable_set_sort_func(
-						GTK_TREE_SORTABLE( store ),
-						IACTIONS_LIST_LABEL_COLUMN,
-						( GtkTreeIterCompareFunc ) sort_actions_list,
-						NULL,
-						NULL );
+				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+						TREE_COLUMN_LABEL, GTK_SORT_ASCENDING );
+
+				gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE( store ),
+						TREE_COLUMN_LABEL, ( GtkTreeIterCompareFunc ) sort_actions_list, NULL, NULL );
 				break;
 
 			case IPREFS_ORDER_ALPHA_DESCENDING:
 
-				gtk_tree_sortable_set_sort_column_id(
-						GTK_TREE_SORTABLE( store ),
-						IACTIONS_LIST_LABEL_COLUMN,
-						GTK_SORT_DESCENDING );
-
-				gtk_tree_sortable_set_sort_func(
-						GTK_TREE_SORTABLE( store ),
-						IACTIONS_LIST_LABEL_COLUMN,
-						( GtkTreeIterCompareFunc ) sort_actions_list,
-						NULL,
-						NULL );
+				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+						TREE_COLUMN_LABEL, GTK_SORT_DESCENDING );
+
+				gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE( store ),
+						TREE_COLUMN_LABEL, ( GtkTreeIterCompareFunc ) sort_actions_list, NULL, NULL );
 				break;
 
 			case IPREFS_ORDER_MANUAL:
 			default:
 
-				gtk_tree_sortable_set_sort_column_id(
-						GTK_TREE_SORTABLE( store ),
-						GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
-						0 );
+				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+						GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, 0 );
 				break;
 		}
 	}
@@ -551,7 +523,7 @@ nact_tree_model_fill( NactTreeModel *model, GList *items )
 
 	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
 
-	g_debug( "%s: model=%p, items=%p (%d items)",
+	g_debug( "%s: model=%p, items=%p (count=%d)",
 			thisfn, ( void * ) model, ( void * ) items, g_list_length( items ));
 
 	if( !model->private->dispose_has_run ){
@@ -569,70 +541,6 @@ nact_tree_model_fill( NactTreeModel *model, GList *items )
 }
 
 /**
- * nact_tree_model_get_item_by_id:
- * @model: this #NactTreeModel object.
- * @id: the searched #NAObjectItem.
- *
- * Returns: a pointer on the searched #NAObjectItem if it exists, or %NULL.
- *
- * The returned pointer is owned by the underlying tree store, and should
- * not be released by the caller.
- */
-NAObjectItem *
-nact_tree_model_get_item_by_id( const NactTreeModel *model, const gchar *id )
-{
-	static const gchar *thisfn = "nact_tree_model_get_item_by_id";
-	GtkTreeStore *store;
-	ntmFindObject nfo;
-
-	g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
-
-	nfo.object = NULL;
-
-	if( !model->private->dispose_has_run ){
-		g_debug( "%s: model=%p, id=%s", thisfn, ( void * ) model, id );
-
-		nfo.id = ( gchar * ) id;
-		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
-		iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) find_item_iter, &nfo );
-	}
-
-	return(( NAObjectItem * ) nfo.object );
-}
-
-/**
- * nact_tree_model_get_items:
- * @model: this #NactTreeModel object.
- * @mode: the content indicator for the returned list
- *
- * Returns: the content of the current store as a newly allocated list
- * which should be na_object_free_items() by the caller.
- */
-GList *
-nact_tree_model_get_items( const NactTreeModel *model, guint mode )
-{
-	static const gchar *thisfn = "nact_tree_model_get_items";
-	GList *items;
-	GtkTreeStore *store;
-	ntmGetItems ngi;
-
-	g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
-
-	items = NULL;
-
-	if( !model->private->dispose_has_run ){
-		g_debug( "%s: model=%p, mode=%x", thisfn, ( void * ) model, mode );
-
-		ngi.mode = mode;
-		ngi.items = NULL;
-		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
-		iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) get_items_iter, &ngi );
-	}
-
-	return( items );
-}
-
-/**
  * nact_tree_model_insert:
  * @model: this #NactTreeModel instance.
  * @object: a #NAObject-derived object to be inserted.
@@ -688,7 +596,7 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
 		/* may be FALSE when store is empty */
 		has_sibling = gtk_tree_model_get_iter( store, &sibling_iter, path );
 		if( has_sibling ){
-			gtk_tree_model_get( store, &sibling_iter, IACTIONS_LIST_NAOBJECT_COLUMN, &sibling_obj, -1 );
+			gtk_tree_model_get( store, &sibling_iter, TREE_COLUMN_NAOBJECT, &sibling_obj, -1 );
 			g_object_unref( sibling_obj );
 		}
 		g_debug( "%s: has_sibling=%s, sibling_obj=%p", thisfn, has_sibling ? "True":"False", ( void * ) sibling_obj );
@@ -701,7 +609,7 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
 			gtk_tree_model_get_iter( store, &parent_iter, parent_path );
 			gtk_tree_path_free( parent_path );
 
-			gtk_tree_model_get( store, &parent_iter, IACTIONS_LIST_NAOBJECT_COLUMN, &parent_obj, -1 );
+			gtk_tree_model_get( store, &parent_iter, TREE_COLUMN_NAOBJECT, &parent_obj, -1 );
 			g_object_unref( parent_obj );
 
 			if( parent && !*parent ){
@@ -722,7 +630,7 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
 				GTK_TREE_STORE( store ), &iter,
 				has_parent ? &parent_iter : NULL,
 				has_sibling ? &sibling_iter : NULL );
-		gtk_tree_store_set( GTK_TREE_STORE( store ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, object, -1 );
+		gtk_tree_store_set( GTK_TREE_STORE( store ), &iter, TREE_COLUMN_NAOBJECT, object, -1 );
 		display_item( GTK_TREE_STORE( store ), model->private->treeview, &iter, object );
 
 		inserted_path = gtk_tree_model_get_path( store, &iter );
@@ -770,14 +678,14 @@ nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTr
 			g_free( path_str );
 			return( NULL );
 		}
-		gtk_tree_model_get( store, &parent_iter, IACTIONS_LIST_NAOBJECT_COLUMN, parent, -1 );
+		gtk_tree_model_get( store, &parent_iter, TREE_COLUMN_NAOBJECT, parent, -1 );
 		g_object_unref( *parent );
 
 		na_object_insert_item( *parent, object, NULL );
 		na_object_set_parent( object, *parent );
 
 		gtk_tree_store_insert_after( GTK_TREE_STORE( store ), &iter, &parent_iter, NULL );
-		gtk_tree_store_set( GTK_TREE_STORE( store ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, object, -1 );
+		gtk_tree_store_set( GTK_TREE_STORE( store ), &iter, TREE_COLUMN_NAOBJECT, object, -1 );
 		display_item( GTK_TREE_STORE( store ), model->private->treeview, &iter, object );
 
 		new_path = gtk_tree_model_get_path( store, &iter );
@@ -787,21 +695,67 @@ nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTr
 }
 
 /**
- * nact_tree_model_iter:
- * @model: this #NactTreeModel instance.
+ * nact_tree_model_get_item_by_id:
+ * @model: this #NactTreeModel object.
+ * @id: the searched #NAObjectItem.
+ *
+ * Returns: a pointer on the searched #NAObjectItem if it exists, or %NULL.
+ *
+ * The returned pointer is owned by the underlying tree store, and should
+ * not be released by the caller.
  */
-void
-nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data )
+NAObjectItem *
+nact_tree_model_get_item_by_id( const NactTreeModel *model, const gchar *id )
 {
+	static const gchar *thisfn = "nact_tree_model_get_item_by_id";
 	GtkTreeStore *store;
+	ntmFindId nfi;
 
-	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+	g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+
+	nfi.object = NULL;
 
 	if( !model->private->dispose_has_run ){
+		g_debug( "%s: model=%p, id=%s", thisfn, ( void * ) model, id );
 
+		nfi.id = ( gchar * ) id;
 		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
-		iter_on_store( model, GTK_TREE_MODEL( store ), NULL, fn, user_data );
+		iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) find_item_iter, &nfi );
+	}
+
+	return(( NAObjectItem * ) nfi.object );
+}
+
+/**
+ * nact_tree_model_get_items:
+ * @model: this #NactTreeModel object.
+ * @mode: the content indicator for the returned list
+ *
+ * Returns: the content of the current store as a newly allocated list
+ * which should be na_object_free_items() by the caller.
+ */
+GList *
+nact_tree_model_get_items( const NactTreeModel *model, guint mode )
+{
+	static const gchar *thisfn = "nact_tree_model_get_items";
+	GList *items;
+	GtkTreeStore *store;
+	ntmGetItems ngi;
+
+	g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+
+	items = NULL;
+
+	if( !model->private->dispose_has_run ){
+		g_debug( "%s: model=%p, mode=%x", thisfn, ( void * ) model, mode );
+
+		ngi.mode = mode;
+		ngi.items = NULL;
+		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+		iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) get_items_iter, &ngi );
 	}
+
+	return( items );
 }
 
 /**
@@ -811,10 +765,11 @@ nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data
  *
  * Returns: the #NAObject at the given @path if any, or NULL.
  *
- * The reference count of the object is not modified.
+ * The reference count of the object is not modified. The returned reference
+ * is owned by the tree store and should not be released by the caller.
  */
 NAObject *
-nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path )
+nact_tree_model_object_at_path( const NactTreeModel *model, GtkTreePath *path )
 {
 	NAObject *object;
 	GtkTreeModel *store;
@@ -827,9 +782,8 @@ nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path )
 	if( !model->private->dispose_has_run ){
 
 		store = gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model ));
-
 		if( gtk_tree_model_get_iter( store, &iter, path )){
-			gtk_tree_model_get( store, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+			gtk_tree_model_get( store, &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
 			g_object_unref( object );
 		}
 	}
@@ -838,6 +792,62 @@ nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path )
 }
 
 /**
+ * nact_tree_model_object_to_path:
+ * @model: this #NactTreeModel.
+ * @object: the searched NAObject.
+ *
+ * Returns: a newly allocated GtkTreePath which is the current position
+ * of @object in the tree store, or %NULL.
+ *
+ * The returned path should be gtk_tree_path_free() by the caller.
+ */
+GtkTreePath *
+nact_tree_model_object_to_path( const NactTreeModel *model, const NAObject *object )
+{
+	static const gchar *thisfn = "nact_tree_model_object_to_path";
+	ntmFindObject nfo;
+	GtkTreeIter iter;
+	GtkTreeStore *store;
+
+	g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+
+	nfo.path = NULL;
+
+	if( !model->private->dispose_has_run ){
+		g_debug( "%s: model=%p, object=%p (%s)",
+				thisfn, ( void * ) model, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+		nfo.object = object;
+		nfo.iter = &iter;
+
+		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+		iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) find_object_iter, &nfo );
+	}
+
+	return( nfo.path );
+}
+
+#if 0
+/**
+ * nact_tree_model_iter:
+ * @model: this #NactTreeModel instance.
+ */
+void
+nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data )
+{
+	GtkTreeStore *store;
+
+	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+
+	if( !model->private->dispose_has_run ){
+
+		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+		iter_on_store( model, GTK_TREE_MODEL( store ), NULL, fn, user_data );
+	}
+}
+#endif
+
+/**
  * nact_tree_model_remove:
  * @model: this #NactTreeModel instance.
  * @object: the #NAObject to be deleted.
@@ -849,28 +859,32 @@ nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path )
 GtkTreePath *
 nact_tree_model_remove( NactTreeModel *model, NAObject *object )
 {
+	GtkTreePath *path;
 	static const gchar *thisfn = "nact_tree_model_remove";
 	GtkTreeIter iter;
 	GtkTreeStore *store;
 	NAObjectItem *parent;
-	GtkTreePath *path = NULL;
 
-	g_debug( "%s: model=%p, object=%p (%s)",
-			thisfn, ( void * ) model, ( void * ) object, object ? G_OBJECT_TYPE_NAME( object ) : "(null)" );
 	g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
 
+	path = NULL;
+
 	if( !model->private->dispose_has_run ){
+		g_debug( "%s: model=%p, object=%p (%s)",
+				thisfn, ( void * ) model, ( void * ) object, object ? G_OBJECT_TYPE_NAME( object ) : "null" );
 
-		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+		path = nact_tree_model_object_to_path( model, object );
 
-		if( search_for_object( model, GTK_TREE_MODEL( store ), object, &iter )){
+		if( path != NULL ){
+			gtk_tree_path_free( path );
+			store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
 			parent = na_object_get_parent( object );
 			g_debug( "%s: object=%p, parent=%p", thisfn, ( void * ) object, ( void * ) parent );
 			if( parent ){
 				na_object_remove_item( parent, object );
 				na_object_check_status_up( parent );
 			}
-			path = gtk_tree_model_get_path( GTK_TREE_MODEL( store ), &iter );
+			gtk_tree_model_get_iter( GTK_TREE_MODEL( store ), &iter, path );
 			remove_items( store, &iter );
 		}
 	}
@@ -885,7 +899,7 @@ append_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *parent, Gt
 					( void * ) object, G_OBJECT( object )->ref_count, ( void * ) parent );*/
 
 	gtk_tree_store_append( model, iter, parent );
-	gtk_tree_store_set( model, iter, IACTIONS_LIST_NAOBJECT_COLUMN, object, -1 );
+	gtk_tree_store_set( model, iter, TREE_COLUMN_NAOBJECT, object, -1 );
 	display_item( model, treeview, iter, object );
 }
 
@@ -893,18 +907,34 @@ static void
 display_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *iter, const NAObject *object )
 {
 	gchar *label = na_object_get_label( object );
-	gtk_tree_store_set( model, iter, IACTIONS_LIST_LABEL_COLUMN, label, -1 );
+	gtk_tree_store_set( model, iter, TREE_COLUMN_LABEL, label, -1 );
 	g_free( label );
 
 	if( NA_IS_OBJECT_ITEM( object )){
 		gchar *icon_name = na_object_get_icon( object );
 		GdkPixbuf *icon = base_gtk_utils_get_pixbuf( icon_name, GTK_WIDGET( treeview ), GTK_ICON_SIZE_MENU );
-		gtk_tree_store_set( model, iter, IACTIONS_LIST_ICON_COLUMN, icon, -1 );
+		gtk_tree_store_set( model, iter, TREE_COLUMN_ICON, icon, -1 );
 		g_object_unref( icon );
 	}
 }
 
 #if 0
+/*
+ * dump:
+ * @model: this #NactTreeModel instance.
+ *
+ * Briefly dumps the content of the tree.
+ */
+static void
+dump( NactTreeModel *model )
+{
+	GList *items;
+
+	items = nact_tree_model_get_items( model, TREE_LIST_ALL );
+	na_object_dump_tree( items );
+	na_object_free_items( items );
+}
+
 static gboolean
 dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpStruct *ntm )
 {
@@ -966,60 +996,64 @@ fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, G
 }
 
 /*
- * only display profiles when we are in edition mode
+ * Only display profiles when we are in edition mode.
+ *
+ * This function is called as soon as a new row is created in the tree store,
+ * so is called the first time _before_ the NAObject be set on the row.
  */
 static gboolean
 filter_visible( GtkTreeModel *store, GtkTreeIter *iter, NactTreeModel *model )
 {
-	/*static const gchar *thisfn = "nact_tree_model_filter_visible";*/
 	NAObject *object;
 	NAObjectAction *action;
 	gint count;
 
-	/*g_debug( "%s: model=%p, iter=%p, window=%p", thisfn, ( void * ) model, ( void * ) iter, ( void * ) window );*/
-	/*g_debug( "%s at %p", G_OBJECT_TYPE_NAME( model ), ( void * ) model );*/
-	/* is a GtkTreeStore */
+	gtk_tree_model_get( store, iter, TREE_COLUMN_NAOBJECT, &object, -1 );
 
-	gtk_tree_model_get( store, iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
-	g_object_unref( object );
-	/*na_object_dump( object );*/
+	if( object ){
+		g_object_unref( object );
 
-	/* an action or a menu
-	 */
-	if( NA_IS_OBJECT_ITEM( object )){
-		return( TRUE );
-	}
+		/* an action or a menu are always displayed, whatever the current
+		 * management mode may be
+		 */
+		if( NA_IS_OBJECT_ITEM( object )){
+			return( TRUE );
+		}
 
-	g_return_val_if_fail( NA_IS_OBJECT_PROFILE( object ), FALSE );
+		/* profiles are just never displayed in selection mode
+		 * in edition mode, they are displayed only when the action has
+		 * more than one profile
+		 */
+		g_return_val_if_fail( NA_IS_OBJECT_PROFILE( object ), FALSE );
 
-	if( NACT_TREE_MODEL( model )->private->mode != TREE_MODE_EDITION ){
-		return( FALSE );
-	}
+		if( NACT_TREE_MODEL( model )->private->mode == TREE_MODE_SELECTION ){
+			return( FALSE );
+		}
 
-	action = NA_OBJECT_ACTION( na_object_get_parent( object ));
-	count = na_object_get_items_count( action );
-	/*g_debug( "action=%p: count=%d", ( void * ) action, count );*/
-	/*return( TRUE );*/
-	return( count > 1 );
+		action = NA_OBJECT_ACTION( na_object_get_parent( object ));
+		count = na_object_get_items_count( action );
+		return( count > 1 );
+	}
 
+	return( FALSE );
 }
 
 /*
  * search for an object, given its id
  */
 static gboolean
-find_item_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFindObject *nfo )
+find_item_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindId *nfi )
 {
 	gchar *id;
 	gboolean found = FALSE;
 
 	if( NA_IS_OBJECT_ITEM( object )){
 		id = na_object_get_id( object );
-		found = ( g_ascii_strcasecmp( id, nfo->id ) == 0 );
+		found = ( g_ascii_strcasecmp( id, nfi->id ) == 0 );
 		g_free( id );
 
 		if( found ){
-			nfo->object = object;
+			nfi->object = object;
 		}
 	}
 
@@ -1027,6 +1061,19 @@ find_item_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFi
 	return( found );
 }
 
+static gboolean
+find_object_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindObject *nfo )
+{
+	if( object == nfo->object ){
+		if( gtk_tree_model_get_iter( GTK_TREE_MODEL( store ), nfo->iter, path )){
+			nfo->path = gtk_tree_path_copy( path );
+		}
+	}
+
+	/* stop iteration when found */
+	return( nfo->path != NULL );
+}
+
 /*
  * Builds the tree by iterating on the store
  * we may want selected, modified or both, or a combination of these modes
@@ -1034,7 +1081,7 @@ find_item_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFi
  * This function is called from iter_on_store_item();
  */
 static gboolean
-get_items_iter( const NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmGetItems *ngi )
+get_items_iter( const NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmGetItems *ngi )
 {
 	if( ngi->mode == TREE_LIST_ALL ){
 		if( gtk_tree_path_get_depth( path ) == 1 ){
@@ -1080,7 +1127,7 @@ iter_on_store_item( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter
 			*/
 
 	path = gtk_tree_model_get_path( store, iter );
-	stop = ( *fn )( model, path, object, user_data );
+	stop = ( *fn )( model, GTK_TREE_STORE( store ), path, object, user_data );
 	gtk_tree_path_free( path );
 
 	if( !stop ){
@@ -1097,24 +1144,24 @@ iter_on_store_item( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter
 static void
 remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *object )
 {
-	ntmFindObject nfo;
+	ntmFindId nfi;
 	GtkTreeIter iter;
 
 	if( NA_IS_OBJECT_ITEM( object )){
 
-		nfo.id = na_object_get_id( object );
-		nfo.object = NULL;
-		nfo.iter = &iter;
+		nfi.id = na_object_get_id( object );
+		nfi.object = NULL;
+		nfi.iter = &iter;
 
-		iter_on_store( model, store, NULL, ( FnIterOnStore ) find_item_iter, &nfo );
+		iter_on_store( model, store, NULL, ( FnIterOnStore ) find_item_iter, &nfi );
 
-		if( nfo.object ){
+		if( nfi.object ){
 			g_debug( "nact_tree_model_remove_if_exists: removing %s %p",
 					G_OBJECT_TYPE_NAME( object ), ( void * ) object );
-			gtk_tree_store_remove( GTK_TREE_STORE( store ), nfo.iter );
+			gtk_tree_store_remove( GTK_TREE_STORE( store ), nfi.iter );
 		}
 
-		g_free( nfo.id );
+		g_free( nfi.id );
 	}
 }
 
@@ -1136,43 +1183,6 @@ remove_items( GtkTreeStore *store, GtkTreeIter *iter )
 	return( valid );
 }
 
-static gboolean
-search_for_object( NactTreeModel *model, GtkTreeModel *store, const NAObject *object, GtkTreeIter *result_iter )
-{
-	gboolean found = FALSE;
-	ntmSearchStruct *ntm;
-	GtkTreeIter iter;
-
-	ntm = g_new0( ntmSearchStruct, 1 );
-	ntm->store = store;
-	ntm->object = object;
-	ntm->found = FALSE;
-	ntm->iter = &iter;
-
-	iter_on_store( model, store, NULL, ( FnIterOnStore ) search_for_object_iter, ntm );
-
-	if( ntm->found ){
-		found = TRUE;
-		memcpy( result_iter, ntm->iter, sizeof( GtkTreeIter ));
-	}
-
-	g_free( ntm );
-	return( found );
-}
-
-static gboolean
-search_for_object_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmSearchStruct *ntm )
-{
-	if( object == ntm->object ){
-		if( gtk_tree_model_get_iter( ntm->store, ntm->iter, path )){
-			ntm->found = TRUE;
-		}
-	}
-
-	/* stop iteration when found */
-	return( ntm->found );
-}
-
 static gint
 sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data )
 {
@@ -1182,8 +1192,8 @@ sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer
 
 	/*g_debug( "%s: model=%p, a=%p, b=%p, window=%p", thisfn, ( void * ) model, ( void * ) a, ( void * ) b, ( void * ) window );*/
 
-	gtk_tree_model_get( model, a, IACTIONS_LIST_NAOBJECT_COLUMN, &obj_a, -1 );
-	gtk_tree_model_get( model, b, IACTIONS_LIST_NAOBJECT_COLUMN, &obj_b, -1 );
+	gtk_tree_model_get( model, a, TREE_COLUMN_NAOBJECT, &obj_a, -1 );
+	gtk_tree_model_get( model, b, TREE_COLUMN_NAOBJECT, &obj_b, -1 );
 
 	g_object_unref( obj_b );
 	g_object_unref( obj_a );
@@ -1197,18 +1207,3 @@ sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer
 	/*g_debug( "%s: ret=%d", thisfn, ret );*/
 	return( ret );
 }
-
-static void
-on_finalizing_window( NactTreeModel *model, GObject *window )
-{
-	static const gchar *thisfn = "nact_tree_model_on_finalizing_window";
-
-	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
-
-	g_debug( "%s: model=%p (%s), window=%p",
-			thisfn, ( void * ) model, G_OBJECT_TYPE_NAME( model ), ( void * ) window );
-
-	dump( model );
-
-	g_object_unref( model );
-}
diff --git a/src/nact/nact-tree-model.h b/src/nact/nact-tree-model.h
index 2089209..4c18322 100644
--- a/src/nact/nact-tree-model.h
+++ b/src/nact/nact-tree-model.h
@@ -76,15 +76,6 @@ typedef struct {
 }
 	NactTreeModelClass;
 
-/* column ordering of the tree view
- */
-enum {
-	IACTIONS_LIST_ICON_COLUMN = 0,
-	IACTIONS_LIST_LABEL_COLUMN,
-	IACTIONS_LIST_NAOBJECT_COLUMN,
-	IACTIONS_LIST_N_COLUMN
-};
-
 /**
  * Column ordering in the tree view
  */
@@ -104,18 +95,18 @@ enum {
 	TREE_LIST_ALL = 0xff,
 };
 
-/* iter on tree store
- */
-typedef gboolean ( *FnIterOnStore )( const NactTreeModel *, GtkTreePath *, NAObject *, gpointer );
-
 GType          nact_tree_model_get_type( void );
 
 NactTreeModel *nact_tree_model_new( BaseWindow *window, GtkTreeView *view, NactTreeMode mode );
 
-void           nact_tree_model_fill( NactTreeModel *model, GList *items );
+void           nact_tree_model_fill       ( NactTreeModel *model, GList *items );
+GtkTreePath   *nact_tree_model_insert     ( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
+GtkTreePath   *nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
 
 NAObjectItem  *nact_tree_model_get_item_by_id( const NactTreeModel *model, const gchar *id );
 GList         *nact_tree_model_get_items     ( const NactTreeModel *model, guint mode );
+NAObject      *nact_tree_model_object_at_path( const NactTreeModel *model, GtkTreePath *path );
+GtkTreePath   *nact_tree_model_object_to_path( const NactTreeModel *model, const NAObject *object );
 
 /* find an item
  * get items (all, selected, modified)
@@ -124,12 +115,9 @@ GList         *nact_tree_model_get_items     ( const NactTreeModel *model, guint
  */
 
 /* *** */
-void         nact_tree_model_display( NactTreeModel *model, NAObject *object );
+/*void         nact_tree_model_display( NactTreeModel *model, NAObject *object );*/
 void         nact_tree_model_display_order_change( NactTreeModel *model, gint order_mode );
-GtkTreePath *nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
-GtkTreePath *nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
-void         nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data );
-NAObject    *nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path );
+/*void         nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data );*/
 GtkTreePath *nact_tree_model_remove( NactTreeModel *model, NAObject *object );
 /* *** */
 
diff --git a/src/nact/nact-tree-view.c b/src/nact/nact-tree-view.c
index d98b8a5..3c9d78e 100644
--- a/src/nact/nact-tree-view.c
+++ b/src/nact/nact-tree-view.c
@@ -39,6 +39,7 @@
 #include "nact-marshal.h"
 #include "nact-tree-view.h"
 #include "nact-tree-model.h"
+#include "nact-tree-ieditable.h"
 
 /* private class data
  */
@@ -120,6 +121,7 @@ static GObjectClass *st_parent_class           = NULL;
 
 static GType    register_type( void );
 static void     class_init( NactTreeViewClass *klass );
+static void     tree_ieditable_iface_init( NactTreeIEditableInterface *iface );
 static void     instance_init( GTypeInstance *instance, gpointer klass );
 static void     instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
 static void     instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
@@ -138,13 +140,13 @@ static void     on_treeview_selection_changed( GtkTreeSelection *selection, Base
 static void     on_content_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, NAObject *edited );
 static void     on_selection_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, GList *selected_items );
 static void     clear_selection( NactTreeView *view );
+static void     display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeView *view );
 static void     extend_selection_to_children( NactTreeView *view, GtkTreeModel *model, GtkTreeIter *parent );
 static GList   *get_selected_items( NactTreeView *view );
 static void     iter_on_selection( NactTreeView *view, FnIterOnSelection fn_iter, gpointer user_data );
 static void     navigate_to_child( NactTreeView *view );
 static void     navigate_to_parent( NactTreeView *view );
 static void     open_popup( BaseWindow *window, NactTreeView *view, GdkEventButton *event );
-static void     select_row_at_path( NactTreeView *view, GtkTreePath *path );
 static void     select_row_at_path_by_string( NactTreeView *view, const gchar *path );
 static void     toggle_collapse( NactTreeView *view );
 static gboolean toggle_collapse_iter( NactTreeView *view, GtkTreeModel *model, GtkTreeIter *iter, NAObject *object, gpointer user_data );
@@ -181,10 +183,18 @@ register_type( void )
 		( GInstanceInitFunc ) instance_init
 	};
 
+	static const GInterfaceInfo tree_ieditable_iface_info = {
+		( GInterfaceInitFunc ) tree_ieditable_iface_init,
+		NULL,
+		NULL
+	};
+
 	g_debug( "%s", thisfn );
 
 	type = g_type_register_static( G_TYPE_OBJECT, "NactTreeView", &info, 0 );
 
+	g_type_add_interface_static( type, NACT_TREE_IEDITABLE_TYPE, &tree_ieditable_iface_info );
+
 	return( type );
 }
 
@@ -428,6 +438,14 @@ class_init( NactTreeViewClass *klass )
 }
 
 static void
+tree_ieditable_iface_init( NactTreeIEditableInterface *iface )
+{
+	static const gchar *thisfn = "nact_main_window_tree_ieditable_iface_init";
+
+	g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
+}
+
+static void
 instance_init( GTypeInstance *instance, gpointer klass )
 {
 	static const gchar *thisfn = "nact_tree_view_instance_init";
@@ -615,6 +633,7 @@ on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_d
 	GtkTreeViewColumn *column;
 	GtkCellRenderer *renderer;
 	GtkTreeSelection *selection;
+	GList *renderers;
 
 	VIEW_WINDOW_VOID( window );
 
@@ -657,6 +676,16 @@ on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_d
 		/* misc properties
 		 */
 		gtk_tree_view_set_enable_tree_lines( treeview, TRUE );
+
+		if( view->private->mode == TREE_MODE_EDITION ){
+			nact_tree_ieditable_initialize( NACT_TREE_IEDITABLE( view ), treeview, window );
+
+			column = gtk_tree_view_get_column( treeview, TREE_COLUMN_LABEL );
+			renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
+			renderer = GTK_CELL_RENDERER( renderers->data );
+			gtk_tree_view_column_set_cell_data_func(
+					column, renderer, ( GtkTreeCellDataFunc ) display_label, view, NULL );
+		}
 	}
 }
 
@@ -978,6 +1007,92 @@ nact_tree_view_get_items( const NactTreeView *view )
 	return( items );
 }
 
+/**
+ * nact_tree_view_get_window:
+ * @view: this #NactTreeView instance.
+ *
+ * Returns: the #BaseWindow.
+ */
+BaseWindow *
+nact_tree_view_get_window( const NactTreeView *view )
+{
+	BaseWindow *window;
+
+	g_return_val_if_fail( NACT_IS_TREE_VIEW( view ), NULL );
+
+	window = NULL;
+
+	if( !view->private->dispose_has_run ){
+
+		window = view->private->window;
+	}
+
+	return( window );
+}
+
+/**
+ * nact_tree_view_select_row_at_path:
+ *
+ *
+ * Select the row at the required path, or the immediate previous, or
+ * the next following, or eventually the immediate parent.
+ *
+ * If nothing can be selected (and notify is allowed), at least send a
+ * message with an empty selection.
+ */
+void
+nact_tree_view_select_row_at_path( NactTreeView *view, GtkTreePath *path )
+{
+	static const gchar *thisfn = "nact_tree_view_select_row_at_path";
+	gchar *path_str;
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	gboolean something = FALSE;
+
+	g_return_if_fail( NACT_IS_TREE_VIEW( view ));
+
+	if( !view->private->dispose_has_run ){
+
+		path_str = gtk_tree_path_to_string( path );
+		g_debug( "%s: view=%p, path=%s", thisfn, ( void * ) view, path_str );
+		g_free( path_str );
+
+		if( path ){
+			gtk_tree_view_expand_to_path( view->private->tree_view, path );
+			model = gtk_tree_view_get_model( view->private->tree_view );
+
+			if( gtk_tree_model_get_iter( model, &iter, path )){
+				gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
+				something = TRUE;
+
+			} else if( gtk_tree_path_prev( path ) && gtk_tree_model_get_iter( model, &iter, path )){
+				gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
+				something = TRUE;
+
+			} else {
+				gtk_tree_path_next( path );
+				if( gtk_tree_model_get_iter( model, &iter, path )){
+					gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
+					something = TRUE;
+
+				} else if( gtk_tree_path_get_depth( path ) > 1 &&
+							gtk_tree_path_up( path ) &&
+							gtk_tree_model_get_iter( model, &iter, path )){
+
+								gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
+								something = TRUE;
+				}
+			}
+		}
+
+		if( !something ){
+			if( view->private->notify_allowed ){
+				g_signal_emit_by_name( view->private->window, TREE_SIGNAL_SELECTION_CHANGED, view, NULL );
+			}
+		}
+	}
+}
+
 static void
 clear_selection( NactTreeView *view )
 {
@@ -988,6 +1103,48 @@ clear_selection( NactTreeView *view )
 }
 
 /*
+ * item modified: italic
+ * item not saveable (invalid): red
+ */
+static void
+display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeView *view )
+{
+	NAObject *object;
+	gchar *label;
+	gboolean modified = FALSE;
+	gboolean valid = TRUE;
+	NAObjectItem *item;
+
+	g_return_if_fail( view->private->mode == TREE_MODE_EDITION );
+
+	gtk_tree_model_get( model, iter, TREE_COLUMN_NAOBJECT, &object, -1 );
+
+	if( object ){
+		g_object_unref( object );
+		g_return_if_fail( NA_IS_OBJECT( object ));
+
+		label = na_object_get_label( object );
+		g_object_set( cell, "style-set", FALSE, NULL );
+		g_object_set( cell, "foreground-set", FALSE, NULL );
+
+		modified = na_object_is_modified( object );
+		valid = na_object_is_valid( object );
+		item = NA_IS_OBJECT_PROFILE( object ) ? na_object_get_parent( object ) : NA_OBJECT_ITEM( object );
+
+		if( modified ){
+			g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
+		}
+
+		if( !valid ){
+			g_object_set( cell, "foreground", "Red", "foreground-set", TRUE, NULL );
+		}
+
+		g_object_set( cell, "text", label, NULL );
+		g_free( label );
+	}
+}
+
+/*
  * when expanding a selected row which has childs
  */
 static void
@@ -1115,7 +1272,7 @@ navigate_to_child( NactTreeView *view )
 			if( gtk_tree_model_iter_has_child( model, &iter )){
 				child_path = gtk_tree_path_copy( path );
 				gtk_tree_path_append_index( child_path, 0 );
-				select_row_at_path( view, child_path );
+				nact_tree_view_select_row_at_path( view, child_path );
 				gtk_tree_path_free( child_path );
 			}
 		}
@@ -1157,7 +1314,7 @@ navigate_to_parent( NactTreeView *view )
 		} else if( gtk_tree_path_get_depth( path ) > 1 ){
 			parent_path = gtk_tree_path_copy( path );
 			gtk_tree_path_up( parent_path );
-			select_row_at_path( view, parent_path );
+			nact_tree_view_select_row_at_path( view, parent_path );
 			gtk_tree_path_free( parent_path );
 		}
 	}
@@ -1172,75 +1329,20 @@ open_popup( BaseWindow *window, NactTreeView *view, GdkEventButton *event )
 	GtkTreePath *path;
 
 	if( gtk_tree_view_get_path_at_pos( view->private->tree_view, event->x, event->y, &path, NULL, NULL, NULL )){
-		select_row_at_path( view, path );
+		nact_tree_view_select_row_at_path( view, path );
 		gtk_tree_path_free( path );
 	}
 
 	g_signal_emit_by_name( window, TREE_SIGNAL_CONTEXT_MENU, view, event );
 }
 
-/*
- * Select the row at the required path, or the immediate previous, or
- * the next following, or eventually the immediate parent.
- *
- * If nothing can be selected (and notify is allowed), at least send a
- * message with an empty selection.
- */
-static void
-select_row_at_path( NactTreeView *view, GtkTreePath *path )
-{
-	static const gchar *thisfn = "nact_tree_view_select_row_at_path";
-	gchar *path_str;
-	GtkTreeIter iter;
-	GtkTreeModel *model;
-	gboolean something = FALSE;
-
-	path_str = gtk_tree_path_to_string( path );
-	g_debug( "%s: view=%p, path=%s", thisfn, ( void * ) view, path_str );
-	g_free( path_str );
-
-	if( path ){
-		gtk_tree_view_expand_to_path( view->private->tree_view, path );
-		model = gtk_tree_view_get_model( view->private->tree_view );
-
-		if( gtk_tree_model_get_iter( model, &iter, path )){
-			gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
-			something = TRUE;
-
-		} else if( gtk_tree_path_prev( path ) && gtk_tree_model_get_iter( model, &iter, path )){
-			gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
-			something = TRUE;
-
-		} else {
-			gtk_tree_path_next( path );
-			if( gtk_tree_model_get_iter( model, &iter, path )){
-				gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
-				something = TRUE;
-
-			} else if( gtk_tree_path_get_depth( path ) > 1 &&
-						gtk_tree_path_up( path ) &&
-						gtk_tree_model_get_iter( model, &iter, path )){
-
-							gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
-							something = TRUE;
-			}
-		}
-	}
-
-	if( !something ){
-		if( view->private->notify_allowed ){
-			g_signal_emit_by_name( view->private->window, TREE_SIGNAL_SELECTION_CHANGED, view, NULL );
-		}
-	}
-}
-
 static void
 select_row_at_path_by_string( NactTreeView *view, const gchar *path_str )
 {
 	GtkTreePath *path;
 
 	path = gtk_tree_path_new_from_string( path_str );
-	select_row_at_path( view, path );
+	nact_tree_view_select_row_at_path( view, path );
 	gtk_tree_path_free( path );
 }
 
diff --git a/src/nact/nact-tree-view.h b/src/nact/nact-tree-view.h
index 856e4ee..0f4883b 100644
--- a/src/nact/nact-tree-view.h
+++ b/src/nact/nact-tree-view.h
@@ -112,6 +112,9 @@ void          nact_tree_view_collapse_all  ( const NactTreeView *view );
 void          nact_tree_view_expand_all    ( const NactTreeView *view );
 NAObjectItem *nact_tree_view_get_item_by_id( const NactTreeView *view, const gchar *id );
 GList        *nact_tree_view_get_items     ( const NactTreeView *view );
+BaseWindow   *nact_tree_view_get_window    ( const NactTreeView *view );
+
+void          nact_tree_view_select_row_at_path( NactTreeView *view, GtkTreePath *path );
 
 G_END_DECLS
 



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