[nautilus-actions] More refactoring



commit 83e758a83aaaef9d0c31a17838caa5cfd3036510
Author: Pierre Wieser <pwieser trychlos org>
Date:   Thu Feb 10 00:33:33 2011 +0100

    More refactoring

 src/api/na-object.h              |    6 +-
 src/core/na-data-boxed.c         |    6 -
 src/core/na-factory-object.c     |    3 +-
 src/core/na-iduplicable.c        |    8 +-
 src/core/na-object-action.c      |   29 ++-
 src/core/na-object-id.c          |    1 -
 src/core/na-object-item.c        |   23 +--
 src/core/na-object-menu.c        |   26 ++-
 src/core/na-object-profile.c     |   26 ++-
 src/core/na-object.c             |   38 +---
 src/nact/base-window.c           |   21 ++
 src/nact/base-window.h           |    1 +
 src/nact/nact-assistant-export.c |    2 +
 src/nact/nact-iaction-tab.c      |    3 +-
 src/nact/nact-main-toolbar.c     |    4 +-
 src/nact/nact-main-window.c      |   63 ++---
 src/nact/nact-main-window.h      |    2 -
 src/nact/nact-menubar-edit.c     |    4 +-
 src/nact/nact-menubar-file.c     |   11 +-
 src/nact/nact-menubar-priv.h     |    7 +-
 src/nact/nact-menubar.c          |   78 ++----
 src/nact/nact-sort-buttons.c     |    6 +-
 src/nact/nact-tree-ieditable.c   |  489 ++++++++++++++++++++++++++------------
 src/nact/nact-tree-ieditable.h   |   23 ++-
 src/nact/nact-tree-model-dnd.c   |   31 +--
 src/nact/nact-tree-model.c       |   40 ++--
 src/nact/nact-tree-view.c        |  145 +++++++-----
 src/nact/nact-tree-view.h        |   30 ++-
 28 files changed, 673 insertions(+), 453 deletions(-)
---
diff --git a/src/api/na-object.h b/src/api/na-object.h
index 4c77cef..6cd2d4c 100644
--- a/src/api/na-object.h
+++ b/src/api/na-object.h
@@ -88,10 +88,8 @@ typedef struct {
 	 *
 	 * Dumps via g_debug the content of the object.
 	 *
-	 * NAObject class takes care of calling this function for each
-	 * derived class, starting from topmost base class up to most-
-	 * derived one. Each derived class has so only to take care of
-	 * dumping its own data.
+	 * The derived class should call its parent class at the end of the
+	 * dump of its own datas.
 	 *
 	 * Since: 2.30
 	 */
diff --git a/src/core/na-data-boxed.c b/src/core/na-data-boxed.c
index 55d5cfe..69c06a9 100644
--- a/src/core/na-data-boxed.c
+++ b/src/core/na-data-boxed.c
@@ -333,7 +333,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 static void
 instance_dispose( GObject *object )
 {
-	static const gchar *thisfn = "na_data_boxed_instance_dispose";
 	NADataBoxed *self;
 
 	g_return_if_fail( NA_IS_DATA_BOXED( object ));
@@ -342,11 +341,6 @@ instance_dispose( GObject *object )
 
 	if( !self->private->dispose_has_run ){
 
-		g_debug( "%s: object=%p (%s), name=%s",
-				thisfn,
-				( void * ) object, G_OBJECT_TYPE_NAME( object ),
-				NA_DATA_BOXED( object )->private->def->name );
-
 		self->private->dispose_has_run = TRUE;
 
 		/* chain up to the parent class */
diff --git a/src/core/na-factory-object.c b/src/core/na-factory-object.c
index 79d0b7f..f2bfdcd 100644
--- a/src/core/na-factory-object.c
+++ b/src/core/na-factory-object.c
@@ -574,11 +574,10 @@ na_factory_object_dump( const NAIFactoryObject *object )
 	length += 1;
 
 	for( it = list ; it ; it = it->next ){
-		/*na_data_boxed_dump( NA_DATA_BOXED( it->data ));*/
 		NADataBoxed *boxed = NA_DATA_BOXED( it->data );
 		NADataDef *def = na_data_boxed_get_data_def( boxed );
 		gchar *value = na_data_boxed_get_as_string( boxed );
-		g_debug( "%s: %*s=%s", thisfn, length, def->name+l_prefix, value );
+		g_debug( "| %s: %*s=%s", thisfn, length, def->name+l_prefix, value );
 		g_free( value );
 	}
 }
diff --git a/src/core/na-iduplicable.c b/src/core/na-iduplicable.c
index b17111f..838fd62 100644
--- a/src/core/na-iduplicable.c
+++ b/src/core/na-iduplicable.c
@@ -242,8 +242,8 @@ na_iduplicable_dispose( const NAIDuplicable *object )
 	if( st_initialized && !st_finalized ){
 
 		str = get_duplicable_str( object );
-
 		g_free( str );
+		g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_DATA_DUPLICABLE, NULL );
 	}
 }
 
@@ -273,9 +273,9 @@ na_iduplicable_dump( const NAIDuplicable *object )
 
 		str = get_duplicable_str( object );
 
-		g_debug( "%s:   origin=%p", thisfn, ( void * ) str->origin );
-		g_debug( "%s: modified=%s", thisfn, str->modified ? "True" : "False" );
-		g_debug( "%s:    valid=%s", thisfn, str->valid ? "True" : "False" );
+		g_debug( "| %s:   origin=%p", thisfn, ( void * ) str->origin );
+		g_debug( "| %s: modified=%s", thisfn, str->modified ? "True" : "False" );
+		g_debug( "| %s:    valid=%s", thisfn, str->valid ? "True" : "False" );
 	}
 }
 
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 58b2f13..3aa54fa 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -73,6 +73,7 @@ static void         instance_dispose( GObject *object );
 static void         instance_finalize( GObject *object );
 
 static void         object_copy( NAObject *target, const NAObject *source, gboolean recursive );
+static void         object_dump( const NAObject *object );
 static gboolean     object_is_valid( const NAObject *object );
 
 static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
@@ -168,8 +169,8 @@ class_init( NAObjectActionClass *klass )
 	object_class->finalize = instance_finalize;
 
 	naobject_class = NA_OBJECT_CLASS( klass );
-	naobject_class->dump = NULL;
 	naobject_class->copy = object_copy;
+	naobject_class->dump = object_dump;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = object_is_valid;
 
@@ -229,9 +230,10 @@ instance_dispose( GObject *object )
 	self = NA_OBJECT_ACTION( object );
 
 	if( !self->private->dispose_has_run ){
-
 		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
 
+		na_object_dump( object );
+
 		self->private->dispose_has_run = TRUE;
 
 		/* chain up to the parent class */
@@ -274,6 +276,29 @@ object_copy( NAObject *target, const NAObject *source, gboolean recursive )
 	}
 }
 
+static void
+object_dump( const NAObject *object )
+{
+	static const char *thisfn = "na_object_action_object_dump";
+	NAObjectAction *self;
+
+	g_return_if_fail( NA_IS_OBJECT_ACTION( object ));
+
+	self = NA_OBJECT_ACTION( object );
+
+	if( !self->private->dispose_has_run ){
+		g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
+				( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
+
+		/* chain up to the parent class */
+		if( NA_OBJECT_CLASS( st_parent_class )->dump ){
+			NA_OBJECT_CLASS( st_parent_class )->dump( object );
+		}
+
+		g_debug( "+- end of dump" );
+	}
+}
+
 static gboolean
 object_is_valid( const NAObject *object )
 {
diff --git a/src/core/na-object-id.c b/src/core/na-object-id.c
index fe6ad07..44c8eff 100644
--- a/src/core/na-object-id.c
+++ b/src/core/na-object-id.c
@@ -114,7 +114,6 @@ class_init( NAObjectIdClass *klass )
 	object_class->finalize = instance_finalize;
 
 	naobject_class = NA_OBJECT_CLASS( klass );
-	naobject_class->dump = NULL;
 	naobject_class->copy = NULL;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = object_is_valid;
diff --git a/src/core/na-object-item.c b/src/core/na-object-item.c
index e83ede5..2da6ad8 100644
--- a/src/core/na-object-item.c
+++ b/src/core/na-object-item.c
@@ -52,17 +52,8 @@ struct _NAObjectItemClassPrivate {
 struct _NAObjectItemPrivate {
 	gboolean   dispose_has_run;
 
-	void      *provider_data;
-
-	/* dynamically set when reading the item from the I/O storage
-	 * subsystem; may be reset from FALSE to TRUE if a write operation
-	 * has returned an error.
-	 * defaults to FALSE for new, not yet written to a provider, item
-	 */
-	gboolean   readonly;
-
 	/* set at load time
-	 * takes into account the above 'readonly' status as well as the i/o
+	 * takes into account the runtime 'readonly' status as well as the i/o
 	 * provider writability status - does not consider the level-zero case
 	 */
 	gboolean   writable;
@@ -238,7 +229,6 @@ object_copy( NAObject *target, const NAObject *source, gboolean recursive )
 			}
 		}
 
-		dest->private->readonly = src->private->readonly;
 		dest->private->writable = src->private->writable;
 		dest->private->reason = src->private->reason;
 	}
@@ -256,10 +246,13 @@ object_dump( const NAObject *object )
 
 	if( !item->private->dispose_has_run ){
 
-		g_debug( "%s: provider_data=%p", thisfn, ( void * ) item->private->provider_data );
-		g_debug( "%s:      readonly=%s", thisfn, item->private->readonly ? "True":"False" );
-		g_debug( "%s:      writable=%s", thisfn, item->private->writable ? "True":"False" );
-		g_debug( "%s:        reason=%u", thisfn, item->private->reason );
+		g_debug( "| %s:      writable=%s", thisfn, item->private->writable ? "True":"False" );
+		g_debug( "| %s:        reason=%u", thisfn, item->private->reason );
+
+		/* chain up to the parent class */
+		if( NA_OBJECT_CLASS( st_parent_class )->dump ){
+			NA_OBJECT_CLASS( st_parent_class )->dump( object );
+		}
 	}
 }
 
diff --git a/src/core/na-object-menu.c b/src/core/na-object-menu.c
index cd72384..7f6e3ff 100644
--- a/src/core/na-object-menu.c
+++ b/src/core/na-object-menu.c
@@ -70,6 +70,7 @@ static void         instance_dispose( GObject *object );
 static void         instance_finalize( GObject *object );
 
 static void         object_copy( NAObject *target, const NAObject *source, gboolean recursive );
+static void         object_dump( const NAObject *object );
 static gboolean     object_is_valid( const NAObject *object );
 
 static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
@@ -159,8 +160,8 @@ class_init( NAObjectMenuClass *klass )
 	object_class->finalize = instance_finalize;
 
 	naobject_class = NA_OBJECT_CLASS( klass );
-	naobject_class->dump = NULL;
 	naobject_class->copy = object_copy;
+	naobject_class->dump = object_dump;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = object_is_valid;
 
@@ -265,6 +266,29 @@ object_copy( NAObject *target, const NAObject *source, gboolean recursive )
 	}
 }
 
+static void
+object_dump( const NAObject *object )
+{
+	static const char *thisfn = "na_object_menu_object_dump";
+	NAObjectMenu *self;
+
+	g_return_if_fail( NA_IS_OBJECT_MENU( object ));
+
+	self = NA_OBJECT_MENU( object );
+
+	if( !self->private->dispose_has_run ){
+		g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
+				( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
+
+		/* chain up to the parent class */
+		if( NA_OBJECT_CLASS( st_parent_class )->dump ){
+			NA_OBJECT_CLASS( st_parent_class )->dump( object );
+		}
+
+		g_debug( "+- end of dump" );
+	}
+}
+
 static gboolean
 object_is_valid( const NAObject *object )
 {
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 53518d2..5c5a82f 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -74,6 +74,7 @@ static void         instance_dispose( GObject *object );
 static void         instance_finalize( GObject *object );
 
 static void         object_copy( NAObject *target, const NAObject *source, gboolean recursive );
+static void         object_dump( const NAObject *object );
 static gboolean     object_is_valid( const NAObject *object );
 
 static void         ifactory_object_iface_init( NAIFactoryObjectInterface *iface );
@@ -169,8 +170,8 @@ class_init( NAObjectProfileClass *klass )
 	object_class->finalize = instance_finalize;
 
 	naobject_class = NA_OBJECT_CLASS( klass );
-	naobject_class->dump = NULL;
 	naobject_class->copy = object_copy;
+	naobject_class->dump = object_dump;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = object_is_valid;
 
@@ -280,6 +281,29 @@ object_copy( NAObject *target, const NAObject *source, gboolean recursive )
 	}
 }
 
+static void
+object_dump( const NAObject *object )
+{
+	static const char *thisfn = "na_object_profile_object_dump";
+	NAObjectProfile *self;
+
+	g_return_if_fail( NA_IS_OBJECT_PROFILE( object ));
+
+	self = NA_OBJECT_PROFILE( object );
+
+	if( !self->private->dispose_has_run ){
+		g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
+				( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
+
+		/* chain up to the parent class */
+		if( NA_OBJECT_CLASS( st_parent_class )->dump ){
+			NA_OBJECT_CLASS( st_parent_class )->dump( object );
+		}
+
+		g_debug( "+- end of dump" );
+	}
+}
+
 static gboolean
 object_is_valid( const NAObject *object )
 {
diff --git a/src/core/na-object.c b/src/core/na-object.c
index b089221..91a4f7e 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -86,7 +86,6 @@ static gboolean iduplicable_is_valid_iter( GObjectClass *class, const NAObject *
 static void     check_status_down_rec( const NAObject *object );
 static void     check_status_up_rec( const NAObject *object, gboolean was_modified, gboolean was_valid );
 static gboolean object_copy_iter( GObjectClass *class, const NAObject *source, CopyIter *data );
-static gboolean dump_class_hierarchy_iter( GObjectClass *class, const NAObject *object, void *user_data );
 static void     dump_tree( GList *tree, gint level );
 static void     iter_on_class_hierarchy( const NAObject *object, HierarchyIterFunc pfn, void *user_data );
 static GList   *build_class_hierarchy( const NAObject *object );
@@ -152,14 +151,12 @@ class_init( NAObjectClass *klass )
 	object_class->finalize = instance_finalize;
 
 	naobject_class = NA_OBJECT_CLASS( klass );
-	naobject_class->dump = NULL;
+	naobject_class->dump = object_dump;
 	naobject_class->copy = NULL;
 	naobject_class->are_equal = NULL;
 	naobject_class->is_valid = NULL;
 
 	klass->private = g_new0( NAObjectClassPrivate, 1 );
-
-	klass->dump = object_dump;
 }
 
 static void
@@ -189,7 +186,6 @@ instance_dispose( GObject *object )
 	self = NA_OBJECT( object );
 
 	if( !self->private->dispose_has_run ){
-
 		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
 
 		self->private->dispose_has_run = TRUE;
@@ -230,15 +226,13 @@ instance_finalize( GObject *object )
 static void
 object_dump( const NAObject *object )
 {
-	static const char *thisfn = "na_object_do_dump";
-
-	g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
-			( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
+	if( !object->private->dispose_has_run ){
 
-	na_iduplicable_dump( NA_IDUPLICABLE( object ));
+		na_iduplicable_dump( NA_IDUPLICABLE( object ));
 
-	if( NA_IS_IFACTORY_OBJECT( object )){
-		na_factory_object_dump( NA_IFACTORY_OBJECT( object ));
+		if( NA_IS_IFACTORY_OBJECT( object )){
+			na_factory_object_dump( NA_IFACTORY_OBJECT( object ));
+		}
 	}
 }
 
@@ -516,10 +510,9 @@ na_object_object_dump( const NAObject *object )
 		na_object_dump_norec( object );
 
 		if( NA_IS_OBJECT_ITEM( object )){
-
 			children = na_object_get_items( object );
-			for( ic = children ; ic ; ic = ic->next ){
 
+			for( ic = children ; ic ; ic = ic->next ){
 				na_object_dump( ic->data );
 			}
 		}
@@ -542,21 +535,10 @@ na_object_object_dump_norec( const NAObject *object )
 	g_return_if_fail( NA_IS_OBJECT( object ));
 
 	if( !object->private->dispose_has_run ){
-
-		iter_on_class_hierarchy( object, ( HierarchyIterFunc ) &dump_class_hierarchy_iter, NULL );
-	}
-}
-
-static gboolean
-dump_class_hierarchy_iter( GObjectClass *class, const NAObject *object, void *user_data )
-{
-	gboolean stop = FALSE;
-
-	if( NA_OBJECT_CLASS( class )->dump ){
-		NA_OBJECT_CLASS( class )->dump( object );
+		if( NA_OBJECT_GET_CLASS( object )->dump ){
+			NA_OBJECT_GET_CLASS( object )->dump( object );
+		}
 	}
-
-	return( stop );
 }
 
 /**
diff --git a/src/nact/base-window.c b/src/nact/base-window.c
index 82d6999..5a9242c 100644
--- a/src/nact/base-window.c
+++ b/src/nact/base-window.c
@@ -1230,3 +1230,24 @@ record_connected_signal( BaseWindow *window, GObject *instance, gulong handler_i
 		g_debug( "%s: connecting signal handler %p:%lu", thisfn, ( void * ) instance, handler_id );
 	}
 }
+
+void
+base_window_signal_disconnect( BaseWindow *window, gulong handler_id )
+{
+	GList *it;
+
+	g_return_if_fail( BASE_IS_WINDOW( window ));
+
+	if( !window->private->dispose_has_run ){
+
+		for( it = window->private->signals ; it ; it = it->next ){
+			RecordedSignal *str = ( RecordedSignal * ) it->data;
+
+			if( str->handler_id == handler_id ){
+				g_signal_handler_disconnect( str->instance, str->handler_id );
+				window->private->signals = g_list_delete_link( window->private->signals, it );
+				g_free( str );
+			}
+		}
+	}
+}
diff --git a/src/nact/base-window.h b/src/nact/base-window.h
index 0a14a5e..0de35f4 100644
--- a/src/nact/base-window.h
+++ b/src/nact/base-window.h
@@ -241,6 +241,7 @@ gulong           base_window_signal_connect          ( BaseWindow *window, GObje
 gulong           base_window_signal_connect_after    ( BaseWindow *window, GObject *instance, const gchar *signal, GCallback fn );
 gulong           base_window_signal_connect_by_name  ( BaseWindow *window, const gchar *name, const gchar *signal, GCallback fn );
 gulong           base_window_signal_connect_with_data( BaseWindow *window, GObject *instance, const gchar *signal, GCallback fn, void *user_data );
+void             base_window_signal_disconnect       ( BaseWindow *window, gulong handler_id );
 
 G_END_DECLS
 
diff --git a/src/nact/nact-assistant-export.c b/src/nact/nact-assistant-export.c
index e18bae0..82e7068 100644
--- a/src/nact/nact-assistant-export.c
+++ b/src/nact/nact-assistant-export.c
@@ -230,6 +230,8 @@ instance_dispose( GObject *window )
 
 		self->private->dispose_has_run = TRUE;
 
+		g_object_unref( self->private->items_view );
+
 		if( self->private->selected_items ){
 			self->private->selected_items = na_object_free_items( self->private->selected_items );
 		}
diff --git a/src/nact/nact-iaction-tab.c b/src/nact/nact-iaction-tab.c
index 20f1923..bc04a15 100644
--- a/src/nact/nact-iaction-tab.c
+++ b/src/nact/nact-iaction-tab.c
@@ -382,7 +382,8 @@ on_main_selection_changed( NactIActionTab *instance, GList *selected_items, gpoi
 	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 );
+		g_debug( "%s: instance=%p, selected_items=%p (count=%u)",
+				thisfn, ( void * ) instance, ( void * ) selected_items, count_selected );
 
 		enable_tab = ( count_selected == 1 );
 		nact_main_tab_enable_page( NACT_MAIN_WINDOW( instance ), TAB_ACTION, enable_tab );
diff --git a/src/nact/nact-main-toolbar.c b/src/nact/nact-main-toolbar.c
index 1f280cf..071e4c5 100644
--- a/src/nact/nact-main-toolbar.c
+++ b/src/nact/nact-main-toolbar.c
@@ -141,7 +141,7 @@ nact_main_toolbar_activate( NactMainWindow *window, int toolbar_id, GtkUIManager
 	}
 
 	toolbar = gtk_ui_manager_get_widget( ui_manager, props->ui_path );
-	g_debug( "%s: toolbar=%p, path=%s, ref=%d", thisfn, ( void * ) toolbar, props->ui_path, G_OBJECT( toolbar )->ref_count );
+	g_debug( "%s: toolbar=%p, path=%s, ref_count=%d", thisfn, ( void * ) toolbar, props->ui_path, G_OBJECT( toolbar )->ref_count );
 	hbox = base_window_get_widget( BASE_WINDOW( window ), "ToolbarHBox" );
 
 	if( is_active ){
@@ -157,7 +157,6 @@ nact_main_toolbar_activate( NactMainWindow *window, int toolbar_id, GtkUIManager
 		gtk_container_add( GTK_CONTAINER( hbox ), handle );
 		reorder_toolbars( GTK_HBOX( hbox ), toolbar_id, handle );
 		gtk_widget_show_all( handle );
-		g_debug( "%s: ref=%d", thisfn, G_OBJECT( toolbar )->ref_count );
 
 	} else {
 		handle = ( GtkWidget * ) g_object_get_data( G_OBJECT( toolbar ), "nact-main-toolbar-handle" );
@@ -167,7 +166,6 @@ nact_main_toolbar_activate( NactMainWindow *window, int toolbar_id, GtkUIManager
 		g_signal_handler_disconnect( handle, attach_id );
 		gtk_container_remove( GTK_CONTAINER( handle ), toolbar );
 		gtk_container_remove( GTK_CONTAINER( hbox ), handle );
-		g_debug( "%s: ref=%d", thisfn, G_OBJECT( toolbar )->ref_count );
 	}
 
 	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index 2fe0a1b..35cabb5 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -119,8 +119,8 @@ struct _NactMainWindowPrivate {
 	 * Some convenience objects and data.
 	 */
 	NactTreeView    *items_view;
+	gboolean         is_tree_modified;
 	NactClipboard   *clipboard;
-	guint            count_modified;
 };
 
 /* properties set against the main window
@@ -179,7 +179,7 @@ static void     on_base_initialize_gtk_toplevel( NactMainWindow *window, GtkWind
 static void     on_base_initialize_base_window( NactMainWindow *window, gpointer user_data );
 static void     on_base_all_widgets_showed( NactMainWindow *window, gpointer user_data );
 
-static void     on_tree_view_modified_count_changed( NactMainWindow *window, guint count, gpointer user_data );
+static void     on_tree_view_modified_status_changed( NactMainWindow *window, gboolean is_modified, gpointer user_data );
 static void     on_tree_view_selection_changed( NactMainWindow *window, 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 );
@@ -352,22 +352,22 @@ class_init( NactMainWindowClass *klass )
 	g_object_class_install_property( object_class, MAIN_PROP_ITEM_ID,
 			g_param_spec_pointer(
 					MAIN_PROP_ITEM,
-					"Edited NAObjectItem",
-					"A pointer to the edited NAObjectItem, an action or a menu",
+					"Current NAObjectItem",
+					"A pointer to the currently edited NAObjectItem, an action or a menu",
 					G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
 
 	g_object_class_install_property( object_class, MAIN_PROP_PROFILE_ID,
 			g_param_spec_pointer(
 					MAIN_PROP_PROFILE,
-					"Edited NAObjectProfile",
-					"A pointer to the edited NAObjectProfile",
+					"Current NAObjectProfile",
+					"A pointer to the currently edited NAObjectProfile",
 					G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
 
 	g_object_class_install_property( object_class, MAIN_PROP_CONTEXT_ID,
 			g_param_spec_pointer(
 					MAIN_PROP_CONTEXT,
 					"Current NAIContext",
-					"The currently edited NAIContext",
+					"A pointer to the currently edited NAIContext",
 					G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
 
 	g_object_class_install_property( object_class, MAIN_PROP_EDITABLE_ID,
@@ -433,24 +433,6 @@ class_init( NactMainWindowClass *klass )
 			G_TYPE_BOOLEAN );
 
 	/**
-	 * main-window-level-zero-order-changed:
-	 *
-	 * This signal is emitted each time a user interaction may led the
-	 * action sensitivities to be updated.
-	 */
-	st_signals[ ORDER_CHANGED ] = g_signal_new(
-			MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED,
-			G_TYPE_OBJECT,
-			G_SIGNAL_RUN_LAST,
-			0,					/* no default handler */
-			NULL,
-			NULL,
-			g_cclosure_marshal_VOID__POINTER,
-			G_TYPE_NONE,
-			1,
-			G_TYPE_POINTER );
-
-	/**
 	 * NactMainWindow::main-selection-changed:
 	 *
 	 * This signal is emitted on the window parent each time the selection
@@ -709,7 +691,7 @@ instance_constructed( GObject *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 ));
+				G_OBJECT( window ), TREE_SIGNAL_MODIFIED_STATUS_CHANGED, G_CALLBACK( on_tree_view_modified_status_changed ));
 
 		/* create the menubar
 		 * it will create itself toolbar and statusbar
@@ -743,6 +725,7 @@ instance_dispose( GObject *window )
 
 		self->private->dispose_has_run = TRUE;
 
+		g_object_unref( self->private->items_view );
 		g_object_unref( self->private->clipboard );
 
 		settings = na_pivot_get_settings( NA_PIVOT( self->private->updater ));
@@ -989,19 +972,19 @@ nact_main_window_reload( NactMainWindow *window )
 }
 
 /*
- * the count of modified NAObjectItem has changed
+ * the modification status of the items view has changed
  */
 static void
-on_tree_view_modified_count_changed( NactMainWindow *window, guint count, gpointer user_data )
+on_tree_view_modified_status_changed( NactMainWindow *window, gboolean is_modified, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_main_window_on_tree_view_modified_count_changed";
+	static const gchar *thisfn = "nact_main_window_on_tree_view_modified_status_changed";
 
-	g_debug( "%s: window=%p, count=%d, user_data=%p",
-			thisfn, ( void * ) window, count, ( void * ) user_data );
+	g_debug( "%s: window=%p, is_modified=%s, user_data=%p",
+			thisfn, ( void * ) window, is_modified ? "True":"False", ( void * ) user_data );
 
 	if( !window->private->dispose_has_run ){
 
-		window->private->count_modified = count;
+		window->private->is_tree_modified = is_modified;
 		setup_dialog_title( window );
 	}
 }
@@ -1043,7 +1026,7 @@ on_tree_view_selection_changed( NactMainWindow *window, GList *selected_items, g
 static void
 on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items )
 {
-	static const gchar *thisfn = "nact_mainw_window_on_selection_changed_cleanup_handler";
+	static const gchar *thisfn = "nact_main_window_on_selection_changed_cleanup_handler";
 
 	g_debug( "%s: window=%p, selected_items=%p (count=%u)",
 			thisfn, ( void * ) window,
@@ -1124,7 +1107,7 @@ setup_dialog_title( NactMainWindow *window )
 		title = tmp;
 	}
 
-	if( window->private->count_modified > 0 ){
+	if( window->private->is_tree_modified ){
 		tmp = g_strdup_printf( "*%s", title );
 		g_free( title );
 		title = tmp;
@@ -1185,7 +1168,7 @@ confirm_for_giveup_from_pivot( const NactMainWindow *window )
 					"You could keep to work with your current list of actions, "
 					"or you may want to reload a fresh one." ));
 
-	if( window->private->count_modified > 0 ){
+	if( window->private->is_tree_modified){
 
 		gchar *tmp = g_strdup_printf( "%s\n\n%s", first,
 				_( "Note that reloading a fresh list of actions requires "
@@ -1214,7 +1197,7 @@ confirm_for_giveup_from_menu( const NactMainWindow *window )
 	gboolean reload_ok = TRUE;
 	gchar *first, *second;
 
-	if( window->private->count_modified > 0 ){
+	if( window->private->is_tree_modified ){
 
 		first = g_strdup(
 					_( "Reloading a fresh list of actions requires "
@@ -1269,7 +1252,7 @@ nact_main_window_quit( NactMainWindow *window )
 	if( !window->private->dispose_has_run ){
 		g_debug( "%s: window=%p (%s)", thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ));
 
-		if( window->private->count_modified == 0  || warn_modified( window )){
+		if( !window->private->is_tree_modified  || warn_modified( window )){
 			g_object_unref( window );
 			terminated = TRUE;
 		}
@@ -1287,7 +1270,8 @@ base_is_willing_to_quit( const BaseWindow *window )
 	g_debug( "%s: window=%p", thisfn, ( void * ) window );
 
 	willing_to = TRUE;
-	if( NACT_MAIN_WINDOW( window )->private->count_modified > 0 ){
+
+	if( NACT_MAIN_WINDOW( window )->private->is_tree_modified ){
 		willing_to = nact_confirm_logout_run( NACT_MAIN_WINDOW( window ));
 	}
 
@@ -1532,8 +1516,7 @@ on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpoin
 		tree = na_pivot_get_items( NA_PIVOT( window->private->updater ));
 
 		if( g_list_length( tree )){
-			g_signal_emit_by_name( window,
-					MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED, GINT_TO_POINTER( TRUE ));
+			g_signal_emit_by_name( window, TREE_SIGNAL_LEVEL_ZERO_CHANGED );
 		}
 	}
 }
diff --git a/src/nact/nact-main-window.h b/src/nact/nact-main-window.h
index 45aa8c8..347e1ef 100644
--- a/src/nact/nact-main-window.h
+++ b/src/nact/nact-main-window.h
@@ -163,8 +163,6 @@ typedef struct {
 #define MAIN_PROP_EDITABLE					"main-editable"
 #define MAIN_PROP_REASON					"main-reason"
 
-#define MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED		"main-window-level-zero-order-changed"
-
 GType           nact_main_window_get_type( void );
 
 NactMainWindow *nact_main_window_new           ( const NactApplication *application );
diff --git a/src/nact/nact-menubar-edit.c b/src/nact/nact-menubar-edit.c
index 1ff9916..b481588 100644
--- a/src/nact/nact-menubar-edit.c
+++ b/src/nact/nact-menubar-edit.c
@@ -225,7 +225,7 @@ nact_menubar_edit_on_cut( GtkAction *gtk_action, BaseWindow *window )
 		nact_clipboard_primary_set( clipboard, to_delete, CLIPBOARD_MODE_CUT );
 		update_clipboard_counters( window );
 		view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
-		nact_tree_ieditable_delete( NACT_TREE_IEDITABLE( view ), to_delete, TRUE );
+		nact_tree_ieditable_delete( NACT_TREE_IEDITABLE( view ), to_delete, TREE_OPE_DELETE );
 	}
 
 	na_object_free_items( items );
@@ -473,7 +473,7 @@ nact_menubar_edit_on_delete( GtkAction *gtk_action, BaseWindow *window )
 
 	if( to_delete ){
 		view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
-		nact_tree_ieditable_delete( NACT_TREE_IEDITABLE( view ), to_delete, TRUE );
+		nact_tree_ieditable_delete( NACT_TREE_IEDITABLE( view ), to_delete, TREE_OPE_DELETE );
 	}
 
 	na_object_free_items( items );
diff --git a/src/nact/nact-menubar-file.c b/src/nact/nact-menubar-file.c
index 0a1a23a..0c711ec 100644
--- a/src/nact/nact-menubar-file.c
+++ b/src/nact/nact-menubar-file.c
@@ -104,7 +104,7 @@ nact_menubar_file_on_update_sensitivities( const NactMenubar *bar )
 	/* save enabled if at least one item has been modified
 	 * or level-zero has been resorted and is writable
 	 */
-	nact_menubar_enable_item( bar, "SaveItem", ( bar->private->count_modified > 0 ));
+	nact_menubar_enable_item( bar, "SaveItem", ( bar->private->is_tree_modified ));
 
 	/* quit always enabled */
 }
@@ -290,8 +290,6 @@ nact_menubar_file_save_items( BaseWindow *window )
 		return;
 	}
 
-	bar->private->level_zero_order_changed = FALSE;
-
 	/* remove deleted items
 	 * so that new actions with same id do not risk to be deleted later
 	 */
@@ -344,12 +342,7 @@ nact_menubar_file_save_items( BaseWindow *window )
 	na_pivot_set_new_items( NA_PIVOT( bar->private->updater ), g_list_reverse( new_pivot ));
 	g_list_free( items );
 
-	/* when new_pivot is empty, then there has been no chance of updating
-	 * sensibilities on check status - so force it there
-	 */
-	if( !new_pivot ){
-		g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
-	}
+	g_signal_emit_by_name( window, TREE_SIGNAL_MODIFIED_STATUS_CHANGED, FALSE );
 }
 
 /*
diff --git a/src/nact/nact-menubar-priv.h b/src/nact/nact-menubar-priv.h
index 883d526..64c98c2 100644
--- a/src/nact/nact-menubar-priv.h
+++ b/src/nact/nact-menubar-priv.h
@@ -73,10 +73,10 @@ struct _NactMenubarPrivate {
 	gboolean         is_action_writable;
 	gboolean         are_parents_writable;		/* cut/delete */
 
-	/* set when the count of modified NAObjectItem changes
-	 * this is a NactTreeIEditable-driven count
+	/* set when the count of modified or deleted NAObjectItem changes
+	 * or when the lever zero is changed
 	 */
-	guint            count_modified;
+	gboolean         is_tree_modified;
 
 	/* set on focus in/out
 	 */
@@ -100,7 +100,6 @@ struct _NactMenubarPrivate {
 	gint            clipboard_menus;
 	gint            clipboard_actions;
 	gint            clipboard_profiles;
-	gboolean        level_zero_order_changed;
 	/* *** */
 };
 
diff --git a/src/nact/nact-menubar.c b/src/nact/nact-menubar.c
index 17d8ab5..3f61073 100644
--- a/src/nact/nact-menubar.c
+++ b/src/nact/nact-menubar.c
@@ -224,21 +224,16 @@ static void     on_menu_item_deselected( GtkMenuItem *proxy, BaseWindow *window
 
 static void     on_tree_view_open_context_menu( BaseWindow *window, GdkEventButton *event, gpointer user_data );
 static void     on_popup_selection_done( GtkMenuShell *menushell, BaseWindow *window );
-static void     on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus, guint actions, guint profiles );
+static void     on_tree_view_count_changed( BaseWindow *window, gboolean reset, gint menus, gint actions, gint profiles );
 static void     on_tree_view_focus_in( BaseWindow *window, gpointer user_data );
 static void     on_tree_view_focus_out( BaseWindow *window, gpointer user_data );
-static void     on_tree_view_modified_count_changed( BaseWindow *window, guint count, gpointer user_data );
+static void     on_tree_view_modified_status_changed( BaseWindow *window, gboolean is_modified, gpointer user_data );
 static void     on_tree_view_selection_changed( BaseWindow *window, GList *selected, gpointer user_data );
 
 static void     on_update_sensitivities( NactMenubar *bar, BaseWindow *window );
 
 static void     on_finalizing_window( NactMenubar *bar, GObject *window );
 
-#if 0
-static void     on_iactions_list_status_changed( BaseWindow *window, gpointer user_data );
-static void     on_level_zero_order_changed( BaseWindow *window, gpointer user_data );
-#endif
-
 GType
 nact_menubar_get_type( void )
 {
@@ -515,19 +510,11 @@ on_base_initialize_window( BaseWindow *window, gpointer user_data )
 				G_OBJECT( window ), TREE_SIGNAL_FOCUS_OUT, G_CALLBACK( on_tree_view_focus_out ));
 
 		base_window_signal_connect( window,
-				G_OBJECT( window ), TREE_SIGNAL_MODIFIED_COUNT_CHANGED, G_CALLBACK( on_tree_view_modified_count_changed ));
+				G_OBJECT( window ), TREE_SIGNAL_MODIFIED_STATUS_CHANGED, G_CALLBACK( on_tree_view_modified_status_changed ));
 
 		base_window_signal_connect( window,
 				G_OBJECT( window ), TREE_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tree_view_selection_changed ));
 
-#if 0
-		base_window_signal_connect( window,
-				G_OBJECT( window ), IACTIONS_LIST_SIGNAL_STATUS_CHANGED, G_CALLBACK( on_iactions_list_status_changed ));
-
-		base_window_signal_connect( window,
-				G_OBJECT( window ), MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED, G_CALLBACK( on_level_zero_order_changed ));
-#endif
-
 		base_window_signal_connect( window,
 				G_OBJECT( bar ), MENUBAR_SIGNAL_UPDATE_SENSITIVITIES, G_CALLBACK( on_update_sensitivities ));
 
@@ -644,14 +631,14 @@ on_popup_selection_done(GtkMenuShell *menushell, BaseWindow *window )
  * that we are knowing if we have some exportables
  */
 static void
-on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus, guint actions, guint profiles )
+on_tree_view_count_changed( BaseWindow *window, gboolean reset, gint menus, gint actions, gint profiles )
 {
 	static const gchar *thisfn = "nact_menubar_on_tree_view_count_changed";
 	gchar *status;
 
 	BAR_WINDOW_VOID( window );
 
-	g_debug( "%s: window=%p, reset=%s, menus=%u, actions=%u, profiles=%u",
+	g_debug( "%s: window=%p, reset=%s, menus=%d, actions=%d, profiles=%d",
 			thisfn, ( void * ) window, reset ? "True":"False", menus, actions, profiles );
 
 	if( reset ){
@@ -667,10 +654,6 @@ on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus, gui
 
 	bar->private->have_exportables = ( bar->private->count_menus + bar->private->count_actions > 0 );
 
-#if 0
-	nact_sort_buttons_enable_buttons( window, bar->private->count_menus + bar->private->count_actions > 0 );
-#endif
-
 	/* i18n: note the space at the beginning of the sentence */
 	status = g_strdup_printf(
 			_( " %d menu(s), %d action(s), %d profile(s) are currently loaded" ),
@@ -681,26 +664,6 @@ on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus, gui
 	g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
 }
 
-/*
- * the count of modified NAObjectItem has changed
- */
-static void
-on_tree_view_modified_count_changed( BaseWindow *window, guint count, gpointer user_data )
-{
-	static const gchar *thisfn = "nact_menubar_on_tree_view_modified_count_changed";
-
-	g_debug( "%s: window=%p, count=%d, user_data=%p",
-			thisfn, ( void * ) window, count, ( void * ) user_data );
-
-	BAR_WINDOW_VOID( window );
-
-	if( !bar->private->dispose_has_run ){
-
-		bar->private->count_modified = count;
-		g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
-	}
-}
-
 static void
 on_tree_view_focus_in( BaseWindow *window, gpointer user_data )
 {
@@ -724,6 +687,26 @@ on_tree_view_focus_out( BaseWindow *window, gpointer user_data )
 }
 
 /*
+ * the count of modified NAObjectItem has changed
+ */
+static void
+on_tree_view_modified_status_changed( BaseWindow *window, gboolean is_modified, gpointer user_data )
+{
+	static const gchar *thisfn = "nact_menubar_on_tree_view_modified_status_changed";
+
+	g_debug( "%s: window=%p, is_modified=%s, user_data=%p",
+			thisfn, ( void * ) window, is_modified ? "True":"False", ( void * ) user_data );
+
+	BAR_WINDOW_VOID( window );
+
+	if( !bar->private->dispose_has_run ){
+
+		bar->private->is_tree_modified = is_modified;
+		g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
+	}
+}
+
+/*
  * when the selection changes in the tree view, see what is selected
  *
  * It happens that this function is triggered after all tabs have already
@@ -930,15 +913,4 @@ on_iactions_list_status_changed( BaseWindow *window, gpointer user_data )
 
 	g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
 }
-
-static void
-on_level_zero_order_changed( BaseWindow *window, gpointer user_data )
-{
-	BAR_WINDOW_VOID( window );
-
-	g_debug( "nact_menubar_on_level_zero_order_changed: change=%s", user_data ? "True":"False" );
-
-	bar->private->level_zero_order_changed = GPOINTER_TO_INT( user_data );
-	g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
-}
 #endif
diff --git a/src/nact/nact-sort-buttons.c b/src/nact/nact-sort-buttons.c
index 513473a..49483cf 100644
--- a/src/nact/nact-sort-buttons.c
+++ b/src/nact/nact-sort-buttons.c
@@ -81,7 +81,7 @@ static void  instance_finalize( GObject *application );
 static void  on_base_initialize_buttons( BaseWindow *window, gpointer user_data );
 static void  on_toggle_button_toggled( GtkToggleButton *button, BaseWindow *window );
 static void  on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpointer new_value, gboolean mandatory, NactSortButtons *sort_buttons );
-static void  on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus_count, guint actions_count, guint profiles_count, gpointer user_data );
+static void  on_tree_view_count_changed( BaseWindow *window, gboolean reset, gint menus_count, gint actions_count, gint profiles_count, gpointer user_data );
 
 static void  enable_buttons( const NactSortButtons *sort_buttons, gboolean enabled );
 static gint  toggle_group_get_from_mode( guint mode );
@@ -361,7 +361,7 @@ on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpoin
 }
 
 static void
-on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus_count, guint actions_count, guint profiles_count, gpointer user_data )
+on_tree_view_count_changed( BaseWindow *window, gboolean reset, gint menus_count, gint actions_count, gint profiles_count, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_sort_buttons_on_tree_view_count_changed";
 	NactSortButtons *sort_buttons;
@@ -371,7 +371,7 @@ on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus_coun
 	sort_buttons = NACT_SORT_BUTTONS( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_SORT_BUTTONS ));
 
 	if( !sort_buttons->private->dispose_has_run ){
-		g_debug( "%s: window=%p, reset=%s, nb_menus=%u, nb_actions=%u, nb_profiles=%u, user_data=%p",
+		g_debug( "%s: window=%p, reset=%s, nb_menus=%d, nb_actions=%d, nb_profiles=%d, user_data=%p",
 				thisfn, ( void * ) window, reset ? "True":"False",
 						menus_count, actions_count, profiles_count, ( void * ) user_data );
 
diff --git a/src/nact/nact-tree-ieditable.c b/src/nact/nact-tree-ieditable.c
index df243b1..aeca979 100644
--- a/src/nact/nact-tree-ieditable.c
+++ b/src/nact/nact-tree-ieditable.c
@@ -55,7 +55,10 @@ typedef struct {
 	BaseWindow    *window;
 	GtkTreeView   *treeview;
 	NactTreeModel *model;
+	gulong         modified_handler_id;
+	gulong         valid_handler_id;
 	guint          count_modified;
+	gboolean       level_zero_changed;
 	GList         *deleted;
 }
 	IEditableData;
@@ -71,14 +74,19 @@ static void           interface_base_finalize( NactTreeIEditableInterface *klass
 
 static gboolean       on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window );
 static void           on_label_edited( GtkCellRendererText *renderer, const gchar *path_str, const gchar *text, BaseWindow *window );
-static void           on_modified_status_changed( NactTreeIEditable *view, NAObject *object, gboolean new_status, BaseWindow *window );
-static void           on_valid_status_changed( NactTreeIEditable *view, NAObject *object, gboolean new_status, BaseWindow *window );
-static void           do_insert_before( NactTreeIEditable *view, IEditableData *ied, GList *items, GtkTreePath *insert_path );
-static GtkTreePath   *do_insert_into( NactTreeIEditable *view, IEditableData *ied, GList *items, GtkTreePath *insert_path );
+static void           on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data );
+static void           on_object_modified_status_changed( NactTreeIEditable *view, NAObject *object, gboolean new_status, BaseWindow *window );
+static void           on_object_valid_status_changed( NactTreeIEditable *view, NAObject *object, gboolean new_status, BaseWindow *window );
+static void           on_tree_view_level_zero_changed( BaseWindow *window, gpointer user_data );
+static void           on_tree_view_modified_status_changed( BaseWindow *window, gboolean is_modified, gpointer user_data );
+static void           add_to_deleted_rec( IEditableData *ied, NAObject *object );
+static void           decrement_counters( NactTreeIEditable *view, IEditableData *ialid, GList *items );
+static GtkTreePath   *do_insert_before( IEditableData *ied, GList *items, GtkTreePath *insert_path );
+static GtkTreePath   *do_insert_into( IEditableData *ied, GList *items, GtkTreePath *insert_path );
 static void           increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items );
 static GtkTreePath   *get_selection_first_path( GtkTreeView *treeview );
+static gboolean       get_modification_status( IEditableData *ied );
 static IEditableData *get_instance_data( NactTreeIEditable *view );
-static void           decrement_counters( NactTreeIEditable *view, IEditableData *ialid, GList *items );
 static void           inline_edition( BaseWindow *window );
 
 GType
@@ -174,7 +182,7 @@ nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treevi
 	application = NACT_APPLICATION( base_window_get_application( window ));
 	ied->updater = nact_application_get_updater( application );
 
-	/* inline label edition */
+	/* inline label edition with F2 */
 	base_window_signal_connect( window,
 			G_OBJECT( treeview ), "key-press-event", G_CALLBACK( on_key_pressed_event ));
 
@@ -186,10 +194,22 @@ nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treevi
 
 	/* monitors status changes to refresh the display */
 	na_iduplicable_register_consumer( G_OBJECT( instance ));
+	ied->modified_handler_id = base_window_signal_connect( window,
+			G_OBJECT( instance ), IDUPLICABLE_SIGNAL_MODIFIED_CHANGED, G_CALLBACK( on_object_modified_status_changed ));
+	ied->valid_handler_id = base_window_signal_connect( window,
+			G_OBJECT( instance ), IDUPLICABLE_SIGNAL_VALID_CHANGED, G_CALLBACK( on_object_valid_status_changed ));
+
+	/* monitors the reloading of the tree */
 	base_window_signal_connect( window,
-			G_OBJECT( instance ), IDUPLICABLE_SIGNAL_MODIFIED_CHANGED, G_CALLBACK( on_modified_status_changed ));
+			G_OBJECT( window ), TREE_SIGNAL_MODIFIED_STATUS_CHANGED, G_CALLBACK( on_tree_view_modified_status_changed ));
+
+	/* monitors the level zero of the tree */
+	base_window_signal_connect( window,
+			G_OBJECT( window ), TREE_SIGNAL_LEVEL_ZERO_CHANGED, G_CALLBACK( on_tree_view_level_zero_changed ));
+
+	/* monitors the main selection */
 	base_window_signal_connect( window,
-			G_OBJECT( instance ), IDUPLICABLE_SIGNAL_VALID_CHANGED, G_CALLBACK( on_valid_status_changed ));
+			G_OBJECT( window ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 }
 
 /**
@@ -208,7 +228,13 @@ nact_tree_ieditable_terminate( NactTreeIEditable *instance )
 
 	ied = get_instance_data( instance );
 
-	g_list_free( ied->deleted );
+	na_object_free_items( ied->deleted );
+
+	base_window_signal_disconnect( ied->window, ied->modified_handler_id );
+	base_window_signal_disconnect( ied->window, ied->valid_handler_id );
+
+	g_free( ied );
+	g_object_set_data( G_OBJECT( instance ), VIEW_DATA_IEDITABLE, NULL );
 }
 
 static gboolean
@@ -243,7 +269,7 @@ on_label_edited( GtkCellRendererText *renderer, const gchar *path_str, const gch
 	GtkTreePath *path;
 	gchar *new_text;
 
-	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 
 	if( nact_tree_view_are_notify_allowed( items_view )){
 		ied = ( IEditableData * ) g_object_get_data( G_OBJECT( items_view ), VIEW_DATA_IEDITABLE );
@@ -255,34 +281,57 @@ on_label_edited( GtkCellRendererText *renderer, const gchar *path_str, const gch
 	}
 }
 
+static void
+on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data )
+{
+	NAObject *object;
+	gboolean object_editable;
+	NactTreeView *items_view;
+	IEditableData *ied;
+	GtkTreeViewColumn *column;
+	GList *renderers;
+	gboolean editable;
+
+	g_object_get( window, MAIN_PROP_ITEM, &object, MAIN_PROP_EDITABLE, &object_editable, NULL );
+	editable = NA_IS_OBJECT( object ) && object_editable;
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
+	ied = ( IEditableData * ) g_object_get_data( G_OBJECT( items_view ), VIEW_DATA_IEDITABLE );
+	column = gtk_tree_view_get_column( ied->treeview, TREE_COLUMN_LABEL );
+	renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
+	g_object_set( G_OBJECT( renderers->data ), "editable", editable, "editable-set", TRUE, NULL );
+}
+
 /*
- * modification status of the edited object has changed
+ * modification status of an edited object has changed
  * - refresh the display
  */
 static void
-on_modified_status_changed( NactTreeIEditable *instance, NAObject *object, gboolean is_modified, BaseWindow *window )
+on_object_modified_status_changed( NactTreeIEditable *instance, NAObject *object, gboolean is_modified, BaseWindow *window )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_on_modified_status_changed";
-	NactTreeView *items_view;
+	static const gchar *thisfn = "nact_tree_ieditable_on_object_modified_status_changed";
 	IEditableData *ied;
+	gboolean prev_status, status;
 
 	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
-		items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
-
-		if( nact_tree_view_are_notify_allowed( items_view )){
-			g_debug( "%s: instance=%p, is_modified=%s, window=%p",
-					thisfn, ( void * ) instance, is_modified ? "True":"False", ( void * ) window );
-
-			ied = ( IEditableData * ) g_object_get_data( G_OBJECT( instance ), VIEW_DATA_IEDITABLE );
-			gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
-
-			if( NA_IS_OBJECT_ITEM( object )){
-				if( is_modified ){
-					ied->count_modified += 1;
-				} else {
-					ied->count_modified -= 1;
-				}
-				g_signal_emit_by_name( window, TREE_SIGNAL_MODIFIED_COUNT_CHANGED, ied->count_modified );
+		g_debug( "%s: instance=%p, is_modified=%s, window=%p",
+				thisfn, ( void * ) instance, is_modified ? "True":"False", ( void * ) window );
+
+		ied = ( IEditableData * ) g_object_get_data( G_OBJECT( instance ), VIEW_DATA_IEDITABLE );
+		prev_status = get_modification_status( ied );
+		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
+
+		if( NA_IS_OBJECT_ITEM( object )){
+			if( is_modified ){
+				ied->count_modified += 1;
+			} else {
+				ied->count_modified -= 1;
+			}
+		}
+
+		if( nact_tree_view_are_notify_allowed( NACT_TREE_VIEW( instance ))){
+			status = get_modification_status( ied );
+			if( status != prev_status ){
+				g_signal_emit_by_name( window, TREE_SIGNAL_MODIFIED_STATUS_CHANGED, status );
 			}
 		}
 	}
@@ -293,69 +342,127 @@ on_modified_status_changed( NactTreeIEditable *instance, NAObject *object, gbool
  * - refresh the display
  */
 static void
-on_valid_status_changed( NactTreeIEditable *instance, NAObject *object, gboolean new_status, BaseWindow *window )
+on_object_valid_status_changed( NactTreeIEditable *instance, NAObject *object, gboolean new_status, BaseWindow *window )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_on_valid_status_changed";
-	NactTreeView *items_view;
+	static const gchar *thisfn = "nact_tree_ieditable_on_object_valid_status_changed";
 	IEditableData *ied;
 
 	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
-		items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+		g_debug( "%s: instance=%p, new_status=%s, window=%p",
+				thisfn, ( void * ) instance, new_status ? "True":"False", ( void * ) window );
 
-		if( nact_tree_view_are_notify_allowed( items_view )){
-			g_debug( "%s: instance=%p, new_status=%s, window=%p",
-					thisfn, ( void * ) instance, new_status ? "True":"False", ( void * ) window );
+		ied = ( IEditableData * ) g_object_get_data( G_OBJECT( instance ), VIEW_DATA_IEDITABLE );
+		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
+	}
+}
 
-			ied = ( IEditableData * ) g_object_get_data( G_OBJECT( instance ), VIEW_DATA_IEDITABLE );
-			gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
+/*
+ * order of items at level zero of the tree has changed
+ */
+static void
+on_tree_view_level_zero_changed( BaseWindow *window, gpointer user_data )
+{
+	NactTreeView *items_view;
+	IEditableData *ied;
+	gboolean prev_status, status;
+
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
+	ied = get_instance_data( NACT_TREE_IEDITABLE( items_view ));
+	prev_status = get_modification_status( ied );
+	ied->level_zero_changed = TRUE;
+
+	if( nact_tree_view_are_notify_allowed( items_view )){
+		status = get_modification_status( ied );
+		if( prev_status != status ){
+			g_signal_emit_by_name( window, TREE_SIGNAL_MODIFIED_STATUS_CHANGED, status );
 		}
 	}
 }
 
+/*
+ * the tree has been reloaded
+ */
+static void
+on_tree_view_modified_status_changed( BaseWindow *window, gboolean is_modified, gpointer user_data )
+{
+	NactTreeView *items_view;
+	IEditableData *ied;
+
+	if( !is_modified ){
+		items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
+		ied = get_instance_data( NACT_TREE_IEDITABLE( items_view ));
+		ied->count_modified = 0;
+		ied->deleted = na_object_free_items( ied->deleted );
+		ied->level_zero_changed = FALSE;
+	}
+}
+
 /**
  * nact_tree_ieditable_delete:
  * @instance: this #NactTreeIEditable instance.
  * @list: list of #NAObject to be deleted.
- * @select_at_end: whether a row should be selected after delete.
+ * @ope: whether the objects are actually to be deleted, or just moved
+ *  to another path of the tree.
  *
  * Deletes the specified list from the underlying tree store.
  *
- * This function takes care of repositionning a new selection if
- * possible, and refilter the display model.
- *
+ * If the items are to be actually deleted, then this function takes care
+ * of repositionning a new selection if possible, and refilter the display
+ * model.
  * Deleted NAObjectItems are added to the 'deleted' list attached to the
  * view, so that they will be actually deleted from the storage subsystem
  * on save.
- *
  * Deleted NAObjectProfiles are not added to the list, because the deletion
  * will be recorded when saving the action.
+ *
+ * If the items are to be actually moved to another path of the tree, then
+ * neither the 'deleted' list nor the 'count_modified' counter are modified.
  */
 void
-nact_tree_ieditable_delete( NactTreeIEditable *instance, GList *items, gboolean select_at_end )
+nact_tree_ieditable_delete( NactTreeIEditable *instance, GList *items, TreeIEditableDeleteOpe ope )
 {
 	static const gchar *thisfn = "nact_tree_ieditable_delete";
 	IEditableData *ied;
-	GtkTreePath *path = NULL;
+	gboolean prev_status, status;
+	GtkTreePath *path;
 	GList *it;
+	NAObjectItem *parent;
 
 	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), select_at_end=%s",
-				thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ), select_at_end ? "True":"False" );
+		g_debug( "%s: instance=%p, items=%p (count=%d), ope=%u",
+				thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ), ope );
 
+		nact_tree_view_set_notify_allowed( NACT_TREE_VIEW( instance ), FALSE );
 		ied = get_instance_data( instance );
+		prev_status = get_modification_status( ied );
 
 		decrement_counters( instance, ied, items );
+		path = NULL;
 
 		for( it = items ; it ; it = it->next ){
 			if( path ){
 				gtk_tree_path_free( path );
 			}
 
+			/* check the status of the parent of the deleted object
+			 * so potentially update the modification status
+			 */
+			parent = na_object_get_parent( it->data );
 			path = nact_tree_model_delete( ied->model, NA_OBJECT( it->data ));
+			if( parent ){
+				na_object_check_status( parent );
+			} else {
+				g_signal_emit_by_name( ied->window, TREE_SIGNAL_LEVEL_ZERO_CHANGED );
+			}
 
-			/*ialid->modified_items = nact_iactions_list_remove_rec( ialid->modified_items, NA_OBJECT( it->data ));*/
+			/* record the deleted item in the 'deleted' list,
+			 * incrementing the 'modified' count if the deleted item was not yet modified
+			 */
+			if( ope == TREE_OPE_DELETE ){
+				add_to_deleted_rec( ied, NA_OBJECT( it->data ));
+			}
 
 			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 );
@@ -364,15 +471,75 @@ nact_tree_ieditable_delete( NactTreeIEditable *instance, GList *items, gboolean
 		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
 
 		if( path ){
-			if( select_at_end ){
+			if( ope == TREE_OPE_DELETE ){
 				nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), path );
 			}
 			gtk_tree_path_free( path );
 		}
+
+		status = get_modification_status( ied );
+		if( status != prev_status ){
+			g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_MODIFIED_STATUS_CHANGED, status );
+
+		}
+
+		nact_tree_view_set_notify_allowed( NACT_TREE_VIEW( instance ), TRUE );
 	}
 }
 
 /**
+ * add_to_deleted_rec:
+ * @list: list of deleted objects.
+ * @object: the object to be added from the list.
+ *
+ * Recursively adds to the 'deleted' list the NAObjectItem object currently being deleted.
+ *
+ * Increments the 'modified' count with the deleted items which were not modified.
+ */
+static void
+add_to_deleted_rec( IEditableData *ied, NAObject *object )
+{
+	GList *subitems, *it;
+
+	if( NA_IS_OBJECT_ITEM( object )){
+
+		if( !g_list_find( ied->deleted, object )){
+			ied->deleted = g_list_prepend( ied->deleted, object );
+
+			if( na_object_is_modified( object )){
+				ied->count_modified -= 1;
+			}
+		}
+
+		if( NA_IS_OBJECT_MENU( object )){
+			subitems = na_object_get_items( object );
+			for( it = subitems ; it ; it = it->next ){
+				add_to_deleted_rec( ied, it->data );
+			}
+		}
+	}
+}
+
+/*
+ * update the total count of elements
+ */
+static void
+decrement_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
+{
+	static const gchar *thisfn = "nact_tree_editable_decrement_counters";
+	gint menus, actions, profiles;
+
+	g_debug( "%s: view=%p, ied=%p, items=%p (count=%u)",
+			thisfn, ( void * ) view, ( void * ) ied, ( void * ) items, g_list_length( items ));
+
+	na_object_count_items( items, &menus, &actions, &profiles );
+	menus *= -1;
+	actions *= -1;
+	profiles *= -1;
+	g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_COUNT_CHANGED, FALSE, menus, actions, profiles );
+}
+
+/**
  * nact_tree_ieditable_insert_items:
  * @instance: this #NactTreeIEditable instance.
  * @items: a list of items to be inserted (e.g. from a paste).
@@ -458,7 +625,10 @@ nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, G
 {
 	static const gchar *thisfn = "nact_tree_ieditable_insert_at_path";
 	IEditableData *ied;
-	guint prev_count;
+	GtkTreePath *actual_path;
+	gboolean prev_status, status;
+	NAObjectItem *parent;
+	GList *it;
 
 	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
 
@@ -466,56 +636,35 @@ nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, G
 		g_debug( "%s: instance=%p, items=%p (count=%d)",
 			thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ));
 
+		nact_tree_view_set_notify_allowed( NACT_TREE_VIEW( instance ), FALSE );
 		ied = get_instance_data( instance );
-		prev_count = ied->count_modified;
+		prev_status = get_modification_status( ied );
 
-		do_insert_before( instance, ied, items, insert_path );
+		actual_path = do_insert_before( ied, items, insert_path );
 
-		/* post insertion
-		 */
-		increment_counters( instance, ied, items );
-		if( ied->count_modified != prev_count ){
-			g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_MODIFIED_COUNT_CHANGED, ied->count_modified );
+		parent = na_object_get_parent( items->data );
+		if( parent ){
+			na_object_check_status( parent );
+		} else {
+			for( it = items ; it ; it = it->next ){
+				na_object_check_status( it->data );
+			}
+			ied->level_zero_changed = TRUE;
 		}
-		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
-		nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), insert_path );
-	}
-}
-
-static void
-do_insert_before( NactTreeIEditable *view, IEditableData *ied, GList *items, GtkTreePath *insert_path )
-{
-	static const gchar *thisfn = "nact_tree_ieditable_do_insert_before";
-	GList *reversed;
-	GList *it;
-	GList *subitems;
-	GtkTreePath *inserted_path;
-
-	reversed = g_list_reverse( g_list_copy( items ));
-
-	for( it = reversed ; it ; it = it->next ){
-		inserted_path = nact_tree_model_insert_before( ied->model, NA_OBJECT( it->data ), insert_path );
-		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 );
 
-		/* after the item has been inserted, and attached to its new parent
-		 * increment modified counters
-		 */
-
-		/* recursively insert subitems
+		/* post insertion
 		 */
-		if( NA_IS_OBJECT_ITEM( it->data )){
-			subitems = na_object_get_items( it->data );
-			if( subitems ){
-				do_insert_into( view, ied, subitems, inserted_path );
-			}
+		status = get_modification_status( ied );
+		if( prev_status != status ){
+			g_signal_emit_by_name( ied->window, TREE_SIGNAL_MODIFIED_STATUS_CHANGED, status );
 		}
+		nact_tree_view_set_notify_allowed( NACT_TREE_VIEW( instance ), TRUE );
 
-		na_object_check_status( it->data );
-		gtk_tree_path_free( inserted_path );
+		increment_counters( instance, ied, items );
+		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
+		nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), actual_path );
+		gtk_tree_path_free( actual_path );
 	}
-
-	g_list_free( reversed );
 }
 
 /**
@@ -544,7 +693,7 @@ nact_tree_ieditable_insert_into( NactTreeIEditable *instance, GList *items )
 	IEditableData *ied;
 	GtkTreePath *insert_path;
 	GtkTreePath *new_path;
-	guint prev_count;
+	NAObjectItem *parent;
 
 	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
 
@@ -552,29 +701,70 @@ nact_tree_ieditable_insert_into( NactTreeIEditable *instance, GList *items )
 		g_debug( "%s: instance=%p, items=%p (count=%d)",
 			thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ));
 
-		insert_path = NULL;
 		ied = get_instance_data( instance );
-		prev_count = ied->count_modified;
 		insert_path = get_selection_first_path( ied->treeview );
 
-		new_path = do_insert_into( instance, ied, items, insert_path );
+		new_path = do_insert_into( ied, items, insert_path );
+
+		parent = na_object_get_parent( items->data );
+		na_object_check_status( parent );
 
 		/* post insertion
 		 */
 		increment_counters( instance, ied, items );
-		if( ied->count_modified != prev_count ){
-			g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_MODIFIED_COUNT_CHANGED, ied->count_modified );
-		}
 		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
 		nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), new_path );
-
 		gtk_tree_path_free( new_path );
 		gtk_tree_path_free( insert_path );
 	}
 }
 
 /*
- * inserting a list of children into an object is as:
+ * inserting a list of objects at path is:
+ * - for each item starting from the end, do
+ *   > insert the item at path
+ *   > recursively insert item children into the insertion path
+ *
+ * Returns the actual insertion path suitable for the next selection.
+ * This path should be gtk_tree_path_free() by the caller.
+ */
+static GtkTreePath *
+do_insert_before( IEditableData *ied, GList *items, GtkTreePath *asked_path )
+{
+	static const gchar *thisfn = "nact_tree_ieditable_do_insert_before";
+	GList *reversed;
+	GList *it;
+	GtkTreePath *path;
+	GtkTreePath *actual_path;
+
+	reversed = g_list_reverse( items );
+	actual_path = NULL;
+
+	for( it = reversed ; it ; it = it->next ){
+		if( actual_path ){
+			path = gtk_tree_path_copy( actual_path );
+			gtk_tree_path_free( actual_path );
+		} else {
+			path = gtk_tree_path_copy( asked_path );
+		}
+		actual_path = nact_tree_model_insert_before( ied->model, NA_OBJECT( it->data ), path );
+		gtk_tree_path_free( path );
+		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 );
+
+		/* recursively insert subitems
+		 */
+		if( NA_IS_OBJECT_ITEM( it->data )){
+			path = do_insert_into( ied, na_object_get_items( it->data ), actual_path );
+			gtk_tree_path_free( path );
+		}
+	}
+
+	return( actual_path );
+}
+
+/*
+ * inserting a list of objects into an object is as:
  * - inserting the last child into the object
  * - then inserting other children just before the last insertion path
  *
@@ -582,43 +772,42 @@ nact_tree_ieditable_insert_into( NactTreeIEditable *instance, GList *items )
  * This path should be gtk_tree_path_free() by the caller.
  */
 static GtkTreePath *
-do_insert_into( NactTreeIEditable *view, IEditableData *ied, GList *items, GtkTreePath *insert_path )
+do_insert_into( IEditableData *ied, GList *items, GtkTreePath *asked_path )
 {
-	static const gchar *thisfn = "nact_tree_ieditable_do_insert_into";
 	GList *copy;
 	GList *last;
-	gchar *insert_path_str;
-	GtkTreePath *inserted_path;
-
-	insert_path_str = gtk_tree_path_to_string( insert_path );
-	g_debug( "%s: view=%p, ied=%p, items=%p (count=%d), insert_path=%p (%s)",
-			thisfn,
-			( void * ) view, ( void * ) ied, ( void * ) items, g_list_length( items ),
-			( void * ) insert_path, insert_path_str );
-	g_free( insert_path_str );
-
-	copy = g_list_copy( items );
-	last = g_list_last( copy );
-	copy = g_list_remove_link( copy, last );
-
-	/* insert the last child into the wished path
-	 * and recursively all its children
-	 */
-	inserted_path = nact_tree_model_insert_into( ied->model, NA_OBJECT( last->data ), insert_path );
-	gtk_tree_view_expand_to_path( ied->treeview, inserted_path );
-
-	if( NA_IS_OBJECT_ITEM( last->data )){
-		do_insert_into( view, ied, na_object_get_items( last->data ), inserted_path );
-		na_object_check_status( last->data );
-	}
+	GtkTreePath *actual_path;
+	GtkTreePath *insertion_path;
+
+	actual_path = NULL;
+
+	if( items ){
+		copy = g_list_copy( items );
+		last = g_list_last( copy );
+		copy = g_list_remove_link( copy, last );
 
-	/* then insert other objects
-	 */
-	do_insert_before( view, ied, copy, inserted_path );
+		/* insert the last child into the wished path
+		 * and recursively all its children
+		 */
+		actual_path = nact_tree_model_insert_into( ied->model, NA_OBJECT( last->data ), asked_path );
+		gtk_tree_view_expand_to_path( ied->treeview, actual_path );
 
-	g_list_free( copy );
+		if( NA_IS_OBJECT_ITEM( last->data )){
+			insertion_path = do_insert_into( ied, na_object_get_items( last->data ), actual_path );
+			gtk_tree_path_free( insertion_path );
+		}
 
-	return( inserted_path );
+		/* then insert other objects
+		 */
+		if( copy ){
+			insertion_path = do_insert_before( ied, copy, actual_path );
+			gtk_tree_path_free( actual_path );
+			actual_path = insertion_path;
+			g_list_free( copy );
+		}
+	}
+
+	return( actual_path );
 }
 
 /*
@@ -627,7 +816,7 @@ do_insert_into( NactTreeIEditable *view, IEditableData *ied, GList *items, GtkTr
 static void
 increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
 {
-	static const gchar *thisfn = "nact_tre_ieditablet_increment_counters";
+	static const gchar *thisfn = "nact_tree_ieditable_increment_counters";
 	gint menus, actions, profiles;
 
 	g_debug( "%s: view=%p, ied=%p, items=%p (count=%d)",
@@ -680,6 +869,17 @@ get_selection_first_path( GtkTreeView *treeview )
 	return( path );
 }
 
+static gboolean
+get_modification_status( IEditableData *ied )
+{
+	gboolean modified;
+
+	modified = ( ied->count_modified > 0 ) ||
+				( g_list_length( ied->deleted ) > 0 ) || ( ied->level_zero_changed );
+
+	return( modified );
+}
+
 static IEditableData *
 get_instance_data( NactTreeIEditable *view )
 {
@@ -695,25 +895,9 @@ get_instance_data( NactTreeIEditable *view )
 	return( ied );
 }
 
-static void
-decrement_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
-{
-	static const gchar *thisfn = "nact_tree_editable_decrement_counters";
-	gint menus, actions, profiles;
-
-	g_debug( "%s: view=%p, ied=%p, items=%p",
-			thisfn, ( void * ) view, ( void * ) ied, ( void * ) items );
-
-	na_object_count_items( items, &menus, &actions, &profiles );
-	menus *= -1;
-	actions *= -1;
-	profiles *= -1;
-	g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_COUNT_CHANGED, FALSE, menus, actions, profiles );
-}
-
 /*
  * triggered by 'F2' key
- * let thelabel be edited
+ * let the label be edited
  */
 static void
 inline_edition( BaseWindow *window )
@@ -722,13 +906,14 @@ inline_edition( BaseWindow *window )
 	IEditableData *ied;
 	GtkTreeSelection *selection;
 	GList *listrows;
+	GtkTreeModel *model;
 	GtkTreePath *path;
 	GtkTreeViewColumn *column;
 
-	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 	ied = ( IEditableData * ) g_object_get_data( G_OBJECT( items_view ), VIEW_DATA_IEDITABLE );
 	selection = gtk_tree_view_get_selection( ied->treeview );
-	listrows = gtk_tree_selection_get_selected_rows( selection, NULL );
+	listrows = gtk_tree_selection_get_selected_rows( selection, &model );
 
 	if( g_list_length( listrows ) == 1 ){
 		path = ( GtkTreePath * ) listrows->data;
diff --git a/src/nact/nact-tree-ieditable.h b/src/nact/nact-tree-ieditable.h
index df0be59..1b7855d 100644
--- a/src/nact/nact-tree-ieditable.h
+++ b/src/nact/nact-tree-ieditable.h
@@ -68,15 +68,24 @@ typedef struct {
 }
 	NactTreeIEditableInterface;
 
-GType nact_tree_ieditable_get_type( void );
+/**
+ * Delete operations
+ */
+typedef enum {
+	TREE_OPE_DELETE = 0,
+	TREE_OPE_MOVE
+}
+	TreeIEditableDeleteOpe;
+
+GType    nact_tree_ieditable_get_type( void );
 
-void  nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treeview, BaseWindow *window );
-void  nact_tree_ieditable_terminate ( NactTreeIEditable *instance );
+void     nact_tree_ieditable_initialize    ( NactTreeIEditable *instance, GtkTreeView *treeview, BaseWindow *window );
+void     nact_tree_ieditable_terminate     ( NactTreeIEditable *instance );
 
-void  nact_tree_ieditable_delete        ( NactTreeIEditable *instance, GList *items, gboolean select_at_end );
-void  nact_tree_ieditable_insert_items  ( NactTreeIEditable *instance, GList *items, NAObject *sibling );
-void  nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, GtkTreePath *path );
-void  nact_tree_ieditable_insert_into   ( NactTreeIEditable *instance, GList *items );
+void     nact_tree_ieditable_delete        ( NactTreeIEditable *instance, GList *items, TreeIEditableDeleteOpe ope );
+void     nact_tree_ieditable_insert_items  ( NactTreeIEditable *instance, GList *items, NAObject *sibling );
+void     nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, GtkTreePath *path );
+void     nact_tree_ieditable_insert_into   ( NactTreeIEditable *instance, GList *items );
 
 #if 0
 void      nact_tree_ieditable_brief_tree_dump( NactTreeIEditable *instance );
diff --git a/src/nact/nact-tree-model-dnd.c b/src/nact/nact-tree-model-dnd.c
index 3b8c418..065400e 100644
--- a/src/nact/nact-tree-model-dnd.c
+++ b/src/nact/nact-tree-model-dnd.c
@@ -551,17 +551,6 @@ nact_tree_model_dnd_on_drag_end( GtkWidget *widget, GdkDragContext *context, Bas
  *
  * Returns: %TRUE if the specified rows were successfully inserted at
  * the given dest, %FALSE else.
- *
- * The dest path is computed based on the current appearance of the list
- * Drop should so occurs inside an inchanged list to keep a valid path
- * in the case of a move, this leads to :
- *  1) marks dragged items as 'to be deleted'
- *  2) insert new dropped items
- *  3) remove 'to be deleted' items
- * -> not an easy idea as we want modify the id of all the dragged
- *    hierarchy
- *
- * adjusting the path: quid if the target dest is not at the same level
  */
 static gboolean
 drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selection_data )
@@ -581,12 +570,14 @@ drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selecti
 	GtkTreeIter iter;
 	GList *deletable;
 	gboolean relabel;
+	NactTreeView *items_view;
 
 	application = NACT_APPLICATION( base_window_get_application( model->private->window ));
 	updater = nact_application_get_updater( application );
 
 	g_return_val_if_fail( NACT_IS_MAIN_WINDOW( model->private->window ), FALSE );
 	main_window = NACT_MAIN_WINDOW( model->private->window );
+	items_view = nact_main_window_get_items_view( main_window );
 
 	/*
 	 * NACT format (may embed profiles, or not)
@@ -618,17 +609,16 @@ drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selecti
 					inserted = ( NAObject * ) na_object_duplicate( current );
 					na_object_set_origin( inserted, NULL );
 					na_object_check_status( inserted );
+					relabel = na_updater_should_pasted_be_relabeled( updater, inserted );
 
 				} else {
 					inserted = na_object_ref( current );
 					deletable = g_list_prepend( NULL, inserted );
-#if 0
-					nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( main_window ), deletable, FALSE );
-#endif
+					nact_tree_ieditable_delete( NACT_TREE_IEDITABLE( items_view ), deletable, TREE_OPE_MOVE );
 					g_list_free( deletable );
+					relabel = FALSE;
 				}
 
-				relabel = na_updater_should_pasted_be_relabeled( updater, inserted );
 				na_object_prepare_for_paste( inserted, relabel, copy_data, parent );
 				object_list = g_list_prepend( object_list, inserted );
 				g_debug( "%s: dropped=%s", thisfn, na_object_get_label( inserted ));
@@ -638,16 +628,9 @@ drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selecti
 	}
 	object_list = g_list_reverse( object_list );
 
-#if 0
-	nact_iactions_list_bis_insert_at_path( NACT_IACTIONS_LIST( main_window ), object_list, new_dest );
-#endif
-
-	if( gtk_tree_path_get_depth( new_dest ) == 1 ){
-		g_signal_emit_by_name( main_window, MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED, GINT_TO_POINTER( TRUE ));
-	}
+	nact_tree_ieditable_insert_at_path( NACT_TREE_IEDITABLE( items_view ), object_list, new_dest );
 
-	g_list_foreach( object_list, ( GFunc ) na_object_object_unref, NULL );
-	g_list_free( object_list );
+	na_object_free_items( object_list );
 	gtk_tree_path_free( new_dest );
 
 	g_list_foreach( rows, ( GFunc ) gtk_tree_row_reference_free, NULL );
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index b96f830..2982c7e 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -125,7 +125,7 @@ static gboolean       get_items_iter( const NactTreeModel *model, GtkTreeStore *
 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       delete_items_rec( GtkTreeStore *store, GtkTreeIter *iter );
 static gint           sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data );
 
 GType
@@ -247,7 +247,6 @@ instance_dispose( GObject *object )
 {
 	static const gchar *thisfn = "nact_tree_model_instance_dispose";
 	NactTreeModel *self;
-	GtkTreeStore *ts_model;
 
 	g_return_if_fail( NACT_IS_TREE_MODEL( object ));
 
@@ -260,10 +259,6 @@ instance_dispose( GObject *object )
 
 		g_object_unref( self->private->clipboard );
 
-		ts_model = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( self )));
-		gtk_tree_store_clear( ts_model );
-		g_debug( "%s: tree store cleared", thisfn );
-
 		/* chain up to the parent class */
 		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
 			G_OBJECT_CLASS( st_parent_class )->dispose( object );
@@ -300,7 +295,7 @@ instance_finalize( GObject *object )
  * Returns: a newly created NactTreeModel object.
  *
  * The returned reference is owned by the #GtkTreeView, which will automatically
- * take care of g_object_unref() its tree model when destroyint its widget.
+ * take care of g_object_unref() its tree model when destroying its widget.
  */
 NactTreeModel *
 nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mode )
@@ -527,16 +522,21 @@ nact_tree_model_delete( NactTreeModel *model, NAObject *object )
 		path = nact_tree_model_object_to_path( model, object );
 
 		if( path != NULL ){
-			gtk_tree_path_free( path );
-			store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+
+			/* detaching to-be-deleted object from its current parent
+			 */
 			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( parent );
 			}
-			gtk_tree_model_get_iter( GTK_TREE_MODEL( store ), &iter, path );
-			remove_items( store, &iter );
+
+			/* then recursively remove the object and its children from the store
+			 */
+			store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+			if( gtk_tree_model_get_iter( GTK_TREE_MODEL( store ), &iter, path )){
+				delete_items_rec( store, &iter );
+			}
 		}
 	}
 
@@ -673,6 +673,10 @@ nact_tree_model_insert_before( NactTreeModel *model, const NAObject *object, Gtk
 		display_item( GTK_TREE_STORE( store ), model->private->treeview, &iter, object );
 
 		inserted_path = gtk_tree_model_get_path( store, &iter );
+		path_str = gtk_tree_path_to_string( inserted_path );
+		g_debug( "%s: object %p (%s) inserted at path %s",
+				thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ), path_str );
+		g_free( path_str );
 	}
 
 	return( inserted_path );
@@ -734,6 +738,10 @@ nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTr
 		display_item( GTK_TREE_STORE( store ), model->private->treeview, &iter, object );
 
 		new_path = gtk_tree_model_get_path( store, &iter );
+		path_str = gtk_tree_path_to_string( new_path );
+		g_debug( "%s: object %p (%s) inserted at path %s",
+				thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ), path_str );
+		g_free( path_str );
 	}
 
 	return( new_path );
@@ -798,7 +806,7 @@ nact_tree_model_get_items( const NactTreeModel *model, guint 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 );
-		items = ngi.items;
+		items = g_list_reverse( ngi.items );
 	}
 
 	return( items );
@@ -1147,17 +1155,17 @@ remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *obj
 }
 
 /*
- * recursively remove child items starting with iter
+ * recursively delete child items starting with iter
  * returns TRUE if iter is always valid after the remove
  */
 static gboolean
-remove_items( GtkTreeStore *store, GtkTreeIter *iter )
+delete_items_rec( GtkTreeStore *store, GtkTreeIter *iter )
 {
 	GtkTreeIter child;
 	gboolean valid;
 
 	while( gtk_tree_model_iter_children( GTK_TREE_MODEL( store ), &child, iter )){
-		remove_items( store, &child );
+		delete_items_rec( store, &child );
 	}
 	valid = gtk_tree_store_remove( store, iter );
 
diff --git a/src/nact/nact-tree-view.c b/src/nact/nact-tree-view.c
index 9384ed3..d2899d6 100644
--- a/src/nact/nact-tree-view.c
+++ b/src/nact/nact-tree-view.c
@@ -38,7 +38,6 @@
 
 #include "base-keysyms.h"
 #include "nact-application.h"
-#include "nact-main-window.h"
 #include "nact-marshal.h"
 #include "nact-tree-view.h"
 #include "nact-tree-model.h"
@@ -88,7 +87,8 @@ enum {
 	COUNT_CHANGED,
 	FOCUS_IN,
 	FOCUS_OUT,
-	MODIFIED_COUNT,
+	LEVEL_ZERO_CHANGED,
+	MODIFIED_STATUS,
 	SELECTION_CHANGED,
 	LAST_SIGNAL
 };
@@ -128,8 +128,8 @@ static gboolean on_button_press_event( GtkWidget *widget, GdkEventButton *event,
 static gboolean on_focus_in( GtkWidget *widget, GdkEventFocus *event, BaseWindow *window );
 static gboolean on_focus_out( GtkWidget *widget, GdkEventFocus *event, BaseWindow *window );
 static gboolean on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window );
-static void     on_treeview_selection_changed( GtkTreeSelection *selection, BaseWindow *window );
 static void     on_content_changed_cleanup_handler( BaseWindow *window, NAObject *edited );
+static void     on_selection_changed( GtkTreeSelection *selection, BaseWindow *window );
 static void     on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items );
 static void     clear_selection( NactTreeView *view );
 static void     display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeView *view );
@@ -143,7 +143,6 @@ static void     select_row_at_path_by_string( NactTreeView *view, const gchar *p
 static void     toggle_collapse( NactTreeView *view );
 static gboolean toggle_collapse_iter( NactTreeView *view, GtkTreeModel *model, GtkTreeIter *iter, NAObject *object, gpointer user_data );
 static void     toggle_collapse_row( GtkTreeView *treeview, GtkTreePath *path, guint *toggle );
-static void     on_finalizing_window( NactTreeView *view, GObject *window );
 
 GType
 nact_tree_view_get_type( void )
@@ -375,32 +374,54 @@ class_init( NactTreeViewClass *klass )
 			0 );
 
 	/**
-	 * NactTreeView::tree-signal-modified-count-changed:
+	 * NactTreeView::tree-signal-level-zero-changed:
+	 *
+	 * This signal is emitted on the BaseWindow each time the level zero
+	 * has changed.
+	 *
+	 * Signal args: none
+	 *
+	 * Handler prototype:
+	 * void ( *handler )( BaseWindow *window, gpointer user_data );
+	 */
+	st_signals[ LEVEL_ZERO_CHANGED ] = g_signal_new(
+			TREE_SIGNAL_LEVEL_ZERO_CHANGED,
+			G_TYPE_OBJECT,
+			G_SIGNAL_RUN_LAST,
+			0,					/* no default handler */
+			NULL,
+			NULL,
+			g_cclosure_marshal_VOID__VOID,
+			G_TYPE_NONE,
+			0 );
+
+	/**
+	 * NactTreeView::tree-signal-modified-status-changed:
 	 *
 	 * This signal is emitted on the BaseWindow when the view detects that
-	 * the count of modified NAObjectItems has changed.
+	 * the count of modified NAObjectItems has changed, when an item is
+	 * deleted, or when the level zero is changed.
+	 *
 	 * The signal is actually emitted by the NactTreeIEditable interface
 	 * which takes care of all edition features.
 	 *
-	 * Having the order of items at level zero changed counts for one.
-	 *
 	 * Signal args:
-	 * - the new count of modified items
+	 * - the new modification status of the tree
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, guint count, gpointer user_data )
+	 * void ( *handler )( BaseWindow *window, gboolean is_modified, gpointer user_data )
 	 */
-	st_signals[ MODIFIED_COUNT ] = g_signal_new(
-			TREE_SIGNAL_MODIFIED_COUNT_CHANGED,
+	st_signals[ MODIFIED_STATUS ] = g_signal_new(
+			TREE_SIGNAL_MODIFIED_STATUS_CHANGED,
 			G_TYPE_OBJECT,
 			G_SIGNAL_RUN_LAST,
 			0,
 			NULL,
 			NULL,
-			g_cclosure_marshal_VOID__INT,
+			g_cclosure_marshal_VOID__BOOLEAN,
 			G_TYPE_NONE,
 			1,
-			G_TYPE_INT );
+			G_TYPE_BOOLEAN );
 
 	/**
 	 * NactTreeView::tree-signal-selection-changed:
@@ -545,7 +566,7 @@ instance_constructed( GObject *object )
 		base_window_signal_connect( self->private->window,
 				G_OBJECT( self->private->window ), BASE_SIGNAL_ALL_WIDGETS_SHOWED, G_CALLBACK( on_base_all_widgets_showed ));
 
-		g_object_weak_ref( G_OBJECT( self->private->window ), ( GWeakNotify ) on_finalizing_window, self );
+		g_object_set_data( G_OBJECT( self->private->window ), WINDOW_DATA_TREE_VIEW, self );
 
 		/* chain up to the parent class */
 		if( G_OBJECT_CLASS( st_parent_class )->constructed ){
@@ -559,6 +580,8 @@ instance_dispose( GObject *object )
 {
 	static const gchar *thisfn = "nact_tree_view_instance_dispose";
 	NactTreeView *self;
+	NactTreeModel *model;
+	GtkTreeStore *ts_model;
 
 	g_return_if_fail( NACT_IS_TREE_VIEW( object ));
 
@@ -569,7 +592,14 @@ instance_dispose( GObject *object )
 
 		self->private->dispose_has_run = TRUE;
 
-		nact_tree_ieditable_terminate( NACT_TREE_IEDITABLE( self ));
+		model = NACT_TREE_MODEL( gtk_tree_view_get_model( self->private->tree_view ));
+		ts_model = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+		gtk_tree_store_clear( ts_model );
+		g_debug( "%s: tree store cleared", thisfn );
+
+		if( self->private->mode == TREE_MODE_EDITION ){
+			nact_tree_ieditable_terminate( NACT_TREE_IEDITABLE( self ));
+		}
 
 		/* chain up to the parent class */
 		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
@@ -636,8 +666,7 @@ on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_d
 	GtkTreeSelection *selection;
 	GList *renderers;
 
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 
 	if( !items_view->private->dispose_has_run ){
 		g_debug( "%s: window=%p (%s), toplevel=%p (%s), user_data=%p",
@@ -696,8 +725,7 @@ on_base_initialize_view( BaseWindow *window, gpointer user_data )
 	GtkTreeView *treeview;
 	GtkTreeSelection *selection;
 
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 
 	if( !items_view->private->dispose_has_run ){
 		g_debug( "%s: window=%p (%s), user_data=%p",
@@ -709,7 +737,7 @@ on_base_initialize_view( BaseWindow *window, gpointer user_data )
 		/* monitors the selection */
 		selection = gtk_tree_view_get_selection( treeview );
 		base_window_signal_connect( window,
-				G_OBJECT( selection ), "changed", G_CALLBACK( on_treeview_selection_changed ));
+				G_OBJECT( selection ), "changed", G_CALLBACK( on_selection_changed ));
 
 		/* expand/collapse with the keyboard */
 		base_window_signal_connect( window,
@@ -738,8 +766,7 @@ on_base_all_widgets_showed( BaseWindow *window, gpointer user_data )
 	static const gchar *thisfn = "nact_tree_view_on_base_all_widgets_showed";
 	NactTreeView *items_view;
 
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 
 	if( !items_view->private->dispose_has_run ){
 		g_debug( "%s: window=%p (%s), user_data=%p",
@@ -798,8 +825,7 @@ on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window
 	gboolean stop = FALSE;
 	NactTreeView *items_view;
 
-	g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), FALSE );
-	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 
 	if( !items_view->private->dispose_has_run ){
 
@@ -821,17 +847,27 @@ on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window
 }
 
 /*
+ * cleanup handler for our TREE_SIGNAL_CONTENT_CHANGED signal
+ */
+static void
+on_content_changed_cleanup_handler( BaseWindow *window, NAObject *edited )
+{
+	static const gchar *thisfn = "nact_tree_view_on_content_changed_cleanup_handler";
+
+	g_debug( "%s: window=%p, edited=%p", thisfn, ( void * ) window, ( void * ) edited );
+}
+
+/*
  * handles the "changed" signal emitted on the GtkTreeSelection
  */
 static void
-on_treeview_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
+on_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
 {
-	static const gchar *thisfn = "nact_tree_view_on_treeview_selection_changed";
+	static const gchar *thisfn = "nact_tree_view_on_selection_changed";
 	NactTreeView *items_view;
 	GList *selected_items;
 
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 
 	if( !items_view->private->dispose_has_run ){
 		if( items_view->private->notify_allowed ){
@@ -844,21 +880,6 @@ on_treeview_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
 }
 
 /*
- * cleanup handler for our TREE_SIGNAL_CONTENT_CHANGED signal
- */
-static void
-on_content_changed_cleanup_handler( BaseWindow *window, NAObject *edited )
-{
-	static const gchar *thisfn = "nact_tree_view_on_content_changed_cleanup_handler";
-
-	g_debug( "%s: window=%p, edited=%p", thisfn, ( void * ) window, ( void * ) edited );
-
-	if( edited ){
-		na_object_unref( edited );
-	}
-}
-
-/*
  * cleanup handler for our TREE_SIGNAL_SELECTION_CHANGED signal
  */
 static void
@@ -902,11 +923,9 @@ nact_tree_view_fill( NactTreeView *view, GList *items )
 		nact_tree_model_fill( model, items );
 
 		view->private->notify_allowed = TRUE;
-
-		g_signal_emit_by_name( view->private->window, TREE_SIGNAL_CONTENT_CHANGED, NULL );
 		na_object_count_items( items, &nb_menus, &nb_actions, &nb_profiles );
 		g_signal_emit_by_name( view->private->window, TREE_SIGNAL_COUNT_CHANGED, TRUE, nb_menus, nb_actions, nb_profiles );
-		g_signal_emit_by_name( view->private->window, TREE_SIGNAL_MODIFIED_COUNT_CHANGED, 0 );
+		g_signal_emit_by_name( view->private->window, TREE_SIGNAL_MODIFIED_STATUS_CHANGED, FALSE );
 
 		select_row_at_path_by_string( view, "0" );
 	}
@@ -936,6 +955,22 @@ nact_tree_view_are_notify_allowed( const NactTreeView *view )
 }
 
 /**
+ * nact_tree_view_set_notify_allowed:
+ * @view: this #NactTreeView instance.
+ * @allow: whether the notifications are to be allowed.
+ */
+void
+nact_tree_view_set_notify_allowed( NactTreeView *view, gboolean allow )
+{
+	g_return_if_fail( NACT_IS_TREE_VIEW( view ));
+
+	if( !view->private->dispose_has_run ){
+
+		view->private->notify_allowed = allow;
+	}
+}
+
+/**
  * nact_tree_view_collapse_all:
  * @view: this #NactTreeView instance.
  *
@@ -1324,8 +1359,7 @@ open_popup( BaseWindow *window, GdkEventButton *event )
 	NactTreeView *items_view;
 	GtkTreePath *path;
 
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 
 	if( gtk_tree_view_get_path_at_pos( items_view->private->tree_view, event->x, event->y, &path, NULL, NULL, NULL )){
 		nact_tree_view_select_row_at_path( items_view, path );
@@ -1417,16 +1451,3 @@ toggle_collapse_row( GtkTreeView *treeview, GtkTreePath *path, guint *toggle )
 		}
 	}
 }
-
-static void
-on_finalizing_window( NactTreeView *view, GObject *window )
-{
-	static const gchar *thisfn = "nact_tree_view_on_finalizing_window";
-
-	g_return_if_fail( NACT_IS_TREE_VIEW( view ));
-
-	g_debug( "%s: view=%p (%s), window=%p",
-			thisfn, ( void * ) view, G_OBJECT_TYPE_NAME( view ), ( void * ) window );
-
-	g_object_unref( view );
-}
diff --git a/src/nact/nact-tree-view.h b/src/nact/nact-tree-view.h
index 1ab604d..c0aba5c 100644
--- a/src/nact/nact-tree-view.h
+++ b/src/nact/nact-tree-view.h
@@ -80,21 +80,22 @@ typedef struct {
  * @TREE_PROP_MODE:           management mode.
  * @TREE_PROP_NOTIFY_ALLOWED: whether notifications are allowed.
  */
-#define TREE_PROP_WINDOW					"tree-prop-window"
-#define TREE_PROP_WIDGET_NAME				"tree-prop-widget-name"
-#define TREE_PROP_MODE						"tree-prop-mode"
-#define TREE_PROP_NOTIFY_ALLOWED			"tree-prop-notify-allowed"
+#define TREE_PROP_WINDOW						"tree-prop-window"
+#define TREE_PROP_WIDGET_NAME					"tree-prop-widget-name"
+#define TREE_PROP_MODE							"tree-prop-mode"
+#define TREE_PROP_NOTIFY_ALLOWED				"tree-prop-notify-allowed"
 
 /**
  * Signals emitted by the NactTreeView instance.
  */
-#define TREE_SIGNAL_CONTENT_CHANGED			"tree-signal-content-changed"
-#define TREE_SIGNAL_CONTEXT_MENU			"tree-signal-open-popup"
-#define TREE_SIGNAL_COUNT_CHANGED			"tree-signal-count-changed"
-#define TREE_SIGNAL_FOCUS_IN				"tree-signal-focus-in"
-#define TREE_SIGNAL_FOCUS_OUT				"tree-signal-focus-out"
-#define TREE_SIGNAL_MODIFIED_COUNT_CHANGED	"tree-signal-modified-count-changed"
-#define TREE_SIGNAL_SELECTION_CHANGED		"tree-signal-selection-changed"
+#define TREE_SIGNAL_CONTENT_CHANGED				"tree-signal-content-changed"
+#define TREE_SIGNAL_CONTEXT_MENU				"tree-signal-open-popup"
+#define TREE_SIGNAL_COUNT_CHANGED				"tree-signal-count-changed"
+#define TREE_SIGNAL_FOCUS_IN					"tree-signal-focus-in"
+#define TREE_SIGNAL_FOCUS_OUT					"tree-signal-focus-out"
+#define TREE_SIGNAL_LEVEL_ZERO_CHANGED			"tree-signal-level-zero-changed"
+#define TREE_SIGNAL_MODIFIED_STATUS_CHANGED		"tree-signal-modified-status-changed"
+#define TREE_SIGNAL_SELECTION_CHANGED			"tree-signal-selection-changed"
 
 typedef enum {
 	TREE_MODE_EDITION = 0,
@@ -104,6 +105,12 @@ typedef enum {
 }
 	NactTreeMode;
 
+/**
+ * The NactTreeView is attached to the parent BaseWindow via a GObject data.
+ * Only NactTreeIEditable interface should use it.
+ */
+#define WINDOW_DATA_TREE_VIEW					"window-data-tree-view"
+
 GType         nact_tree_view_get_type( void );
 
 NactTreeView *nact_tree_view_new( BaseWindow *window, const gchar *treeview_name, NactTreeMode mode );
@@ -111,6 +118,7 @@ NactTreeView *nact_tree_view_new( BaseWindow *window, const gchar *treeview_name
 void          nact_tree_view_fill     ( NactTreeView *view, GList *items );
 
 gboolean      nact_tree_view_are_notify_allowed( const NactTreeView *view );
+void          nact_tree_view_set_notify_allowed( NactTreeView *view, gboolean allow );
 
 void          nact_tree_view_collapse_all      ( const NactTreeView *view );
 void          nact_tree_view_expand_all        ( const NactTreeView *view );



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