[nautilus-actions] NactSortButtons: new convenience class



commit 845f734d79bce829b67b3c84e726a8dc11a6e247
Author: Pierre Wieser <pwieser trychlos org>
Date:   Tue Feb 8 00:57:35 2011 +0100

    NactSortButtons: new convenience class

 src/core/na-iduplicable.c          |   58 +++--
 src/core/na-marshal.def            |    4 +
 src/core/na-updater.c              |   27 ++-
 src/nact/nact-assistant-export.c   |   18 +-
 src/nact/nact-iaction-tab.c        |  110 +++++----
 src/nact/nact-icommand-tab.c       |    4 +-
 src/nact/nact-iproperties-tab.c    |   15 +-
 src/nact/nact-main-window.c        |   67 ++---
 src/nact/nact-main-window.h        |   69 +++++
 src/nact/nact-marshal.def          |   16 +-
 src/nact/nact-menubar-edit.c       |    4 +-
 src/nact/nact-menubar-file.c       |   82 +++---
 src/nact/nact-menubar-help.c       |    4 +-
 src/nact/nact-menubar-maintainer.c |    4 +-
 src/nact/nact-menubar-priv.h       |   44 ++--
 src/nact/nact-menubar-tools.c      |    4 +-
 src/nact/nact-menubar-view.c       |    4 +-
 src/nact/nact-menubar.c            |   41 ++--
 src/nact/nact-menubar.h            |    2 +
 src/nact/nact-sort-buttons.c       |  512 +++++++++++++++++++++---------------
 src/nact/nact-sort-buttons.h       |   51 +++-
 src/nact/nact-tree-ieditable.c     |  109 +++++++--
 src/nact/nact-tree-view.c          |  297 ++++++++++++----------
 src/nact/nact-tree-view.h          |   18 +-
 24 files changed, 933 insertions(+), 631 deletions(-)
---
diff --git a/src/core/na-iduplicable.c b/src/core/na-iduplicable.c
index 316b357..b17111f 100644
--- a/src/core/na-iduplicable.c
+++ b/src/core/na-iduplicable.c
@@ -34,6 +34,8 @@
 
 #include <api/na-iduplicable.h>
 
+#include "na-marshal.h"
+
 /* private interface data
  */
 struct _NAIDuplicableInterfacePrivate {
@@ -74,9 +76,9 @@ static gboolean       v_is_valid( const NAIDuplicable *object );
 
 static DuplicableStr *get_duplicable_str( const NAIDuplicable *object );
 
-static void           on_modified_changed_class_handler( NAIDuplicable *instance, gboolean is_modified );
-static void           on_valid_changed_class_handler( NAIDuplicable *instance, gboolean is_valid );
-static void           propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal, gboolean new_status );
+static void           on_modified_changed_class_handler( NAIDuplicable *instance, GObject *object, gboolean is_modified );
+static void           on_valid_changed_class_handler( NAIDuplicable *instance, GObject *object, gboolean is_valid );
+static void           propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal, GObject *object, gboolean new_status );
 static void           release_signal_consumers( GList *consumers );
 
 GType
@@ -147,7 +149,13 @@ interface_base_init( NAIDuplicableInterface *klass )
 		 * Signal args: New modification status
 		 *
 		 * Handler prototype:
-		 * void ( *handler )( NAIDuplicable *duplicable, gboolean is_modified, gpointer user_data );
+		 * void ( *handler )( NAIDuplicable *duplicable, NAObject *object, gboolean is_modified, gpointer user_data );
+		 *
+		 * When the signal is first emitted, thus on NAIDuplicable, @duplicable
+		 * and @object are pointers to the same address. This duplication is
+		 * relevant when propagating the signal to customer, as the signal is
+		 * emitted on the customer itself, while we still need the @object
+		 * pointer.
 		 */
 		st_signals[ MODIFIED_CHANGED ] = g_signal_new_class_handler(
 				IDUPLICABLE_SIGNAL_MODIFIED_CHANGED,
@@ -156,10 +164,10 @@ interface_base_init( NAIDuplicableInterface *klass )
 				G_CALLBACK( on_modified_changed_class_handler ),
 				NULL,
 				NULL,
-				g_cclosure_marshal_VOID__BOOLEAN,
+				na_cclosure_marshal_VOID__POINTER_BOOLEAN,
 				G_TYPE_NONE,
-				1,
-				G_TYPE_BOOLEAN );
+				2,
+				G_TYPE_POINTER, G_TYPE_BOOLEAN );
 
 		/**
 		 * NAIDuplicable::valid-changed:
@@ -170,10 +178,16 @@ interface_base_init( NAIDuplicableInterface *klass )
 		 * The default class handler propagates the signal to registered
 		 * consumers.
 		 *
-		 * Signal args: Newvalidity status
+		 * Signal args: New validity status
 		 *
 		 * Handler prototype:
-		 * void ( *handler )( NAIDuplicable *duplicable, gboolean is_valid, gpointer user_data );
+		 * void ( *handler )( NAIDuplicable *duplicable, NAObject *object, gboolean is_valid, gpointer user_data );
+		 *
+		 * When the signal is first emitted, thus on NAIDuplicable, @duplicable
+		 * and @object are pointers to the same address. This duplication is
+		 * relevant when propagating the signal to customer, as the signal is
+		 * emitted on the customer itself, while we still need the @object
+		 * pointer.
 		 */
 		st_signals[ VALID_CHANGED ] = g_signal_new_class_handler(
 				IDUPLICABLE_SIGNAL_VALID_CHANGED,
@@ -182,10 +196,10 @@ interface_base_init( NAIDuplicableInterface *klass )
 				G_CALLBACK( on_valid_changed_class_handler ),
 				NULL,
 				NULL,
-				g_cclosure_marshal_VOID__BOOLEAN,
+				na_cclosure_marshal_VOID__POINTER_BOOLEAN,
 				G_TYPE_NONE,
-				1,
-				G_TYPE_BOOLEAN );
+				2,
+				G_TYPE_POINTER, G_TYPE_BOOLEAN );
 
 		st_interface = klass;
 
@@ -371,7 +385,7 @@ na_iduplicable_check_status( const NAIDuplicable *object )
 		if( was_modified != str->modified ){
 			g_debug( "%s: %p (%s) status changed to modified=%s",
 					thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ), str->modified ? "True":"False" );
-			g_signal_emit_by_name( G_OBJECT( object ), IDUPLICABLE_SIGNAL_MODIFIED_CHANGED, str->modified );
+			g_signal_emit_by_name( G_OBJECT( object ), IDUPLICABLE_SIGNAL_MODIFIED_CHANGED, object, str->modified );
 		}
 
 		str->valid = v_is_valid( object );
@@ -379,7 +393,7 @@ na_iduplicable_check_status( const NAIDuplicable *object )
 		if( was_valid != str->valid ){
 			g_debug( "%s: %p (%s) status changed to valid=%s",
 					thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ), str->valid ? "True":"False" );
-			g_signal_emit_by_name( G_OBJECT( object ), IDUPLICABLE_SIGNAL_VALID_CHANGED, str->valid );
+			g_signal_emit_by_name( G_OBJECT( object ), IDUPLICABLE_SIGNAL_VALID_CHANGED, object, str->valid );
 		}
 	}
 }
@@ -572,19 +586,23 @@ na_iduplicable_register_consumer( GObject *consumer )
 }
 
 static void
-on_modified_changed_class_handler( NAIDuplicable *instance, gboolean is_modified )
+on_modified_changed_class_handler( NAIDuplicable *instance, GObject *object, gboolean is_modified )
 {
-	propagate_signal_to_consumers( instance, IDUPLICABLE_SIGNAL_MODIFIED_CHANGED, is_modified );
+	if( NA_IS_IDUPLICABLE( instance )){
+		propagate_signal_to_consumers( instance, IDUPLICABLE_SIGNAL_MODIFIED_CHANGED, object, is_modified );
+	}
 }
 
 static void
-on_valid_changed_class_handler( NAIDuplicable *instance, gboolean is_valid )
+on_valid_changed_class_handler( NAIDuplicable *instance, GObject *object, gboolean is_valid )
 {
-	propagate_signal_to_consumers( instance, IDUPLICABLE_SIGNAL_VALID_CHANGED, is_valid );
+	if( NA_IS_IDUPLICABLE( instance )){
+		propagate_signal_to_consumers( instance, IDUPLICABLE_SIGNAL_VALID_CHANGED, object, is_valid );
+	}
 }
 
 static void
-propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal, gboolean new_status )
+propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal, GObject *object, gboolean new_status )
 {
 	static const gchar *thisfn = "na_iduplicable_propagate_signals_to_consumers";
 	GList *ic;
@@ -595,7 +613,7 @@ propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal, gbo
 		g_debug( "%s: instance=%p, signal=%s", thisfn, ( void * ) instance, signal );
 
 		for( ic = st_interface->private->consumers ; ic ; ic = ic->next ){
-			g_signal_emit_by_name( ic->data, signal, new_status );
+			g_signal_emit_by_name( ic->data, signal, object, new_status );
 		}
 	}
 }
diff --git a/src/core/na-marshal.def b/src/core/na-marshal.def
index d061759..5578e08 100644
--- a/src/core/na-marshal.def
+++ b/src/core/na-marshal.def
@@ -1,2 +1,6 @@
+# NAIDuplicable:: IDUPLICABLE_SIGNAL_MODIFIED_CHANGED
+# NAIDuplicable:: IDUPLICABLE_SIGNAL_VALID_CHANGED
+VOID:POINTER,BOOLEAN
+#
 # NASettings:: SETTINGS_SIGNAL_KEY_CHANGED
 VOID:STRING,STRING,POINTER,BOOLEAN
diff --git a/src/core/na-updater.c b/src/core/na-updater.c
index 4606647..b32ad56 100644
--- a/src/core/na-updater.c
+++ b/src/core/na-updater.c
@@ -270,8 +270,8 @@ na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item,
 		 * (cf. e.g. io-desktop/nadp-reader.c:read_done_item_is_writable()).
 		 * Though I'm plenty conscious that this status is subject to many
 		 * changes during the life of the item (e.g. by modifying permissions
-		 * on the underlying store), it is just simpler to not reevaluate
-		 * this status each time we need it
+		 * on the underlying store), it is just more efficient to not reevaluate
+		 * this status each time we need it, and enough for our needs..
 		 */
 		if( writable ){
 			if( na_object_is_readonly( item )){
@@ -287,7 +287,7 @@ na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item,
 			if( provider ){
 				writable = na_io_provider_is_finally_writable( provider, reason );
 
-			/* the get_writable_provider() api already takes above checks
+			/* the get_writable_provider() api already takes care of above checks
 			 */
 			} else {
 				provider = na_io_provider_find_writable_io_provider( NA_PIVOT( updater ));
@@ -308,10 +308,13 @@ na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item,
  * na_updater_is_level_zero_writable:
  * @updater: the #NAUpdater application object.
  *
- * As of 3.1.0, level-zero order is written as a user preference.
- * This function so considers if the level_zero is a mandatory
- * preference, and to be writable, if preferences are globally
- * locked.
+ * As of 3.1.0, level-zero is written as a user preference.
+ *
+ * This function considers that the level_zero is writable if it is not
+ * a mandatory preference.
+ * Whether preferences themselves are or not globally locked is not
+ * considered here (as imho, level zero is not really and semantically
+ * part of user preferences).
  *
  * This function only considers the case of the level zero itself.
  * It does not take into account whether the i/o provider (if any)
@@ -331,8 +334,7 @@ na_updater_is_level_zero_writable( const NAUpdater *updater )
 
 	if( !updater->private->dispose_has_run ){
 
-		is_writable =
-				updater->private->is_level_zero_writable && !updater->private->are_preferences_locked;
+		is_writable = updater->private->is_level_zero_writable;
 	}
 
 	return( is_writable );
@@ -342,12 +344,13 @@ static gboolean
 are_preferences_locked( const NAUpdater *updater )
 {
 	gboolean are_locked;
+	gboolean mandatory;
 	NASettings *settings;
 
 	settings = na_pivot_get_settings( NA_PIVOT( updater ));
-	are_locked = na_settings_get_boolean( settings, NA_IPREFS_ADMIN_PREFERENCES_LOCKED, NULL, NULL );
+	are_locked = na_settings_get_boolean( settings, NA_IPREFS_ADMIN_PREFERENCES_LOCKED, NULL, &mandatory );
 
-	return( are_locked );
+	return( are_locked && mandatory );
 }
 
 static gboolean
@@ -507,6 +510,7 @@ na_updater_should_pasted_be_relabeled( const NAUpdater *updater, const NAObject
 GList *
 na_updater_load_items( NAUpdater *updater )
 {
+	static const gchar *thisfn = "na_updater_load_items";
 	GList *tree;
 
 	g_return_val_if_fail( NA_IS_UPDATER( updater ), NULL );
@@ -514,6 +518,7 @@ na_updater_load_items( NAUpdater *updater )
 	tree = NULL;
 
 	if( !updater->private->dispose_has_run ){
+		g_debug( "%s: updater=%p (%s)", thisfn, ( void * ) updater, G_OBJECT_TYPE_NAME( updater ));
 
 		na_pivot_load_items( NA_PIVOT( updater ));
 		tree = na_pivot_get_items( NA_PIVOT( updater ));
diff --git a/src/nact/nact-assistant-export.c b/src/nact/nact-assistant-export.c
index 5831ccb..e18bae0 100644
--- a/src/nact/nact-assistant-export.c
+++ b/src/nact/nact-assistant-export.c
@@ -113,7 +113,7 @@ static void            on_base_all_widgets_showed( NactAssistantExport *dialog,
 static void            assist_runtime_init_intro( NactAssistantExport *window, GtkAssistant *assistant );
 
 static void            assist_runtime_init_actions_list( NactAssistantExport *window, GtkAssistant *assistant );
-static void            on_tree_view_selection_changed( NactAssistantExport *window, NactTreeView *view, GList *selected_items, gpointer user_data );
+static void            on_tree_view_selection_changed( NactAssistantExport *window, GList *selected_items, gpointer user_data );
 static void            assist_initial_load_target_folder( NactAssistantExport *window, GtkAssistant *assistant );
 static void            assist_runtime_init_target_folder( NactAssistantExport *window, GtkAssistant *assistant );
 static GtkFileChooser *get_folder_chooser( NactAssistantExport *window );
@@ -396,7 +396,7 @@ assist_runtime_init_actions_list( NactAssistantExport *window, GtkAssistant *ass
 }
 
 static void
-on_tree_view_selection_changed( NactAssistantExport *instance, NactTreeView *view, GList *selected_items, gpointer user_data )
+on_tree_view_selection_changed( NactAssistantExport *window, GList *selected_items, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_assistant_export_on_tree_view_selection_changed";
 	GtkAssistant *assistant;
@@ -404,22 +404,22 @@ on_tree_view_selection_changed( NactAssistantExport *instance, NactTreeView *vie
 	gboolean enabled;
 	GtkWidget *content;
 
-	g_return_if_fail( NACT_IS_ASSISTANT_EXPORT( instance ));
+	g_return_if_fail( NACT_IS_ASSISTANT_EXPORT( window ));
 
-	g_debug( "%s: instance=%p, view=%p, selected_items=%p (count=%d), user_data=%p",
-			thisfn, ( void * ) instance, ( void * ) view,
+	g_debug( "%s: window=%p, selected_items=%p (count=%d), user_data=%p",
+			thisfn, ( void * ) window,
 			( void * ) selected_items, g_list_length( selected_items ), ( void * ) user_data );
 
-	if( instance->private->selected_items ){
-		instance->private->selected_items = na_object_free_items( instance->private->selected_items );
+	if( window->private->selected_items ){
+		window->private->selected_items = na_object_free_items( window->private->selected_items );
 	}
 
-	assistant = GTK_ASSISTANT( base_window_get_gtk_toplevel( BASE_WINDOW( instance )));
+	assistant = GTK_ASSISTANT( base_window_get_gtk_toplevel( BASE_WINDOW( window )));
 	pos = gtk_assistant_get_current_page( assistant );
 
 	if( pos == ASSIST_PAGE_ACTIONS_SELECTION ){
 		enabled = ( g_list_length( selected_items ) > 0 );
-		instance->private->selected_items = na_object_copyref_items( selected_items );
+		window->private->selected_items = na_object_copyref_items( selected_items );
 		content = gtk_assistant_get_nth_page( assistant, pos );
 		gtk_assistant_set_page_complete( assistant, content, enabled );
 		gtk_assistant_update_buttons_state( assistant );
diff --git a/src/nact/nact-iaction-tab.c b/src/nact/nact-iaction-tab.c
index ecec9f8..20f1923 100644
--- a/src/nact/nact-iaction-tab.c
+++ b/src/nact/nact-iaction-tab.c
@@ -66,7 +66,7 @@ static GType         register_type( void );
 static void          interface_base_init( NactIActionTabInterface *klass );
 static void          interface_base_finalize( NactIActionTabInterface *klass );
 
-static void          on_tree_view_content_changed( NactIActionTab *instance, NactTreeView *view, NAObject *object, gpointer user_data );
+static void          on_tree_view_content_changed( NactIActionTab *instance, NAObject *object, gpointer user_data );
 static void          on_main_selection_changed( NactIActionTab *instance, GList *selected_items, gpointer user_data );
 
 static void          on_target_selection_toggled( GtkToggleButton *button, NactIActionTab *instance );
@@ -342,7 +342,7 @@ nact_iaction_tab_has_label( NactIActionTab *instance )
 }
 
 static void
-on_tree_view_content_changed( NactIActionTab *instance, NactTreeView *view, NAObject *object, gpointer user_data )
+on_tree_view_content_changed( NactIActionTab *instance, NAObject *object, gpointer user_data )
 {
 	GtkWidget *label_widget;
 	gchar *label;
@@ -486,7 +486,6 @@ on_target_selection_toggled( GtkToggleButton *button, NactIActionTab *instance )
 	gboolean editable;
 
 	if( !st_on_selection_change ){
-
 		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
 
 		g_object_get(
@@ -524,7 +523,6 @@ on_target_location_toggled( GtkToggleButton *button, NactIActionTab *instance )
 	gboolean editable;
 
 	if( !st_on_selection_change ){
-
 		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
 
 		g_object_get(
@@ -590,24 +588,29 @@ check_for_label( NactIActionTab *instance, GtkEntry *entry, const gchar *label )
 static void
 on_label_changed( GtkEntry *entry, NactIActionTab *instance )
 {
+	static const gchar *thisfn = "nact_iaction_tab_on_label_changed";
 	NAObjectItem *item;
 	const gchar *label;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			MAIN_PROP_ITEM, &item,
-			NULL );
+	if( !st_on_selection_change ){
+		g_debug( "%s: entry=%p, instance=%p", thisfn, ( void * ) entry, ( void * ) instance );
 
-	if( item ){
-		label = gtk_entry_get_text( entry );
-		na_object_set_label( item, label );
-		check_for_label( instance, entry, label );
+		g_object_get(
+				G_OBJECT( instance ),
+				MAIN_PROP_ITEM, &item,
+				NULL );
 
-		if( NA_IS_OBJECT_ACTION( item )){
-			setup_toolbar_label( instance, item, label );
-		}
+		if( item ){
+			label = gtk_entry_get_text( entry );
+			na_object_set_label( item, label );
+			check_for_label( instance, entry, label );
 
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, TRUE );
+			if( NA_IS_OBJECT_ACTION( item )){
+				setup_toolbar_label( instance, item, label );
+			}
+
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, TRUE );
+		}
 	}
 }
 
@@ -640,7 +643,6 @@ on_target_toolbar_toggled( GtkToggleButton *button, NactIActionTab *instance )
 	gboolean editable;
 
 	if( !st_on_selection_change ){
-
 		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
 
 		g_object_get(
@@ -752,19 +754,24 @@ setup_toolbar_label( NactIActionTab *instance, NAObjectItem *item, const gchar *
 static void
 on_toolbar_label_changed( GtkEntry *entry, NactIActionTab *instance )
 {
+	static const gchar *thisfn = "nact_iaction_tab_on_toolbar_label_changed";
 	NAObjectItem *item;
 	const gchar *label;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			MAIN_PROP_ITEM, &item,
-			NULL );
+	if( !st_on_selection_change ){
+		g_debug( "%s: entry=%p, instance=%p", thisfn, ( void * ) entry, ( void * ) instance );
 
-	if( item && NA_IS_OBJECT_ACTION( item )){
-		label = gtk_entry_get_text( entry );
-		na_object_set_toolbar_label( NA_OBJECT_ACTION( item ), label );
+		g_object_get(
+				G_OBJECT( instance ),
+				MAIN_PROP_ITEM, &item,
+				NULL );
+
+		if( item && NA_IS_OBJECT_ACTION( item )){
+			label = gtk_entry_get_text( entry );
+			na_object_set_toolbar_label( NA_OBJECT_ACTION( item ), label );
 
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, FALSE );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, FALSE );
+		}
 	}
 }
 
@@ -784,16 +791,21 @@ toolbar_label_set_sensitive( NactIActionTab *instance, NAObjectItem *item )
 static void
 on_tooltip_changed( GtkEntry *entry, NactIActionTab *instance )
 {
+	static const gchar *thisfn = "nact_iaction_tab_on_tooltip_changed";
 	NAObjectItem *item;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			MAIN_PROP_ITEM, &item,
-			NULL );
+	if( !st_on_selection_change ){
+		g_debug( "%s: entry=%p, instance=%p", thisfn, ( void * ) entry, ( void * ) instance );
 
-	if( item ){
-		na_object_set_tooltip( item, gtk_entry_get_text( entry ));
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, FALSE );
+		g_object_get(
+				G_OBJECT( instance ),
+				MAIN_PROP_ITEM, &item,
+				NULL );
+
+		if( item ){
+			na_object_set_tooltip( item, gtk_entry_get_text( entry ));
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, FALSE );
+		}
 	}
 }
 
@@ -835,24 +847,26 @@ on_icon_changed( GtkEntry *icon_entry, NactIActionTab *instance )
 	NAObjectItem *item;
 	const gchar *icon_name;
 
-	g_debug( "%s: entry=%p, instance=%p", thisfn, ( void * ) icon_entry, ( void * ) instance );
+	if( !st_on_selection_change ){
+		g_debug( "%s: entry=%p, instance=%p", thisfn, ( void * ) icon_entry, ( void * ) instance );
 
-	icon_name = NULL;
+		icon_name = NULL;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			MAIN_PROP_ITEM, &item,
-			NULL );
+		g_object_get(
+				G_OBJECT( instance ),
+				MAIN_PROP_ITEM, &item,
+				NULL );
 
-	if( item ){
-		icon_name = gtk_entry_get_text( icon_entry );
-		na_object_set_icon( item, icon_name );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, TRUE );
-	}
+		if( item ){
+			icon_name = gtk_entry_get_text( icon_entry );
+			na_object_set_icon( item, icon_name );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, TRUE );
+		}
 
-	/* icon_name may be null if there is no current item
-	 * in such a case, we blank the image
-	 */
-	image = GTK_IMAGE( base_window_get_widget( BASE_WINDOW( instance ), "ActionIconImage" ));
-	base_gtk_utils_render( icon_name, image, GTK_ICON_SIZE_SMALL_TOOLBAR );
+		/* icon_name may be null if there is no current item
+		 * in such a case, we blank the image
+		 */
+		image = GTK_IMAGE( base_window_get_widget( BASE_WINDOW( instance ), "ActionIconImage" ));
+		base_gtk_utils_render( icon_name, image, GTK_ICON_SIZE_SMALL_TOOLBAR );
+	}
 }
diff --git a/src/nact/nact-icommand-tab.c b/src/nact/nact-icommand-tab.c
index 7c5f4b9..c9c8ba4 100644
--- a/src/nact/nact-icommand-tab.c
+++ b/src/nact/nact-icommand-tab.c
@@ -70,7 +70,7 @@ static GType      register_type( void );
 static void       interface_base_init( NactICommandTabInterface *klass );
 static void       interface_base_finalize( NactICommandTabInterface *klass );
 
-static void       on_tree_view_content_changed( NactICommandTab *instance, NactTreeView *view, NAObject *object, gpointer user_data );
+static void       on_tree_view_content_changed( NactICommandTab *instance, NAObject *object, gpointer user_data );
 static void       on_main_selection_changed( NactICommandTab *instance, GList *selected_items, gpointer user_data );
 
 static GtkWidget *get_label_entry( NactICommandTab *instance );
@@ -315,7 +315,7 @@ nact_icommand_tab_dispose( NactICommandTab *instance )
 }
 
 static void
-on_tree_view_content_changed( NactICommandTab *instance, NactTreeView *view, NAObject *object, gpointer user_data )
+on_tree_view_content_changed( NactICommandTab *instance, NAObject *object, gpointer user_data )
 {
 	GtkWidget *label_widget;
 	gchar *label;
diff --git a/src/nact/nact-iproperties-tab.c b/src/nact/nact-iproperties-tab.c
index 2dadaad..a411109 100644
--- a/src/nact/nact-iproperties-tab.c
+++ b/src/nact/nact-iproperties-tab.c
@@ -338,10 +338,10 @@ on_enabled_toggled( GtkToggleButton *button, NactIPropertiesTab *instance )
 	gboolean enabled;
 	gboolean editable;
 
-	g_debug( "%s: button=%p, instance=%p, on_selection_change=%s",
-			thisfn, ( void * ) button, ( void * ) instance, st_on_selection_change ? "True":"False" );
-
 	if( !st_on_selection_change ){
+		g_debug( "%s: button=%p, instance=%p, on_selection_change=%s",
+				thisfn, ( void * ) button, ( void * ) instance, st_on_selection_change ? "True":"False" );
+
 		g_object_get(
 				G_OBJECT( instance ),
 				MAIN_PROP_ITEM, &item,
@@ -385,10 +385,10 @@ on_readonly_toggled( GtkToggleButton *button, NactIPropertiesTab *instance )
 	static const gchar *thisfn = "nact_iproperties_tab_on_readonly_toggled";
 	gboolean active;
 
-	g_debug( "%s: button=%p, instance=%p, on_selection_change=%s",
-			thisfn, ( void * ) button, ( void * ) instance, st_on_selection_change ? "True":"False" );
-
 	if( !st_on_selection_change ){
+		g_debug( "%s: button=%p, instance=%p, on_selection_change=%s",
+				thisfn, ( void * ) button, ( void * ) instance, st_on_selection_change ? "True":"False" );
+
 		active = gtk_toggle_button_get_active( button );
 
 		g_signal_handlers_block_by_func(( gpointer ) button, on_readonly_toggled, instance );
@@ -482,13 +482,10 @@ on_shortcut_clicked( GtkButton *button, NactIPropertiesTab *instance )
 static void
 display_provider_name( NactIPropertiesTab *instance, NAObjectItem *item )
 {
-	static const gchar *thisfn = "nact_iproperties_tab_display_provider_name";
 	GtkWidget *label_widget;
 	gchar *label;
 	NAIOProvider *provider;
 
-	g_debug( "%s: instance=%p, item=%p", thisfn, ( void * ) instance, ( void * ) item );
-
 	label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionItemProvider" );
 	label = NULL;
 	if( item ){
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index f96e7f1..2fe0a1b 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -179,8 +179,8 @@ 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, NactTreeView *view, guint count, gpointer user_data );
-static void     on_tree_view_selection_changed( NactMainWindow *window, NactTreeView *view, GList *selected_items, gpointer user_data );
+static void     on_tree_view_modified_count_changed( NactMainWindow *window, guint count, 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 );
 static void     setup_current_selection( NactMainWindow *window, NAObjectId *selected_row );
@@ -189,7 +189,7 @@ static void     setup_writability_status( NactMainWindow *window );
 static void     on_pivot_items_changed( NAUpdater *updater, NactMainWindow *window );
 static gboolean confirm_for_giveup_from_pivot( const NactMainWindow *window );
 static gboolean confirm_for_giveup_from_menu( const NactMainWindow *window );
-static void     reload_items( NactMainWindow *window );
+static void     load_or_reload_items( NactMainWindow *window );
 
 static gboolean base_is_willing_to_quit( const BaseWindow *window );
 static gboolean on_delete_event( GtkWidget *toplevel, GdkEvent *event, NactMainWindow *window );
@@ -751,8 +751,6 @@ instance_dispose( GObject *window )
 		pos = gtk_paned_get_position( GTK_PANED( pane ));
 		na_settings_set_uint( settings, NA_IPREFS_MAIN_PANED, pos );
 
-		nact_sort_buttons_dispose( BASE_WINDOW( self ));
-
 		nact_iaction_tab_dispose( NACT_IACTION_TAB( window ));
 		nact_icommand_tab_dispose( NACT_ICOMMAND_TAB( window ));
 		nact_ibasenames_tab_dispose( NACT_IBASENAMES_TAB( window ));
@@ -877,10 +875,6 @@ on_base_initialize_base_window( NactMainWindow *window, gpointer user_data )
 
 		na_settings_register_key_callback( settings, NA_IPREFS_ITEMS_LIST_ORDER_MODE, G_CALLBACK( on_settings_order_mode_changed ), window );
 
-		/* other initializations
-		 */
-		nact_sort_buttons_runtime_init( BASE_WINDOW( window ));
-
 		/* terminate the application by clicking the top right [X] button
 		 */
 		base_window_signal_connect( BASE_WINDOW( window ),
@@ -893,7 +887,6 @@ static void
 on_base_all_widgets_showed( NactMainWindow *window, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_main_window_on_base_all_widgets_showed";
-	GList *tree;
 
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
 	g_return_if_fail( NACT_IS_IACTION_TAB( window ));
@@ -909,13 +902,6 @@ on_base_all_widgets_showed( NactMainWindow *window, gpointer user_data )
 	if( !window->private->dispose_has_run ){
 		g_debug( "%s: window=%p, user_data=%p", thisfn, ( void * ) window, ( void * ) user_data );
 
-		raz_selection_properties( window );
-
-		/* fill the items tree view at last so that all signals are connected
-		 */
-		tree = na_updater_load_items( window->private->updater );
-		nact_tree_view_fill( window->private->items_view, tree );
-
 		nact_iaction_tab_all_widgets_showed( NACT_IACTION_TAB( window ));
 		nact_icommand_tab_all_widgets_showed( NACT_ICOMMAND_TAB( window ));
 		nact_ibasenames_tab_all_widgets_showed( NACT_IBASENAMES_TAB( window ));
@@ -927,7 +913,7 @@ on_base_all_widgets_showed( NactMainWindow *window, gpointer user_data )
 		nact_iexecution_tab_all_widgets_showed( NACT_IEXECUTION_TAB( window ));
 		nact_iproperties_tab_all_widgets_showed( NACT_IPROPERTIES_TAB( window ));
 
-		nact_sort_buttons_all_widgets_showed( BASE_WINDOW( window ));
+		load_or_reload_items( window );
 	}
 }
 
@@ -997,7 +983,7 @@ nact_main_window_reload( NactMainWindow *window )
 		reload_ok = confirm_for_giveup_from_menu( window );
 
 		if( reload_ok ){
-			reload_items( window );
+			load_or_reload_items( window );
 		}
 	}
 }
@@ -1006,16 +992,17 @@ nact_main_window_reload( NactMainWindow *window )
  * the count of modified NAObjectItem has changed
  */
 static void
-on_tree_view_modified_count_changed( NactMainWindow *window, NactTreeView *view, guint count, gpointer user_data )
+on_tree_view_modified_count_changed( NactMainWindow *window, guint count, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_main_window_on_tree_view_modified_count_changed";
 
-	g_debug( "%s: window=%p, view=%p, count=%d, user_data=%p",
-			thisfn, ( void * ) window, ( void * ) view, count, ( void * ) user_data );
+	g_debug( "%s: window=%p, count=%d, user_data=%p",
+			thisfn, ( void * ) window, count, ( void * ) user_data );
 
 	if( !window->private->dispose_has_run ){
 
 		window->private->count_modified = count;
+		setup_dialog_title( window );
 	}
 }
 
@@ -1023,18 +1010,17 @@ on_tree_view_modified_count_changed( NactMainWindow *window, NactTreeView *view,
  * tree view selection has changed
  */
 static void
-on_tree_view_selection_changed( NactMainWindow *window, NactTreeView *view, GList *selected_items, gpointer user_data )
+on_tree_view_selection_changed( NactMainWindow *window, GList *selected_items, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_main_window_on_tree_view_selection_changed";
 	guint count;
 
 	count = g_list_length( selected_items );
 
-	g_debug( "%s: window=%p, view=%p, selected_items=%p (count=%d), user_data=%p",
-			thisfn, ( void * ) window, ( void * ) view,
-			( void * ) selected_items, count, ( void * ) user_data );
-
 	if( !window->private->dispose_has_run ){
+		g_debug( "%s: window=%p, selected_items=%p (count=%d), user_data=%p",
+				thisfn, ( void * ) window,
+				( void * ) selected_items, count, ( void * ) user_data );
 
 		raz_selection_properties( window );
 
@@ -1178,7 +1164,7 @@ on_pivot_items_changed( NAUpdater *updater, NactMainWindow *window )
 		reload_ok = confirm_for_giveup_from_pivot( window );
 
 		if( reload_ok ){
-			reload_items( window );
+			load_or_reload_items( window );
 		}
 	}
 }
@@ -1246,9 +1232,9 @@ confirm_for_giveup_from_menu( const NactMainWindow *window )
 }
 
 static void
-reload_items( NactMainWindow *window )
+load_or_reload_items( NactMainWindow *window )
 {
-	static const gchar *thisfn = "nact_main_window_reload";
+	static const gchar *thisfn = "nact_main_window_load_or_reload_items";
 	GList *tree;
 
 	g_debug( "%s: window=%p", thisfn, ( void * ) window );
@@ -1257,6 +1243,8 @@ reload_items( NactMainWindow *window )
 
 	tree = na_updater_load_items( window->private->updater );
 	nact_tree_view_fill( window->private->items_view, tree );
+
+	g_debug( "%s: end of tree view filling", thisfn );
 }
 
 /**
@@ -1495,25 +1483,22 @@ on_main_window_level_zero_order_changed( NactMainWindow *window, gpointer user_d
 
 	setup_dialog_title( window );
 }
-
-static void
-on_iactions_list_status_changed( NactMainWindow *window, gpointer user_data )
-{
-	g_debug( "nact_main_window_on_iactions_list_status_changed" );
-
-	setup_dialog_title( window );
-}
 #endif
 
 static void
 on_tab_updatable_item_updated( NactMainWindow *window, gpointer user_data, gboolean force_display )
 {
-	/*static const gchar *thisfn = "nact_main_window_on_tab_updatable_item_updated";*/
+	static const gchar *thisfn = "nact_main_window_on_tab_updatable_item_updated";
 
-	/*g_debug( "%s: window=%p, user_data=%p", thisfn, ( void * ) window, ( void * ) user_data );*/
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
 
 	if( !window->private->dispose_has_run ){
+		g_debug( "%s: window=%p, user_data=%p, force_display=%s",
+				thisfn, ( void * ) window, ( void * ) user_data, force_display ? "True":"False" );
+
+		if( window->private->current_item ){
+			na_object_check_status( window->private->current_item );
+		}
 	}
 }
 
@@ -1541,8 +1526,8 @@ on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpoin
 
 #if 0
 		nact_iactions_list_display_order_change( NACT_IACTIONS_LIST( window ), order_mode );
-#endif
 		nact_sort_buttons_display_order_change( BASE_WINDOW( window ), order_mode );
+#endif
 
 		tree = na_pivot_get_items( NA_PIVOT( window->private->updater ));
 
diff --git a/src/nact/nact-main-window.h b/src/nact/nact-main-window.h
index d1d1a0c..45aa8c8 100644
--- a/src/nact/nact-main-window.h
+++ b/src/nact/nact-main-window.h
@@ -46,6 +46,75 @@
  * - the hierarchical list of items,
  * - a notebook which displays the content of the current item,
  * - a status bar.
+ *
+ * NactApplication    NactMainWindow    NactTreeView    NactTreeModel   NactMenubar
+ *  |
+ *  +- nact_main_window_new()
+ *  |   |
+ *  |   +----- connect to base-init-gtk-toplevel
+ *  |   |                 base-init-window
+ *  |   |                 base-all-widgets-showed
+ *  |   |                 pivot-items-changed
+ *  |   |                 tab-item-updated
+ *  |   |
+ *  |   +----- nact_tree_view_new()
+ *  |   |       |
+ *  |   |       +-------------- connect to base-init-gtk-toplevel
+ *  |   |                                  base-init-window
+ *  |   |                                  base-all-widgets-showed
+ *  |   |
+ *  |   +----- connect to tree-selection-changed
+ *  |   |                 tree-modified-count-changed
+ *  |   |
+ *  |   +----- nact_menubar_new()
+ *  |           |
+ *  |           +---------------------------------------------------- connect to base-init-window
+ *  |
+ * emit 'base-init-gtk-toplevel'
+ *  |
+ *  +--------- init gtk toplevel in each tab
+ *  |          init gtk toplevel in statusbar
+ *  |
+ *  +-------------------------- nact_tree_model_new()
+ *  |                            |
+ *  |                            +------------------- connect to base-init-window
+ *  |                                                 attach the model to the view
+ * emit 'base-init-window'
+ *  |
+ *  +--------- init runtime window in each tab
+ *  |          init sort buttons
+ *  |          connect to delete-event
+ *  |
+ *  +-------------------------- connect to treeview events
+ *  |                           nact_tree_ieditable_initialize()
+ *  |                            |
+ *  |                            +-- register as iduplicable consumer
+ *  |                                connect to iduplicable signals
+ *  |
+ *  +------------------------------------------------ connect to dnd events
+ *  |
+ *  +---------------------------------------------------------------- instanciate UI manager
+ *  |                                                                 connect to tree signals
+ * emit 'base-all-widgets-showed'
+ *  |
+ *  +--------- na_updater_load_items()
+ *  |           |
+ *  |           +-- check and set items modification/validity status
+ *  |           |    +-> which generates lot of iduplicable events
+ *  |           |
+ *  |           +-- check and set items writability status
+ *  |
+ *  +--------- na_tree_view_fill()
+ *  |           +-> which generates lot of selection-changed events
+ *  |
+ *  |          all widgets showed on all tab
+ *  |          all widgets showed on sort buttons
+ *  |
+ *  +-------------------------- grab focus
+ *  |                           allow notifications
+ *  |                           select first row (if any)
+ *  |
+ * [X] End of initialization process
  */
 
 #include "nact-application.h"
diff --git a/src/nact/nact-marshal.def b/src/nact/nact-marshal.def
index 3fa1ae5..cc9cc2d 100644
--- a/src/nact/nact-marshal.def
+++ b/src/nact/nact-marshal.def
@@ -1,19 +1,5 @@
-# NactTreeView:: TREE_SIGNAL_CONTENT_CHANGED
-# NactTreeView:: TREE_SIGNAL_CONTEXT_MENU
-# NactTreeView:: TREE_SIGNAL_SELECTION_CHANGED
-VOID:POINTER,POINTER
-#
-# NactTreeView:: TREE_SIGNAL_MODIFIED_COUNT_CHANGED
-VOID:POINTER,INT
-#
 # NactTreeView:: TREE_SIGNAL_COUNT_CHANGED
-VOID:POINTER,BOOLEAN,INT,INT,INT
-#
-# NactIActionsList::nact-iactions-list-count-updated
-VOID:INT,INT,INT
-#
-# NactIActionsList::nact-iactions-list-column-edited
-VOID:POINTER,POINTER,INT
+VOID:BOOLEAN,INT,INT,INT
 #
 # NactMainWindow::nact-tab-updatable-item-updated
 VOID:POINTER,BOOLEAN
diff --git a/src/nact/nact-menubar-edit.c b/src/nact/nact-menubar-edit.c
index 3d61e31..1ff9916 100644
--- a/src/nact/nact-menubar-edit.c
+++ b/src/nact/nact-menubar-edit.c
@@ -53,9 +53,7 @@ static void    update_clipboard_counters( BaseWindow *window );
 
 /**
  * nact_menubar_edit_on_update_sensitivities:
- * @window: the #BaseWindow main window.
- * user_data: the data passed to the function via the signal.
- * @mis: the #MenubarIndicatorsStruct struct.
+ * @bar: this #NactMenubar object.
  *
  * Update sensitivity of items of the Edit menu.
  */
diff --git a/src/nact/nact-menubar-file.c b/src/nact/nact-menubar-file.c
index 6fd30c7..0a1a23a 100644
--- a/src/nact/nact-menubar-file.c
+++ b/src/nact/nact-menubar-file.c
@@ -45,6 +45,7 @@
 #include "nact-main-statusbar.h"
 #include "nact-main-tab.h"
 #include "nact-menubar-priv.h"
+#include "nact-tree-ieditable.h"
 
 static NATimeout st_autosave_prefs_timeout = { 0 };
 static guint     st_event_autosave         = 0;
@@ -57,16 +58,25 @@ static gchar *st_delete_error     = N_( "Some items cannot have been deleted" );
 #endif
 
 static gboolean save_item( BaseWindow *window, NAUpdater *updater, NAObjectItem *item, GSList **messages );
+static void     install_autosave( NactMenubar *bar );
 static void     on_autosave_prefs_changed( const gchar *group, const gchar *key, gconstpointer new_value, gpointer user_data );
-static void     on_autosave_prefs_timeout( BaseWindow *window );
-static gboolean autosave_callback( BaseWindow *window );
-static void     autosave_destroyed( BaseWindow *window );
+static void     on_autosave_prefs_timeout( NactMenubar *bar );
+static gboolean autosave_callback( NactMenubar *bar );
+static void     autosave_destroyed( NactMenubar *bar );
+
+/*
+ * nact_menubar_file_initialize:
+ * @bar: this #NactMenubar object.
+ */
+void
+nact_menubar_file_initialize( NactMenubar *bar )
+{
+	install_autosave( bar );
+}
 
 /**
  * nact_menubar_file_on_update_sensitivities:
- * @window: the #BaseWindow main window.
- * user_data: the data passed to the function via the signal.
- * @mis: the #MenubarIndicatorsStruct struct.
+ * @bar: this #NactMenubar object.
  *
  * Update sensitivity of items of the File menu.
  */
@@ -110,6 +120,7 @@ void
 nact_menubar_file_on_new_menu( GtkAction *gtk_action, BaseWindow *window )
 {
 	NAObjectMenu *menu;
+	NactTreeView *items_view;
 	GList *items;
 
 	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
@@ -118,9 +129,8 @@ nact_menubar_file_on_new_menu( GtkAction *gtk_action, BaseWindow *window )
 	menu = na_object_menu_new_with_defaults();
 	na_object_check_status( menu );
 	items = g_list_prepend( NULL, menu );
-#if 0
-	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-#endif
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	nact_tree_ieditable_insert_items( NACT_TREE_IEDITABLE( items_view ), items, NULL );
 	na_object_free_items( items );
 }
 
@@ -135,6 +145,7 @@ void
 nact_menubar_file_on_new_action( GtkAction *gtk_action, BaseWindow *window )
 {
 	NAObjectAction *action;
+	NactTreeView *items_view;
 	GList *items;
 
 	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
@@ -143,9 +154,8 @@ nact_menubar_file_on_new_action( GtkAction *gtk_action, BaseWindow *window )
 	action = na_object_action_new_with_defaults();
 	na_object_check_status( action );
 	items = g_list_prepend( NULL, action );
-#if 0
-	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-#endif
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	nact_tree_ieditable_insert_items( NACT_TREE_IEDITABLE( items_view ), items, NULL );
 	na_object_free_items( items );
 }
 
@@ -161,6 +171,7 @@ nact_menubar_file_on_new_profile( GtkAction *gtk_action, BaseWindow *window )
 {
 	NAObjectAction *action;
 	NAObjectProfile *profile;
+	NactTreeView *items_view;
 	gchar *name;
 	GList *items;
 
@@ -184,9 +195,8 @@ nact_menubar_file_on_new_profile( GtkAction *gtk_action, BaseWindow *window )
 	na_object_check_status( profile );
 
 	items = g_list_prepend( NULL, profile );
-#if 0
-	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-#endif
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	nact_tree_ieditable_insert_items( NACT_TREE_IEDITABLE( items_view ), items, NULL );
 	na_object_free_items( items );
 }
 
@@ -434,33 +444,27 @@ nact_menubar_file_on_quit( GtkAction *gtk_action, BaseWindow *window )
 	nact_main_window_quit( NACT_MAIN_WINDOW( window ));
 }
 
-/**
+/*
  * nact_menubar_file_install_autosave:
- * @window: the #BaseWindow main window.
+ * @bar: this #NactMenubar instance.
  *
  * Setup the autosave feature and initialize its monitoring.
  */
-void
-nact_menubar_file_install_autosave( BaseWindow *window )
+static void
+install_autosave( NactMenubar *bar )
 {
-	NactApplication *application;
-	NAUpdater *updater;
 	NASettings *settings;
 
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
 	st_autosave_prefs_timeout.timeout = 100;
 	st_autosave_prefs_timeout.handler = ( NATimeoutFunc ) on_autosave_prefs_timeout;
-	st_autosave_prefs_timeout.user_data = window;
+	st_autosave_prefs_timeout.user_data = bar;
 
-	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-	settings = na_pivot_get_settings( NA_PIVOT( updater ));
+	settings = na_pivot_get_settings( NA_PIVOT( bar->private->updater ));
 
 	na_settings_register_key_callback( settings, NA_IPREFS_MAIN_SAVE_AUTO, G_CALLBACK( on_autosave_prefs_changed ), NULL );
 	na_settings_register_key_callback( settings, NA_IPREFS_MAIN_SAVE_PERIOD, G_CALLBACK( on_autosave_prefs_changed ), NULL );
 
-	on_autosave_prefs_timeout( window );
+	on_autosave_prefs_timeout( bar );
 }
 
 static void
@@ -470,20 +474,16 @@ on_autosave_prefs_changed( const gchar *group, const gchar *key, gconstpointer n
 }
 
 static void
-on_autosave_prefs_timeout( BaseWindow *window )
+on_autosave_prefs_timeout( NactMenubar *bar )
 {
 	static const gchar *thisfn = "nact_menubar_file_on_autosave_prefs_timeout";
-	NactApplication *application;
-	NAUpdater *updater;
 	NASettings *settings;
 	gboolean autosave_on;
 	guint autosave_period;
 
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+	g_return_if_fail( NACT_IS_MENUBAR( bar ));
 
-	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-	settings = na_pivot_get_settings( NA_PIVOT( updater ));
+	settings = na_pivot_get_settings( NA_PIVOT( bar->private->updater ));
 
 	autosave_on = na_settings_get_boolean( settings, NA_IPREFS_MAIN_SAVE_AUTO, NULL, NULL );
 	autosave_period = na_settings_get_uint( settings, NA_IPREFS_MAIN_SAVE_PERIOD, NULL, NULL );
@@ -500,26 +500,26 @@ on_autosave_prefs_timeout( BaseWindow *window )
 				G_PRIORITY_DEFAULT,
 				autosave_period * 60,
 				( GSourceFunc ) autosave_callback,
-				window,
+				bar,
 				( GDestroyNotify ) autosave_destroyed );
 	}
 }
 
 static gboolean
-autosave_callback( BaseWindow *window )
+autosave_callback( NactMenubar *bar )
 {
 	const gchar *context = "autosave-context";
 	g_debug( "nact_menubar_file_autosave_callback" );
 
-	nact_main_statusbar_display_status( NACT_MAIN_WINDOW( window ), context, _( "Automatically saving pending modifications..." ));
-	nact_menubar_file_save_items( window );
-	nact_main_statusbar_hide_status( NACT_MAIN_WINDOW( window ), context );
+	nact_main_statusbar_display_status( NACT_MAIN_WINDOW( bar->private->window ), context, _( "Automatically saving pending modifications..." ));
+	nact_menubar_file_save_items( bar->private->window );
+	nact_main_statusbar_hide_status( NACT_MAIN_WINDOW( bar->private->window ), context );
 
 	return( TRUE );
 }
 
 static void
-autosave_destroyed( BaseWindow *window )
+autosave_destroyed( NactMenubar *bar )
 {
 	g_debug( "nact_menubar_file_autosave_destroyed" );
 }
diff --git a/src/nact/nact-menubar-help.c b/src/nact/nact-menubar-help.c
index 0bca89e..b7da768 100644
--- a/src/nact/nact-menubar-help.c
+++ b/src/nact/nact-menubar-help.c
@@ -38,9 +38,7 @@
 
 /**
  * nact_menubar_help_on_update_sensitivities:
- * @window: the #BaseWindow main application window.
- * @user_data: user data ?
- * @mis: the #MenubarIndicatorsStruct structure.
+ * @bar: this #NactMenubar object.
  *
  * Update sensitivities on the Help menu.
  */
diff --git a/src/nact/nact-menubar-maintainer.c b/src/nact/nact-menubar-maintainer.c
index 514c83b..5afc9df 100644
--- a/src/nact/nact-menubar-maintainer.c
+++ b/src/nact/nact-menubar-maintainer.c
@@ -40,9 +40,7 @@
 
 /**
  * nact_menubar_maintainer_on_update_sensitivities:
- * @window: the #BaseWindow main application window.
- * @user_data: user data ?
- * @mis: the #MenubarIndicatorsStruct structure.
+ * @bar: this #NactMenubar object.
  *
  * Update sensitivities on the Maintainer menu.
  */
diff --git a/src/nact/nact-menubar-priv.h b/src/nact/nact-menubar-priv.h
index 64f0602..883d526 100644
--- a/src/nact/nact-menubar-priv.h
+++ b/src/nact/nact-menubar-priv.h
@@ -43,53 +43,55 @@
 #include <core/na-updater.h>
 
 #include "nact-menubar.h"
+#include "nact-sort-buttons.h"
 
 G_BEGIN_DECLS
 
 struct _NactMenubarPrivate {
 	/*< private >*/
-	gboolean        dispose_has_run;
+	gboolean         dispose_has_run;
 
 	/* set at instanciation time
 	 */
-	BaseWindow     *window;
+	BaseWindow      *window;
 
 	/* set at initialization time
 	 */
-	GtkUIManager   *ui_manager;
-	GtkActionGroup *action_group;
-	NAUpdater      *updater;
-	gboolean        is_level_zero_writable;
-	gboolean        has_writable_providers;
+	NAUpdater       *updater;
+	NactSortButtons *sort_buttons;
+	GtkUIManager    *ui_manager;
+	GtkActionGroup  *action_group;
+	gboolean         is_level_zero_writable;
+	gboolean         has_writable_providers;
 
 	/* set when the selection changes
 	 */
-	guint           count_selected;
-	GList          *selected_items;
-	gboolean        is_parent_writable;		/* new menu/new action/paste menu or action */
-	gboolean        enable_new_profile;		/* new profile/paste a profile */
-	gboolean        is_action_writable;
-	gboolean        are_parents_writable;	/* cut/delete */
+	guint            count_selected;
+	GList           *selected_items;
+	gboolean         is_parent_writable;		/* new menu/new action/paste menu or action */
+	gboolean         enable_new_profile;		/* new profile/paste a profile */
+	gboolean         is_action_writable;
+	gboolean         are_parents_writable;		/* cut/delete */
 
 	/* set when the count of modified NAObjectItem changes
 	 * this is a NactTreeIEditable-driven count
 	 */
-	guint           count_modified;
+	guint            count_modified;
 
 	/* set on focus in/out
 	 */
-	gboolean        treeview_has_focus;
+	gboolean         treeview_has_focus;
 
 	/* opening a contextual popup menu
 	 */
-	gulong          popup_handler;
+	gulong           popup_handler;
 
 	/* set when total count of items changes
 	 */
-	gint            count_menus;
-	gint            count_actions;
-	gint            count_profiles;
-	gboolean        have_exportables;
+	gint             count_menus;
+	gint             count_actions;
+	gint             count_profiles;
+	gboolean         have_exportables;
 
 	/* *** */
 	gint            selected_menus;
@@ -135,6 +137,7 @@ void nact_menubar_edit_on_delete       ( GtkAction *action, BaseWindow *window )
 void nact_menubar_edit_on_reload       ( GtkAction *action, BaseWindow *window );
 void nact_menubar_edit_on_prefererences( GtkAction *action, BaseWindow *window );
 
+void nact_menubar_file_initialize             (       NactMenubar *bar );
 void nact_menubar_file_on_update_sensitivities( const NactMenubar *bar );
 
 void nact_menubar_file_on_new_menu   ( GtkAction *action, BaseWindow *window );
@@ -144,7 +147,6 @@ void nact_menubar_file_on_save       ( GtkAction *action, BaseWindow *window );
 void nact_menubar_file_on_quit       ( GtkAction *action, BaseWindow *window );
 
 void nact_menubar_file_save_items      ( BaseWindow *window );
-void nact_menubar_file_install_autosave( BaseWindow *window );
 
 void nact_menubar_help_on_update_sensitivities( const NactMenubar *bar );
 
diff --git a/src/nact/nact-menubar-tools.c b/src/nact/nact-menubar-tools.c
index 1d3a70f..7cf1cfc 100644
--- a/src/nact/nact-menubar-tools.c
+++ b/src/nact/nact-menubar-tools.c
@@ -38,9 +38,7 @@
 
 /**
  * nact_menubar_tools_on_update_sensitivities:
- * @window: the #BaseWindow main application window.
- * @user_data: user data ?
- * @mis: the #MenubarIndicatorsStruct structure.
+ * @bar: this #NactMenubar object.
  *
  * Update sensitivities on the Tools menu.
  */
diff --git a/src/nact/nact-menubar-view.c b/src/nact/nact-menubar-view.c
index 090485b..2511497 100644
--- a/src/nact/nact-menubar-view.c
+++ b/src/nact/nact-menubar-view.c
@@ -39,9 +39,7 @@ static void on_view_toolbar_activated( GtkToggleAction *action, BaseWindow *wind
 
 /**
  * nact_menubar_view_on_update_sensitivities:
- * @window: the #BaseWindow main window.
- * user_data: the data passed to the function via the signal.
- * @mis: the #MenubarIndicatorsStruct struct.
+ * @bar: this #NactMenubar object.
  *
  * Update sensitivity of items of the View menu.
  */
diff --git a/src/nact/nact-menubar.c b/src/nact/nact-menubar.c
index a2396b0..17d8ab5 100644
--- a/src/nact/nact-menubar.c
+++ b/src/nact/nact-menubar.c
@@ -222,13 +222,13 @@ static void     on_ui_manager_proxy_connect( GtkUIManager *ui_manager, GtkAction
 static void     on_menu_item_selected( GtkMenuItem *proxy, BaseWindow *window );
 static void     on_menu_item_deselected( GtkMenuItem *proxy, BaseWindow *window );
 
-static void     on_tree_view_open_context_menu( BaseWindow *window, NactTreeView *view, GdkEventButton *event, gpointer user_data );
+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, NactTreeView *view, gboolean reset, guint menus, guint actions, guint profiles );
-static void     on_tree_view_focus_in( BaseWindow *window, NactTreeView *view, gpointer user_data );
-static void     on_tree_view_focus_out( BaseWindow *window, NactTreeView *view, gpointer user_data );
-static void     on_tree_view_modified_count_changed( BaseWindow *window, NactTreeView *view, guint count, gpointer user_data );
-static void     on_tree_view_selection_changed( BaseWindow *window, NactTreeView *view, GList *selected, gpointer user_data );
+static void     on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus, guint actions, guint 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_selection_changed( BaseWindow *window, GList *selected, gpointer user_data );
 
 static void     on_update_sensitivities( NactMenubar *bar, BaseWindow *window );
 
@@ -350,6 +350,7 @@ instance_dispose( GObject *object )
 
 		g_object_unref( self->private->action_group );
 		g_object_unref( self->private->ui_manager );
+		g_object_unref( self->private->sort_buttons );
 
 		if( self->private->selected_items ){
 			self->private->selected_items = na_object_free_items( self->private->selected_items );
@@ -384,7 +385,7 @@ instance_finalize( GObject *instance )
 
 /**
  * nact_menubar_new:
- * @window: the main window which embeds the menubar, usually the #BaseWindow.
+ * @window: the window which embeds the menubar, usually the #NactMainWindow.
  *
  * The created menubar attachs itself to the @window; it also connect a weak
  * reference to this same @window, thus automatically g_object_unref() -ing
@@ -405,6 +406,7 @@ nact_menubar_new( BaseWindow *window )
 	bar = g_object_new( NACT_MENUBAR_TYPE, NULL );
 
 	bar->private->window = window;
+	bar->private->sort_buttons = nact_sort_buttons_new( window );
 
 	base_window_signal_connect( window,
 			G_OBJECT( window ), BASE_SIGNAL_INITIALIZE_WINDOW, G_CALLBACK( on_base_initialize_window ));
@@ -529,6 +531,7 @@ on_base_initialize_window( BaseWindow *window, gpointer user_data )
 		base_window_signal_connect( window,
 				G_OBJECT( bar ), MENUBAR_SIGNAL_UPDATE_SENSITIVITIES, G_CALLBACK( on_update_sensitivities ));
 
+		nact_menubar_file_initialize( bar );
 		nact_main_toolbar_init( window, bar->private->action_group );
 	}
 }
@@ -610,7 +613,7 @@ on_menu_item_deselected( GtkMenuItem *proxy, BaseWindow *window )
  * Opens a popup menu.
  */
 static void
-on_tree_view_open_context_menu( BaseWindow *window, NactTreeView *view, GdkEventButton *event, gpointer user_data )
+on_tree_view_open_context_menu( BaseWindow *window, GdkEventButton *event, gpointer user_data )
 {
 	GtkWidget *menu;
 
@@ -641,16 +644,15 @@ 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,
-		NactTreeView *view, gboolean reset, guint menus, guint actions, guint profiles )
+on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus, guint actions, guint profiles )
 {
 	static const gchar *thisfn = "nact_menubar_on_tree_view_count_changed";
 	gchar *status;
 
 	BAR_WINDOW_VOID( window );
 
-	g_debug( "%s: window=%p, view=%p, reset=%s, menus=%u, actions=%u, profiles=%u",
-			thisfn, ( void * ) window, ( void * ) view, reset ? "True":"False", menus, actions, profiles );
+	g_debug( "%s: window=%p, reset=%s, menus=%u, actions=%u, profiles=%u",
+			thisfn, ( void * ) window, reset ? "True":"False", menus, actions, profiles );
 
 	if( reset ){
 		bar->private->count_menus = menus;
@@ -665,7 +667,9 @@ on_tree_view_count_changed( BaseWindow *window,
 
 	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(
@@ -681,23 +685,24 @@ on_tree_view_count_changed( BaseWindow *window,
  * the count of modified NAObjectItem has changed
  */
 static void
-on_tree_view_modified_count_changed( BaseWindow *window, NactTreeView *view, guint count, gpointer user_data )
+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, view=%p, count=%d, user_data=%p",
-			thisfn, ( void * ) window, ( void * ) view, count, ( void * ) user_data );
+	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, NactTreeView *view, gpointer user_data )
+on_tree_view_focus_in( BaseWindow *window, gpointer user_data )
 {
 	BAR_WINDOW_VOID( window );
 
@@ -708,7 +713,7 @@ on_tree_view_focus_in( BaseWindow *window, NactTreeView *view, gpointer user_dat
 }
 
 static void
-on_tree_view_focus_out( BaseWindow *window, NactTreeView *view, gpointer user_data )
+on_tree_view_focus_out( BaseWindow *window, gpointer user_data )
 {
 	BAR_WINDOW_VOID( window );
 
@@ -725,7 +730,7 @@ on_tree_view_focus_out( BaseWindow *window, NactTreeView *view, gpointer user_da
  * dealt with the MAIN_SIGNAL_SELECTION_CHANGED signal
  */
 static void
-on_tree_view_selection_changed( BaseWindow *window, NactTreeView *view, GList *selected, gpointer user_data )
+on_tree_view_selection_changed( BaseWindow *window, GList *selected, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_menubar_on_tree_view_selection_changed";
 	NAObject *first;
diff --git a/src/nact/nact-menubar.h b/src/nact/nact-menubar.h
index cceefec..f0079cd 100644
--- a/src/nact/nact-menubar.h
+++ b/src/nact/nact-menubar.h
@@ -56,6 +56,8 @@
  * It is up to the application to update these indicators.
  * Each time an indicator is updated, it triggers an update of all relevant
  * menu items sensitivities.
+ *
+ * Toolbar and sort buttons are also driven by this menubar.
  */
 
 #include "base-window.h"
diff --git a/src/nact/nact-sort-buttons.c b/src/nact/nact-sort-buttons.c
index 34c6fe4..513473a 100644
--- a/src/nact/nact-sort-buttons.c
+++ b/src/nact/nact-sort-buttons.c
@@ -37,266 +37,377 @@
 
 #include "nact-application.h"
 #include "nact-sort-buttons.h"
+#include "nact-tree-view.h"
+
+/* private class data
+ */
+struct _NactSortButtonsClassPrivate {
+	void *empty;						/* so that gcc -pedantic is happy */
+};
+
+struct _NactSortButtonsPrivate {
+	gboolean    dispose_has_run;
+	BaseWindow *window;
+	NAUpdater  *updater;
+	gboolean    toggling;
+	gint        active;
+	guint       count_items;
+};
 
 typedef struct {
-	gchar    *btn_name;
-	/*GCallback on_btn_toggled;*/
-	guint     order_mode;
+	gchar           *btn_name;
+	guint            order_mode;
+	GtkToggleButton *button;
 }
 	ToggleGroup;
 
-static gboolean st_set_sort_order = FALSE;
-static gboolean st_in_toggle      = FALSE;
-static gboolean st_enable_buttons = FALSE;
-static gint     st_last_active    = -1;
-
-static void enable_buttons( BaseWindow *window );
-static void on_toggle_button_toggled( GtkToggleButton *button, BaseWindow *window );
-static void set_new_sort_order( BaseWindow *window, guint order_mode );
-static void display_sort_order( BaseWindow *window, guint order_mode );
-static gint toggle_group_get_active( ToggleGroup *group, BaseWindow *window );
-static gint toggle_group_get_for_mode( ToggleGroup *group, guint mode );
-static void toggle_group_set_active( ToggleGroup *group, BaseWindow *window, gint idx );
-static gint toggle_group_get_from_button( ToggleGroup *group, BaseWindow *window, GtkToggleButton *toggled_button );
-
 static ToggleGroup st_toggle_group [] = {
-		{ "SortManualButton", IPREFS_ORDER_MANUAL },
-		{ "SortUpButton",     IPREFS_ORDER_ALPHA_ASCENDING },
-		{ "SortDownButton",   IPREFS_ORDER_ALPHA_DESCENDING },
+		{ "SortManualButton", IPREFS_ORDER_MANUAL,           NULL },
+		{ "SortUpButton",     IPREFS_ORDER_ALPHA_ASCENDING,  NULL },
+		{ "SortDownButton",   IPREFS_ORDER_ALPHA_DESCENDING, NULL },
 		{ NULL }
 };
 
-/**
- * nact_sort_buttons_runtime_init:
- * @window: the #BaseWindow.
- *
- * Initialization of the UI each time it is displayed.
- *
- * At end, buttons are all :
- * - off,
- * - connected,
- * - enabled (sensitive) if level zero is writable
- */
-void
-nact_sort_buttons_runtime_init( BaseWindow *window )
-{
-	static const gchar *thisfn = "nact_sort_buttons_runtime_init";
-	GtkToggleButton *button;
-	gint i;
+#define WINDOW_DATA_SORT_BUTTONS				"window-data-sort-buttons"
 
-	g_debug( "%s: window=%p", thisfn, ( void * ) window );
+static GObjectClass *st_parent_class = NULL;
 
-	i = 0;
-	while( st_toggle_group[i].btn_name ){
+static GType register_type( void );
+static void  class_init( NactSortButtonsClass *klass );
+static void  instance_init( GTypeInstance *instance, gpointer klass );
+static void  instance_dispose( GObject *application );
+static void  instance_finalize( GObject *application );
 
-		button = GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( window ), st_toggle_group[i].btn_name ));
-		base_window_signal_connect(
-				BASE_WINDOW( window ),
-				G_OBJECT( button ),
-				"toggled",
-				G_CALLBACK( on_toggle_button_toggled ));
+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 );
 
-		i += 1;
+static void  enable_buttons( const NactSortButtons *sort_buttons, gboolean enabled );
+static gint  toggle_group_get_from_mode( guint mode );
+static gint  toggle_group_get_from_button( GtkToggleButton *toggled_button );
+
+GType
+nact_sort_buttons_get_type( void )
+{
+	static GType type = 0;
+
+	if( !type ){
+		type = register_type();
 	}
 
-	enable_buttons( window );
+	return( type );
 }
 
-/**
- * nact_sort_buttons_all_widgets_showed:
- * @window: the #BaseWindow.
- *
- * Called when all the widgets are showed after end of all runtime
- * initializations.
- */
-void
-nact_sort_buttons_all_widgets_showed( BaseWindow *window )
+static GType
+register_type( void )
 {
-	static const gchar *thisfn = "nact_sort_buttons_all_widgets_showed";
+	static const gchar *thisfn = "nact_sort_buttons_register_type";
+	GType type;
+
+	static GTypeInfo info = {
+		sizeof( NactSortButtonsClass ),
+		( GBaseInitFunc ) NULL,
+		( GBaseFinalizeFunc ) NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( NactSortButtons ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	g_debug( "%s", thisfn );
+
+	type = g_type_register_static( G_TYPE_OBJECT, "NactSortButtons", &info, 0 );
+
+	return( type );
+}
 
-	g_debug( "%s: window=%p", thisfn, ( void * ) window );
+static void
+class_init( NactSortButtonsClass *klass )
+{
+	static const gchar *thisfn = "nact_sort_buttons_class_init";
+	GObjectClass *object_class;
+
+	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
 
-	st_set_sort_order = TRUE;
+	klass->private = g_new0( NactSortButtonsClassPrivate, 1 );
 }
 
-/**
- * nact_sort_buttons_enable_buttons:
- * @window: the #BaseWindow.
- * @enable: whether we wish enable or disable these sort buttons.
- *
- * Enable or disable the sort buttons, while keeping relevant with
- * writability status of the various stages.
- *
- * This function may be called when application wishes enable or disable
- * the sort buttons, typically when there is no record to sort.
- */
-void
-nact_sort_buttons_enable_buttons( BaseWindow *window, gboolean enable )
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
 {
-	static const gchar *thisfn = "nact_sort_buttons_enable_buttons";
+	static const gchar *thisfn = "nact_sort_buttons_instance_init";
+	NactSortButtons *self;
+
+	g_return_if_fail( NACT_IS_SORT_BUTTONS( instance ));
+
+	g_debug( "%s: instance=%p (%s), klass=%p",
+			thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
+
+	self = NACT_SORT_BUTTONS( instance );
 
-	g_debug( "%s: window=%p, enable=%s", thisfn, ( void * ) window, enable ? "True":"False" );
+	self->private = g_new0( NactSortButtonsPrivate, 1 );
 
-	st_enable_buttons = enable;
-	enable_buttons( window );
+	self->private->dispose_has_run = FALSE;
+	self->private->toggling = FALSE;
+	self->private->active = -1;
+	self->private->count_items = 0;
 }
 
-/**
- * nact_sort_buttons_dispose:
- * @window: the #BaseWindow.
- *
- * The main window is disposed.
- */
-void
-nact_sort_buttons_dispose( BaseWindow *window )
+static void
+instance_dispose( GObject *object )
 {
-	static const gchar *thisfn = "nact_sort_buttons_dispose";
+	static const gchar *thisfn = "nact_sort_buttons_instance_dispose";
+	NactSortButtons *self;
+
+	g_return_if_fail( NACT_IS_SORT_BUTTONS( object ));
+
+	self = NACT_SORT_BUTTONS( object );
+
+	if( !self->private->dispose_has_run ){
+		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
 
-	g_debug( "%s: window=%p", thisfn, ( void * ) window );
+		self->private->dispose_has_run = TRUE;
+
+		/* chain up to the parent class */
+		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
+			G_OBJECT_CLASS( st_parent_class )->dispose( object );
+		}
+	}
 }
 
-/**
- * nact_sort_buttons_display_order_change:
- * @window: the #BaseWindow.
- * @order_mode: the new order mode.
- *
- * Relayed via BaseWindow, this is a NAIPivotConsumer notification.
- */
-void
-nact_sort_buttons_display_order_change( BaseWindow *window, guint order_mode )
+static void
+instance_finalize( GObject *instance )
 {
-	static const gchar *thisfn = "nact_sort_buttons_display_order_change";
+	static const gchar *thisfn = "nact_sort_buttons_instance_finalize";
+	NactSortButtons *self;
+
+	g_return_if_fail( NACT_IS_SORT_BUTTONS( instance ));
 
-	g_debug( "%s: window=%p", thisfn, ( void * ) window );
+	g_debug( "%s: instance=%p (%s)", thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
 
-	display_sort_order( window, order_mode );
+	self = NACT_SORT_BUTTONS( instance );
+
+	g_free( self->private );
+
+	/* chain call to parent class */
+	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( instance );
+	}
 }
 
 /**
- * nact_sort_buttons_level_zero_writability_change:
- * @window: the #BaseWindow.
+ * nact_sort_buttons_new:
+ * @window: the main window.
  *
- * Relayed via BaseWindow, this is a NAIPivotConsumer notification.
+ * Returns: a new #NactSortButtons object.
  */
-void
-nact_sort_buttons_level_zero_writability_change( BaseWindow *window )
+NactSortButtons *
+nact_sort_buttons_new( BaseWindow *window )
 {
-	static const gchar *thisfn = "nact_sort_buttons_level_zero_writability_change";
+	NactSortButtons *obj;
+	NactApplication *application;
 
-	g_debug( "%s: window=%p", thisfn, ( void * ) window );
+	g_return_val_if_fail( BASE_IS_WINDOW( window ), NULL );
 
-	enable_buttons( window );
-}
+	obj = g_object_new( NACT_SORT_BUTTONS_TYPE, NULL );
 
-static void
-enable_buttons( BaseWindow *window )
-{
-	NactApplication *application;
-	NAUpdater *updater;
-	gboolean writable;
-	GtkWidget *button;
-	gint i;
+	base_window_signal_connect( window,
+			G_OBJECT( window ), BASE_SIGNAL_INITIALIZE_WINDOW, G_CALLBACK( on_base_initialize_buttons ));
 
-	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-	writable = na_updater_is_level_zero_writable( updater );
+	base_window_signal_connect( window,
+			G_OBJECT( window ), TREE_SIGNAL_COUNT_CHANGED, G_CALLBACK( on_tree_view_count_changed ));
 
-	i = 0;
-	while( st_toggle_group[i].btn_name ){
-		button = base_window_get_widget( BASE_WINDOW( window ), st_toggle_group[i].btn_name );
-		gtk_widget_set_sensitive( button, writable && st_enable_buttons );
-		i += 1;
-	}
+	g_object_set_data( G_OBJECT( window ), WINDOW_DATA_SORT_BUTTONS, obj );
+
+	obj->private->window = window;
+
+	application = NACT_APPLICATION( base_window_get_application( window ));
+	obj->private->updater = nact_application_get_updater( application );
+
+	return( obj );
 }
 
+/*
+ * on_base_initialize_buttons:
+ * @window: the #BaseWindow.
+ *
+ * Initialization of the UI each time it is displayed.
+ *
+ * At end, buttons are all :
+ * - all off,
+ * - connected to a toggle handler,
+ * - enabled (sensitive) if sort order mode is modifiable.
+ */
 static void
-on_toggle_button_toggled( GtkToggleButton *toggled_button, BaseWindow *window )
+on_base_initialize_buttons( BaseWindow *window, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_sort_buttons_on_toggle_button_toggled";
-	gint ibtn, iprev;
+	static const gchar *thisfn = "nact_sort_buttons_on_base_initialize_buttons";
+	NactSortButtons *sort_buttons;
+	gint i;
+	NASettings *settings;
 
-	if( !st_in_toggle ){
+	g_return_if_fail( BASE_IS_WINDOW( window ));
 
-		ibtn = toggle_group_get_from_button( st_toggle_group, BASE_WINDOW( window ), toggled_button );
-		g_return_if_fail( ibtn >= 0 );
+	g_debug( "%s: window=%p, user_data=%p", thisfn, ( void * ) window, ( void * ) user_data );
 
-		iprev = toggle_group_get_active( st_toggle_group, BASE_WINDOW( window ));
+	sort_buttons = NACT_SORT_BUTTONS( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_SORT_BUTTONS ));
 
-		g_debug( "%s: iprev=%d, ibtn=%d", thisfn, iprev, ibtn );
+	for( i = 0 ; st_toggle_group[i].btn_name ; ++i ){
+		st_toggle_group[i].button =
+				GTK_TOGGLE_BUTTON( base_window_get_widget( window, st_toggle_group[i].btn_name ));
+		base_window_signal_connect( window,
+				G_OBJECT( st_toggle_group[i].button ), "toggled", G_CALLBACK( on_toggle_button_toggled ));
+	}
 
-		if( iprev == ibtn ){
-			gtk_toggle_button_set_active( toggled_button, TRUE );
+	settings = na_pivot_get_settings( NA_PIVOT( sort_buttons->private->updater ));
+	na_settings_register_key_callback( settings,
+			NA_IPREFS_ITEMS_LIST_ORDER_MODE, G_CALLBACK( on_settings_order_mode_changed ), sort_buttons );
 
-		} else {
-			toggle_group_set_active( st_toggle_group, BASE_WINDOW( window ), ibtn );
-			set_new_sort_order( window, st_toggle_group[ibtn].order_mode );
-		}
-	}
+	/* for now, disable the sort buttons
+	 * they will be enabled as soon as we receive the count of displayed items
+	 */
+	enable_buttons( sort_buttons, FALSE );
 }
 
+/*
+ * if the user re-clicks on the already active buttons, reset it active
+ */
 static void
-set_new_sort_order( BaseWindow *window, guint order_mode )
+on_toggle_button_toggled( GtkToggleButton *toggled_button, BaseWindow *window )
 {
-	static const gchar *thisfn = "nact_sort_buttons_set_new_sort_order";
-	NactApplication *application;
-	NAUpdater *updater;
-
-	if( st_set_sort_order ){
-		g_debug( "%s: order_mode=%d", thisfn, order_mode );
-
-		application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-		updater = nact_application_get_updater( application );
-
-		na_iprefs_set_order_mode( NA_PIVOT( updater ), order_mode );
+	NactSortButtons *sort_buttons;
+	gint i, ibtn;
+
+	g_return_if_fail( BASE_IS_WINDOW( window ));
+
+	sort_buttons = NACT_SORT_BUTTONS( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_SORT_BUTTONS ));
+
+	if( !sort_buttons->private->dispose_has_run ){
+		if( !sort_buttons->private->toggling ){
+
+			sort_buttons->private->toggling = TRUE;
+			ibtn = toggle_group_get_from_button( toggled_button );
+
+			/* the user re-clicks on the already active button
+			 * do not let it becomes false, but keep it active
+			 */
+			if( ibtn == sort_buttons->private->active ){
+				gtk_toggle_button_set_active( st_toggle_group[ibtn].button, TRUE );
+
+			/* reset all buttons to false, then the clicked one to active
+			 */
+			} else {
+				for( i = 0 ; st_toggle_group[i].btn_name ; ++i ){
+					gtk_toggle_button_set_active( st_toggle_group[i].button, FALSE );
+				}
+				gtk_toggle_button_set_active( toggled_button, TRUE );
+				sort_buttons->private->active = ibtn;
+				na_iprefs_set_order_mode(
+						NA_PIVOT( sort_buttons->private->updater ), st_toggle_group[ibtn].order_mode );
+			}
+
+			sort_buttons->private->toggling = FALSE;
+		}
 	}
 }
 
 /*
+ * NASettings callback for a change on NA_IPREFS_ITEMS_LIST_ORDER_MODE key
+ *
  * activate the button corresponding to the new sort order
  * desactivate the previous button
  * do nothing if new button and previous button are the sames
+ *
+ * testing 'toggling' is useless here because NASettings slightly delay the
+ * notifications: when we toggle a button, and update the settings, then
+ * we already have reset 'toggling' to FALSE when we are coming here
  */
 static void
-display_sort_order( BaseWindow *window, guint order_mode )
+on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpointer new_value, gboolean mandatory, NactSortButtons *sort_buttons )
 {
-	static const gchar *thisfn = "nact_sort_buttons_display_sort_order";
-	gint iprev, inew;
+	static const gchar *thisfn = "nact_sort_buttons_on_settings_order_mode_changed";
+	const gchar *order_mode_str;
+	guint order_mode;
+	gint ibtn;
 
-	iprev = toggle_group_get_active( st_toggle_group, BASE_WINDOW( window ));
+	g_return_if_fail( NACT_IS_SORT_BUTTONS( sort_buttons ));
 
-	inew = toggle_group_get_for_mode( st_toggle_group, order_mode );
-	g_return_if_fail( inew >= 0 );
+	if( !sort_buttons->private->dispose_has_run ){
 
-	g_debug( "%s: iprev=%d, inew=%d", thisfn, iprev, inew );
+		order_mode_str = ( const gchar * ) new_value;
+		order_mode = na_iprefs_get_order_mode_by_label( order_mode_str );
 
-	if( iprev == -1 || inew != iprev ){
-		toggle_group_set_active( st_toggle_group, BASE_WINDOW( window ), inew );
+		g_debug( "%s: group=%s, key=%s, order_mode=%u (%s), mandatory=%s, sort_buttons=%p (%s)",
+				thisfn, group, key, order_mode, order_mode_str,
+				mandatory ? "True":"False", ( void * ) sort_buttons, G_OBJECT_TYPE_NAME( sort_buttons ));
+
+		ibtn = toggle_group_get_from_mode( order_mode );
+		g_return_if_fail( ibtn >= 0 );
+
+		if( sort_buttons->private->active == -1 || ibtn != sort_buttons->private->active ){
+			sort_buttons->private->active = ibtn;
+			gtk_toggle_button_set_active( st_toggle_group[ibtn].button, TRUE );
+		}
 	}
 }
 
-/*
- * returns the index of the button currently active
- * or -1 if not found
- */
-static gint
-toggle_group_get_active( ToggleGroup *group, BaseWindow *window )
+static void
+on_tree_view_count_changed( BaseWindow *window, gboolean reset, guint menus_count, guint actions_count, guint profiles_count, gpointer user_data )
 {
-	GtkToggleButton *button;
-	gint i = 0;
+	static const gchar *thisfn = "nact_sort_buttons_on_tree_view_count_changed";
+	NactSortButtons *sort_buttons;
 
-	if( st_last_active != -1 ){
-		return( st_last_active );
-	}
+	g_return_if_fail( BASE_IS_WINDOW( window ));
 
-	while( group[i].btn_name ){
-		button = GTK_TOGGLE_BUTTON( base_window_get_widget( window, group[i].btn_name ));
-		if( gtk_toggle_button_get_active( button )){
-			return( i );
+	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",
+				thisfn, ( void * ) window, reset ? "True":"False",
+						menus_count, actions_count, profiles_count, ( void * ) user_data );
+
+		if( reset ){
+			sort_buttons->private->count_items = menus_count + actions_count;
+		} else {
+			sort_buttons->private->count_items += menus_count + actions_count;
 		}
-		i += 1;
+
+		enable_buttons( sort_buttons, sort_buttons->private->count_items > 0 );
 	}
 
-	return( -1 );
+}
+
+static void
+enable_buttons( const NactSortButtons *sort_buttons, gboolean enabled )
+{
+	gboolean level_zero_writable;
+	gboolean preferences_locked;
+	gboolean finally_enabled;
+	gint i;
+	guint order_mode;
+
+	level_zero_writable = na_updater_is_level_zero_writable( sort_buttons->private->updater );
+	preferences_locked = na_updater_are_preferences_locked( sort_buttons->private->updater );
+	finally_enabled = level_zero_writable && !preferences_locked && enabled;
+
+	for( i=0 ; st_toggle_group[i].btn_name ; ++i ){
+		gtk_widget_set_sensitive( GTK_WIDGET( st_toggle_group[i].button ), finally_enabled );
+	}
+
+	if( finally_enabled && sort_buttons->private->active == -1 ){
+		order_mode = na_iprefs_get_order_mode( NA_PIVOT( sort_buttons->private->updater ), NULL );
+		i = toggle_group_get_from_mode( order_mode );
+		gtk_toggle_button_set_active( st_toggle_group[i].button, TRUE );
+	}
 }
 
 /*
@@ -304,54 +415,31 @@ toggle_group_get_active( ToggleGroup *group, BaseWindow *window )
  * or -1 if not found
  */
 static gint
-toggle_group_get_for_mode( ToggleGroup *group, guint mode )
+toggle_group_get_from_mode( guint mode )
 {
-	gint i = 0;
+	guint i;
 
-	while( group[i].btn_name ){
-		if( group[i].order_mode == mode ){
+	for( i = 0 ; st_toggle_group[i].btn_name ; ++ i ){
+		if( st_toggle_group[i].order_mode == mode ){
 			return( i );
 		}
-		i += 1;
 	}
 
 	return( -1 );
 }
 
-static void
-toggle_group_set_active( ToggleGroup *group, BaseWindow *window, gint idx )
-{
-	static const gchar *thisfn = "nact_sort_buttons_toggle_group_set_active";
-	GtkToggleButton *button;
-	gint i;
-
-	g_debug( "%s: idx=%d", thisfn, idx );
-
-	i = 0;
-	st_in_toggle = TRUE;
-
-	while( group[i].btn_name ){
-		button = GTK_TOGGLE_BUTTON( base_window_get_widget( window, group[i].btn_name ));
-		gtk_toggle_button_set_active( button, i==idx );
-		i += 1;
-	}
-
-	st_in_toggle = FALSE;
-	st_last_active = idx;
-}
-
+/*
+ * returns the index of the toggle button, or -1
+ */
 static gint
-toggle_group_get_from_button( ToggleGroup *group, BaseWindow *window, GtkToggleButton *toggled_button )
+toggle_group_get_from_button( GtkToggleButton *toggled_button )
 {
-	GtkToggleButton *button;
-	gint i = 0;
+	gint i;
 
-	while( group[i].btn_name ){
-		button = GTK_TOGGLE_BUTTON( base_window_get_widget( window, group[i].btn_name ));
-		if( button == toggled_button ){
+	for( i = 0 ; st_toggle_group[i].btn_name ; ++i ){
+		if( st_toggle_group[i].button == toggled_button ){
 			return( i );
 		}
-		i += 1;
 	}
 
 	return( -1 );
diff --git a/src/nact/nact-sort-buttons.h b/src/nact/nact-sort-buttons.h
index 221c844..7e0b612 100644
--- a/src/nact/nact-sort-buttons.h
+++ b/src/nact/nact-sort-buttons.h
@@ -32,21 +32,54 @@
 #define __NACT_SORT_BUTTONS_H__
 
 /**
- * SECTION: nact_sort_buttons
- * @short_description: Manage the sort buttons in the main window.
- * @include: nact/nact-sort-buttons.h
+ * SECTION: nact-sort-buttons
+ * @title: NactSortButtons
+ * @short_description: The Sort Buttons class definition
+ * @include: nact-sort-buttons.h
+ *
+ * A convenience class to manager sort buttons in the user interface.
+ *
+ * The sort order mode is monitored, so that buttons automatically display
+ * the right order mode if it is modified by another way (e.g. from
+ * Preferences editor).
+ *
+ * Modifying the sort order mode requires that:
+ * - level zero is writable (see NAUpdater)
+ * - preferences are not locked (see NAUpdater)
+ * - sort order mode is not a mandatory preference.
  */
 
 #include "base-window.h"
 
 G_BEGIN_DECLS
 
-void  nact_sort_buttons_runtime_init                 ( BaseWindow *window );
-void  nact_sort_buttons_all_widgets_showed           ( BaseWindow *window );
-void  nact_sort_buttons_enable_buttons               ( BaseWindow *window, gboolean enable );
-void  nact_sort_buttons_dispose                      ( BaseWindow *window );
-void  nact_sort_buttons_display_order_change         ( BaseWindow *window, guint order_mode );
-void  nact_sort_buttons_level_zero_writability_change( BaseWindow *window );
+#define NACT_SORT_BUTTONS_TYPE                ( nact_sort_buttons_get_type())
+#define NACT_SORT_BUTTONS( object )           ( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_SORT_BUTTONS_TYPE, NactSortButtons ))
+#define NACT_SORT_BUTTONS_CLASS( klass )      ( G_TYPE_CHECK_CLASS_CAST( klass, NACT_SORT_BUTTONS_TYPE, NactSortButtonsClass ))
+#define NACT_IS_SORT_BUTTONS( object )        ( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_SORT_BUTTONS_TYPE ))
+#define NACT_IS_SORT_BUTTONS_CLASS( klass )   ( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_SORT_BUTTONS_TYPE ))
+#define NACT_SORT_BUTTONS_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_SORT_BUTTONS_TYPE, NactSortButtonsClass ))
+
+typedef struct _NactSortButtonsPrivate        NactSortButtonsPrivate;
+
+typedef struct {
+	/*< private >*/
+	GObject                 parent;
+	NactSortButtonsPrivate *private;
+}
+	NactSortButtons;
+
+typedef struct _NactSortButtonsClassPrivate   NactSortButtonsClassPrivate;
+
+typedef struct {
+	/*< private >*/
+	GObjectClass                 parent;
+	NactSortButtonsClassPrivate *private;
+}
+	NactSortButtonsClass;
+
+GType            nact_sort_buttons_get_type( void );
+NactSortButtons *nact_sort_buttons_new     ( BaseWindow *window );
 
 G_END_DECLS
 
diff --git a/src/nact/nact-tree-ieditable.c b/src/nact/nact-tree-ieditable.c
index f5534c4..df243b1 100644
--- a/src/nact/nact-tree-ieditable.c
+++ b/src/nact/nact-tree-ieditable.c
@@ -71,12 +71,14 @@ 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           increment_count_items( NactTreeIEditable *view, IEditableData *ied, GList *items );
+static void           increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items );
 static GtkTreePath   *get_selection_first_path( GtkTreeView *treeview );
 static IEditableData *get_instance_data( NactTreeIEditable *view );
-static void           decrement_counters( NactTreeIEditable *instance, IEditableData *ialid, GList *items );
+static void           decrement_counters( NactTreeIEditable *view, IEditableData *ialid, GList *items );
 static void           inline_edition( BaseWindow *window );
 
 GType
@@ -172,7 +174,7 @@ nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treevi
 	application = NACT_APPLICATION( base_window_get_application( window ));
 	ied->updater = nact_application_get_updater( application );
 
-	/* expand/collapse with the keyboard */
+	/* inline label edition */
 	base_window_signal_connect( window,
 			G_OBJECT( treeview ), "key-press-event", G_CALLBACK( on_key_pressed_event ));
 
@@ -181,6 +183,13 @@ nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treevi
 	renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
 	base_window_signal_connect( window,
 			G_OBJECT( renderers->data ), "edited", G_CALLBACK( on_label_edited ));
+
+	/* monitors status changes to refresh the display */
+	na_iduplicable_register_consumer( G_OBJECT( instance ));
+	base_window_signal_connect( window,
+			G_OBJECT( instance ), IDUPLICABLE_SIGNAL_MODIFIED_CHANGED, G_CALLBACK( on_modified_status_changed ));
+	base_window_signal_connect( window,
+			G_OBJECT( instance ), IDUPLICABLE_SIGNAL_VALID_CHANGED, G_CALLBACK( on_valid_status_changed ));
 }
 
 /**
@@ -235,12 +244,72 @@ on_label_edited( GtkCellRendererText *renderer, const gchar *path_str, const gch
 	gchar *new_text;
 
 	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
-	ied = ( IEditableData * ) g_object_get_data( G_OBJECT( items_view ), VIEW_DATA_IEDITABLE );
-	path = gtk_tree_path_new_from_string( path_str );
-	object = nact_tree_model_object_at_path( ied->model, path );
-	new_text = g_strdup( text );
 
-	g_signal_emit_by_name( window, TREE_SIGNAL_CONTENT_CHANGED, items_view, object );
+	if( nact_tree_view_are_notify_allowed( items_view )){
+		ied = ( IEditableData * ) g_object_get_data( G_OBJECT( items_view ), VIEW_DATA_IEDITABLE );
+		path = gtk_tree_path_new_from_string( path_str );
+		object = nact_tree_model_object_at_path( ied->model, path );
+		new_text = g_strdup( text );
+
+		g_signal_emit_by_name( window, TREE_SIGNAL_CONTENT_CHANGED, object );
+	}
+}
+
+/*
+ * modification status of the edited object has changed
+ * - refresh the display
+ */
+static void
+on_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;
+	IEditableData *ied;
+
+	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 );
+			}
+		}
+	}
+}
+
+/*
+ * validity status of the edited object has changed
+ * - refresh the display
+ */
+static void
+on_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;
+	IEditableData *ied;
+
+	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, 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 ));
+		}
+	}
 }
 
 /**
@@ -404,10 +473,9 @@ nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, G
 
 		/* post insertion
 		 */
-		increment_count_items( instance, ied, items );
+		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, NACT_TREE_VIEW( instance ), ied->count_modified );
+			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 ), insert_path );
@@ -420,6 +488,7 @@ do_insert_before( NactTreeIEditable *view, IEditableData *ied, GList *items, Gtk
 	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 ));
@@ -436,7 +505,10 @@ do_insert_before( NactTreeIEditable *view, IEditableData *ied, GList *items, Gtk
 		/* recursively insert subitems
 		 */
 		if( NA_IS_OBJECT_ITEM( it->data )){
-			do_insert_into( view, ied, na_object_get_items( it->data ), inserted_path );
+			subitems = na_object_get_items( it->data );
+			if( subitems ){
+				do_insert_into( view, ied, subitems, inserted_path );
+			}
 		}
 
 		na_object_check_status( it->data );
@@ -489,10 +561,9 @@ nact_tree_ieditable_insert_into( NactTreeIEditable *instance, GList *items )
 
 		/* post insertion
 		 */
-		increment_count_items( instance, ied, items );
+		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, NACT_TREE_VIEW( instance ), ied->count_modified );
+			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 );
@@ -554,16 +625,16 @@ do_insert_into( NactTreeIEditable *view, IEditableData *ied, GList *items, GtkTr
  * we pass here after each insertion operation (apart initial fill)
  */
 static void
-increment_count_items( NactTreeIEditable *view, IEditableData *ied, GList *items )
+increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
 {
-	static const gchar *thisfn = "nact_tre_ieditablet_increment_count_items";
+	static const gchar *thisfn = "nact_tre_ieditablet_increment_counters";
 	gint menus, actions, profiles;
 
 	g_debug( "%s: view=%p, ied=%p, items=%p (count=%d)",
 			thisfn, ( void * ) view, ( void * ) ied, ( void * ) items, items ? g_list_length( items ) : 0 );
 
 	na_object_count_items( items, &menus, &actions, &profiles );
-	g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_COUNT_CHANGED, view, FALSE, menus, actions, profiles );
+	g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_COUNT_CHANGED, FALSE, menus, actions, profiles );
 }
 
 #if 0
@@ -637,7 +708,7 @@ decrement_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
 	menus *= -1;
 	actions *= -1;
 	profiles *= -1;
-	g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_COUNT_CHANGED, view, FALSE, menus, actions, profiles );
+	g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_COUNT_CHANGED, FALSE, menus, actions, profiles );
 }
 
 /*
diff --git a/src/nact/nact-tree-view.c b/src/nact/nact-tree-view.c
index da777da..9384ed3 100644
--- a/src/nact/nact-tree-view.c
+++ b/src/nact/nact-tree-view.c
@@ -32,10 +32,13 @@
 #include <config.h>
 #endif
 
+#include <glib/gi18n.h>
+
 #include <api/na-object-api.h>
 
 #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"
@@ -72,6 +75,7 @@ enum {
 	TREE_PROP_WINDOW_ID,
 	TREE_PROP_WIDGET_NAME_ID,
 	TREE_PROP_MODE_ID,
+	TREE_PROP_NOTIFY_ALLOWED_ID,
 
 	TREE_PROP_N_PROPERTIES
 };
@@ -104,18 +108,6 @@ enum {
  */
 typedef gboolean ( *FnIterOnSelection )( NactTreeView *, GtkTreeModel *, GtkTreeIter *, NAObject *, gpointer );
 
-#define WINDOW_DATA_TREE_VIEW				"window-data-tree-view"
-
-#define VIEW_WINDOW_VOID( window ) \
-	g_return_if_fail( BASE_IS_WINDOW( window )); \
-	NactTreeView *view = ( NactTreeView * ) g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ); \
-	g_return_if_fail( NACT_IS_TREE_VIEW( view ));
-
-#define VIEW_WINDOW_VALUE( window, value ) \
-	g_return_val_if_fail( BASE_IS_WINDOW( window ), value ); \
-	NactTreeView *view = ( NactTreeView * ) g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ); \
-	g_return_val_if_fail( NACT_IS_TREE_VIEW( view ), value );
-
 static gint          st_signals[ LAST_SIGNAL ] = { 0 };
 static GObjectClass *st_parent_class           = NULL;
 
@@ -137,8 +129,8 @@ static gboolean on_focus_in( GtkWidget *widget, GdkEventFocus *event, BaseWindow
 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, NactTreeView *view, NAObject *edited );
-static void     on_selection_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, GList *selected_items );
+static void     on_content_changed_cleanup_handler( BaseWindow *window, NAObject *edited );
+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 );
 static void     extend_selection_to_children( NactTreeView *view, GtkTreeModel *model, GtkTreeIter *parent );
@@ -146,7 +138,7 @@ static GList   *get_selected_items( NactTreeView *view );
 static void     iter_on_selection( NactTreeView *view, FnIterOnSelection fn_iter, gpointer user_data );
 static void     navigate_to_child( NactTreeView *view );
 static void     navigate_to_parent( NactTreeView *view );
-static void     open_popup( BaseWindow *window, NactTreeView *view, GdkEventButton *event );
+static void     open_popup( BaseWindow *window, GdkEventButton *event );
 static void     select_row_at_path_by_string( NactTreeView *view, const gchar *path );
 static void     toggle_collapse( NactTreeView *view );
 static gboolean toggle_collapse_iter( NactTreeView *view, GtkTreeModel *model, GtkTreeIter *iter, NAObject *object, gpointer user_data );
@@ -218,28 +210,37 @@ class_init( NactTreeViewClass *klass )
 	g_object_class_install_property( object_class, TREE_PROP_WINDOW_ID,
 			g_param_spec_pointer(
 					TREE_PROP_WINDOW,
-					"BaseWindow",
-					"The BaseWindow parent",
+					/* i18n: this is a class name and should not be translated */
+					_( "BaseWindow" ),
+					_( "The BaseWindow parent" ),
 					G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
 
 	g_object_class_install_property( object_class, TREE_PROP_WIDGET_NAME_ID,
 			g_param_spec_string(
 					TREE_PROP_WIDGET_NAME,
-					"Widget name",
-					"The name of GtkTreeView widget",
+					_( "Widget name" ),
+					_( "The name of GtkTreeView widget" ),
 					"",
 					G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
 
 	g_object_class_install_property( object_class, TREE_PROP_MODE_ID,
 			g_param_spec_uint(
 					TREE_PROP_MODE,
-					"Management mode",
-					"Management mode of the tree view, selection or edition",
+					_( "Management mode" ),
+					_( "Management mode of the tree view, selection or edition" ),
 					0,
 					TREE_MODE_N_MODES,
 					TREE_MODE_SELECTION,
 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
 
+	g_object_class_install_property( object_class, TREE_PROP_NOTIFY_ALLOWED_ID,
+			g_param_spec_boolean(
+					TREE_PROP_NOTIFY_ALLOWED,
+					_( "Allow notify" ),
+					_( "Whether notifications are allowed" ),
+					FALSE,
+					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
 	/**
 	 * NactTreeView::tree-signal-content-changed:
 	 *
@@ -249,12 +250,11 @@ class_init( NactTreeViewClass *klass )
 	 * - a row is edited.
 	 *
 	 * Signal args:
-	 * - a pointer on the view
-	 * - a poointer on the edited NAObject element, or NULL if the whole
+	 * - a pointer on the edited NAObject element, or NULL if the whole
 	 *   list has changed.
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, NactTreeView *view, NAObject *edited, gpointer user_data );
+	 * void ( *handler )( BaseWindow *window, NAObject *edited, gpointer user_data );
 	 */
 	st_signals[ CONTENT_CHANGED ] = g_signal_new_class_handler(
 			TREE_SIGNAL_CONTENT_CHANGED,
@@ -263,10 +263,10 @@ class_init( NactTreeViewClass *klass )
 			G_CALLBACK( on_content_changed_cleanup_handler ),
 			NULL,
 			NULL,
-			nact_cclosure_marshal_VOID__POINTER_POINTER,
+			g_cclosure_marshal_VOID__POINTER,
 			G_TYPE_NONE,
-			2,
-			G_TYPE_POINTER, G_TYPE_POINTER );
+			1,
+			G_TYPE_POINTER );
 
 	/**
 	 * NactTreeView::tree-signal-open-popup
@@ -275,11 +275,10 @@ class_init( NactTreeViewClass *klass )
 	 * clicks on the tree view.
 	 *
 	 * Signal args:
-	 * - a pointer on the view
 	 * - the GdkEvent.
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, NactTreeView *view, GdkEvent *event, gpointer user_data );
+	 * void ( *handler )( BaseWindow *window, GdkEvent *event, gpointer user_data );
 	 */
 	st_signals[ CONTEXT_MENU ] = g_signal_new(
 			TREE_SIGNAL_CONTEXT_MENU,
@@ -288,10 +287,10 @@ class_init( NactTreeViewClass *klass )
 			0,
 			NULL,
 			NULL,
-			nact_cclosure_marshal_VOID__POINTER_POINTER,
+			g_cclosure_marshal_VOID__POINTER,
 			G_TYPE_NONE,
-			2,
-			G_TYPE_POINTER, G_TYPE_POINTER );
+			1,
+			G_TYPE_POINTER );
 
 	/**
 	 * NactTreeView::tree-signal-count-changed:
@@ -310,14 +309,13 @@ class_init( NactTreeViewClass *klass )
 	 *   when inserting or pasting (resp. deleting) rows in the list.
 	 *
 	 * Signal args:
-	 * - a pointer on the view
 	 * - reset if %TRUE, add if %FALSE
 	 * - menus count/increment (may be negative)
 	 * - actions count/increment (may be negative)
 	 * - profiles count/increment (may be negative)
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, NactTreeView *view, gboolean reset,
+	 * void ( *handler )( BaseWindow *window, gboolean reset,
 	 *                    guint menus_count, guint actions_count, guint profiles_count, gpointer user_data );
 	 */
 	st_signals[ COUNT_CHANGED ] = g_signal_new(
@@ -327,22 +325,21 @@ class_init( NactTreeViewClass *klass )
 			0,						/* no default handler */
 			NULL,
 			NULL,
-			nact_cclosure_marshal_VOID__POINTER_BOOLEAN_INT_INT_INT,
+			nact_cclosure_marshal_VOID__BOOLEAN_INT_INT_INT,
 			G_TYPE_NONE,
-			5,
-			G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT );
+			4,
+			G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT );
 
 	/**
 	 * NactTreeView::tree-signal-focus-in:
 	 *
-	 * This signal is emitted on the BaseWindow when the view gains the
-	 * focus. In particular, edition menu is disabled outside of the treeview.
+	 * This signal is emitted on the window when the view gains the focus.
+	 * In particular, edition menu is disabled outside of the treeview.
 	 *
-	 * Signal args:
-	 * - a pointer on the view
+	 * Signal args: none
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, NactTreeView *view, gpointer user_data )
+	 * void ( *handler )( BaseWindow *window, gpointer user_data )
 	 */
 	st_signals[ FOCUS_IN ] = g_signal_new(
 			TREE_SIGNAL_FOCUS_IN,
@@ -351,22 +348,20 @@ class_init( NactTreeViewClass *klass )
 			0,
 			NULL,
 			NULL,
-			g_cclosure_marshal_VOID__POINTER,
+			g_cclosure_marshal_VOID__VOID,
 			G_TYPE_NONE,
-			1,
-			G_TYPE_POINTER );
+			0 );
 
 	/**
 	 * NactTreeView::tree-signal-focus-out:
 	 *
-	 * This signal is emitted on the BaseWindow when the view loses the
-	 * focus. In particular, edition menu is disabled outside of the treeview.
+	 * This signal is emitted on the window when the view loses the focus.
+	 * In particular, edition menu is disabled outside of the treeview.
 	 *
-	 * Signal args:
-	 * - a pointer on the view
+	 * Signal args: none
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, NactTreeView *view, gpointer user_data )
+	 * void ( *handler )( BaseWindow *window, gpointer user_data )
 	 */
 	st_signals[ FOCUS_OUT ] = g_signal_new(
 			TREE_SIGNAL_FOCUS_OUT,
@@ -375,10 +370,9 @@ class_init( NactTreeViewClass *klass )
 			0,
 			NULL,
 			NULL,
-			g_cclosure_marshal_VOID__POINTER,
+			g_cclosure_marshal_VOID__VOID,
 			G_TYPE_NONE,
-			1,
-			G_TYPE_POINTER );
+			0 );
 
 	/**
 	 * NactTreeView::tree-signal-modified-count-changed:
@@ -391,11 +385,10 @@ class_init( NactTreeViewClass *klass )
 	 * Having the order of items at level zero changed counts for one.
 	 *
 	 * Signal args:
-	 * - a pointer on the view
 	 * - the new count of modified items
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, NactTreeView *view, guint count, gpointer user_data )
+	 * void ( *handler )( BaseWindow *window, guint count, gpointer user_data )
 	 */
 	st_signals[ MODIFIED_COUNT ] = g_signal_new(
 			TREE_SIGNAL_MODIFIED_COUNT_CHANGED,
@@ -404,10 +397,10 @@ class_init( NactTreeViewClass *klass )
 			0,
 			NULL,
 			NULL,
-			nact_cclosure_marshal_VOID__POINTER_INT,
+			g_cclosure_marshal_VOID__INT,
 			G_TYPE_NONE,
-			2,
-			G_TYPE_POINTER, G_TYPE_INT );
+			1,
+			G_TYPE_INT );
 
 	/**
 	 * NactTreeView::tree-signal-selection-changed:
@@ -416,11 +409,10 @@ class_init( NactTreeViewClass *klass )
 	 * has changed in the treeview.
 	 *
 	 * Signal args:
-	 * - a pointer on the view
 	 * - a #GList of currently selected #NAObjectItems.
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, NactTreeView *view, GList *selected, gpointer user_data );
+	 * void ( *handler )( BaseWindow *window, GList *selected, gpointer user_data );
 	 */
 	st_signals[ SELECTION_CHANGED ] = g_signal_new_class_handler(
 			TREE_SIGNAL_SELECTION_CHANGED,
@@ -429,10 +421,10 @@ class_init( NactTreeViewClass *klass )
 			G_CALLBACK( on_selection_changed_cleanup_handler ),
 			NULL,
 			NULL,
-			nact_cclosure_marshal_VOID__POINTER_POINTER,
+			g_cclosure_marshal_VOID__POINTER,
 			G_TYPE_NONE,
-			2,
-			G_TYPE_POINTER, G_TYPE_POINTER );
+			1,
+			G_TYPE_POINTER );
 
 	klass->private = g_new0( NactTreeViewClassPrivate, 1 );
 }
@@ -486,6 +478,10 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 				g_value_set_uint( value, self->private->mode );
 				break;
 
+			case TREE_PROP_NOTIFY_ALLOWED_ID:
+				g_value_set_boolean( value, self->private->notify_allowed );
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
 				break;
@@ -517,6 +513,10 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 				self->private->mode = g_value_get_uint( value );
 				break;
 
+			case TREE_PROP_NOTIFY_ALLOWED_ID:
+				self->private->notify_allowed = g_value_get_boolean( value );
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
 				break;
@@ -545,8 +545,6 @@ 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_set_data( G_OBJECT( self->private->window ), WINDOW_DATA_TREE_VIEW, self );
-
 		g_object_weak_ref( G_OBJECT( self->private->window ), ( GWeakNotify ) on_finalizing_window, self );
 
 		/* chain up to the parent class */
@@ -630,6 +628,7 @@ static void
 on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_tree_view_on_base_initialize_gtk";
+	NactTreeView *items_view;
 	GtkTreeView *treeview;
 	GtkWidget *label;
 	GtkTreeViewColumn *column;
@@ -637,16 +636,16 @@ on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_d
 	GtkTreeSelection *selection;
 	GList *renderers;
 
-	VIEW_WINDOW_VOID( window );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
 
-	g_debug( "%s: window=%p (%s), toplevel=%p (%s), user_data=%p",
-			thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ),
-			( void * ) toplevel, G_OBJECT_TYPE_NAME( toplevel ), ( void * ) user_data );
-
-	if( !view->private->dispose_has_run ){
+	if( !items_view->private->dispose_has_run ){
+		g_debug( "%s: window=%p (%s), toplevel=%p (%s), user_data=%p",
+				thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ),
+				( void * ) toplevel, G_OBJECT_TYPE_NAME( toplevel ), ( void * ) user_data );
 
-		treeview = GTK_TREE_VIEW( base_window_get_widget( window, view->private->widget_name ));
-		nact_tree_model_new( window, treeview, view->private->mode );
+		treeview = GTK_TREE_VIEW( base_window_get_widget( window, items_view->private->widget_name ));
+		nact_tree_model_new( window, treeview, items_view->private->mode );
 
 		/* associates the ItemsView to the label */
 		label = base_window_get_widget( window, "ActionsListLabel" );
@@ -679,14 +678,12 @@ on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_d
 		 */
 		gtk_tree_view_set_enable_tree_lines( treeview, TRUE );
 
-		if( view->private->mode == TREE_MODE_EDITION ){
-			nact_tree_ieditable_initialize( NACT_TREE_IEDITABLE( view ), treeview, window );
-
+		if( items_view->private->mode == TREE_MODE_EDITION ){
 			column = gtk_tree_view_get_column( treeview, TREE_COLUMN_LABEL );
 			renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
 			renderer = GTK_CELL_RENDERER( renderers->data );
 			gtk_tree_view_column_set_cell_data_func(
-					column, renderer, ( GtkTreeCellDataFunc ) display_label, view, NULL );
+					column, renderer, ( GtkTreeCellDataFunc ) display_label, items_view, NULL );
 		}
 	}
 }
@@ -695,18 +692,19 @@ static void
 on_base_initialize_view( BaseWindow *window, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_tree_view_on_base_initialize_view";
+	NactTreeView *items_view;
 	GtkTreeView *treeview;
 	GtkTreeSelection *selection;
 
-	VIEW_WINDOW_VOID( window );
-
-	g_debug( "%s: window=%p (%s), user_data=%p",
-			thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ), ( void * ) user_data );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
 
-	if( !view->private->dispose_has_run ){
+	if( !items_view->private->dispose_has_run ){
+		g_debug( "%s: window=%p (%s), user_data=%p",
+				thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ), ( void * ) user_data );
 
-		treeview = GTK_TREE_VIEW( base_window_get_widget( window, view->private->widget_name ));
-		view->private->tree_view = treeview;
+		treeview = GTK_TREE_VIEW( base_window_get_widget( window, items_view->private->widget_name ));
+		items_view->private->tree_view = treeview;
 
 		/* monitors the selection */
 		selection = gtk_tree_view_get_selection( treeview );
@@ -727,6 +725,10 @@ on_base_initialize_view( BaseWindow *window, gpointer user_data )
 		/* monitors mouse events */
 		base_window_signal_connect( window,
 				G_OBJECT( treeview ), "button-press-event", G_CALLBACK( on_button_press_event ));
+
+		if( items_view->private->mode == TREE_MODE_EDITION ){
+			nact_tree_ieditable_initialize( NACT_TREE_IEDITABLE( items_view ), treeview, window );
+		}
 	}
 }
 
@@ -734,20 +736,19 @@ static void
 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;
 
-	VIEW_WINDOW_VOID( window );
-
-	g_debug( "%s: window=%p (%s), user_data=%p",
-			thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ), ( void * ) user_data );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
 
-	if( !view->private->dispose_has_run ){
+	if( !items_view->private->dispose_has_run ){
+		g_debug( "%s: window=%p (%s), user_data=%p",
+				thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ), ( void * ) user_data );
 
 		/* force the treeview to have the focus at start
 		 * and select the first row if it exists
 		 */
-		gtk_widget_grab_focus( GTK_WIDGET( view->private->tree_view ));
-		view->private->notify_allowed = TRUE;
-		select_row_at_path_by_string( view, "0" );
+		gtk_widget_grab_focus( GTK_WIDGET( items_view->private->tree_view ));
 	}
 }
 
@@ -756,11 +757,9 @@ on_button_press_event( GtkWidget *widget, GdkEventButton *event, BaseWindow *win
 {
 	gboolean stop = FALSE;
 
-	VIEW_WINDOW_VALUE( window, FALSE );
-
 	/* single click on right button */
 	if( event->type == GDK_BUTTON_PRESS && event->button == 3 ){
-		open_popup( window, view, event );
+		open_popup( window, event );
 		stop = TRUE;
 	}
 
@@ -778,9 +777,7 @@ on_focus_in( GtkWidget *widget, GdkEventFocus *event, BaseWindow *window )
 {
 	gboolean stop = FALSE;
 
-	VIEW_WINDOW_VALUE( window, FALSE );
-
-	g_signal_emit_by_name( window, TREE_SIGNAL_FOCUS_IN, view );
+	g_signal_emit_by_name( window, TREE_SIGNAL_FOCUS_IN );
 
 	return( stop );
 }
@@ -790,9 +787,7 @@ on_focus_out( GtkWidget *widget, GdkEventFocus *event, BaseWindow *window )
 {
 	gboolean stop = FALSE;
 
-	VIEW_WINDOW_VALUE( window, FALSE );
-
-	g_signal_emit_by_name( window, TREE_SIGNAL_FOCUS_OUT, view );
+	g_signal_emit_by_name( window, TREE_SIGNAL_FOCUS_OUT );
 
 	return( stop );
 }
@@ -801,21 +796,23 @@ static gboolean
 on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window )
 {
 	gboolean stop = FALSE;
+	NactTreeView *items_view;
 
-	VIEW_WINDOW_VALUE( window, FALSE );
+	g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), FALSE );
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
 
-	if( !view->private->dispose_has_run ){
+	if( !items_view->private->dispose_has_run ){
 
 		if( event->keyval == NACT_KEY_Return || event->keyval == NACT_KEY_KP_Enter ){
-			toggle_collapse( view );
+			toggle_collapse( items_view );
 			stop = TRUE;
 		}
 		if( event->keyval == NACT_KEY_Right ){
-			navigate_to_child( view );
+			navigate_to_child( items_view );
 			stop = TRUE;
 		}
 		if( event->keyval == NACT_KEY_Left ){
-			navigate_to_parent( view );
+			navigate_to_parent( items_view );
 			stop = TRUE;
 		}
 	}
@@ -830,17 +827,18 @@ static void
 on_treeview_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
 {
 	static const gchar *thisfn = "nact_tree_view_on_treeview_selection_changed";
+	NactTreeView *items_view;
 	GList *selected_items;
 
-	VIEW_WINDOW_VOID( window );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
 
-	g_debug( "%s: selection=%p, window=%p", thisfn, ( void * ) selection, ( void * ) window );
+	if( !items_view->private->dispose_has_run ){
+		if( items_view->private->notify_allowed ){
+			g_debug( "%s: selection=%p, window=%p", thisfn, ( void * ) selection, ( void * ) window );
 
-	if( !view->private->dispose_has_run ){
-
-		if( view->private->notify_allowed ){
-			selected_items = get_selected_items( view );
-			g_signal_emit_by_name( window, TREE_SIGNAL_SELECTION_CHANGED, view, selected_items );
+			selected_items = get_selected_items( items_view );
+			g_signal_emit_by_name( window, TREE_SIGNAL_SELECTION_CHANGED, selected_items );
 		}
 	}
 }
@@ -849,12 +847,11 @@ 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, NactTreeView *view, NAObject *edited )
+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, view=%p, edited=%p",
-			thisfn, ( void * ) window, ( void * ) view, ( void * ) edited );
+	g_debug( "%s: window=%p, edited=%p", thisfn, ( void * ) window, ( void * ) edited );
 
 	if( edited ){
 		na_object_unref( edited );
@@ -865,12 +862,12 @@ on_content_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, NAOb
  * cleanup handler for our TREE_SIGNAL_SELECTION_CHANGED signal
  */
 static void
-on_selection_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, GList *selected_items )
+on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items )
 {
 	static const gchar *thisfn = "nact_tree_view_on_selection_changed_cleanup_handler";
 
-	g_debug( "%s: window=%p, view=%p, selected_items=%p (count=%u)",
-			thisfn, ( void * ) window, ( void * ) view,
+	g_debug( "%s: window=%p, selected_items=%p (count=%u)",
+			thisfn, ( void * ) window,
 			( void * ) selected_items, g_list_length( selected_items ));
 
 	na_object_free_items( selected_items );
@@ -891,7 +888,6 @@ nact_tree_view_fill( NactTreeView *view, GList *items )
 {
 	static const gchar *thisfn = "nact_tree_view_fill";
 	NactTreeModel *model;
-	gboolean prev;
 	gint nb_menus, nb_actions, nb_profiles;
 
 	g_return_if_fail( NACT_IS_TREE_VIEW( view ));
@@ -901,24 +897,45 @@ nact_tree_view_fill( NactTreeView *view, GList *items )
 				thisfn, ( void * ) view, ( void * ) items, g_list_length( items ));
 
 		clear_selection( view );
-		prev = view->private->notify_allowed;
 		view->private->notify_allowed = FALSE;
 		model = NACT_TREE_MODEL( gtk_tree_view_get_model( view->private->tree_view ));
 		nact_tree_model_fill( model, items );
-		view->private->notify_allowed = prev;
 
-		if( view->private->notify_allowed ){
-			g_signal_emit_by_name( view->private->window, TREE_SIGNAL_CONTENT_CHANGED, view, NULL );
-			na_object_count_items( items, &nb_menus, &nb_actions, &nb_profiles );
-			g_signal_emit_by_name( view->private->window, TREE_SIGNAL_COUNT_CHANGED, view, TRUE, nb_menus, nb_actions, nb_profiles );
-			g_signal_emit_by_name( view->private->window, TREE_SIGNAL_MODIFIED_COUNT_CHANGED, view, 0 );
-		}
+		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 );
 
 		select_row_at_path_by_string( view, "0" );
 	}
 }
 
 /**
+ * nact_tree_view_are_notify_allowed:
+ * @view: this #NactTreeView instance.
+ *
+ * Returns: %TRUE if notifications are allowed, %FALSE else.
+ */
+gboolean
+nact_tree_view_are_notify_allowed( const NactTreeView *view )
+{
+	gboolean are_allowed;
+
+	g_return_val_if_fail( NACT_IS_TREE_VIEW( view ), FALSE );
+
+	are_allowed = FALSE;
+
+	if( !view->private->dispose_has_run ){
+
+		are_allowed = view->private->notify_allowed;
+	}
+
+	return( are_allowed );
+}
+
+/**
  * nact_tree_view_collapse_all:
  * @view: this #NactTreeView instance.
  *
@@ -1009,7 +1026,8 @@ nact_tree_view_get_items( const NactTreeView *view )
 
 /**
  * nact_tree_view_select_row_at_path:
- *
+ * @view: this #NactTreeView object.
+ * @path: the #GtkTreePath to be selected.
  *
  * Select the row at the required path, or the immediate previous, or
  * the next following, or eventually the immediate parent.
@@ -1064,7 +1082,7 @@ nact_tree_view_select_row_at_path( NactTreeView *view, GtkTreePath *path )
 
 		if( !something ){
 			if( view->private->notify_allowed ){
-				g_signal_emit_by_name( view->private->window, TREE_SIGNAL_SELECTION_CHANGED, view, NULL );
+				g_signal_emit_by_name( view->private->window, TREE_SIGNAL_SELECTION_CHANGED, NULL );
 			}
 		}
 	}
@@ -1301,18 +1319,29 @@ navigate_to_parent( NactTreeView *view )
 }
 
 static void
-open_popup( BaseWindow *window, NactTreeView *view, GdkEventButton *event )
+open_popup( BaseWindow *window, GdkEventButton *event )
 {
+	NactTreeView *items_view;
 	GtkTreePath *path;
 
-	if( gtk_tree_view_get_path_at_pos( view->private->tree_view, event->x, event->y, &path, NULL, NULL, NULL )){
-		nact_tree_view_select_row_at_path( view, path );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+
+	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 );
 		gtk_tree_path_free( path );
 	}
 
-	g_signal_emit_by_name( window, TREE_SIGNAL_CONTEXT_MENU, view, event );
+	g_signal_emit_by_name( window, TREE_SIGNAL_CONTEXT_MENU, event );
 }
 
+/*
+ * nact_tree_view_select_row_at_path_by_string:
+ * @view: this #NactTreeView object.
+ * @path: the #GtkTreePath to be selected.
+ *
+ * cf. nact_tree_view_select_row_at_path().
+ */
 static void
 select_row_at_path_by_string( NactTreeView *view, const gchar *path_str )
 {
diff --git a/src/nact/nact-tree-view.h b/src/nact/nact-tree-view.h
index 4c51e03..1ab604d 100644
--- a/src/nact/nact-tree-view.h
+++ b/src/nact/nact-tree-view.h
@@ -75,13 +75,15 @@ typedef struct {
  * Properties defined by the NactTreeView class.
  * They should be provided at object instantiation time.
  *
- * @TREE_PROP_WINDOW:      the BaseWindow parent.
- * @TREE_PROP_WIDGET_NAME: the widget name.
- * @TREE_PROP_MODE:        management mode.
+ * @TREE_PROP_WINDOW:         the BaseWindow parent.
+ * @TREE_PROP_WIDGET_NAME:    the widget name.
+ * @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"
 
 /**
  * Signals emitted by the NactTreeView instance.
@@ -108,10 +110,12 @@ NactTreeView *nact_tree_view_new( BaseWindow *window, const gchar *treeview_name
 
 void          nact_tree_view_fill     ( NactTreeView *view, GList *items );
 
-void          nact_tree_view_collapse_all  ( const NactTreeView *view );
-void          nact_tree_view_expand_all    ( const NactTreeView *view );
-NAObjectItem *nact_tree_view_get_item_by_id( const NactTreeView *view, const gchar *id );
-GList        *nact_tree_view_get_items     ( const NactTreeView *view );
+gboolean      nact_tree_view_are_notify_allowed( const NactTreeView *view );
+
+void          nact_tree_view_collapse_all      ( const NactTreeView *view );
+void          nact_tree_view_expand_all        ( const NactTreeView *view );
+NAObjectItem *nact_tree_view_get_item_by_id    ( const NactTreeView *view, const gchar *id );
+GList        *nact_tree_view_get_items         ( const NactTreeView *view );
 
 void          nact_tree_view_select_row_at_path( NactTreeView *view, GtkTreePath *path );
 



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