[nautilus-actions] Most of refactoring done



commit cd7bd25238cc0fd4a7e647067c7174f5114dfe52
Author: Pierre Wieser <pwieser trychlos org>
Date:   Fri Feb 11 01:17:18 2011 +0100

    Most of refactoring done
    
    - Old classes (NactWindow) and interfaces (NactIActionsList) are removed
    - Signals have yet to be rationalized.

 src/core/na-object-action.c        |    2 -
 src/core/na-object.c               |   18 +-
 src/core/na-settings.c             |   29 -
 src/nact/Makefile.am               |    2 -
 src/nact/base-window.c             |   11 +-
 src/nact/nact-iaction-tab.c        |   54 +-
 src/nact/nact-iactions-list-bis.c  | 1131 -------------------------------
 src/nact/nact-iactions-list-priv.c |  110 ---
 src/nact/nact-iactions-list-priv.h |   75 --
 src/nact/nact-iactions-list.c      | 1308 ------------------------------------
 src/nact/nact-iactions-list.h      |  148 ----
 src/nact/nact-ibasenames-tab.c     |    2 +-
 src/nact/nact-icommand-tab.c       |   10 +-
 src/nact/nact-ienvironment-tab.c   |   18 +-
 src/nact/nact-iexecution-tab.c     |    8 +-
 src/nact/nact-iproperties-tab.c    |   22 +-
 src/nact/nact-main-tab.h           |    1 -
 src/nact/nact-main-window.c        |  413 ++++--------
 src/nact/nact-main-window.h        |   79 ++-
 src/nact/nact-marshal.def          |    5 +-
 src/nact/nact-match-list.c         |   10 +-
 src/nact/nact-menubar-file.c       |  109 ++--
 src/nact/nact-menubar-maintainer.c |    8 +-
 src/nact/nact-menubar.c            |   45 --
 src/nact/nact-menubar.h            |    3 +-
 src/nact/nact-tree-ieditable.c     |  173 ++++-
 src/nact/nact-tree-ieditable.h     |   25 +-
 src/nact/nact-tree-model.c         |  228 ++++---
 src/nact/nact-tree-model.h         |   21 -
 src/nact/nact-tree-view.c          |   81 +--
 src/nact/nact-tree-view.h          |   12 +-
 src/nact/nact-window.c             |  312 ---------
 src/nact/nact-window.h             |   85 ---
 33 files changed, 677 insertions(+), 3881 deletions(-)
---
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 3aa54fa..3a2fac0 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -232,8 +232,6 @@ instance_dispose( GObject *object )
 	if( !self->private->dispose_has_run ){
 		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
 
-		na_object_dump( object );
-
 		self->private->dispose_has_run = TRUE;
 
 		/* chain up to the parent class */
diff --git a/src/core/na-object.c b/src/core/na-object.c
index 91a4f7e..3ba8197 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -661,20 +661,22 @@ na_object_object_ref( NAObject *object )
  * Recursively unref the @object and all its children, decrementing their
  * reference_count by 1.
  *
+ * Note that we may want to free a copy+ref of a list of items whichy have
+ * had already disposed (which is probably a bug somewhere). So first test
+ * is the object is still alive.
+ *
  * Since: 2.30
  */
 void
 na_object_object_unref( NAObject *object )
 {
-	g_return_if_fail( NA_IS_OBJECT( object ));
-
-	if( !object->private->dispose_has_run ){
-
-		if( NA_IS_OBJECT_ITEM( object )){
-			g_list_foreach( na_object_get_items( object ), ( GFunc ) na_object_object_unref, NULL );
+	if( NA_IS_OBJECT( object )){
+		if( !object->private->dispose_has_run ){
+			if( NA_IS_OBJECT_ITEM( object )){
+				g_list_foreach( na_object_get_items( object ), ( GFunc ) na_object_object_unref, NULL );
+			}
+			g_object_unref( object );
 		}
-
-		g_object_unref( object );
 	}
 }
 
diff --git a/src/core/na-settings.c b/src/core/na-settings.c
index 23deb1f..de70ed7 100644
--- a/src/core/na-settings.c
+++ b/src/core/na-settings.c
@@ -429,35 +429,6 @@ na_settings_register_key_callback( NASettings *settings, const gchar *key, GCall
 	}
 }
 
-#if 0
-/**
- * na_settings_register_global_callback:
- * @settings: this #NASettings instance.
- * @callback: the function to be called when the value of the key changes.
- * @user_data: data to be passed to the @callback function.
- *
- * Registers a new consumer of the monitoring of the configuration files.
- *
- * Since: 3.1.0
- */
-void
-na_settings_register_global_callback( NASettings *settings, GCallback callback, gpointer user_data )
-{
-	g_return_if_fail( NA_IS_SETTINGS( settings ));
-
-	if( !settings->private->dispose_has_run ){
-
-		Consumer *consumer = g_new0( Consumer, 1 );
-
-		consumer->key = NULL;
-		consumer->callback = callback;
-		consumer->user_data = user_data;
-		settings->private->consumers = g_list_prepend( settings->private->consumers, consumer );
-	}
-
-}
-#endif
-
 /**
  * na_settings_get_boolean:
  * @settings: this #NASettings instance.
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index 5c01e36..fccc4c5 100644
--- a/src/nact/Makefile.am
+++ b/src/nact/Makefile.am
@@ -145,8 +145,6 @@ nautilus_actions_config_tool_SOURCES = \
 	nact-tree-model-dnd.c								\
 	nact-tree-view.c									\
 	nact-tree-view.h									\
-	nact-window.c										\
-	nact-window.h										\
 	$(BUILT_SOURCES)									\
 	$(NULL)
 
diff --git a/src/nact/base-window.c b/src/nact/base-window.c
index 5a9242c..6296bbf 100644
--- a/src/nact/base-window.c
+++ b/src/nact/base-window.c
@@ -458,13 +458,16 @@ instance_dispose( GObject *window )
 		base_gtk_utils_save_window_position( self, self->private->wsp_name );
 
 		/* signals must be deconnected before quitting main loop
+		 * (if objects are still alive)
 		 */
 		for( is = self->private->signals ; is ; is = is->next ){
 			RecordedSignal *str = ( RecordedSignal * ) is->data;
-			if( g_signal_handler_is_connected( str->instance, str->handler_id )){
-				g_signal_handler_disconnect( str->instance, str->handler_id );
-				if( st_debug_signal_connect ){
-					g_debug( "%s: disconnecting signal handler %p:%lu", thisfn, str->instance, str->handler_id );
+			if( G_IS_OBJECT( str->instance )){
+				if( g_signal_handler_is_connected( str->instance, str->handler_id )){
+					g_signal_handler_disconnect( str->instance, str->handler_id );
+					if( st_debug_signal_connect ){
+						g_debug( "%s: disconnecting signal handler %p:%lu", thisfn, str->instance, str->handler_id );
+					}
 				}
 			}
 			g_free( str );
diff --git a/src/nact/nact-iaction-tab.c b/src/nact/nact-iaction-tab.c
index bc04a15..f80ebcc 100644
--- a/src/nact/nact-iaction-tab.c
+++ b/src/nact/nact-iaction-tab.c
@@ -221,7 +221,7 @@ nact_iaction_tab_runtime_init_toplevel( NactIActionTab *instance )
 				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		base_window_signal_connect( BASE_WINDOW( instance ),
-				G_OBJECT( instance ), TREE_SIGNAL_CONTENT_CHANGED, G_CALLBACK( on_tree_view_content_changed ));
+				G_OBJECT( instance ), MAIN_SIGNAL_ITEM_UPDATED, G_CALLBACK( on_tree_view_content_changed ));
 
 		button = base_window_get_widget( BASE_WINDOW( instance ), "ActionTargetSelectionButton" );
 		base_window_signal_connect(
@@ -504,7 +504,7 @@ on_target_selection_toggled( GtkToggleButton *button, NactIActionTab *instance )
 
 			if( editable ){
 				na_object_set_target_selection( item, is_target );
-				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, 0 );
 
 			} else {
 				g_signal_handlers_block_by_func(( gpointer ) button, on_target_selection_toggled, instance );
@@ -541,7 +541,7 @@ on_target_location_toggled( GtkToggleButton *button, NactIActionTab *instance )
 
 			if( editable ){
 				na_object_set_target_location( item, is_target );
-				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, 0 );
 
 			} else {
 				g_signal_handlers_block_by_func(( gpointer ) button, on_target_location_toggled, instance );
@@ -610,7 +610,7 @@ on_label_changed( GtkEntry *entry, NactIActionTab *instance )
 				setup_toolbar_label( instance, item, label );
 			}
 
-			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, TRUE );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, MAIN_DATA_LABEL );
 		}
 	}
 }
@@ -661,7 +661,7 @@ on_target_toolbar_toggled( GtkToggleButton *button, NactIActionTab *instance )
 
 			if( editable ){
 				na_object_set_target_toolbar( item, is_target );
-				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, 0 );
 				toolbar_same_label_set_sensitive( instance, NA_OBJECT_ITEM( item ));
 				toolbar_label_set_sensitive( instance, NA_OBJECT_ITEM( item ));
 
@@ -710,7 +710,7 @@ on_toolbar_same_label_toggled( GtkToggleButton *button, NactIActionTab *instance
 					g_free( 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, 0 );
 				toolbar_same_label_set_sensitive( instance, NA_OBJECT_ITEM( item ));
 				toolbar_label_set_sensitive( instance, NA_OBJECT_ITEM( item ));
 
@@ -771,7 +771,7 @@ on_toolbar_label_changed( GtkEntry *entry, NactIActionTab *instance )
 			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, 0 );
 		}
 	}
 }
@@ -805,7 +805,7 @@ on_tooltip_changed( GtkEntry *entry, NactIActionTab *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_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, 0 );
 		}
 	}
 }
@@ -846,28 +846,32 @@ on_icon_changed( GtkEntry *icon_entry, NactIActionTab *instance )
 	static const gchar *thisfn = "nact_iaction_tab_on_icon_changed";
 	GtkImage *image;
 	NAObjectItem *item;
-	const gchar *icon_name;
+	gchar *icon_name;
 
-	if( !st_on_selection_change ){
-		g_debug( "%s: entry=%p, instance=%p", thisfn, ( void * ) icon_entry, ( void * ) instance );
+	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 );
+	if( item ){
+		if( !st_on_selection_change ){
+			icon_name = g_strdup( 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 );
-		}
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, item, MAIN_DATA_ICON );
 
-		/* 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 );
+		} else {
+			icon_name = na_object_get_icon( item );
+		}
 	}
+
+	/* 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 );
+	g_free( icon_name );
 }
diff --git a/src/nact/nact-ibasenames-tab.c b/src/nact/nact-ibasenames-tab.c
index da198ba..67eaef2 100644
--- a/src/nact/nact-ibasenames-tab.c
+++ b/src/nact/nact-ibasenames-tab.c
@@ -281,7 +281,7 @@ on_matchcase_toggled( GtkToggleButton *button, BaseWindow *window )
 
 			if( editable ){
 				na_object_set_matchcase( context, matchcase );
-				g_signal_emit_by_name( G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+				g_signal_emit_by_name( G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 
 			} else {
 				g_signal_handlers_block_by_func(( gpointer ) button, on_matchcase_toggled, window );
diff --git a/src/nact/nact-icommand-tab.c b/src/nact/nact-icommand-tab.c
index c9c8ba4..4672ab4 100644
--- a/src/nact/nact-icommand-tab.c
+++ b/src/nact/nact-icommand-tab.c
@@ -265,7 +265,7 @@ nact_icommand_tab_runtime_init_toplevel( NactICommandTab *instance )
 				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		base_window_signal_connect( BASE_WINDOW( instance ),
-				G_OBJECT( instance ), TREE_SIGNAL_CONTENT_CHANGED, G_CALLBACK( on_tree_view_content_changed ));
+				G_OBJECT( instance ), MAIN_SIGNAL_ITEM_UPDATED, G_CALLBACK( on_tree_view_content_changed ));
 
 		/* allocate a static fake NATokens object which will be user to build
 		 * the example label - this object will be unreffed on dispose
@@ -506,7 +506,7 @@ on_label_changed( GtkEntry *entry, NactICommandTab *instance )
 		if( profile ){
 			label = gtk_entry_get_text( entry );
 			na_object_set_label( profile, label );
-			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, TRUE );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, MAIN_DATA_LABEL );
 		}
 	}
 }
@@ -543,7 +543,7 @@ on_parameters_changed( GtkEntry *entry, NactICommandTab *instance )
 
 		if( profile ){
 			na_object_set_parameters( profile, gtk_entry_get_text( entry ));
-			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, FALSE );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
 			update_example_label( instance, profile );
 		}
 	}
@@ -571,7 +571,7 @@ on_path_changed( GtkEntry *entry, NactICommandTab *instance )
 
 		if( profile ){
 			na_object_set_path( profile, gtk_entry_get_text( entry ));
-			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, FALSE );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
 			update_example_label( instance, profile );
 		}
 	}
@@ -609,7 +609,7 @@ on_wdir_changed( GtkEntry *entry, NactICommandTab *instance )
 
 		if( profile ){
 			na_object_set_working_dir( profile, gtk_entry_get_text( entry ));
-			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, FALSE );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
 		}
 	}
 }
diff --git a/src/nact/nact-ienvironment-tab.c b/src/nact/nact-ienvironment-tab.c
index 49dd865..5020ebf 100644
--- a/src/nact/nact-ienvironment-tab.c
+++ b/src/nact/nact-ienvironment-tab.c
@@ -496,7 +496,7 @@ on_selection_count_changed( NactIEnvironmentTab *instance )
 			na_object_set_selection_count( context, selcount );
 			g_free( selcount );
 
-			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 		}
 	}
 }
@@ -542,7 +542,7 @@ on_show_always_toggled( GtkToggleButton *toggle_button, NactIEnvironmentTab *ins
 				raz_desktop_listview( instance );
 				na_object_set_only_show_in( context, NULL );
 				na_object_set_not_show_in( context, NULL );
-				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 			}
 
 		} else {
@@ -583,7 +583,7 @@ on_only_show_toggled( GtkToggleButton *toggle_button, NactIEnvironmentTab *insta
 
 			} else {
 				na_object_set_only_show_in( context, NULL );
-				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 			}
 
 		} else {
@@ -624,7 +624,7 @@ on_do_not_show_toggled( GtkToggleButton *toggle_button, NactIEnvironmentTab *ins
 
 			} else {
 				na_object_set_not_show_in( context, NULL );
-				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 			}
 
 		} else {
@@ -672,7 +672,7 @@ on_desktop_toggled( GtkCellRendererToggle *renderer, gchar *path, BaseWindow *wi
 					na_object_set_not_desktop( context, desktop, !state );
 				}
 
-				g_signal_emit_by_name( G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+				g_signal_emit_by_name( G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 
 				g_free( desktop );
 
@@ -696,7 +696,7 @@ on_try_exec_changed( GtkEntry *entry, NactIEnvironmentTab *instance )
 	if( context ){
 		text = gtk_entry_get_text( entry );
 		na_object_set_try_exec( context, text );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 	}
 }
 
@@ -724,7 +724,7 @@ on_show_if_registered_changed( GtkEntry *entry, NactIEnvironmentTab *instance )
 	if( context ){
 		text = gtk_entry_get_text( entry );
 		na_object_set_show_if_registered( context, text );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 	}
 }
 
@@ -739,7 +739,7 @@ on_show_if_true_changed( GtkEntry *entry, NactIEnvironmentTab *instance )
 	if( context ){
 		text = gtk_entry_get_text( entry );
 		na_object_set_show_if_true( context, text );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 	}
 }
 
@@ -754,7 +754,7 @@ on_show_if_running_changed( GtkEntry *entry, NactIEnvironmentTab *instance )
 	if( context ){
 		text = gtk_entry_get_text( entry );
 		na_object_set_show_if_running( context, text );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 	}
 }
 
diff --git a/src/nact/nact-iexecution-tab.c b/src/nact/nact-iexecution-tab.c
index 4c7ee87..7f6a7f0 100644
--- a/src/nact/nact-iexecution-tab.c
+++ b/src/nact/nact-iexecution-tab.c
@@ -361,7 +361,7 @@ execution_mode_toggle( NactIExecutionTab *instance, GtkToggleButton *toggle_butt
 				widget = base_window_get_widget( BASE_WINDOW( instance ), "StartupWMClassEntry" );
 				gtk_widget_set_sensitive( widget, is_normal );
 
-				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, FALSE );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
 			}
 
 		} else {
@@ -388,7 +388,7 @@ on_startup_notify_toggled( GtkToggleButton *toggle_button, NactIExecutionTab *in
 
 		if( editable ){
 			na_object_set_startup_notify( profile, active );
-			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, FALSE );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
 
 		} else {
 			g_signal_handlers_block_by_func(( gpointer ) toggle_button, on_startup_notify_toggled, instance );
@@ -412,7 +412,7 @@ on_startup_class_changed( GtkEntry *entry, NactIExecutionTab *instance )
 	if( profile ){
 		text = gtk_entry_get_text( entry );
 		na_object_set_startup_class( profile, text );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, FALSE );
+		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
 	}
 }
 
@@ -430,6 +430,6 @@ on_execute_as_changed( GtkEntry *entry, NactIExecutionTab *instance )
 	if( profile ){
 		text = gtk_entry_get_text( entry );
 		na_object_set_execute_as( profile, text );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, FALSE );
+		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
 	}
 }
diff --git a/src/nact/nact-iproperties-tab.c b/src/nact/nact-iproperties-tab.c
index a411109..52cfdfb 100644
--- a/src/nact/nact-iproperties-tab.c
+++ b/src/nact/nact-iproperties-tab.c
@@ -62,7 +62,7 @@ static void       interface_base_init( NactIPropertiesTabInterface *klass );
 static void       interface_base_finalize( NactIPropertiesTabInterface *klass );
 
 static void       on_main_selection_changed( NactIPropertiesTab *instance, GList *selected_items, gpointer user_data );
-static void       on_tab_updatable_provider_changed( NactIPropertiesTab *instance, NAObjectItem *item );
+static void       on_main_item_updated( NactIPropertiesTab *instance, NAObjectItem *item, guint data, gpointer user_data );
 
 static GtkButton *get_enabled_button( NactIPropertiesTab *instance );
 static void       on_enabled_toggled( GtkToggleButton *button, NactIPropertiesTab *instance );
@@ -168,7 +168,7 @@ nact_iproperties_tab_runtime_init_toplevel( NactIPropertiesTab *instance )
 				G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
 
 		base_window_signal_connect( BASE_WINDOW( instance ),
-				G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED, G_CALLBACK( on_tab_updatable_provider_changed ));
+				G_OBJECT( instance ), MAIN_SIGNAL_ITEM_UPDATED, G_CALLBACK( on_main_item_updated ));
 
 		enabled_button = get_enabled_button( instance );
 		base_window_signal_connect( BASE_WINDOW( instance ),
@@ -313,14 +313,16 @@ on_main_selection_changed( NactIPropertiesTab *instance, GList *selected_items,
 }
 
 static void
-on_tab_updatable_provider_changed( NactIPropertiesTab *instance, NAObjectItem *item )
+on_main_item_updated( NactIPropertiesTab *instance, NAObjectItem *item, guint data, gpointer user_data )
 {
-	static const gchar *thisfn = "nact_iproperties_tab_on_tab_updatable_provider_changed";
+	static const gchar *thisfn = "nact_iproperties_tab_on_main_item_updated";
 
 	if( st_initialized && !st_finalized ){
-		g_debug( "%s: instance=%p, item=%p", thisfn, ( void * ) instance, ( void * ) item );
-
-		display_provider_name( instance, item );
+		if( data & MAIN_DATA_PROVIDER ){
+			g_debug( "%s: instance=%p, item=%p, data=%u, user_data=%p",
+					thisfn, ( void * ) instance, ( void * ) item, data, ( void * ) user_data );
+			display_provider_name( instance, item );
+		}
 	}
 }
 
@@ -353,7 +355,7 @@ on_enabled_toggled( GtkToggleButton *button, NactIPropertiesTab *instance )
 
 			if( editable ){
 				na_object_set_enabled( item, enabled );
-				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, 0 );
 
 			} else {
 				g_signal_handlers_block_by_func(( gpointer ) button, on_enabled_toggled, instance );
@@ -460,7 +462,7 @@ on_description_changed( GtkTextBuffer *buffer, NactIPropertiesTab *instance )
 		gtk_text_buffer_get_end_iter( buffer, &end );
 		text = gtk_text_buffer_get_text( buffer, &start, &end, TRUE );
 		na_object_set_description( item, text );
-		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, 0 );
 	}
 }
 
@@ -475,7 +477,7 @@ on_shortcut_clicked( GtkButton *button, NactIPropertiesTab *instance )
 			NULL );
 
 	if( item ){
-		/*g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );*/
+		/*g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, 0 );*/
 	}
 }
 
diff --git a/src/nact/nact-main-tab.h b/src/nact/nact-main-tab.h
index 682ea65..dba0cf0 100644
--- a/src/nact/nact-main-tab.h
+++ b/src/nact/nact-main-tab.h
@@ -46,7 +46,6 @@
 /* signals
  */
 #define TAB_UPDATABLE_SIGNAL_ITEM_UPDATED				"nact-tab-updatable-item-updated"
-#define TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED			"nact-tab-updatable-provider-changed"
 
 /* notebook tabs
  */
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index 35cabb5..0dc87a8 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -36,6 +36,7 @@
 #include <stdlib.h>
 
 #include <api/na-object-api.h>
+#include <api/na-timeout.h>
 
 #include <core/na-iabout.h>
 #include <core/na-iprefs.h>
@@ -121,6 +122,10 @@ struct _NactMainWindowPrivate {
 	NactTreeView    *items_view;
 	gboolean         is_tree_modified;
 	NactClipboard   *clipboard;
+	NactMenubar     *menubar;
+
+	gulong           pivot_handler_id;
+	NATimeout        pivot_timeout;
 };
 
 /* properties set against the main window
@@ -141,9 +146,8 @@ enum {
 /* signals
  */
 enum {
-	PROVIDER_CHANGED,
-	ITEM_UPDATED,
-	ORDER_CHANGED,
+	MAIN_ITEM_UPDATED,
+	TAB_ITEM_UPDATED,
 	SELECTION_CHANGED,
 	LAST_SIGNAL
 };
@@ -152,56 +156,56 @@ static const gchar     *st_xmlui_filename         = PKGDATADIR "/nautilus-action
 static const gchar     *st_toplevel_name          = "MainWindow";
 static const gchar     *st_wsp_name               = NA_IPREFS_MAIN_WINDOW_WSP;
 
-static NactWindowClass *st_parent_class           = NULL;
+static gint             st_burst_timeout          = 2500;		/* burst timeout in msec */
+static BaseWindowClass *st_parent_class           = NULL;
 static gint             st_signals[ LAST_SIGNAL ] = { 0 };
 
-static GType    register_type( void );
-static void     class_init( NactMainWindowClass *klass );
-static void     iaction_tab_iface_init( NactIActionTabInterface *iface );
-static void     icommand_tab_iface_init( NactICommandTabInterface *iface );
-static void     ibasenames_tab_iface_init( NactIBasenamesTabInterface *iface );
-static void     imimetypes_tab_iface_init( NactIMimetypesTabInterface *iface );
-static void     ifolders_tab_iface_init( NactIFoldersTabInterface *iface );
-static void     ischemes_tab_iface_init( NactISchemesTabInterface *iface );
-static void     icapabilities_tab_iface_init( NactICapabilitiesTabInterface *iface );
-static void     ienvironment_tab_iface_init( NactIEnvironmentTabInterface *iface );
-static void     iexecution_tab_iface_init( NactIExecutionTabInterface *iface );
-static void     iproperties_tab_iface_init( NactIPropertiesTabInterface *iface );
-static void     iabout_iface_init( NAIAboutInterface *iface );
-static void     instance_init( GTypeInstance *instance, gpointer klass );
-static void     instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
-static void     instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
-static void     instance_constructed( GObject *application );
-static void     instance_dispose( GObject *application );
-static void     instance_finalize( GObject *application );
-
-static void     on_base_initialize_gtk_toplevel( NactMainWindow *window, GtkWindow *toplevel, gpointer user_data );
-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_status_changed( NactMainWindow *window, gboolean is_modified, gpointer user_data );
-static void     on_tree_view_selection_changed( NactMainWindow *window, GList *selected_items, gpointer user_data );
-static void     on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items );
-static void     raz_selection_properties( NactMainWindow *window );
-static void     setup_current_selection( NactMainWindow *window, NAObjectId *selected_row );
-static void     setup_dialog_title( NactMainWindow *window );
-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     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 );
-static gboolean warn_modified( NactMainWindow *window );
-
-/* *** */
-#if 0
-static gboolean actually_delete_item( NactMainWindow *window, NAObject *item, NAUpdater *updater, GList **not_deleted, GSList **messages );
-static void     on_main_window_level_zero_order_changed( NactMainWindow *window, gpointer user_data );
-#endif
-static void     on_tab_updatable_item_updated( NactMainWindow *window, gpointer user_data, gboolean force_display );
-static void     on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpointer new_value, gboolean mandatory, NactMainWindow *window );
+static GType      register_type( void );
+static void       class_init( NactMainWindowClass *klass );
+static void       iaction_tab_iface_init( NactIActionTabInterface *iface );
+static void       icommand_tab_iface_init( NactICommandTabInterface *iface );
+static void       ibasenames_tab_iface_init( NactIBasenamesTabInterface *iface );
+static void       imimetypes_tab_iface_init( NactIMimetypesTabInterface *iface );
+static void       ifolders_tab_iface_init( NactIFoldersTabInterface *iface );
+static void       ischemes_tab_iface_init( NactISchemesTabInterface *iface );
+static void       icapabilities_tab_iface_init( NactICapabilitiesTabInterface *iface );
+static void       ienvironment_tab_iface_init( NactIEnvironmentTabInterface *iface );
+static void       iexecution_tab_iface_init( NactIExecutionTabInterface *iface );
+static void       iproperties_tab_iface_init( NactIPropertiesTabInterface *iface );
+static void       iabout_iface_init( NAIAboutInterface *iface );
+static void       instance_init( GTypeInstance *instance, gpointer klass );
+static void       instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
+static void       instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
+static void       instance_constructed( GObject *application );
+static void       instance_dispose( GObject *application );
+static void       instance_finalize( GObject *application );
+
+static void       on_base_initialize_gtk_toplevel( NactMainWindow *window, GtkWindow *toplevel, gpointer user_data );
+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_block_items_changed_timeout( NactMainWindow *window );
+static void       on_tree_view_modified_status_changed( NactMainWindow *window, gboolean is_modified, gpointer user_data );
+static void       on_tree_view_selection_changed( NactMainWindow *window, GList *selected_items, gpointer user_data );
+static void       on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items );
+static void       on_tab_updatable_item_updated( NactMainWindow *window, NAIContext *context, guint data, gpointer user_data );
+static void       raz_selection_properties( NactMainWindow *window );
+static void       setup_current_selection( NactMainWindow *window, NAObjectId *selected_row );
+static void       setup_dialog_title( NactMainWindow *window );
+static void       setup_writability_status( NactMainWindow *window );
+
+/* items have changed */
+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       load_or_reload_items( NactMainWindow *window );
+
+/* application termination */
+static gboolean   base_is_willing_to_quit( const BaseWindow *window );
+static gboolean   on_delete_event( GtkWidget *toplevel, GdkEvent *event, NactMainWindow *window );
+static gboolean   warn_modified( NactMainWindow *window );
+
+/* NAIAbout interface */
 static gchar     *iabout_get_application_name( NAIAbout *instance );
 static GtkWindow *iabout_get_toplevel( NAIAbout *instance );
 
@@ -304,7 +308,7 @@ register_type( void )
 
 	g_debug( "%s", thisfn );
 
-	type = g_type_register_static( NACT_WINDOW_TYPE, "NactMainWindow", &info, 0 );
+	type = g_type_register_static( BASE_WINDOW_TYPE, "NactMainWindow", &info, 0 );
 
 	g_type_add_interface_static( type, NACT_IACTION_TAB_TYPE, &iaction_tab_iface_info );
 
@@ -390,24 +394,27 @@ class_init( NactMainWindowClass *klass )
 	base_class->is_willing_to_quit = base_is_willing_to_quit;
 
 	/**
-	 * nact-tab-updatable-provider-changed:
+	 * NactMainWindow::main-item-updated:
+	 *
+	 * This signal is emitted on the BaseWindow when the item has been modified
+	 * elsewhere that in a tab. The tabs should so update accordingly their
+	 * widgets.
 	 *
-	 * This signal is emitted at save time, when we are noticing that
-	 * the save operation has led to a modification of the I/O provider.
-	 * This signal may be caught by a tab in order to display the
-	 * new provider's name.
+	 * Args:
+	 * - an OR-ed list of the modified data, or 0 if not relevant.
 	 */
-	st_signals[ PROVIDER_CHANGED ] = g_signal_new(
-			TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED,
+	st_signals[ MAIN_ITEM_UPDATED ] = g_signal_new(
+			MAIN_SIGNAL_ITEM_UPDATED,
 			G_TYPE_OBJECT,
 			G_SIGNAL_RUN_LAST,
 			0,					/* no default handler */
 			NULL,
 			NULL,
-			g_cclosure_marshal_VOID__POINTER,
+			nact_cclosure_marshal_VOID__POINTER_UINT,
 			G_TYPE_NONE,
-			1,
-			G_TYPE_POINTER );
+			2,
+			G_TYPE_POINTER,
+			G_TYPE_UINT );
 
 	/**
 	 * nact-tab-updatable-item-updated:
@@ -415,22 +422,25 @@ class_init( NactMainWindowClass *klass )
 	 * This signal is emitted by the notebook tabs, when any property
 	 * of an item has been modified.
 	 *
+	 * Args:
+	 * - an OR-ed list of the modified data, or 0 if not relevant.
+	 *
 	 * This main window is rather the only consumer of this message,
 	 * does its tricks (title, etc.), and then reforward an item-updated
 	 * message to IActionsList.
 	 */
-	st_signals[ ITEM_UPDATED ] = g_signal_new(
+	st_signals[ TAB_ITEM_UPDATED ] = g_signal_new(
 			TAB_UPDATABLE_SIGNAL_ITEM_UPDATED,
 			G_TYPE_OBJECT,
 			G_SIGNAL_RUN_LAST,
 			0,					/* no default handler */
 			NULL,
 			NULL,
-			nact_cclosure_marshal_VOID__POINTER_BOOLEAN,
+			nact_cclosure_marshal_VOID__POINTER_UINT,
 			G_TYPE_NONE,
 			2,
 			G_TYPE_POINTER,
-			G_TYPE_BOOLEAN );
+			G_TYPE_UINT );
 
 	/**
 	 * NactMainWindow::main-selection-changed:
@@ -569,6 +579,13 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self->private = g_new0( NactMainWindowPrivate, 1 );
 
 	self->private->dispose_has_run = FALSE;
+
+	/* initialize timeout parameters when blocking 'pivot-items-changed' handler
+	 */
+	self->private->pivot_timeout.timeout = st_burst_timeout;
+	self->private->pivot_timeout.handler = ( NATimeoutFunc ) on_block_items_changed_timeout;
+	self->private->pivot_timeout.user_data = self;
+	self->private->pivot_timeout.source_id = 0;
 }
 
 static void
@@ -677,7 +694,7 @@ instance_constructed( GObject *window )
 		application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
 		self->private->updater = nact_application_get_updater( application );
 
-		base_window_signal_connect( BASE_WINDOW( window ),
+		self->private->pivot_handler_id = base_window_signal_connect( BASE_WINDOW( window ),
 				G_OBJECT( self->private->updater ), PIVOT_SIGNAL_ITEMS_CHANGED, G_CALLBACK( on_pivot_items_changed ));
 
 		base_window_signal_connect( BASE_WINDOW( window ),
@@ -693,11 +710,9 @@ instance_constructed( GObject *window )
 		base_window_signal_connect( BASE_WINDOW( window ),
 				G_OBJECT( window ), TREE_SIGNAL_MODIFIED_STATUS_CHANGED, G_CALLBACK( on_tree_view_modified_status_changed ));
 
-		/* create the menubar
-		 * it will create itself toolbar and statusbar
+		/* create the menubar and other convenience objects
 		 */
-		nact_menubar_new( BASE_WINDOW( window ));
-
+		self->private->menubar = nact_menubar_new( BASE_WINDOW( window ));
 		self->private->clipboard = nact_clipboard_new( BASE_WINDOW( window ));
 
 		/* chain up to the parent class */
@@ -727,6 +742,7 @@ instance_dispose( GObject *window )
 
 		g_object_unref( self->private->items_view );
 		g_object_unref( self->private->clipboard );
+		g_object_unref( self->private->menubar );
 
 		settings = na_pivot_get_settings( NA_PIVOT( self->private->updater ));
 
@@ -856,8 +872,6 @@ on_base_initialize_base_window( NactMainWindow *window, gpointer user_data )
 		nact_iexecution_tab_runtime_init_toplevel( NACT_IEXECUTION_TAB( window ));
 		nact_iproperties_tab_runtime_init_toplevel( NACT_IPROPERTIES_TAB( window ));
 
-		na_settings_register_key_callback( settings, NA_IPREFS_ITEMS_LIST_ORDER_MODE, G_CALLBACK( on_settings_order_mode_changed ), window );
-
 		/* terminate the application by clicking the top right [X] button
 		 */
 		base_window_signal_connect( BASE_WINDOW( window ),
@@ -971,6 +985,38 @@ nact_main_window_reload( NactMainWindow *window )
 	}
 }
 
+/**
+ * nact_main_window_block_reload:
+ * @window: this #NactMainWindow instance.
+ *
+ * Temporarily blocks the handling of pivot-items-changed signal.
+ */
+void
+nact_main_window_block_reload( NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_window_block_reload";
+
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	if( !window->private->dispose_has_run ){
+
+		g_debug( "%s: blocking %s signal", thisfn, PIVOT_SIGNAL_ITEMS_CHANGED );
+		g_signal_handler_block( window->private->updater, window->private->pivot_handler_id );
+		na_timeout_event( &window->private->pivot_timeout );
+	}
+}
+
+static void
+on_block_items_changed_timeout( NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_window_on_block_items_changed_timeout";
+
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	g_debug( "%s: unblocking %s signal", thisfn, PIVOT_SIGNAL_ITEMS_CHANGED );
+	g_signal_handler_unblock( window->private->updater, window->private->pivot_handler_id );
+}
+
 /*
  * the modification status of the items view has changed
  */
@@ -1036,6 +1082,24 @@ on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items
 }
 
 static void
+on_tab_updatable_item_updated( NactMainWindow *window, NAIContext *context, guint data, gpointer user_data )
+{
+	static const gchar *thisfn = "nact_main_window_on_tab_updatable_item_updated";
+
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	if( !window->private->dispose_has_run ){
+		g_debug( "%s: window=%p, context=%p (%s), data=%u, user_data=%p",
+				thisfn, ( void * ) window, ( void * ) context, G_OBJECT_TYPE_NAME( context ),
+				data, ( void * ) user_data );
+
+		if( context ){
+			na_object_check_status( context );
+		}
+	}
+}
+
+static void
 raz_selection_properties( NactMainWindow *window )
 {
 	window->private->current_item = NULL;
@@ -1093,6 +1157,7 @@ setup_dialog_title( NactMainWindow *window )
 	gchar *title;
 	gchar *label;
 	gchar *tmp;
+	gboolean is_modified;
 
 	g_debug( "%s: window=%p", thisfn, ( void * ) window );
 
@@ -1101,18 +1166,13 @@ setup_dialog_title( NactMainWindow *window )
 
 	if( window->private->current_item ){
 		label = na_object_get_label( window->private->current_item );
-		tmp = g_strdup_printf( "%s - %s", label, title );
+		is_modified = na_object_is_modified( window->private->current_item );
+		tmp = g_strdup_printf( "%s%s - %s", is_modified ? "*" : "", label, title );
 		g_free( label );
 		g_free( title );
 		title = tmp;
 	}
 
-	if( window->private->is_tree_modified ){
-		tmp = g_strdup_printf( "*%s", title );
-		g_free( title );
-		title = tmp;
-	}
-
 	toplevel = base_window_get_gtk_toplevel( BASE_WINDOW( window ));
 	gtk_window_set_title( toplevel, title );
 	g_free( title );
@@ -1142,7 +1202,8 @@ on_pivot_items_changed( NAUpdater *updater, NactMainWindow *window )
 
 	if( !window->private->dispose_has_run ){
 		g_debug( "%s: updater=%p (%s), window=%p (%s)", thisfn,
-				( void * ) updater, G_OBJECT_TYPE_NAME( updater ), ( void * ) window, G_OBJECT_TYPE_NAME( window ));
+				( void * ) updater, G_OBJECT_TYPE_NAME( updater ),
+				( void * ) window, G_OBJECT_TYPE_NAME( window ));
 
 		reload_ok = confirm_for_giveup_from_pivot( window );
 
@@ -1329,198 +1390,6 @@ warn_modified( NactMainWindow *window )
 	return( confirm );
 }
 
-#if 0
-/**
- * nact_main_window_move_to_deleted:
- * @window: this #NactMainWindow instance.
- * @items: list of deleted objects.
- *
- * Adds the given list to the deleted one.
- *
- * Note that we move the ref from @items list to our own deleted list.
- * So that the caller should not try to na_object_free_items_list() the
- * provided list.
- */
-void
-nact_main_window_move_to_deleted( NactMainWindow *window, GList *items )
-{
-	static const gchar *thisfn = "nact_main_window_move_to_deleted";
-	GList *it;
-
-	g_debug( "%s: window=%p, items=%p (%d items)",
-			thisfn, ( void * ) window, ( void * ) items, g_list_length( items ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	if( !window->private->dispose_has_run ){
-
-		for( it = items ; it ; it = it->next ){
-			g_debug( "%s: %p (%s, ref_count=%d)", thisfn,
-					( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ), G_OBJECT( it->data )->ref_count );
-		}
-
-		window->private->deleted = g_list_concat( window->private->deleted, items );
-		g_debug( "%s: main_deleted has %d items", thisfn, g_list_length( window->private->deleted ));
-	}
-}
-
-/**
- * nact_main_window_remove_deleted:
- * @window: this #NactMainWindow instance.
- * @messages: a pointer to a #GSList of error messages.
- *
- * Removes the deleted items from the underlying I/O storage subsystem.
- *
- * Each item of <structfield>NactMainWindow::private::deleted</structfield>
- * #GList may actually itself be a tree (e.g. a #NAObjectMenu). The embedded
- * items will be recursivelly removed, starting from the root.
- *
- * Returns: %TRUE if all candidate items have been successfully deleted,
- * %FALSE else.
- *
- * @messages #GSList is only filled up in case of an error has occured.
- * If there is no error (nact_main_window_remove_deleted() returns %TRUE),
- * then the caller may safely assume that @messages is returned in the
- * same state that it has been provided.
- */
-gboolean
-nact_main_window_remove_deleted( NactMainWindow *window, GSList **messages )
-{
-	gboolean delete_ok = TRUE;
-	GList *it;
-	NAObject *item;
-	GList *not_deleted;
-
-	g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), FALSE );
-
-	if( !window->private->dispose_has_run ){
-
-		not_deleted = NULL;
-
-		for( it = window->private->deleted ; it ; it = it->next ){
-			item = NA_OBJECT( it->data );
-			delete_ok = actually_delete_item( window, item, window->private->updater, &not_deleted, messages );
-		}
-
-		window->private->deleted = na_object_free_items( window->private->deleted );
-
-		setup_dialog_title( window );
-
-#if 0
-		if( g_list_length( not_deleted )){
-			nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), not_deleted, NULL );
-			na_object_free_items( not_deleted );
-		}
-#endif
-	}
-
-	return( delete_ok );
-}
-
-/*
- * If the deleted item is a profile, then do nothing because the parent
- * action has been marked as modified when the profile has been deleted,
- * and thus updated in the storage subsystem as well as in the pivot
- */
-static gboolean
-actually_delete_item( NactMainWindow *window, NAObject *item, NAUpdater *updater, GList **not_deleted, GSList **messages )
-{
-	gboolean delete_ok = TRUE;
-	GList *items, *it;
-	NAObject *origin;
-	gchar *msg;
-
-	g_debug( "nact_main_window_actually_delete_item: item=%p (%s)",
-			( void * ) item, G_OBJECT_TYPE_NAME( item ));
-
-	if( NA_IS_OBJECT_ITEM( item )){
-		msg = NULL;
-		delete_ok = nact_window_delete_item( NACT_WINDOW( window ), NA_OBJECT_ITEM( item ), &msg );
-
-		if( !delete_ok ){
-			*messages = g_slist_append( *messages, msg );
-			*not_deleted = g_list_append( *not_deleted, na_object_ref( item ));
-			g_free( msg );
-
-		} else if( NA_IS_OBJECT_MENU( item )){
-			items = na_object_get_items( item );
-			for( it = items ; delete_ok && it ; it = it->next ){
-				delete_ok &= actually_delete_item( window, NA_OBJECT( it->data ), updater, not_deleted, messages );
-			}
-		}
-
-		if( delete_ok ){
-			origin = ( NAObject * ) na_object_get_origin( item );
-			if( origin ){
-				na_updater_remove_item( updater, origin );
-				g_object_unref( origin );
-			}
-		}
-	}
-
-	return( delete_ok );
-}
-
-static void
-on_main_window_level_zero_order_changed( NactMainWindow *window, gpointer user_data )
-{
-	g_debug( "nact_main_window_on_main_window_level_zero_order_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";
-
-	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 );
-		}
-	}
-}
-
-/*
- * NASettings callback for a change on NA_IPREFS_ITEMS_LIST_ORDER_MODE key
- */
-static void
-on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpointer new_value, gboolean mandatory, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_window_on_settings_order_mode_changed";
-	const gchar *order_mode_str;
-	guint order_mode;
-	GList *tree;
-
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	if( !window->private->dispose_has_run ){
-
-		order_mode_str = ( const gchar * ) new_value;
-		order_mode = na_iprefs_get_order_mode_by_label( order_mode_str );
-
-		g_debug( "%s: group=%s, key=%s, order_mode=%u (%s), mandatory=%s, window=%p (%s)",
-				thisfn, group, key, order_mode, order_mode_str,
-				mandatory ? "True":"False", ( void * ) window, G_OBJECT_TYPE_NAME( window ));
-
-#if 0
-		nact_iactions_list_display_order_change( NACT_IACTIONS_LIST( window ), order_mode );
-		nact_sort_buttons_display_order_change( BASE_WINDOW( window ), order_mode );
-#endif
-
-		tree = na_pivot_get_items( NA_PIVOT( window->private->updater ));
-
-		if( g_list_length( tree )){
-			g_signal_emit_by_name( window, TREE_SIGNAL_LEVEL_ZERO_CHANGED );
-		}
-	}
-}
-
 static gchar *
 iabout_get_application_name( NAIAbout *instance )
 {
diff --git a/src/nact/nact-main-window.h b/src/nact/nact-main-window.h
index 347e1ef..e49b560 100644
--- a/src/nact/nact-main-window.h
+++ b/src/nact/nact-main-window.h
@@ -115,11 +115,66 @@
  *  |                           select first row (if any)
  *  |
  * [X] End of initialization process
+ *
+ * Signals, their rules and uses
+ * =============================
+ * TREE_SIGNAL_SELECTION_CHANGED
+ *   The signal is sent on the BaseWindow by the tree view each time the selection
+ *   changes.
+ *   Args:
+ *   - the list of selected items, may be NULL.
+ *   Consumers:
+ *   - the main window updates its 'current' properties, then send the
+ *     MAIN_SIGNAL_SELECTION_CHANGED signal
+ *   - the menubar updates its indicator depending of the current selection
+ *
+ * MAIN_SIGNAL_SELECTION_CHANGED
+ *   The signal is sent on the BaseWindow by the main window when the selection has
+ *   changed. 'current' main window properties have been set to reflect this new
+ *   selection.
+ *   Args:
+ *   - the list of selected items, may be NULL.
+ *   Consumers:
+ *   - All tabs should take advantage of this signal to enable/disable their
+ *     page, setup the content of their widgets, and so on.
+ *
+ * TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
+ *   The signal is sent on the BaseWindow each time a widget is updated; the widget
+ *   callback must setup the edited object with the new value, and then should call
+ *   this signal with a flag indicating if the tree display should be refreshed now.
+ *   Args:
+ *   - an OR-ed list of modified flags, or 0 if not relevant
+ *   Consumers are:
+ *   - the main window checks the modification/validity status of the object
+ *   - if the 'refresh tree display' flag is set, then the tree model refreshes
+ *     the current row with current label and icon, then flags current row as
+ *     modified
+ *
+ * MAIN_SIGNAL_ITEM_UPDATED
+ *   The signal is sent on the BaseWindow after a data has been modified elsewhere
+ *   that in a tab: either the label the label has been edited inline in the tree
+ *   view, or a new i/o provider has been identified. The relevant NAObject has
+ *   been updated accordingly.
+ *   Args:
+ *   - an OR-ed list of modified flags, or 0 if not relevant
+ *   Consumers are:
+ *   - IActionTab and ICommandTab should update their label widgets
+ *   - IPropertiesTab updates its provider label
+ *
+ * TREE_SIGNAL_FOCUS_IN
+ * TREE_SIGNAL_FOCUS_OUT
+ * TREE_SIGNAL_CONTEXT_MENU
+ * TREE_SIGNAL_COUNT_CHANGED
+ * TREE_SIGNAL_LEVEL_ZERO_CHANGED
+ * TREE_SIGNAL_MODIFIED_STATUS_CHANGED
+ *
+ * TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED
+ *
+ * Object
  */
 
 #include "nact-application.h"
 #include "nact-clipboard.h"
-#include "nact-window.h"
 #include "nact-tree-view.h"
 
 G_BEGIN_DECLS
@@ -135,7 +190,7 @@ typedef struct _NactMainWindowPrivate        NactMainWindowPrivate;
 
 typedef struct {
 	/*< private >*/
-	NactWindow             parent;
+	BaseWindow             parent;
 	NactMainWindowPrivate *private;
 }
 	NactMainWindow;
@@ -144,7 +199,7 @@ typedef struct _NactMainWindowClassPrivate   NactMainWindowClassPrivate;
 
 typedef struct {
 	/*< private >*/
-	NactWindowClass             parent;
+	BaseWindowClass             parent;
 	NactMainWindowClassPrivate *private;
 }
 	NactMainWindowClass;
@@ -152,9 +207,21 @@ typedef struct {
 /**
  * Signals emitted by the main window
  */
+#define MAIN_SIGNAL_ITEM_UPDATED			"main-item-updated"
 #define MAIN_SIGNAL_SELECTION_CHANGED		"main-selection-changed"
 
 /**
+ * The data which, when modified, should be redisplayed asap.
+ * This is used by MAIN_SIGNAL_ITEM_UPDATED and TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
+ * signals.
+ */
+enum {
+	MAIN_DATA_LABEL    = 1<<0,
+	MAIN_DATA_ICON     = 1<<1,
+	MAIN_DATA_PROVIDER = 1<<2,
+};
+
+/**
  * Properties set against the main window
  */
 #define MAIN_PROP_ITEM						"main-current-item"
@@ -170,9 +237,9 @@ NactMainWindow *nact_main_window_new           ( const NactApplication *applicat
 NactClipboard  *nact_main_window_get_clipboard ( const NactMainWindow *window );
 NactTreeView   *nact_main_window_get_items_view( const NactMainWindow *window );
 
-void            nact_main_window_reload( NactMainWindow *window );
-
-gboolean        nact_main_window_quit  ( NactMainWindow *window );
+void            nact_main_window_reload      ( NactMainWindow *window );
+void            nact_main_window_block_reload( NactMainWindow *window );
+gboolean        nact_main_window_quit        ( NactMainWindow *window );
 
 G_END_DECLS
 
diff --git a/src/nact/nact-marshal.def b/src/nact/nact-marshal.def
index cc9cc2d..4623a90 100644
--- a/src/nact/nact-marshal.def
+++ b/src/nact/nact-marshal.def
@@ -1,5 +1,6 @@
 # NactTreeView:: TREE_SIGNAL_COUNT_CHANGED
 VOID:BOOLEAN,INT,INT,INT
 #
-# NactMainWindow::nact-tab-updatable-item-updated
-VOID:POINTER,BOOLEAN
+# NactMainWindow::TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
+# NactMainWindow::MAIN_SIGNAL_ITEM_UPDATED
+VOID:POINTER,UINT
diff --git a/src/nact/nact-match-list.c b/src/nact/nact-match-list.c
index f0e1619..ec3acb0 100644
--- a/src/nact/nact-match-list.c
+++ b/src/nact/nact-match-list.c
@@ -530,7 +530,7 @@ on_filter_edited( GtkCellRendererText *renderer, const gchar *path_str, const gc
 	na_core_utils_slist_free( filters );
 	g_free( old_text );
 
-	g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+	g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 }
 
 static gboolean
@@ -615,7 +615,7 @@ on_must_match_toggled( GtkCellRendererToggle *cell_renderer, gchar *path_str, Ma
 			na_core_utils_slist_free( filters );
 			g_free( filter );
 
-			g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+			g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 		}
 	} else {
 		g_signal_handlers_block_by_func(( gpointer ) cell_renderer, on_must_match_toggled, data );
@@ -666,7 +666,7 @@ on_must_not_match_toggled( GtkCellRendererToggle *cell_renderer, gchar *path_str
 			na_core_utils_slist_free( filters );
 			g_free( filter );
 
-			g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+			g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 		}
 	} else {
 		g_signal_handlers_block_by_func(( gpointer ) cell_renderer, on_must_not_match_toggled, data );
@@ -704,7 +704,7 @@ add_filter( MatchListStr *data, const gchar *filter, const gchar *prefix )
 		( *data->pset )( context, filters );
 		na_core_utils_slist_free( filters );
 
-		g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+		g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 	}
 }
 
@@ -761,7 +761,7 @@ delete_current_row( MatchListStr *data )
 				( *data->pset )( context, filters );
 				na_core_utils_slist_free( filters );
 
-				g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, FALSE );
+				g_signal_emit_by_name( G_OBJECT( data->window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, context, 0 );
 			}
 		}
 
diff --git a/src/nact/nact-menubar-file.c b/src/nact/nact-menubar-file.c
index 0c711ec..7ae56a6 100644
--- a/src/nact/nact-menubar-file.c
+++ b/src/nact/nact-menubar-file.c
@@ -53,9 +53,7 @@ static guint     st_event_autosave         = 0;
 static gchar *st_save_error       = N_( "Save error" );
 static gchar *st_save_warning     = N_( "Some items may not have been saved" );
 static gchar *st_level_zero_write = N_( "Unable to rewrite the level-zero items list" );
-#if 0
-static gchar *st_delete_error     = N_( "Some items cannot have been deleted" );
-#endif
+static gchar *st_delete_error     = N_( "Some items have not be deleted" );
 
 static gboolean save_item( BaseWindow *window, NAUpdater *updater, NAObjectItem *item, GSList **messages );
 static void     install_autosave( NactMenubar *bar );
@@ -261,7 +259,6 @@ nact_menubar_file_save_items( BaseWindow *window )
 	static const gchar *thisfn = "nact_menubar_file_save_items";
 	NactTreeView *items_view;
 	GList *items, *it;
-	gchar *label;
 	GList *new_pivot;
 	NAObjectItem *duplicate;
 	GSList *messages;
@@ -276,25 +273,30 @@ nact_menubar_file_save_items( BaseWindow *window )
 	 */
 	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
 	items = nact_tree_view_get_items( items_view );
+	na_object_dump_tree( items );
 	messages = NULL;
 
-	if( !na_iprefs_write_level_zero( NA_PIVOT( bar->private->updater ), items, &messages )){
-		if( g_slist_length( messages )){
-			msg = na_core_utils_slist_join_at_end( messages, "\n" );
-		} else {
-			msg = g_strdup( gettext( st_level_zero_write ));
+	if( nact_tree_ieditable_is_level_zero_modified( NACT_TREE_IEDITABLE( items_view ))){
+		if( !na_iprefs_write_level_zero( NA_PIVOT( bar->private->updater ), items, &messages )){
+			if( g_slist_length( messages )){
+				msg = na_core_utils_slist_join_at_end( messages, "\n" );
+			} else {
+				msg = g_strdup( gettext( st_level_zero_write ));
+			}
+			base_window_display_error_dlg( window, gettext( st_save_error ), msg );
+			g_free( msg );
+			na_core_utils_slist_free( messages );
 		}
-		base_window_display_error_dlg( window, gettext( st_save_error ), msg );
-		g_free( msg );
-		na_core_utils_slist_free( messages );
-		return;
+
+	} else {
+		g_signal_emit_by_name( window, TREE_SIGNAL_LEVEL_ZERO_CHANGED, FALSE );
 	}
 
 	/* remove deleted items
 	 * so that new actions with same id do not risk to be deleted later
+	 * not deleted items are reinserted in the tree
 	 */
-#if 0
-	if( !nact_main_window_remove_deleted( NACT_MAIN_WINDOW( window ), &messages )){
+	if( !nact_tree_ieditable_remove_deleted( NACT_TREE_IEDITABLE( items_view ), &messages )){
 		if( g_slist_length( messages )){
 			msg = na_core_utils_slist_join_at_end( messages, "\n" );
 		} else {
@@ -303,9 +305,11 @@ nact_menubar_file_save_items( BaseWindow *window )
 		base_window_display_error_dlg( window, gettext( st_save_error ), msg );
 		g_free( msg );
 		na_core_utils_slist_free( messages );
-		return;
+
+	} else {
+		na_object_free_items( items );
+		items = nact_tree_view_get_items( items_view );
 	}
-#endif
 
 	/* recursively save the modified items
 	 * check is useless here if item was not modified, but not very costly;
@@ -316,16 +320,7 @@ nact_menubar_file_save_items( BaseWindow *window )
 	messages = NULL;
 
 	for( it = items ; it ; it = it->next ){
-		label = na_object_get_label( it->data );
-		g_debug( "%s saving item %s %p (%s), modified=%s",
-				thisfn,
-				G_OBJECT_TYPE_NAME( it->data ),
-				( void * ) it->data, label,
-				na_object_is_modified( it->data ) ? "True":"False" );
-		g_free( label );
-
 		save_item( window, bar->private->updater, NA_OBJECT_ITEM( it->data ), &messages );
-
 		duplicate = NA_OBJECT_ITEM( na_object_duplicate( it->data ));
 		na_object_reset_origin( it->data, duplicate );
 		na_object_check_status( it->data );
@@ -340,79 +335,57 @@ nact_menubar_file_save_items( BaseWindow *window )
 	}
 
 	na_pivot_set_new_items( NA_PIVOT( bar->private->updater ), g_list_reverse( new_pivot ));
-	g_list_free( items );
-
+	na_object_free_items( items );
+	nact_main_window_block_reload( NACT_MAIN_WINDOW( window ));
 	g_signal_emit_by_name( window, TREE_SIGNAL_MODIFIED_STATUS_CHANGED, FALSE );
 }
 
 /*
  * iterates here on each and every NAObjectItem row stored in the tree
- *
- * do not deal with profiles as they are directly managed by the action
- * they are attached to
- *
- * level zero order has already been saved from tree store order, so that
- * we actually do not care of the exact order of level zero NAPivot items
- *
- * saving means recursively save modified NAObjectItem, simultaneously
- * reproducing the new item in NAPivot
- *  +- A
- *  |  +- B
- *  |  |  +- C
- *  |  |  |  +- D
- *  |  |  |  +- E
- *  |  |  +- F
- *  |  +- G
- *  +- H
- *  |  +- ...
- *  save order: A-B-C-D-E-F-G-H (first parent, then children)
  */
 static gboolean
 save_item( BaseWindow *window, NAUpdater *updater, NAObjectItem *item, GSList **messages )
 {
+	static const gchar *thisfn = "nact_menubar_file_save_item";
 	gboolean ret;
 	NAIOProvider *provider_before;
 	NAIOProvider *provider_after;
 	GList *subitems, *it;
-	gchar *msg;
+	gchar *label;
+	guint save_ret;
 
 	g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), FALSE );
 	g_return_val_if_fail( NA_IS_UPDATER( updater ), FALSE );
 	g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), FALSE );
 
 	ret = TRUE;
+
+	if( NA_IS_OBJECT_MENU( item )){
+		subitems = na_object_get_items( item );
+		for( it = subitems ; it ; it = it->next ){
+			ret &= save_item( window, updater, NA_OBJECT_ITEM( it->data ), messages );
+		}
+	}
+
 	provider_before = na_object_get_provider( item );
 
 	if( na_object_is_modified( item )){
-		ret = FALSE;
-		msg = NULL;
+		label = na_object_get_label( item );
+		g_debug( "%s: saving %p (%s) '%s'", thisfn, ( void * ) item, G_OBJECT_TYPE_NAME( item ), label );
+		g_free( label );
 
-		if( nact_window_save_item( NACT_WINDOW( window ), item, &msg )){
+		save_ret = na_updater_write_item( updater, item, messages );
+		ret = ( save_ret == NA_IIO_PROVIDER_CODE_OK );
 
+		if( ret ){
 			if( NA_IS_OBJECT_ACTION( item )){
 				na_object_reset_last_allocated( item );
 			}
 
-#if 0
-			nact_iactions_list_bis_remove_modified( NACT_IACTIONS_LIST( window ), item );
-#endif
-
 			provider_after = na_object_get_provider( item );
 			if( provider_after != provider_before ){
-				g_signal_emit_by_name( window, TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED, item );
+				g_signal_emit_by_name( window, MAIN_SIGNAL_ITEM_UPDATED, item, MAIN_DATA_PROVIDER );
 			}
-
-		} else {
-			/* TODO:
-			 * add the error message to the GSList
-			 */
-		}
-	}
-
-	if( NA_IS_OBJECT_MENU( item )){
-		subitems = na_object_get_items( item );
-		for( it = subitems ; it ; it = it->next ){
-			ret &= save_item( window, updater, NA_OBJECT_ITEM( it->data ), messages );
 		}
 	}
 
diff --git a/src/nact/nact-menubar-maintainer.c b/src/nact/nact-menubar-maintainer.c
index 5afc9df..4b226b7 100644
--- a/src/nact/nact-menubar-maintainer.c
+++ b/src/nact/nact-menubar-maintainer.c
@@ -37,6 +37,7 @@
 #include "nact-clipboard.h"
 #include "nact-menubar-priv.h"
 #include "nact-main-window.h"
+#include "nact-tree-ieditable.h"
 
 /**
  * nact_menubar_maintainer_on_update_sensitivities:
@@ -97,9 +98,10 @@ nact_menubar_maintainer_on_brief_tree_store_dump( GtkAction *action, BaseWindow
 void
 nact_menubar_maintainer_on_list_modified_items( GtkAction *action, BaseWindow *window )
 {
-#if 0
-	nact_iactions_list_bis_list_modified_items( NACT_IACTIONS_LIST( window ));
-#endif
+	NactTreeView *items_view;
+
+	items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( window ));
+	nact_tree_ieditable_dump_modified( NACT_TREE_IEDITABLE( items_view ));
 }
 
 /**
diff --git a/src/nact/nact-menubar.c b/src/nact/nact-menubar.c
index 3f61073..5301497 100644
--- a/src/nact/nact-menubar.c
+++ b/src/nact/nact-menubar.c
@@ -232,8 +232,6 @@ static void     on_tree_view_selection_changed( BaseWindow *window, GList *selec
 
 static void     on_update_sensitivities( NactMenubar *bar, BaseWindow *window );
 
-static void     on_finalizing_window( NactMenubar *bar, GObject *window );
-
 GType
 nact_menubar_get_type( void )
 {
@@ -406,8 +404,6 @@ nact_menubar_new( BaseWindow *window )
 	base_window_signal_connect( window,
 			G_OBJECT( window ), BASE_SIGNAL_INITIALIZE_WINDOW, G_CALLBACK( on_base_initialize_window ));
 
-	g_object_weak_ref( G_OBJECT( window ), ( GWeakNotify ) on_finalizing_window, bar );
-
 	g_object_set_data( G_OBJECT( window ), WINDOW_DATA_MENUBAR, bar );
 
 	return( bar );
@@ -873,44 +869,3 @@ nact_menubar_save_items( BaseWindow *window )
 {
 	nact_menubar_file_save_items( window );
 }
-
-/*
- * triggered just before the BaseWindow is finalized
- */
-static void
-on_finalizing_window( NactMenubar *bar, GObject *window )
-{
-	static const gchar *thisfn = "nact_menubar_on_finalizing_window";
-
-	g_return_if_fail( NACT_IS_MENUBAR( bar ));
-
-	g_debug( "%s: bar=%p (%s), window=%p", thisfn,
-			( void * ) bar, G_OBJECT_TYPE_NAME( bar ), ( void * ) window );
-
-	g_object_unref( bar );
-}
-
-#if 0
-/**
- * nact_menubar_is_level_zero_order_changed:
- * @window: the #BaseWindow main window.
- *
- * Returns: %TRUE if the level zero has changed, %FALSE else.
- */
-gboolean
-nact_menubar_is_level_zero_order_changed( const BaseWindow *window )
-{
-	BAR_WINDOW_VALUE( window, FALSE );
-	return( bar->private->level_zero_order_changed );
-}
-
-static void
-on_iactions_list_status_changed( BaseWindow *window, gpointer user_data )
-{
-	g_debug( "nact_menubar_on_iactions_list_status_changed" );
-
-	BAR_WINDOW_VOID( window );
-
-	g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
-}
-#endif
diff --git a/src/nact/nact-menubar.h b/src/nact/nact-menubar.h
index f0079cd..c27b76d 100644
--- a/src/nact/nact-menubar.h
+++ b/src/nact/nact-menubar.h
@@ -40,8 +40,7 @@
  * This is a convenience class which embeds the menubar of the application.
  *
  * There is one object (because there is one menubar). It is created by
- * the main window at initialization time. It attachs itself to the window,
- * and destroys itself - via a weak ref - when the window is finalizing.
+ * the main window at initialization time.
  *
  * Attaching the object to the window let us connect easily to all 'window'-
  * class messages, thus reducing the count of needed public functions.
diff --git a/src/nact/nact-tree-ieditable.c b/src/nact/nact-tree-ieditable.c
index aeca979..6354c8e 100644
--- a/src/nact/nact-tree-ieditable.c
+++ b/src/nact/nact-tree-ieditable.c
@@ -77,7 +77,7 @@ static void           on_label_edited( GtkCellRendererText *renderer, const gcha
 static void           on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data );
 static void           on_object_modified_status_changed( NactTreeIEditable *view, NAObject *object, gboolean new_status, BaseWindow *window );
 static void           on_object_valid_status_changed( NactTreeIEditable *view, NAObject *object, gboolean new_status, BaseWindow *window );
-static void           on_tree_view_level_zero_changed( BaseWindow *window, gpointer user_data );
+static void           on_tree_view_level_zero_changed( BaseWindow *window, gboolean is_modified, gpointer user_data );
 static void           on_tree_view_modified_status_changed( BaseWindow *window, gboolean is_modified, gpointer user_data );
 static void           add_to_deleted_rec( IEditableData *ied, NAObject *object );
 static void           decrement_counters( NactTreeIEditable *view, IEditableData *ialid, GList *items );
@@ -267,7 +267,6 @@ on_label_edited( GtkCellRendererText *renderer, const gchar *path_str, const gch
 	IEditableData *ied;
 	NAObject *object;
 	GtkTreePath *path;
-	gchar *new_text;
 
 	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 
@@ -275,9 +274,9 @@ on_label_edited( GtkCellRendererText *renderer, const gchar *path_str, const gch
 		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 );
+		na_object_set_label( object, text );
 
-		g_signal_emit_by_name( window, TREE_SIGNAL_CONTENT_CHANGED, object );
+		g_signal_emit_by_name( window, MAIN_SIGNAL_ITEM_UPDATED, object );
 	}
 }
 
@@ -357,10 +356,10 @@ on_object_valid_status_changed( NactTreeIEditable *instance, NAObject *object, g
 }
 
 /*
- * order of items at level zero of the tree has changed
+ * order or list of items at level zero of the tree has changed
  */
 static void
-on_tree_view_level_zero_changed( BaseWindow *window, gpointer user_data )
+on_tree_view_level_zero_changed( BaseWindow *window, gboolean is_modified, gpointer user_data )
 {
 	NactTreeView *items_view;
 	IEditableData *ied;
@@ -369,7 +368,7 @@ on_tree_view_level_zero_changed( BaseWindow *window, gpointer user_data )
 	items_view = NACT_TREE_VIEW( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ));
 	ied = get_instance_data( NACT_TREE_IEDITABLE( items_view ));
 	prev_status = get_modification_status( ied );
-	ied->level_zero_changed = TRUE;
+	ied->level_zero_changed = is_modified;
 
 	if( nact_tree_view_are_notify_allowed( items_view )){
 		status = get_modification_status( ied );
@@ -454,7 +453,7 @@ nact_tree_ieditable_delete( NactTreeIEditable *instance, GList *items, TreeIEdit
 			if( parent ){
 				na_object_check_status( parent );
 			} else {
-				g_signal_emit_by_name( ied->window, TREE_SIGNAL_LEVEL_ZERO_CHANGED );
+				g_signal_emit_by_name( ied->window, TREE_SIGNAL_LEVEL_ZERO_CHANGED, TRUE );
 			}
 
 			/* record the deleted item in the 'deleted' list,
@@ -470,6 +469,8 @@ nact_tree_ieditable_delete( NactTreeIEditable *instance, GList *items, TreeIEdit
 
 		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( ied->model ));
 
+		nact_tree_view_set_notify_allowed( NACT_TREE_VIEW( instance ), TRUE );
+
 		if( path ){
 			if( ope == TREE_OPE_DELETE ){
 				nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), path );
@@ -482,8 +483,6 @@ nact_tree_ieditable_delete( NactTreeIEditable *instance, GList *items, TreeIEdit
 			g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_MODIFIED_STATUS_CHANGED, status );
 
 		}
-
-		nact_tree_view_set_notify_allowed( NACT_TREE_VIEW( instance ), TRUE );
 	}
 }
 
@@ -540,6 +539,104 @@ decrement_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
 }
 
 /**
+ * nact_tree_ieditable_remove_deleted:
+ * @instance: this #NactTreeIEditable *instance.
+ * @messages: a pointer to a #GSList of error messages.
+ *
+ * Actually removes the deleted items from the underlying I/O storage subsystem.
+ *
+ * @messages #GSList is only filled up in case of an error has occured.
+ * If there is no error (nact_tree_ieditable_remove_deleted() returns %TRUE),
+ * then the caller may safely assume that @messages is returned in the
+ * same state that it has been provided.
+ *
+ * Returns: %TRUE if all candidate items have been successfully deleted,
+ * %FALSE else.
+ */
+gboolean
+nact_tree_ieditable_remove_deleted( NactTreeIEditable *instance, GSList **messages )
+{
+	static const gchar *thisfn = "nact_tree_ieditable_remove_deleted";
+	gboolean delete_ok;
+	IEditableData *ied;
+	GList *it;
+	NAObjectItem *item;
+	GList *not_deleted;
+	guint delete_ret;
+
+	g_return_val_if_fail( NACT_IS_TREE_IEDITABLE( instance ), TRUE );
+
+	delete_ok = TRUE;
+
+	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+
+		ied = get_instance_data( instance );
+		not_deleted = NULL;
+
+		for( it = ied->deleted ; it ; it = it->next ){
+			item = NA_OBJECT_ITEM( it->data );
+			g_debug( "%s: item=%p (%s)", thisfn, ( void * ) item, G_OBJECT_TYPE_NAME( item ));
+			na_object_dump_norec( item );
+
+			delete_ret = na_updater_delete_item( ied->updater, item, messages );
+			delete_ok = ( delete_ret == NA_IIO_PROVIDER_CODE_OK );
+
+			if( !delete_ok ){
+				not_deleted = g_list_prepend( not_deleted, na_object_ref( item ));
+
+#if 0
+			} else {
+				origin = ( NAObject * ) na_object_get_origin( item );
+				if( origin ){
+					na_updater_remove_item( updater, origin );
+					g_object_unref( origin );
+				}
+#endif
+			}
+		}
+
+		ied->deleted = na_object_free_items( ied->deleted );
+
+		/* items that we cannot delete are reinserted in the tree view
+		 * in the state they were when they were deleted
+		 * (i.e. possibly modified)
+		 */
+		if( not_deleted ){
+			nact_tree_ieditable_insert_items( instance, not_deleted, NULL );
+			na_object_free_items( not_deleted );
+		}
+	}
+
+	return( delete_ok );
+}
+
+/**
+ * nact_tree_ieditable_get_deleted:
+ * @instance: this #NactTreeIEditable *instance.
+ *
+ * Returns: a copy of the 'deleted' list, which should be na_object_free_items()
+ * by the caller.
+ */
+GList *
+nact_tree_ieditable_get_deleted( NactTreeIEditable *instance )
+{
+	GList *deleted;
+	IEditableData *ied;
+
+	g_return_val_if_fail( NACT_IS_TREE_IEDITABLE( instance ), NULL );
+
+	deleted = NULL;
+
+	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+
+		ied = get_instance_data( instance );
+		deleted = na_object_copyref_items( ied->deleted );
+	}
+
+	return( deleted );
+}
+
+/**
  * nact_tree_ieditable_insert_items:
  * @instance: this #NactTreeIEditable instance.
  * @items: a list of items to be inserted (e.g. from a paste).
@@ -649,7 +746,7 @@ nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, G
 			for( it = items ; it ; it = it->next ){
 				na_object_check_status( it->data );
 			}
-			ied->level_zero_changed = TRUE;
+			g_signal_emit_by_name( ied->window, TREE_SIGNAL_LEVEL_ZERO_CHANGED, TRUE );
 		}
 
 		/* post insertion
@@ -826,24 +923,54 @@ increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
 	g_signal_emit_by_name( G_OBJECT( ied->window ), TREE_SIGNAL_COUNT_CHANGED, FALSE, menus, actions, profiles );
 }
 
-#if 0
-static void
-increment_counters_modified( NAObject *object, IEditableData *ied )
+/**
+ * nact_tree_ieditable_dump_modified:
+ * @instance: this #NactTreeIEditable *instance.
+ *
+ * Dump informations about modified items.
+ */
+void
+nact_tree_ieditable_dump_modified( const NactTreeIEditable *instance )
 {
-	gboolean writable;
-	guint reason;
+	static const gchar *thisfn = "nact_tree_ieditable_dump_modified";
+	IEditableData *ied;
 
-	if( NA_IS_OBJECT_ITEM( object )){
+	g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
 
-		if( !na_object_get_provider( object )){
-			ied->count_modified += 1;
-		}
+	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
 
-		writable = na_updater_is_item_writable( ied->updater, NA_OBJECT_ITEM( object ), &reason );
-		na_object_set_writability_status( object, writable, reason );
+		ied = get_instance_data(( NactTreeIEditable * ) instance );
+
+		g_debug( "%s:      count_deleted=%u", thisfn, g_list_length( ied->deleted ));
+		g_debug( "%s:     count_modified=%u", thisfn, ied->count_modified );
+		g_debug( "%s: level_zero_changed=%s", thisfn, ied->level_zero_changed ? "True":"False" );
 	}
 }
-#endif
+
+/**
+ * nact_tree_ieditable_is_level_zero_modified:
+ * @instance: this #NactTreeIEditable *instance.
+ *
+ * Returns: %TRUE if the level zero must be saved, %FALSE else.
+ */
+gboolean
+nact_tree_ieditable_is_level_zero_modified( const NactTreeIEditable *instance )
+{
+	IEditableData *ied;
+	gboolean is_modified;
+
+	g_return_val_if_fail( NACT_IS_TREE_IEDITABLE( instance ), FALSE );
+
+	is_modified = FALSE;
+
+	if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+
+		ied = get_instance_data(( NactTreeIEditable * ) instance );
+		is_modified = ied->level_zero_changed;
+	}
+
+	return( is_modified );
+}
 
 static GtkTreePath *
 get_selection_first_path( GtkTreeView *treeview )
diff --git a/src/nact/nact-tree-ieditable.h b/src/nact/nact-tree-ieditable.h
index 1b7855d..74af706 100644
--- a/src/nact/nact-tree-ieditable.h
+++ b/src/nact/nact-tree-ieditable.h
@@ -83,30 +83,15 @@ void     nact_tree_ieditable_initialize    ( NactTreeIEditable *instance, GtkTre
 void     nact_tree_ieditable_terminate     ( NactTreeIEditable *instance );
 
 void     nact_tree_ieditable_delete        ( NactTreeIEditable *instance, GList *items, TreeIEditableDeleteOpe ope );
+gboolean nact_tree_ieditable_remove_deleted( NactTreeIEditable *instance, GSList **messages );
+GList   *nact_tree_ieditable_get_deleted   ( NactTreeIEditable *instance );
+
 void     nact_tree_ieditable_insert_items  ( NactTreeIEditable *instance, GList *items, NAObject *sibling );
 void     nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, GtkTreePath *path );
 void     nact_tree_ieditable_insert_into   ( NactTreeIEditable *instance, GList *items );
 
-#if 0
-void      nact_tree_ieditable_brief_tree_dump( NactTreeIEditable *instance );
-void      nact_tree_ieditable_display_order_change( NactTreeIEditable *instance, gint order_mode );
-gint      nact_tree_ieditable_get_management_mode( NactTreeIEditable *instance );
-gboolean  nact_tree_ieditable_has_modified_items( NactTreeIEditable *instance );
-GList    *nact_tree_ieditable_remove_rec( GList *list, NAObject *object );
-
-void      nact_tree_ieditable_bis_clear_selection( NactTreeIEditable *instance, GtkTreeView *treeview );
-void      nact_tree_ieditable_bis_collapse_to_parent( NactTreeIEditable *instance );
-void      nact_tree_ieditable_bis_expand_to_first_child( NactTreeIEditable *instance );
-NAObject *nact_tree_ieditable_bis_get_item( NactTreeIEditable *instance, const gchar *id );
-GList    *nact_tree_ieditable_bis_get_items( NactTreeIEditable *instance );
-GList    *nact_tree_ieditable_bis_get_selected_items( NactTreeIEditable *instance );
-void      nact_tree_ieditable_bis_list_modified_items( NactTreeIEditable *instance );
-void      nact_tree_ieditable_bis_remove_modified( NactTreeIEditable *instance, const NAObjectItem *item );
-void      nact_tree_ieditable_bis_select_first_row( NactTreeIEditable *instance );
-void      nact_tree_ieditable_bis_select_row_at_path( NactTreeIEditable *instance, GtkTreeView *treeview, GtkTreeModel *model, GtkTreePath *path );
-void      nact_tree_ieditable_bis_toggle_collapse( NactTreeIEditable *instance );
-void      nact_tree_ieditable_bis_toggle_collapse_object( NactTreeIEditable *instance, const NAObject *item );
-#endif
+void     nact_tree_ieditable_dump_modified         ( const NactTreeIEditable *instance );
+gboolean nact_tree_ieditable_is_level_zero_modified( const NactTreeIEditable *instance );
 
 G_END_DECLS
 
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 2982c7e..165ac0f 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -41,6 +41,7 @@
 #include "nact-application.h"
 #include "nact-clipboard.h"
 #include "base-gtk-utils.h"
+#include "nact-main-tab.h"
 #include "nact-tree-model.h"
 #include "nact-tree-model-priv.h"
 
@@ -101,32 +102,35 @@ extern guint          tree_model_dnd_dest_formats_count;
 
 static GtkTreeModelFilterClass *st_parent_class = NULL;
 
-static GType          register_type( void );
-static void           class_init( NactTreeModelClass *klass );
-static void           imulti_drag_source_init( EggTreeMultiDragSourceIface *iface );
-static void           idrag_dest_init( GtkTreeDragDestIface *iface );
-static void           instance_init( GTypeInstance *instance, gpointer klass );
-static void           instance_dispose( GObject *model );
-static void           instance_finalize( GObject *model );
-
-static void           on_initialize_model( BaseWindow *window, gpointer user_data );
-
-static void           append_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *parent, GtkTreeIter *iter, const NAObject *object );
-static void           display_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *iter, const NAObject *object );
+static GType    register_type( void );
+static void     class_init( NactTreeModelClass *klass );
+static void     imulti_drag_source_init( EggTreeMultiDragSourceIface *iface );
+static void     idrag_dest_init( GtkTreeDragDestIface *iface );
+static void     instance_init( GTypeInstance *instance, gpointer klass );
+static void     instance_dispose( GObject *model );
+static void     instance_finalize( GObject *model );
+
+static void     on_initialize_model( BaseWindow *window, gpointer user_data );
+static void     on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpointer new_value, gboolean mandatory, NactTreeModel *model );
+static void     on_tab_updatable_item_updated( BaseWindow *window, NAIContext *context, guint data, gpointer user_data );
+
+static void     append_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *parent, GtkTreeIter *iter, const NAObject *object );
+static void     display_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *iter, const NAObject *object );
+static void     display_order_change( NactTreeModel *model, gint order_mode );
 #if 0
-static void           dump( NactTreeModel *model );
-static gboolean       dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpStruct *ntm );
+static void     dump( NactTreeModel *model );
+static gboolean dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpStruct *ntm );
 #endif
-static void           fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, GtkTreeIter *parent );
-static gboolean       filter_visible( GtkTreeModel *store, GtkTreeIter *iter, NactTreeModel *model );
-static gboolean       find_item_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindId *nfo );
-static gboolean       find_object_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindObject *nfo );
-static gboolean       get_items_iter( const NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmGetItems *ngi );
-static void           iter_on_store( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *parent, FnIterOnStore fn, gpointer user_data );
-static gboolean       iter_on_store_item( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *iter, FnIterOnStore fn, gpointer user_data );
-static void           remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *object );
-static gboolean       delete_items_rec( GtkTreeStore *store, GtkTreeIter *iter );
-static gint           sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data );
+static void     fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, GtkTreeIter *parent );
+static gboolean filter_visible( GtkTreeModel *store, GtkTreeIter *iter, NactTreeModel *model );
+static gboolean find_item_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindId *nfo );
+static gboolean find_object_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindObject *nfo );
+static gboolean get_items_iter( const NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmGetItems *ngi );
+static void     iter_on_store( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *parent, FnIterOnStore fn, gpointer user_data );
+static gboolean iter_on_store_item( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *iter, FnIterOnStore fn, gpointer user_data );
+static void     remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *object );
+static gboolean delete_items_rec( GtkTreeStore *store, GtkTreeIter *iter );
+static gint     sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data );
 
 GType
 nact_tree_model_get_type( void )
@@ -327,7 +331,7 @@ nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mod
 	application = NACT_APPLICATION( base_window_get_application( window ));
 	updater = nact_application_get_updater( application );
 	order_mode = na_iprefs_get_order_mode( NA_PIVOT( updater ), NULL );
-	nact_tree_model_display_order_change( model, order_mode );
+	display_order_change( model, order_mode );
 
 	/* setup instanciation time data
 	 */
@@ -353,15 +357,13 @@ nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mod
 
 /*
  * on_initialize_model:
- * @model: this #NactTreeModel instance.
- * @have_dnd: whether the tree model must implement drag and drop
- * interfaces.
+ * @window: the #BaseWindow which embeds the tree view.
+ * @user_data: not used (this same @window).
  *
  * Initializes the tree model.
  *
  * We use drag and drop:
- * - inside of treeview, for duplicating items, or moving items between
- *   menus
+ * - inside of treeview, for duplicating items, or moving items between menus
  * - from treeview to the outside world (e.g. Nautilus) to export actions
  * - from outside world (e.g. Nautilus) to import actions
  */
@@ -369,6 +371,9 @@ static void
 on_initialize_model( BaseWindow *window, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_tree_model_on_initialize_model";
+	NactApplication *application;
+	NAUpdater *updater;
+	NASettings *settings;
 
 	WINDOW_MODEL_VOID( window );
 
@@ -401,94 +406,72 @@ on_initialize_model( BaseWindow *window, gpointer user_data )
 
 			base_window_signal_connect( window,
 					G_OBJECT( model->private->treeview ), "drag-end", G_CALLBACK( nact_tree_model_dnd_on_drag_end ));
+
+			application = NACT_APPLICATION( base_window_get_application( window ));
+			updater = nact_application_get_updater( application );
+			settings = na_pivot_get_settings( NA_PIVOT( updater ));
+			na_settings_register_key_callback( settings, NA_IPREFS_ITEMS_LIST_ORDER_MODE, G_CALLBACK( on_settings_order_mode_changed ), model );
+
+			base_window_signal_connect( window,
+					G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, G_CALLBACK( on_tab_updatable_item_updated ));
 		}
 	}
 }
 
-#if 0
-/**
- * nact_tree_model_display:
- * @model: this #NactTreeModel instance.
- * @object: the object whose display is to be refreshed.
- *
- * Refresh the display of a #NAObject.
+/*
+ * NASettings callback for a change on NA_IPREFS_ITEMS_LIST_ORDER_MODE key
  */
-void
-nact_tree_model_display( NactTreeModel *model, NAObject *object )
+static void
+on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpointer new_value, gboolean mandatory, NactTreeModel *model )
 {
-	static const gchar *thisfn = "nact_tree_model_display";
-	GtkTreeStore *store;
-	GtkTreeIter iter;
-	GtkTreePath *path;
+	static const gchar *thisfn = "nact_tree_model_on_settings_order_mode_changed";
+	const gchar *order_mode_str;
+	guint order_mode;
 
 	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
 
-	g_debug( "%s: model=%p (%s), object=%p (%s)",
-			thisfn,
-			( void * ) model, G_OBJECT_TYPE_NAME( model ),
-			( void * ) object, G_OBJECT_TYPE_NAME( object ));
-
 	if( !model->private->dispose_has_run ){
 
-		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+		order_mode_str = ( const gchar * ) new_value;
+		order_mode = na_iprefs_get_order_mode_by_label( order_mode_str );
 
-		if( search_for_object( model, GTK_TREE_MODEL( store ), object, &iter )){
-			display_item( store, model->private->treeview, &iter, object );
-			path = gtk_tree_model_get_path( GTK_TREE_MODEL( store ), &iter );
-			gtk_tree_model_row_changed( GTK_TREE_MODEL( store ), path, &iter );
-			gtk_tree_path_free( path );
-		}
+		g_debug( "%s: group=%s, key=%s, order_mode=%u (%s), mandatory=%s, model=%p (%s)",
+				thisfn, group, key, order_mode, order_mode_str,
+				mandatory ? "True":"False", ( void * ) model, G_OBJECT_TYPE_NAME( model ));
 
-		/*gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));*/
+		display_order_change( model, order_mode );
 	}
 }
-#endif
 
-/**
- * nact_tree_model_display_order_change:
- * @model: this #NactTreeModel.
- * @order_mode: the new order mode.
- *
- * Setup the new order mode.
+/*
+ * if force_display is true, then refresh the display of the view
  */
-void
-nact_tree_model_display_order_change( NactTreeModel *model, gint order_mode )
+static void
+on_tab_updatable_item_updated( BaseWindow *window, NAIContext *context, guint data, gpointer user_data )
 {
+	static const gchar *thisfn = "nact_tree_model_on_tab_updatable_item_updated";
+	NactTreeModel *model;
+	GtkTreePath *path;
 	GtkTreeStore *store;
+	GtkTreeIter iter;
 
-	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+	model = NACT_TREE_MODEL( g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_MODEL ));
 
 	if( !model->private->dispose_has_run ){
-
-		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
-		g_object_set_data( G_OBJECT( store ), TREE_MODEL_ORDER_MODE, GINT_TO_POINTER( order_mode ));
-
-		switch( order_mode ){
-
-			case IPREFS_ORDER_ALPHA_ASCENDING:
-
-				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
-						TREE_COLUMN_LABEL, GTK_SORT_ASCENDING );
-
-				gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE( store ),
-						TREE_COLUMN_LABEL, ( GtkTreeIterCompareFunc ) sort_actions_list, NULL, NULL );
-				break;
-
-			case IPREFS_ORDER_ALPHA_DESCENDING:
-
-				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
-						TREE_COLUMN_LABEL, GTK_SORT_DESCENDING );
-
-				gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE( store ),
-						TREE_COLUMN_LABEL, ( GtkTreeIterCompareFunc ) sort_actions_list, NULL, NULL );
-				break;
-
-			case IPREFS_ORDER_MANUAL:
-			default:
-
-				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
-						GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, 0 );
-				break;
+		g_debug( "%s: window=%p, context=%p (%s), data=%u, user_data=%p",
+				thisfn, ( void * ) window, ( void * ) context, G_OBJECT_TYPE_NAME( context ),
+				data, ( void * ) user_data );
+
+		if( data & ( MAIN_DATA_LABEL | MAIN_DATA_ICON )){
+			path = nact_tree_model_object_to_path( model, ( NAObject * ) context );
+			if( path ){
+				store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+				if( gtk_tree_model_get_iter( GTK_TREE_MODEL( store ), &iter, path )){
+					display_item( store, model->private->treeview, &iter, ( NAObject * ) context );
+					gtk_tree_model_row_changed( GTK_TREE_MODEL( store ), path, &iter );
+				}
+				gtk_tree_path_free( path );
+			}
 		}
 	}
 }
@@ -800,7 +783,7 @@ nact_tree_model_get_items( const NactTreeModel *model, guint mode )
 	items = NULL;
 
 	if( !model->private->dispose_has_run ){
-		g_debug( "%s: model=%p, mode=%x", thisfn, ( void * ) model, mode );
+		g_debug( "%s: model=%p, mode=0x%xh", thisfn, ( void * ) model, mode );
 
 		ngi.mode = mode;
 		ngi.items = NULL;
@@ -907,6 +890,55 @@ display_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *iter, con
 	}
 }
 
+/*
+ * nact_tree_model_display_order_change:
+ * @model: this #NactTreeModel.
+ * @order_mode: the new order mode.
+ *
+ * Setup the new order mode.
+ */
+static void
+display_order_change( NactTreeModel *model, gint order_mode )
+{
+	GtkTreeStore *store;
+
+	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+
+	if( !model->private->dispose_has_run ){
+
+		store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+		g_object_set_data( G_OBJECT( store ), TREE_MODEL_ORDER_MODE, GINT_TO_POINTER( order_mode ));
+
+		switch( order_mode ){
+
+			case IPREFS_ORDER_ALPHA_ASCENDING:
+
+				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+						TREE_COLUMN_LABEL, GTK_SORT_ASCENDING );
+
+				gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE( store ),
+						TREE_COLUMN_LABEL, ( GtkTreeIterCompareFunc ) sort_actions_list, NULL, NULL );
+				break;
+
+			case IPREFS_ORDER_ALPHA_DESCENDING:
+
+				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+						TREE_COLUMN_LABEL, GTK_SORT_DESCENDING );
+
+				gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE( store ),
+						TREE_COLUMN_LABEL, ( GtkTreeIterCompareFunc ) sort_actions_list, NULL, NULL );
+				break;
+
+			case IPREFS_ORDER_MANUAL:
+			default:
+
+				gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+						GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, 0 );
+				break;
+		}
+	}
+}
+
 #if 0
 /*
  * dump:
@@ -1072,7 +1104,7 @@ find_object_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path,
 static gboolean
 get_items_iter( const NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmGetItems *ngi )
 {
-	if( ngi->mode == TREE_LIST_ALL ){
+	if( ngi->mode & TREE_LIST_ALL ){
 		if( gtk_tree_path_get_depth( path ) == 1 ){
 			ngi->items = g_list_prepend( ngi->items, na_object_ref( object ));
 		}
diff --git a/src/nact/nact-tree-model.h b/src/nact/nact-tree-model.h
index b326261..f7d9aa3 100644
--- a/src/nact/nact-tree-model.h
+++ b/src/nact/nact-tree-model.h
@@ -86,15 +86,6 @@ enum {
 	TREE_N_COLUMN
 };
 
-/**
- * When getting a list of items; these indcators may be OR-ed.
- */
-enum {
-	TREE_LIST_SELECTED = 1<<0,
-	TREE_LIST_MODIFIED = 1<<1,
-	TREE_LIST_ALL = 0xff,
-};
-
 GType          nact_tree_model_get_type( void );
 
 NactTreeModel *nact_tree_model_new( BaseWindow *window, GtkTreeView *view, NactTreeMode mode );
@@ -109,18 +100,6 @@ GList         *nact_tree_model_get_items     ( const NactTreeModel *model, guint
 NAObject      *nact_tree_model_object_at_path( const NactTreeModel *model, GtkTreePath *path );
 GtkTreePath   *nact_tree_model_object_to_path( const NactTreeModel *model, const NAObject *object );
 
-/* find an item
- * get items (all, selected, modified)
- * remove a list of items
- * insert a list of items (here, inside)
- */
-
-/* *** */
-/*void         nact_tree_model_display( NactTreeModel *model, NAObject *object );*/
-void         nact_tree_model_display_order_change( NactTreeModel *model, gint order_mode );
-/*void         nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data );*/
-/* *** */
-
 G_END_DECLS
 
 #endif /* __NACT_TREE_MODEL_H__ */
diff --git a/src/nact/nact-tree-view.c b/src/nact/nact-tree-view.c
index d2899d6..9e63829 100644
--- a/src/nact/nact-tree-view.c
+++ b/src/nact/nact-tree-view.c
@@ -82,7 +82,6 @@ enum {
 /* signals
  */
 enum {
-	CONTENT_CHANGED,
 	CONTEXT_MENU,
 	COUNT_CHANGED,
 	FOCUS_IN,
@@ -128,7 +127,6 @@ static gboolean on_button_press_event( GtkWidget *widget, GdkEventButton *event,
 static gboolean on_focus_in( GtkWidget *widget, GdkEventFocus *event, BaseWindow *window );
 static gboolean on_focus_out( GtkWidget *widget, GdkEventFocus *event, BaseWindow *window );
 static gboolean on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window );
-static void     on_content_changed_cleanup_handler( BaseWindow *window, NAObject *edited );
 static void     on_selection_changed( GtkTreeSelection *selection, BaseWindow *window );
 static void     on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items );
 static void     clear_selection( NactTreeView *view );
@@ -241,33 +239,6 @@ class_init( NactTreeViewClass *klass )
 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
 
 	/**
-	 * NactTreeView::tree-signal-content-changed:
-	 *
-	 * This signal is emitted on the BaseWindow parent when the content
-	 * of the tree changes. It may change in two occurrences:
-	 * - the whole model is refilled with a new items list;
-	 * - a row is edited.
-	 *
-	 * Signal args:
-	 * - a pointer on the edited NAObject element, or NULL if the whole
-	 *   list has changed.
-	 *
-	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, NAObject *edited, gpointer user_data );
-	 */
-	st_signals[ CONTENT_CHANGED ] = g_signal_new_class_handler(
-			TREE_SIGNAL_CONTENT_CHANGED,
-			G_TYPE_OBJECT,
-			G_SIGNAL_RUN_CLEANUP,
-			G_CALLBACK( on_content_changed_cleanup_handler ),
-			NULL,
-			NULL,
-			g_cclosure_marshal_VOID__POINTER,
-			G_TYPE_NONE,
-			1,
-			G_TYPE_POINTER );
-
-	/**
 	 * NactTreeView::tree-signal-open-popup
 	 *
 	 * This signal is emitted on the BaseWindow parent when the user right
@@ -377,12 +348,15 @@ class_init( NactTreeViewClass *klass )
 	 * NactTreeView::tree-signal-level-zero-changed:
 	 *
 	 * This signal is emitted on the BaseWindow each time the level zero
-	 * has changed.
+	 * has changed because an item has been removed or inserted, or when
+	 * the level zero has been saved.
 	 *
-	 * Signal args: none
+	 * Signal args:
+	 * - whether the level zero has changed (%TRUE), or comes to be saved
+	 *   (%FALSE).
 	 *
 	 * Handler prototype:
-	 * void ( *handler )( BaseWindow *window, gpointer user_data );
+	 * void ( *handler )( BaseWindow *window, gboolean is_modified, gpointer user_data );
 	 */
 	st_signals[ LEVEL_ZERO_CHANGED ] = g_signal_new(
 			TREE_SIGNAL_LEVEL_ZERO_CHANGED,
@@ -391,9 +365,10 @@ class_init( NactTreeViewClass *klass )
 			0,					/* no default handler */
 			NULL,
 			NULL,
-			g_cclosure_marshal_VOID__VOID,
+			g_cclosure_marshal_VOID__BOOLEAN,
 			G_TYPE_NONE,
-			0 );
+			1,
+			G_TYPE_BOOLEAN );
 
 	/**
 	 * NactTreeView::tree-signal-modified-status-changed:
@@ -847,17 +822,6 @@ on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window
 }
 
 /*
- * cleanup handler for our TREE_SIGNAL_CONTENT_CHANGED signal
- */
-static void
-on_content_changed_cleanup_handler( BaseWindow *window, NAObject *edited )
-{
-	static const gchar *thisfn = "nact_tree_view_on_content_changed_cleanup_handler";
-
-	g_debug( "%s: window=%p, edited=%p", thisfn, ( void * ) window, ( void * ) edited );
-}
-
-/*
  * handles the "changed" signal emitted on the GtkTreeSelection
  */
 static void
@@ -1043,8 +1007,23 @@ nact_tree_view_get_item_by_id( const NactTreeView *view, const gchar *id )
 GList *
 nact_tree_view_get_items( const NactTreeView *view )
 {
+	return( nact_tree_view_get_items_ex( view, TREE_LIST_ALL ));
+}
+
+/**
+ * nact_tree_view_get_items_ex:
+ * @view: this #NactTreeView instance.
+ * @mode: the list content
+ *
+ * Returns: the content of the current tree as a newly allocated list
+ * which should be na_object_free_items() by the caller.
+ */
+GList *
+nact_tree_view_get_items_ex( const NactTreeView *view, guint mode )
+{
 	GList *items;
 	NactTreeModel *model;
+	GList *deleted;
 
 	g_return_val_if_fail( NACT_IS_TREE_VIEW( view ), NULL );
 
@@ -1052,8 +1031,18 @@ nact_tree_view_get_items( const NactTreeView *view )
 
 	if( !view->private->dispose_has_run ){
 
+		deleted = NULL;
+
+		if( view->private->mode == TREE_MODE_EDITION ){
+			if( mode & TREE_LIST_DELETED ){
+				deleted = nact_tree_ieditable_get_deleted( NACT_TREE_IEDITABLE( view ));
+			}
+		}
+
 		model = NACT_TREE_MODEL( gtk_tree_view_get_model( view->private->tree_view ));
-		items = nact_tree_model_get_items( model, TREE_LIST_ALL );
+		items = nact_tree_model_get_items( model, mode );
+
+		items = g_list_concat( items, deleted );
 	}
 
 	return( items );
diff --git a/src/nact/nact-tree-view.h b/src/nact/nact-tree-view.h
index c0aba5c..ca90eee 100644
--- a/src/nact/nact-tree-view.h
+++ b/src/nact/nact-tree-view.h
@@ -88,7 +88,6 @@ typedef struct {
 /**
  * Signals emitted by the NactTreeView instance.
  */
-#define TREE_SIGNAL_CONTENT_CHANGED				"tree-signal-content-changed"
 #define TREE_SIGNAL_CONTEXT_MENU				"tree-signal-open-popup"
 #define TREE_SIGNAL_COUNT_CHANGED				"tree-signal-count-changed"
 #define TREE_SIGNAL_FOCUS_IN					"tree-signal-focus-in"
@@ -106,6 +105,16 @@ typedef enum {
 	NactTreeMode;
 
 /**
+ * When getting a list of items; these indcators may be OR-ed.
+ */
+enum {
+	TREE_LIST_SELECTED = 1<<0,
+	TREE_LIST_MODIFIED = 1<<1,
+	TREE_LIST_ALL      = 1<<7,
+	TREE_LIST_DELETED  = 1<<8,
+};
+
+/**
  * The NactTreeView is attached to the parent BaseWindow via a GObject data.
  * Only NactTreeIEditable interface should use it.
  */
@@ -124,6 +133,7 @@ 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 );
+GList        *nact_tree_view_get_items_ex      ( const NactTreeView *view, guint mode );
 
 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]