[nautilus-actions] Split all action management from the menubar in a per-menu basis



commit b83cc0cbeb4cf24d7b660763944885f4de8a2586
Author: Pierre Wieser <pwieser trychlos org>
Date:   Thu Mar 25 20:55:47 2010 +0100

    Split all action management from the menubar in a per-menu basis

 ChangeLog                               |   10 +
 po/POTFILES.in                          |    2 +
 src/nact/Makefile.am                    |    6 +
 src/nact/nact-confirm-logout.c          |    4 +-
 src/nact/nact-main-menubar-edit.c       |  658 ++++++++++++++++++++
 src/nact/nact-main-menubar-edit.h       |   61 ++
 src/nact/nact-main-menubar-file.c       |  393 ++++++++++++
 src/nact/nact-main-menubar-file.h       |   58 ++
 src/nact/nact-main-menubar-help.c       |    3 +-
 src/nact/nact-main-menubar-help.h       |    4 +-
 src/nact/nact-main-menubar-maintainer.c |    3 +-
 src/nact/nact-main-menubar-maintainer.h |    4 +-
 src/nact/nact-main-menubar-tools.c      |   14 +-
 src/nact/nact-main-menubar-tools.h      |    4 +-
 src/nact/nact-main-menubar-view.c       |  152 +++++
 src/nact/nact-main-menubar-view.h       |   57 ++
 src/nact/nact-main-menubar.c            | 1003 ++-----------------------------
 src/nact/nact-main-menubar.h            |   43 +-
 src/nact/nact-tree-model-dnd.c          |    4 +-
 19 files changed, 1477 insertions(+), 1006 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b5ea77b..017753b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2009-03-25 Pierre Wieser <pwieser trychlos org>
 
+	* src/nact/nact-main-menubar-edit.c:
+	* src/nact/nact-main-menubar-edit.h:
+	* src/nact/nact-main-menubar-file.c:
+	* src/nact/nact-main-menubar-file.h:
+	* src/nact/nact-main-menubar-view.c:
+	* src/nact/nact-main-menubar-view.h: New files.
+
+	* po/POTFILES.in:
+	* src/nact/Makefile.am: Updated accordingly.
+
 	* src/nact/nact-main-window.c
 	(ipivot_consumer_on_mandatory_prefs_changed):
 	Implement NAIPivotConsumer notification.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0ac9ca9..a270a17 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -32,6 +32,8 @@ src/nact/nact-iaction-tab.c
 src/nact/nact-icommand-tab.c
 src/nact/nact-ifolders-tab.c
 src/nact/nact-main-menubar.c
+src/nact/nact-main-menubar-edit.c
+src/nact/nact-main-menubar-file.c
 src/nact/nact-main-window.c
 src/nact/nact-preferences.ui
 src/nact/nact-providers-list.c
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index 3342203..572f01e 100644
--- a/src/nact/Makefile.am
+++ b/src/nact/Makefile.am
@@ -106,12 +106,18 @@ nautilus_actions_config_tool_SOURCES = \
 	nact-main.c											\
 	nact-main-menubar.c									\
 	nact-main-menubar.h									\
+	nact-main-menubar-edit.c							\
+	nact-main-menubar-edit.h							\
+	nact-main-menubar-file.c							\
+	nact-main-menubar-file.h							\
 	nact-main-menubar-help.c							\
 	nact-main-menubar-help.h							\
 	nact-main-menubar-maintainer.c						\
 	nact-main-menubar-maintainer.h						\
 	nact-main-menubar-tools.c							\
 	nact-main-menubar-tools.h							\
+	nact-main-menubar-view.c							\
+	nact-main-menubar-view.h							\
 	nact-main-statusbar.c								\
 	nact-main-statusbar.h								\
 	nact-main-tab.c										\
diff --git a/src/nact/nact-confirm-logout.c b/src/nact/nact-confirm-logout.c
index 9cd16c3..a811f97 100644
--- a/src/nact/nact-confirm-logout.c
+++ b/src/nact/nact-confirm-logout.c
@@ -33,7 +33,7 @@
 #endif
 
 #include "nact-confirm-logout.h"
-#include "nact-main-menubar.h"
+#include "nact-main-menubar-file.h"
 
 /* private class data
  */
@@ -323,7 +323,7 @@ on_save_and_quit_clicked( GtkButton *button, NactConfirmLogout *editor )
 	g_debug( "%s: button=%p, editor=%p", thisfn, ( void * ) button, ( void * ) editor );
 
 	main_window = NACT_MAIN_WINDOW( base_window_get_parent( BASE_WINDOW( editor )));
-	nact_main_menubar_save_items( main_window );
+	nact_main_menubar_file_save_items( main_window );
 
 	close_dialog( editor, TRUE );
 }
diff --git a/src/nact/nact-main-menubar-edit.c b/src/nact/nact-main-menubar-edit.c
new file mode 100644
index 0000000..05b0788
--- /dev/null
+++ b/src/nact/nact-main-menubar-edit.c
@@ -0,0 +1,658 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+
+#include <api/na-core-utils.h>
+
+#include <core/na-io-provider.h>
+#include <core/na-iprefs.h>
+
+#include "nact-application.h"
+#include "nact-iactions-list.h"
+#include "nact-main-tab.h"
+#include "nact-main-menubar-edit.h"
+#include "nact-preferences-editor.h"
+
+static GList  *prepare_for_paste( NactMainWindow *window );
+static GList  *get_deletables( NAUpdater *updater, GList *tree, GSList **not_deletable );
+static GSList *get_deletables_rec( NAUpdater *updater, GList *tree );
+static gchar  *add_non_deletable_msg( const NAObjectItem *item, gint reason );
+static void    update_clipboard_counters( NactMainWindow *window );
+
+/**
+ * nact_main_menubar_edit_on_update_sensitivities:
+ * @window: the #NactMainWindow main window.
+ * user_data: the data passed to the function via the signal.
+ * @mis: the #MenubarIndicatorsStruct struct.
+ *
+ * Update sensitivity of items of the Edit menu.
+ */
+void
+nact_main_menubar_edit_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis )
+{
+	gboolean cut_enabled;
+	gboolean copy_enabled;
+	gboolean paste_enabled;
+	gboolean paste_into_enabled;
+	gboolean duplicate_enabled;
+	gboolean delete_enabled;
+	GList *is;
+	NAObject *parent_item;
+	NAObject *selected_action;
+	NAObject *selected_item;
+	gboolean are_parents_writable;
+	gboolean is_clipboard_empty;
+
+	is_clipboard_empty = ( mis->clipboard_menus + mis->clipboard_actions + mis->clipboard_profiles == 0 );
+
+	/* cut requires a non-empty selection
+	 * and that all parents are writable (as implies a delete operation)
+	 */
+	cut_enabled = mis->treeview_has_focus || mis->popup_handler;
+	cut_enabled &= mis->count_selected > 0;
+	are_parents_writable = TRUE;
+	for( is = mis->selected_items ; is ; is = is->next ){
+		parent_item = ( NAObject * ) na_object_get_parent( is->data );
+		if( parent_item ){
+			if( !na_updater_is_item_writable( mis->updater, NA_OBJECT_ITEM( parent_item ), NULL )){
+				are_parents_writable = FALSE;
+				break;
+			}
+		} else if( !mis->is_level_zero_writable ){
+			are_parents_writable = FALSE;
+			break;
+		}
+	}
+	cut_enabled &= are_parents_writable;
+	nact_main_menubar_enable_item( window, "CutItem", cut_enabled );
+
+	/* copy only requires a non-empty selection */
+	copy_enabled = mis->treeview_has_focus || mis->popup_handler;
+	copy_enabled &= mis->count_selected > 0;
+	nact_main_menubar_enable_item( window, "CopyItem", copy_enabled );
+
+	/* paste enabled if
+	 * - clipboard is not empty
+	 * - current selection is not multiple
+	 * - if clipboard contains only profiles,
+	 *   then current selection must be a profile or an action
+	 *   and the action must be writable
+	 * - if clipboard contains actions or menus,
+	 *   then current selection (if any) must be a menu or an action
+	 *   and its parent must be writable
+	 */
+	paste_enabled = mis->treeview_has_focus || mis->popup_handler;
+	paste_enabled &= !is_clipboard_empty;
+	paste_enabled &= mis->count_selected <= 1;
+	if( mis->clipboard_profiles ){
+		paste_enabled &= mis->count_selected == 1;
+		if( paste_enabled ){
+			selected_action = NA_OBJECT(
+					NA_IS_OBJECT_PROFILE( mis->selected_items->data )
+							? na_object_get_parent( mis->selected_items->data )
+							: mis->selected_items->data );
+			paste_enabled &= NA_IS_OBJECT_ACTION( selected_action );
+			paste_enabled &= na_updater_is_item_writable( mis->updater, NA_OBJECT_ITEM( selected_action ), NULL );
+		}
+	} else {
+		paste_enabled &= mis->has_writable_providers;
+		if( mis->count_selected ){
+			selected_item = NA_OBJECT( mis->selected_items->data );
+			paste_enabled &= NA_IS_OBJECT_ITEM( selected_item );
+			if( paste_enabled ){
+				parent_item = ( NAObject * ) na_object_get_parent( selected_item );
+				paste_enabled &= parent_item
+						? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( parent_item ), NULL )
+						: mis->is_level_zero_writable;
+			}
+		} else {
+			paste_enabled &= mis->is_level_zero_writable;
+		}
+	}
+	nact_main_menubar_enable_item( window, "PasteItem", paste_enabled );
+
+	/* paste into enabled if
+	 * - clipboard is not empty
+	 * - current selection is not multiple
+	 * - if clipboard contains only profiles,
+	 *   then current selection must be an action
+	 *   and the action must be writable
+	 * - if clipboard contains actions or menus,
+	 *   then current selection (if any) must be a menu
+	 *   and its parent must be writable
+	 */
+	paste_into_enabled = mis->treeview_has_focus || mis->popup_handler;
+	paste_into_enabled &= !is_clipboard_empty;
+	paste_into_enabled &= mis->count_selected <= 1;
+	if( mis->clipboard_profiles ){
+		paste_into_enabled &= mis->count_selected == 1;
+		if( paste_into_enabled ){
+			selected_action = NA_OBJECT( mis->selected_items->data );
+			paste_into_enabled &= NA_IS_OBJECT_ACTION( selected_action );
+			paste_into_enabled &= nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( selected_action ), NULL );
+		}
+	} else {
+		paste_into_enabled &= mis->has_writable_providers;
+		if( mis->count_selected ){
+			selected_item = NA_OBJECT( mis->selected_items->data );
+			paste_into_enabled &= NA_IS_OBJECT_MENU( selected_item );
+			if( paste_into_enabled ){
+				parent_item = ( NAObject * ) na_object_get_parent( selected_item );
+				paste_into_enabled &= parent_item
+						? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( parent_item ), NULL )
+						: mis->is_level_zero_writable;
+			}
+		} else {
+			paste_into_enabled &= mis->is_level_zero_writable;
+		}
+	}
+	nact_main_menubar_enable_item( window, "PasteIntoItem", paste_into_enabled );
+
+	/* duplicate items will be duplicated besides each one
+	 * selection must be non-empty
+	 * each parent must be writable
+	 * -> so this is the same than cut
+	 */
+	duplicate_enabled = cut_enabled;
+	nact_main_menubar_enable_item( window, "DuplicateItem", duplicate_enabled );
+
+	/* delete is same that cut
+	 * but items themselves must be writable (because physically deleted)
+	 * this will be checked on delete activated
+	 */
+	delete_enabled = cut_enabled;
+	nact_main_menubar_enable_item( window, "DeleteItem", delete_enabled );
+
+	/* reload items always enabled */
+
+	/* preferences always enabled */
+}
+
+/**
+ * nact_main_menubar_edit_on_cut:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * cuts the visible selection
+ * - (tree) get new refs on selected items
+ * - (main) add selected items to main list of deleted,
+ *          moving newref from list_from_tree to main_list_of_deleted
+ * - (menu) install in clipboard a copy of selected objects
+ * - (tree) remove selected items, unreffing objects
+ */
+void
+nact_main_menubar_edit_on_cut( GtkAction *gtk_action, NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_edit_on_cut";
+	NactApplication *application;
+	NAUpdater *updater;
+	GList *items;
+	NactClipboard *clipboard;
+	GList *to_delete;
+	GSList *non_deletables;
+
+	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
+	updater = nact_application_get_updater( application );
+	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
+
+	non_deletables = NULL;
+	to_delete = get_deletables( updater, items, &non_deletables );
+
+	if( non_deletables ){
+		gchar *second = na_core_utils_slist_join_at_end( non_deletables, "\n" );
+		base_window_error_dlg(
+				BASE_WINDOW( window ),
+				GTK_MESSAGE_INFO,
+				_( "Not all items have been cut as following ones are not modifiable:" ),
+				second );
+		g_free( second );
+		na_core_utils_slist_free( non_deletables );
+	}
+
+	if( to_delete ){
+		nact_main_window_move_to_deleted( window, to_delete );
+		clipboard = nact_main_window_get_clipboard( window );
+		nact_clipboard_primary_set( clipboard, to_delete, CLIPBOARD_MODE_CUT );
+		update_clipboard_counters( window );
+		nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( window ), to_delete, TRUE );
+	}
+
+	na_object_unref_selected_items( items );
+}
+
+/**
+ * nact_main_menubar_edit_on_copy:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * copies the visible selection
+ * - (tree) get new refs on selected items
+ * - (menu) install in clipboard a copy of selected objects
+ *          renumbering actions/menus id to ensure unicity at paste time
+ * - (menu) release refs on selected items
+ * - (menu) refresh actions sensitivy (as selection doesn't change)
+ */
+void
+nact_main_menubar_edit_on_copy( GtkAction *gtk_action, NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_edit_on_copy";
+	GList *items;
+	NactClipboard *clipboard;
+
+	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
+	clipboard = nact_main_window_get_clipboard( window );
+	nact_clipboard_primary_set( clipboard, items, CLIPBOARD_MODE_COPY );
+	update_clipboard_counters( window );
+	na_object_unref_selected_items( items );
+
+	g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
+}
+
+/**
+ * nact_main_menubar_edit_on_paste:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * pastes the current content of the clipboard at the current position
+ * (same path, same level)
+ * - (menu) get from clipboard a copy of installed items
+ *          the clipboard will return a new copy
+ *          and renumber its own data for allowing a new paste
+ * - (tree) insert new items, the tree store will ref them
+ *          attaching each item to its parent
+ *          recursively checking edition status of the topmost parent
+ *          selecting the first item at end
+ * - (menu) unreffing the copy got from clipboard
+ */
+void
+nact_main_menubar_edit_on_paste( GtkAction *gtk_action, NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_edit_on_paste";
+	GList *items;
+
+	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
+
+	items = prepare_for_paste( window );
+	if( items ){
+		nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
+		na_object_unref_items( items );
+	}
+}
+
+/**
+ * nact_main_menubar_edit_on_paste_into:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * pastes the current content of the clipboard as the first child of
+ * currently selected item
+ * - (menu) get from clipboard a copy of installed items
+ *          the clipboard will return a new copy
+ *          and renumber its own data for allowing a new paste
+ * - (tree) insert new items, the tree store will ref them
+ *          attaching each item to its parent
+ *          recursively checking edition status of the topmost parent
+ *          selecting the first item at end
+ * - (menu) unreffing the copy got from clipboard
+ */
+void
+nact_main_menubar_edit_on_paste_into( GtkAction *gtk_action, NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_edit_on_paste_into";
+	GList *items;
+
+	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
+
+	items = prepare_for_paste( window );
+	if( items ){
+		nact_iactions_list_bis_insert_into( NACT_IACTIONS_LIST( window ), items );
+		na_object_unref_items( items );
+	}
+}
+
+static GList *
+prepare_for_paste( NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_edit_prepare_for_paste";
+	GList *items, *it;
+	NactClipboard *clipboard;
+	NAObjectAction *action;
+	gboolean relabel;
+	gboolean renumber;
+	NactApplication *application;
+	NAUpdater *updater;
+
+	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
+	updater = nact_application_get_updater( application );
+
+	clipboard = nact_main_window_get_clipboard( window );
+	items = nact_clipboard_primary_get( clipboard, &renumber );
+	action = NULL;
+
+	/* if pasted items are profiles, then setup the target action
+	 */
+	for( it = items ; it ; it = it->next ){
+
+		if( NA_IS_OBJECT_PROFILE( it->data )){
+			if( !action ){
+				g_object_get( G_OBJECT( window ), TAB_UPDATABLE_PROP_EDITED_ACTION, &action, NULL );
+				g_return_val_if_fail( NA_IS_OBJECT_ACTION( action ), NULL );
+			}
+		}
+
+		relabel = nact_main_menubar_edit_is_pasted_object_relabeled( NA_OBJECT( it->data ), NA_PIVOT( updater ));
+		na_object_prepare_for_paste( it->data, relabel, renumber, action );
+		na_object_check_status( it->data );
+	}
+
+	g_debug( "%s: action=%p (%s)",
+			thisfn, ( void * ) action, action ? G_OBJECT_TYPE_NAME( action ): "(null)" );
+
+	return( items );
+}
+
+/**
+ * nact_main_menubar_edit_on_duplicate:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * duplicate is just as paste, with the difference that content comes
+ * from the current selection, instead of coming from the clipboard
+ *
+ * this is nonetheless a bit more complicated because when we duplicate
+ * some items (e.g. a multiple selection), we expect to see the new
+ * items just besides the original ones...
+ */
+void
+nact_main_menubar_edit_on_duplicate( GtkAction *gtk_action, NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_edit_on_duplicate";
+	NactApplication *application;
+	NAUpdater *updater;
+	NAObjectAction *action;
+	GList *items, *it;
+	GList *dup;
+	NAObject *obj;
+	gboolean relabel;
+
+	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
+	updater = nact_application_get_updater( application );
+
+	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
+	for( it = items ; it ; it = it->next ){
+		obj = NA_OBJECT( na_object_duplicate( it->data ));
+		action = NULL;
+
+		/* duplicating a profile
+		 * as we insert in sibling mode, the parent doesn't change
+		 */
+		if( NA_IS_OBJECT_PROFILE( obj )){
+			action = NA_OBJECT_ACTION( na_object_get_parent( it->data ));
+		}
+
+		relabel = nact_main_menubar_edit_is_pasted_object_relabeled( obj, NA_PIVOT( updater ));
+		na_object_prepare_for_paste( obj, relabel, TRUE, action );
+		na_object_set_origin( obj, NULL );
+		na_object_check_status( obj );
+		dup = g_list_prepend( NULL, obj );
+		nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), dup, it->data );
+		na_object_unref_items( dup );
+	}
+
+	na_object_unref_selected_items( items );
+}
+
+/**
+ * nact_main_menubar_edit_on_delete:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * deletes the visible selection
+ * - (tree) get new refs on selected items
+ * - (tree) remove selected items, unreffing objects
+ * - (main) add selected items to main list of deleted,
+ *          moving newref from list_from_tree to main_list_of_deleted
+ * - (tree) select next row (if any, or previous if any, or none)
+ *
+ * note that we get from selection a list of trees, but we don't have
+ * yet ensured that each element of this tree is actually deletable
+ * each branch of this list must be recursively deletable in order
+ * this branch itself be deleted
+ */
+void
+nact_main_menubar_edit_on_delete( GtkAction *gtk_action, NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_edit_on_delete";
+	NactApplication *application;
+	NAUpdater *updater;
+	GList *items;
+	GList *to_delete;
+	GSList *non_deletables;
+
+	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
+	updater = nact_application_get_updater( application );
+	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
+
+	non_deletables = NULL;
+	to_delete = get_deletables( updater, items, &non_deletables );
+
+	if( non_deletables ){
+		gchar *second = na_core_utils_slist_join_at_end( non_deletables, "\n" );
+		base_window_error_dlg(
+				BASE_WINDOW( window ),
+				GTK_MESSAGE_INFO,
+				_( "Not all items have been deleted as following ones are not modifiable:" ),
+				second );
+		g_free( second );
+		na_core_utils_slist_free( non_deletables );
+	}
+
+	if( to_delete ){
+		nact_main_window_move_to_deleted( window, to_delete );
+		nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( window ), to_delete, TRUE );
+	}
+
+	na_object_unref_selected_items( items );
+}
+
+static GList *
+get_deletables( NAUpdater *updater, GList *selected, GSList **non_deletables )
+{
+	GList *to_delete;
+	GList *it;
+	GList *subitems;
+	GSList *sub_deletables;
+	gint reason;
+
+	to_delete = NULL;
+	for( it = selected ; it ; it = it->next ){
+
+		if( !na_updater_is_item_writable( updater, NA_OBJECT_ITEM( it->data ), &reason )){
+			*non_deletables = g_slist_prepend(
+					*non_deletables, add_non_deletable_msg( NA_OBJECT_ITEM( it->data ), reason ));
+			continue;
+		}
+
+		if( NA_IS_OBJECT_MENU( it->data )){
+			subitems = na_object_get_items( it->data );
+			sub_deletables = get_deletables_rec( updater, subitems );
+
+			if( sub_deletables ){
+				*non_deletables = g_slist_concat( *non_deletables, sub_deletables );
+				continue;
+			}
+		}
+
+		to_delete = g_list_prepend( to_delete, na_object_ref( it->data ));
+	}
+
+	return( to_delete );
+}
+
+static GSList *
+get_deletables_rec( NAUpdater *updater, GList *tree )
+{
+	GSList *msgs;
+	GList *it;
+	GList *subitems;
+	gint reason;
+
+	msgs = NULL;
+	for( it = tree ; it ; it = it->next ){
+
+		if( !na_updater_is_item_writable( updater, NA_OBJECT_ITEM( it->data ), &reason )){
+			msgs = g_slist_prepend(
+					msgs, add_non_deletable_msg( NA_OBJECT_ITEM( it->data ), reason ));
+			continue;
+		}
+
+		if( NA_IS_OBJECT_MENU( it->data )){
+			subitems = na_object_get_items( it->data );
+			msgs = g_slist_concat( msgs, get_deletables_rec( updater, subitems ));
+		}
+	}
+
+	return( msgs );
+}
+
+static gchar *
+add_non_deletable_msg( const NAObjectItem *item, gint reason )
+{
+	gchar *msg;
+	gchar *label;
+	gchar *reason_str;
+
+	label = na_object_get_label( item );
+	reason_str = na_io_provider_get_readonly_tooltip( reason );
+
+	msg = g_strdup_printf( "%s: %s", label, reason_str );
+
+	g_free( reason_str );
+	g_free( label );
+
+	return( msg );
+}
+
+/*
+ * as we are coming from cut or copy to clipboard, report selection
+ * counters to clipboard ones
+ */
+static void
+update_clipboard_counters( NactMainWindow *window )
+{
+	MenubarIndicatorsStruct *mis;
+
+	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
+
+	mis->clipboard_menus = mis->selected_menus;
+	mis->clipboard_actions = mis->selected_actions;
+	mis->clipboard_profiles = mis->selected_profiles;
+
+	g_debug( "nact_main_menubar_update_clipboard_counters: menus=%d, actions=%d, profiles=%d",
+			mis->clipboard_menus, mis->clipboard_actions, mis->clipboard_profiles );
+
+	g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
+}
+
+/**
+ * nact_main_menubar_edit_on_reload:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Reload items from I/O storage subsystems.
+ */
+void
+nact_main_menubar_edit_on_reload( GtkAction *gtk_action, NactMainWindow *window )
+{
+	nact_main_window_reload( window );
+}
+
+/**
+ * nact_main_menubar_edit_on_preferences:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Edit preferences.
+ */
+void
+nact_main_menubar_edit_on_prefererences( GtkAction *gtk_action, NactMainWindow *window )
+{
+	nact_preferences_editor_run( BASE_WINDOW( window ));
+}
+
+/**
+ * nact_main_menubar_edit_is_pasted_object_relabeled:
+ * @object: the considered #NAObject-derived object.
+ * @pivot: the #NAPivot instance.
+ *
+ * Whether the specified object should be relabeled when pasted ?
+ *
+ * Returns: %TRUE if the object should be relabeled, %FALSE else.
+ */
+gboolean
+nact_main_menubar_edit_is_pasted_object_relabeled( NAObject *object, NAPivot *pivot )
+{
+	static const gchar *thisfn = "nact_main_menubar_edit_is_pasted_object_relabeled";
+	gboolean relabel;
+
+	if( NA_IS_OBJECT_MENU( object )){
+		relabel = na_iprefs_read_bool( NA_IPREFS( pivot ), IPREFS_RELABEL_MENUS, FALSE );
+	} else if( NA_IS_OBJECT_ACTION( object )){
+		relabel = na_iprefs_read_bool( NA_IPREFS( pivot ), IPREFS_RELABEL_ACTIONS, FALSE );
+	} else if( NA_IS_OBJECT_PROFILE( object )){
+		relabel = na_iprefs_read_bool( NA_IPREFS( pivot ), IPREFS_RELABEL_PROFILES, FALSE );
+	} else {
+		g_warning( "%s: unknown object type at %p", thisfn, ( void * ) object );
+		g_return_val_if_reached( FALSE );
+	}
+
+	return( relabel );
+}
diff --git a/src/nact/nact-main-menubar-edit.h b/src/nact/nact-main-menubar-edit.h
new file mode 100644
index 0000000..f9cc6c3
--- /dev/null
+++ b/src/nact/nact-main-menubar-edit.h
@@ -0,0 +1,61 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NACT_MAIN_MENUBAR_EDIT_H__
+#define __NACT_MAIN_MENUBAR_EDIT_H__
+
+/**
+ * SECTION: nact_main_menubar
+ * @short_description: Main menubar Edit menu management.
+ * @include: nact/nact-main-menubar-edit.h
+ */
+
+#include <gtk/gtk.h>
+
+#include "nact-main-menubar.h"
+
+G_BEGIN_DECLS
+
+void     nact_main_menubar_edit_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis );
+
+void     nact_main_menubar_edit_on_cut          ( GtkAction *action, NactMainWindow *window );
+void     nact_main_menubar_edit_on_copy         ( GtkAction *action, NactMainWindow *window );
+void     nact_main_menubar_edit_on_paste        ( GtkAction *action, NactMainWindow *window );
+void     nact_main_menubar_edit_on_paste_into   ( GtkAction *action, NactMainWindow *window );
+void     nact_main_menubar_edit_on_duplicate    ( GtkAction *action, NactMainWindow *window );
+void     nact_main_menubar_edit_on_delete       ( GtkAction *action, NactMainWindow *window );
+void     nact_main_menubar_edit_on_reload       ( GtkAction *action, NactMainWindow *window );
+void     nact_main_menubar_edit_on_prefererences( GtkAction *action, NactMainWindow *window );
+
+gboolean nact_main_menubar_edit_is_pasted_object_relabeled( NAObject *object, NAPivot *pivot );
+
+G_END_DECLS
+
+#endif /* __NACT_NACT_MENUBAR_EDIT_H__ */
diff --git a/src/nact/nact-main-menubar-file.c b/src/nact/nact-main-menubar-file.c
new file mode 100644
index 0000000..8816701
--- /dev/null
+++ b/src/nact/nact-main-menubar-file.c
@@ -0,0 +1,393 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+
+#include <core/na-io-provider.h>
+
+#include "nact-application.h"
+#include "nact-iactions-list.h"
+#include "nact-main-tab.h"
+#include "nact-main-menubar-file.h"
+
+static void save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item );
+
+/**
+ * nact_main_menubar_file_on_update_sensitivities:
+ * @window: the #NactMainWindow main window.
+ * user_data: the data passed to the function via the signal.
+ * @mis: the #MenubarIndicatorsStruct struct.
+ *
+ * Update sensitivity of items of the File menu.
+ */
+void
+nact_main_menubar_file_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis )
+{
+	static const gchar *thisfn = "nact_main_menubar_file_on_update_sensitivities";
+	gboolean new_item_enabled;
+	gboolean new_profile_enabled;
+	NAObject *first_parent;
+	NAObject *selected_action;
+	NAObject *parent_item;
+	gboolean is_first_parent_writable;
+	gboolean has_modified_items;
+	GList *is;
+
+	first_parent = mis->selected_items && g_list_length( mis->selected_items )
+			? ( NAObject * ) na_object_get_parent( mis->selected_items->data )
+			: NULL;
+	is_first_parent_writable = first_parent
+			? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( first_parent ), NULL )
+			: mis->is_level_zero_writable;
+
+	has_modified_items = nact_main_window_has_modified_items( window );
+	g_debug( "%s: has_modified_items=%s", thisfn, has_modified_items ? "True":"False" );
+
+	/* new menu / new action
+	 * new item will be inserted just before beginning of selection
+	 * parent of the first selected row must be writable
+	 * we must have at least one writable provider
+	 */
+	new_item_enabled = is_first_parent_writable && mis->has_writable_providers;
+	nact_main_menubar_enable_item( window, "NewMenuItem", new_item_enabled );
+	nact_main_menubar_enable_item( window, "NewActionItem", new_item_enabled );
+
+	/* new profile enabled if selection is relative to only one writable action
+	 * i.e. contains profile(s) of the same action, or only contains one action
+	 * action must be writable
+	 */
+	new_profile_enabled = TRUE;
+	selected_action = NULL;
+	for( is = mis->selected_items ; is ; is = is->next ){
+
+		if( NA_IS_OBJECT_MENU( is->data )){
+			new_profile_enabled = FALSE;
+			break;
+
+		} else if( NA_IS_OBJECT_ACTION( is->data )){
+			if( !selected_action ){
+				selected_action = NA_OBJECT( is->data );
+			} else if( selected_action != is->data ){
+				new_profile_enabled = FALSE;
+				break;
+			}
+
+		} else if( NA_IS_OBJECT_PROFILE( is->data )){
+			parent_item = NA_OBJECT( na_object_get_parent( is->data ));
+			if( !selected_action ){
+				selected_action = parent_item;
+			} else if( selected_action != parent_item ){
+				new_profile_enabled = FALSE;
+				break;
+			}
+		}
+	}
+	nact_main_menubar_enable_item( window, "NewProfileItem",
+			new_profile_enabled &&
+			selected_action != NULL &&
+			nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( selected_action ), NULL ));
+
+	/* save enabled if at least one item has been modified
+	 * or level-zero has been resorted and is writable
+	 */
+	nact_main_menubar_enable_item( window, "SaveItem",
+			has_modified_items || ( mis->level_zero_order_changed && mis->is_level_zero_writable ));
+
+	/* quit always enabled */
+}
+
+/**
+ * nact_main_menubar_file_on_new_menu:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers File / New menu item.
+ */
+void
+nact_main_menubar_file_on_new_menu( GtkAction *gtk_action, NactMainWindow *window )
+{
+	NAObjectMenu *menu;
+	GList *items;
+
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	menu = na_object_menu_new_with_defaults();
+	na_object_check_status( menu );
+	items = g_list_prepend( NULL, menu );
+	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
+	na_object_unref_items( items );
+}
+
+/**
+ * nact_main_menubar_file_on_new_action:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers File / New action item.
+ */
+void
+nact_main_menubar_file_on_new_action( GtkAction *gtk_action, NactMainWindow *window )
+{
+	NAObjectAction *action;
+	GList *items;
+
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	action = na_object_action_new_with_defaults();
+	na_object_check_status( action );
+	items = g_list_prepend( NULL, action );
+	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
+	na_object_unref_items( items );
+}
+
+/**
+ * nact_main_menubar_file_on_new_profile:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers File / New profile item.
+ */
+void
+nact_main_menubar_file_on_new_profile( GtkAction *gtk_action, NactMainWindow *window )
+{
+	NAObjectAction *action;
+	NAObjectProfile *profile;
+	gchar *name;
+	GList *items;
+
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	g_object_get(
+			G_OBJECT( window ),
+			TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
+			NULL );
+
+	profile = na_object_profile_new_with_defaults();
+	na_object_set_label( profile, _( "New profile" ));
+
+	name = na_object_action_get_new_profile_name( action );
+	na_object_set_id( profile, name );
+	g_free( name );
+
+	/*na_object_attach_profile( action, profile );*/
+
+	na_object_check_status( profile );
+
+	items = g_list_prepend( NULL, profile );
+	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
+	na_object_unref_items( items );
+}
+
+/**
+ * nact_main_menubar_file_on_save:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers File /Save item.
+ *
+ * Saving is not only saving modified items, but also saving hierarchy
+ * (and order if alpha order is not set).
+ *
+ * This is the same function that #nact_main_menubar_file_save_items(), just with
+ * different arguments.
+ */
+void
+nact_main_menubar_file_on_save( GtkAction *gtk_action, NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_file_on_save";
+
+	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	nact_main_menubar_file_save_items( window );
+}
+
+/**
+ * nact_main_menubar_file_save_items:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Save items.
+ * This is the same function that #nact_main_menubar_file_on_save(), just with
+ * different arguments.
+ */
+void
+nact_main_menubar_file_save_items( NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_file_save_items";
+	GList *items, *it;
+	NactApplication *application;
+	NAUpdater *updater;
+	MenubarIndicatorsStruct *mis;
+
+	g_debug( "%s: window=%p", thisfn, ( void * ) window );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	/* remove deleted items
+	 * so that new actions with same id do not risk to be deleted later
+	 */
+	nact_main_window_remove_deleted( window );
+
+	/* always write the level zero list of items
+	 * and reset the corresponding modification flag
+	 */
+	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
+	updater = nact_application_get_updater( application );
+	items = nact_iactions_list_bis_get_items( NACT_IACTIONS_LIST( window ));
+	na_pivot_write_level_zero( NA_PIVOT( updater ), items );
+
+	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
+	mis->level_zero_order_changed = FALSE;
+
+	/* recursively save the modified items
+	 * check is useless here if item was not modified, but not very costly
+	 * above all, it is less costly to check the status here, than to check
+	 * recursively each and every modified item
+	 */
+	for( it = items ; it ; it = it->next ){
+		save_item( window, updater, NA_OBJECT_ITEM( it->data ));
+		na_object_check_status( it->data );
+	}
+	g_list_free( items );
+
+	/* get ride of notification messages of IOProviders
+	 */
+	na_ipivot_consumer_delay_notify( NA_IPIVOT_CONSUMER( window ));
+}
+
+/*
+ * iterates here on each and every row stored in the tree
+ * - do not deal with profiles as they are directly managed by their
+ *   action parent
+ * - do not deal with not modified, or not valid, items, but allow
+ *   for save their subitems
+ */
+static void
+save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item )
+{
+	static const gchar *thisfn = "nact_main_menubar_file_save_item";
+	NAObjectItem *origin;
+	NAObjectItem *dup_pivot;
+	GList *subitems, *it;
+	NAObjectItem *parent;
+	gint pos;
+	NAIOProvider *provider_before;
+	NAIOProvider *provider_after;
+
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+	g_return_if_fail( NA_IS_UPDATER( updater ));
+	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
+
+	if( NA_IS_OBJECT_MENU( item )){
+		subitems = na_object_get_items( item );
+		for( it = subitems ; it ; it = it->next ){
+			save_item( window, updater, NA_OBJECT_ITEM( it->data ));
+		}
+	}
+
+	provider_before = na_object_get_provider( item );
+
+	if( na_object_is_modified( item ) &&
+		nact_window_save_item( NACT_WINDOW( window ), item )){
+
+			if( NA_IS_OBJECT_ACTION( item )){
+				na_object_reset_last_allocated( item );
+			}
+
+			/* now that the NAObjectItem has been (non recursively) saved,
+			 * we have to update NAPivot so that the next na_object_check_status()
+			 * will show us that this treeview item is no more modified
+			 */
+			origin = ( NAObjectItem * ) na_object_get_origin( item );
+			g_debug( "%s: origin=%p", thisfn, ( void * ) origin );
+
+			parent = NULL;
+			pos = -1;
+
+			if( origin ){
+				parent = na_object_get_parent( origin );
+				if( parent ){
+					pos = na_object_get_position( parent, origin );
+				}
+				na_updater_remove_item( updater, NA_OBJECT( origin ));
+			}
+
+			dup_pivot = NA_OBJECT_ITEM( na_object_duplicate( item ));
+			na_object_reset_origin( item, dup_pivot );
+			na_object_set_parent( dup_pivot, parent );
+			if( parent ){
+				if( pos == -1 ){
+					na_object_append_item( parent, dup_pivot );
+				} else {
+					na_object_insert_at( parent, dup_pivot, pos );
+				}
+			} else {
+				na_updater_append_item( updater, dup_pivot );
+			}
+
+			nact_iactions_list_bis_remove_modified( NACT_IACTIONS_LIST( window ), item );
+
+			provider_after = na_object_get_provider( item );
+			if( provider_after != provider_before ){
+				g_signal_emit_by_name( window, TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED, item );
+			}
+	}
+}
+
+/**
+ * nact_main_menubar_file_on_quit:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers the File / Quit item.
+ */
+void
+nact_main_menubar_file_on_quit( GtkAction *gtk_action, NactMainWindow *window )
+{
+	static const gchar *thisfn = "nact_main_menubar_file_on_quit";
+	gboolean has_modified;
+
+	g_debug( "%s: item=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
+	g_return_if_fail( GTK_IS_ACTION( gtk_action ) || gtk_action == NULL );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	has_modified = nact_main_window_has_modified_items( window );
+	if( !has_modified || nact_window_warn_modified( NACT_WINDOW( window ))){
+		g_object_unref( window );
+	}
+}
diff --git a/src/nact/nact-main-menubar-file.h b/src/nact/nact-main-menubar-file.h
new file mode 100644
index 0000000..59fad37
--- /dev/null
+++ b/src/nact/nact-main-menubar-file.h
@@ -0,0 +1,58 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NACT_MAIN_MENUBAR_FILE_H__
+#define __NACT_MAIN_MENUBAR_FILE_H__
+
+/**
+ * SECTION: nact_main_menubar
+ * @short_description: Main menubar File menu management.
+ * @include: nact/nact-main-menubar-file.h
+ */
+
+#include <gtk/gtk.h>
+
+#include "nact-main-menubar.h"
+
+G_BEGIN_DECLS
+
+void nact_main_menubar_file_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis );
+
+void nact_main_menubar_file_on_new_menu   ( GtkAction *action, NactMainWindow *window );
+void nact_main_menubar_file_on_new_action ( GtkAction *action, NactMainWindow *window );
+void nact_main_menubar_file_on_new_profile( GtkAction *action, NactMainWindow *window );
+void nact_main_menubar_file_on_save       ( GtkAction *action, NactMainWindow *window );
+void nact_main_menubar_file_on_quit       ( GtkAction *action, NactMainWindow *window );
+
+void nact_main_menubar_file_save_items( NactMainWindow *window );
+
+G_END_DECLS
+
+#endif /* __NACT_NACT_MENUBAR_FILE_H__ */
diff --git a/src/nact/nact-main-menubar-help.c b/src/nact/nact-main-menubar-help.c
index 5711810..cdfde5e 100644
--- a/src/nact/nact-main-menubar-help.c
+++ b/src/nact/nact-main-menubar-help.c
@@ -41,11 +41,12 @@
  * nact_main_menubar_help_on_update_sensitivities:
  * @window: the #NactMainWindow main application window.
  * @user_data: user data ?
+ * @mis: the #MenubarIndicatorsStruct structure.
  *
  * Update sensitivities on the Help menu.
  */
 void
-nact_main_menubar_help_on_update_sensitivities( NactMainWindow *window, gpointer user_data )
+nact_main_menubar_help_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis )
 {
 	/* TODO: help temporarily disabled */
 	nact_main_menubar_enable_item( window, "HelpItem", FALSE );
diff --git a/src/nact/nact-main-menubar-help.h b/src/nact/nact-main-menubar-help.h
index 6aa0efa..caaf4c8 100644
--- a/src/nact/nact-main-menubar-help.h
+++ b/src/nact/nact-main-menubar-help.h
@@ -39,11 +39,11 @@
 
 #include <gtk/gtk.h>
 
-#include "nact-main-window.h"
+#include "nact-main-menubar.h"
 
 G_BEGIN_DECLS
 
-void nact_main_menubar_help_on_update_sensitivities( NactMainWindow *window, gpointer user_data );
+void nact_main_menubar_help_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis );
 
 void nact_main_menubar_help_on_help ( GtkAction *action, NactMainWindow *window );
 void nact_main_menubar_help_on_about( GtkAction *action, NactMainWindow *window );
diff --git a/src/nact/nact-main-menubar-maintainer.c b/src/nact/nact-main-menubar-maintainer.c
index df1e175..6b61806 100644
--- a/src/nact/nact-main-menubar-maintainer.c
+++ b/src/nact/nact-main-menubar-maintainer.c
@@ -43,11 +43,12 @@
  * nact_main_menubar_maintainer_on_update_sensitivities:
  * @window: the #NactMainWindow main application window.
  * @user_data: user data ?
+ * @mis: the #MenubarIndicatorsStruct structure.
  *
  * Update sensitivities on the Maintainer menu.
  */
 void
-nact_main_menubar_maintainer_on_update_sensitivities( NactMainWindow *window, gpointer user_data )
+nact_main_menubar_maintainer_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis )
 {
 }
 
diff --git a/src/nact/nact-main-menubar-maintainer.h b/src/nact/nact-main-menubar-maintainer.h
index f816301..a99a730 100644
--- a/src/nact/nact-main-menubar-maintainer.h
+++ b/src/nact/nact-main-menubar-maintainer.h
@@ -39,11 +39,11 @@
 
 #include <gtk/gtk.h>
 
-#include "nact-main-window.h"
+#include "nact-main-menubar.h"
 
 G_BEGIN_DECLS
 
-void nact_main_menubar_maintainer_on_update_sensitivities( NactMainWindow *window, gpointer user_data );
+void nact_main_menubar_maintainer_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis );
 
 void nact_main_menubar_maintainer_on_dump_selection       ( GtkAction *action, NactMainWindow *window );
 void nact_main_menubar_maintainer_on_brief_tree_store_dump( GtkAction *action, NactMainWindow *window );
diff --git a/src/nact/nact-main-menubar-tools.c b/src/nact/nact-main-menubar-tools.c
index c97a45c..fea1403 100644
--- a/src/nact/nact-main-menubar-tools.c
+++ b/src/nact/nact-main-menubar-tools.c
@@ -41,23 +41,15 @@
  * nact_main_menubar_tools_on_update_sensitivities:
  * @window: the #NactMainWindow main application window.
  * @user_data: user data ?
+ * @mis: the #MenubarIndicatorsStruct structure.
  *
  * Update sensitivities on the Tools menu.
  */
 void
-nact_main_menubar_tools_on_update_sensitivities( NactMainWindow *window, gpointer user_data )
+nact_main_menubar_tools_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis )
 {
-	static const gchar *thisfn = "nact_main_menubar_tools_on_update_sensitivities";
-	MenubarIndicatorsStruct *mis;
-	gboolean has_writable_providers;
-
-	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
-
-	has_writable_providers = nact_window_has_writable_providers( NACT_WINDOW( window ));
-	g_debug( "%s: has_writable_providers=%s", thisfn, has_writable_providers ? "True":"False" );
-
 	/* import item enabled if at least one writable provider */
-	nact_main_menubar_enable_item( window, "ImportItem", has_writable_providers );
+	nact_main_menubar_enable_item( window, "ImportItem", mis->has_writable_providers );
 
 	/* export item enabled if IActionsList store contains actions */
 	nact_main_menubar_enable_item( window, "ExportItem", mis->have_exportables );
diff --git a/src/nact/nact-main-menubar-tools.h b/src/nact/nact-main-menubar-tools.h
index 660807b..719f2d2 100644
--- a/src/nact/nact-main-menubar-tools.h
+++ b/src/nact/nact-main-menubar-tools.h
@@ -39,11 +39,11 @@
 
 #include <gtk/gtk.h>
 
-#include "nact-main-window.h"
+#include "nact-main-menubar.h"
 
 G_BEGIN_DECLS
 
-void nact_main_menubar_tools_on_update_sensitivities( NactMainWindow *window, gpointer user_data );
+void nact_main_menubar_tools_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis );
 
 void nact_main_menubar_tools_on_import( GtkAction *action, NactMainWindow *window );
 void nact_main_menubar_tools_on_export( GtkAction *action, NactMainWindow *window );
diff --git a/src/nact/nact-main-menubar-view.c b/src/nact/nact-main-menubar-view.c
new file mode 100644
index 0000000..a5b7faa
--- /dev/null
+++ b/src/nact/nact-main-menubar-view.c
@@ -0,0 +1,152 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "nact-iactions-list.h"
+#include "nact-main-toolbar.h"
+#include "nact-main-menubar-view.h"
+
+static void on_view_toolbar_activated( GtkToggleAction *action, NactMainWindow *window, int toolbar_id );
+
+/**
+ * nact_main_menubar_view_on_update_sensitivities:
+ * @window: the #NactMainWindow main window.
+ * user_data: the data passed to the function via the signal.
+ * @mis: the #MenubarIndicatorsStruct struct.
+ *
+ * Update sensitivity of items of the View menu.
+ */
+void
+nact_main_menubar_view_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis )
+{
+	guint count_list;
+
+	/* expand all/collapse all requires at least one item in the list */
+	count_list = mis->list_menus + mis->list_actions + mis->list_profiles;
+	nact_main_menubar_enable_item( window, "ExpandAllItem", count_list > 0 );
+	nact_main_menubar_enable_item( window, "CollapseAllItem", count_list > 0 );
+}
+
+/**
+ * nact_main_menubar_view_on_expand_all:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers View / Expand all item.
+ */
+void
+nact_main_menubar_view_on_expand_all( GtkAction *gtk_action, NactMainWindow *window )
+{
+	nact_iactions_list_expand_all( NACT_IACTIONS_LIST( window ));
+}
+
+/**
+ * nact_main_menubar_view_on_collapse_all:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers View / Collapse all item.
+ */
+void
+nact_main_menubar_view_on_collapse_all( GtkAction *gtk_action, NactMainWindow *window )
+{
+	nact_iactions_list_collapse_all( NACT_IACTIONS_LIST( window ));
+}
+
+/**
+ * nact_main_menubar_view_on_toolbar_file:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers View / Toolbar / File item.
+ */
+void
+nact_main_menubar_view_on_toolbar_file( GtkToggleAction *action, NactMainWindow *window )
+{
+	/*on_view_toolbar_activated( action, window, MENUBAR_IPREFS_FILE_TOOLBAR, "/ui/FileToolbar", MENUBAR_FILE_TOOLBAR_POS );*/
+	on_view_toolbar_activated( action, window, MAIN_TOOLBAR_FILE_ID );
+}
+
+/**
+ * nact_main_menubar_view_on_toolbar_edit:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers View / Toolbar / Edit item.
+ */
+void
+nact_main_menubar_view_on_toolbar_edit( GtkToggleAction *action, NactMainWindow *window )
+{
+	/*on_view_toolbar_activated( action, window, MENUBAR_IPREFS_EDIT_TOOLBAR, "/ui/EditToolbar", MENUBAR_EDIT_TOOLBAR_POS );*/
+	on_view_toolbar_activated( action, window, MAIN_TOOLBAR_EDIT_ID );
+}
+
+/**
+ * nact_main_menubar_view_on_toolbar_tools:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers View / Toolbar / Tools item.
+ */
+void
+nact_main_menubar_view_on_toolbar_tools( GtkToggleAction *action, NactMainWindow *window )
+{
+	/*on_view_toolbar_activated( action, window, MENUBAR_IPREFS_TOOLS_TOOLBAR, "/ui/ToolsToolbar", MENUBAR_TOOLS_TOOLBAR_POS );*/
+	on_view_toolbar_activated( action, window, MAIN_TOOLBAR_TOOLS_ID );
+}
+
+/**
+ * nact_main_menubar_view_on_toolbar_help:
+ * @gtk_action: the #GtkAction action.
+ * @window: the #NactMainWindow main window.
+ *
+ * Triggers View / Toolbar / Help item.
+ */
+void
+nact_main_menubar_view_on_toolbar_help( GtkToggleAction *action, NactMainWindow *window )
+{
+	/*on_view_toolbar_activated( action, window, MENUBAR_IPREFS_HELP_TOOLBAR, "/ui/HelpToolbar", MENUBAR_HELP_TOOLBAR_POS );*/
+	on_view_toolbar_activated( action, window, MAIN_TOOLBAR_HELP_ID );
+}
+
+static void
+on_view_toolbar_activated( GtkToggleAction *action, NactMainWindow *window, int toolbar_id )
+{
+	gboolean is_active;
+	GtkUIManager *ui_manager;
+
+	is_active = gtk_toggle_action_get_active( action );
+	ui_manager = ( GtkUIManager * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_UI_MANAGER );
+
+	nact_main_toolbar_activate( window, toolbar_id, ui_manager, is_active );
+}
diff --git a/src/nact/nact-main-menubar-view.h b/src/nact/nact-main-menubar-view.h
new file mode 100644
index 0000000..1ad1882
--- /dev/null
+++ b/src/nact/nact-main-menubar-view.h
@@ -0,0 +1,57 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NACT_MAIN_MENUBAR_VIEW_H__
+#define __NACT_MAIN_MENUBAR_VIEW_H__
+
+/**
+ * SECTION: nact_main_menubar
+ * @short_description: Main menubar View menu management.
+ * @include: nact/nact-main-menubar-view.h
+ */
+
+#include <gtk/gtk.h>
+
+#include "nact-main-menubar.h"
+
+G_BEGIN_DECLS
+
+void nact_main_menubar_view_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis );
+
+void nact_main_menubar_view_on_expand_all   ( GtkAction *action, NactMainWindow *window );
+void nact_main_menubar_view_on_collapse_all ( GtkAction *action, NactMainWindow *window );
+void nact_main_menubar_view_on_toolbar_file ( GtkToggleAction *action, NactMainWindow *window );
+void nact_main_menubar_view_on_toolbar_edit ( GtkToggleAction *action, NactMainWindow *window );
+void nact_main_menubar_view_on_toolbar_tools( GtkToggleAction *action, NactMainWindow *window );
+void nact_main_menubar_view_on_toolbar_help ( GtkToggleAction *action, NactMainWindow *window );
+
+G_END_DECLS
+
+#endif /* __NACT_NACT_MENUBAR_VIEW_H__ */
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index 341a023..d45f60d 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -43,20 +43,21 @@
 #include <core/na-io-provider.h>
 
 #include "nact-application.h"
-#include "nact-preferences-editor.h"
 #include "nact-iactions-list.h"
 #include "nact-clipboard.h"
 #include "nact-main-statusbar.h"
 #include "nact-main-toolbar.h"
 #include "nact-main-tab.h"
 #include "nact-main-menubar.h"
+#include "nact-main-menubar-file.h"
+#include "nact-main-menubar-edit.h"
+#include "nact-main-menubar-view.h"
 #include "nact-main-menubar-tools.h"
 #include "nact-main-menubar-maintainer.h"
 #include "nact-main-menubar-help.h"
 
 #define MENUBAR_PROP_STATUS_CONTEXT			"nact-menubar-status-context"
 #define MENUBAR_PROP_MAIN_STATUS_CONTEXT	"nact-menubar-main-status-context"
-#define MENUBAR_PROP_UI_MANAGER				"nact-menubar-ui-manager"
 #define MENUBAR_PROP_ACTIONS_GROUP			"nact-menubar-actions-group"
 #define MENUBAR_IPREFS_FILE_TOOLBAR			"main-file-toolbar"
 #define MENUBAR_IPREFS_EDIT_TOOLBAR			"main-edit-toolbar"
@@ -92,35 +93,6 @@ static void     on_iactions_list_status_changed( NactMainWindow *window, gpointe
 static void     on_level_zero_order_changed( NactMainWindow *window, gpointer user_data );
 static void     on_update_sensitivities( NactMainWindow *window, gpointer user_data );
 
-static void     on_new_menu_activated( GtkAction *action, NactMainWindow *window );
-static void     on_new_action_activated( GtkAction *action, NactMainWindow *window );
-static void     on_new_profile_activated( GtkAction *action, NactMainWindow *window );
-static void     on_save_activated( GtkAction *action, NactMainWindow *window );
-static void     save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item );
-static void     on_quit_activated( GtkAction *action, NactMainWindow *window );
-
-static void     on_cut_activated( GtkAction *action, NactMainWindow *window );
-static void     on_copy_activated( GtkAction *action, NactMainWindow *window );
-static void     on_paste_activated( GtkAction *action, NactMainWindow *window );
-static void     on_paste_into_activated( GtkAction *action, NactMainWindow *window );
-static GList   *prepare_for_paste( NactMainWindow *window );
-static void     on_duplicate_activated( GtkAction *action, NactMainWindow *window );
-static void     on_delete_activated( GtkAction *action, NactMainWindow *window );
-static GList   *get_deletables( NAUpdater *updater, GList *tree, GSList **not_deletable );
-static GSList  *get_deletables_rec( NAUpdater *updater, GList *tree );
-static gchar   *add_non_deletable_msg( const NAObjectItem *item, gint reason );
-static void     update_clipboard_counters( NactMainWindow *window );
-static void     on_reload_activated( GtkAction *action, NactMainWindow *window );
-static void     on_preferences_activated( GtkAction *action, NactMainWindow *window );
-
-static void     on_expand_all_activated( GtkAction *action, NactMainWindow *window );
-static void     on_collapse_all_activated( GtkAction *action, NactMainWindow *window );
-static void     on_view_file_toolbar_activated( GtkToggleAction *action, NactMainWindow *window );
-static void     on_view_edit_toolbar_activated( GtkToggleAction *action, NactMainWindow *window );
-static void     on_view_tools_toolbar_activated( GtkToggleAction *action, NactMainWindow *window );
-static void     on_view_help_toolbar_activated( GtkToggleAction *action, NactMainWindow *window );
-static void     on_view_toolbar_activated( GtkToggleAction *action, NactMainWindow *window, int toolbar_id );
-
 static gboolean on_delete_event( GtkWidget *toplevel, GdkEvent *event, NactMainWindow *window );
 static void     on_destroy_callback( gpointer data );
 static void     on_menu_item_selected( GtkMenuItem *proxy, NactMainWindow *window );
@@ -142,63 +114,63 @@ static const GtkActionEntry entries[] = {
 		{ "NewMenuItem", NULL, N_( "New _menu" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the 'New menu' item */
 				N_( "Insert a new menu at the current position" ),
-				G_CALLBACK( on_new_menu_activated ) },
+				G_CALLBACK( nact_main_menubar_file_on_new_menu ) },
 		{ "NewActionItem", GTK_STOCK_NEW, N_( "_New action" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the 'New action' item */
 				N_( "Define a new action" ),
-				G_CALLBACK( on_new_action_activated ) },
+				G_CALLBACK( nact_main_menubar_file_on_new_action ) },
 		{ "NewProfileItem", NULL, N_( "New _profile" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the 'New profile' item */
 				N_( "Define a new profile attached to the current action" ),
-				G_CALLBACK( on_new_profile_activated ) },
+				G_CALLBACK( nact_main_menubar_file_on_new_profile ) },
 		{ "SaveItem", GTK_STOCK_SAVE, NULL, NULL,
 				/* i18n: tooltip displayed in the status bar when selecting 'Save' item */
 				N_( "Record all the modified actions. Invalid actions will be silently ignored" ),
-				G_CALLBACK( on_save_activated ) },
+				G_CALLBACK( nact_main_menubar_file_on_save ) },
 		{ "QuitItem", GTK_STOCK_QUIT, NULL, NULL,
 				/* i18n: tooltip displayed in the status bar when selecting 'Quit' item */
 				N_( "Quit the application" ),
-				G_CALLBACK( on_quit_activated ) },
+				G_CALLBACK( nact_main_menubar_file_on_quit ) },
 		{ "CutItem" , GTK_STOCK_CUT, NULL, NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the Cut item */
 				N_( "Cut the selected item(s) to the clipboard" ),
-				G_CALLBACK( on_cut_activated ) },
+				G_CALLBACK( nact_main_menubar_edit_on_cut ) },
 		{ "CopyItem" , GTK_STOCK_COPY, NULL, NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the Copy item */
 				N_( "Copy the selected item(s) to the clipboard" ),
-				G_CALLBACK( on_copy_activated ) },
+				G_CALLBACK( nact_main_menubar_edit_on_copy ) },
 		{ "PasteItem" , GTK_STOCK_PASTE, NULL, NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the Paste item */
 				N_( "Insert the content of the clipboard just before the current position" ),
-				G_CALLBACK( on_paste_activated ) },
+				G_CALLBACK( nact_main_menubar_edit_on_paste ) },
 		{ "PasteIntoItem" , NULL, N_( "Paste _into" ), "<Shift><Ctrl>V",
 				/* i18n: tooltip displayed in the status bar when selecting the Paste Into item */
 				N_( "Insert the content of the clipboard as first child of the current item" ),
-				G_CALLBACK( on_paste_into_activated ) },
+				G_CALLBACK( nact_main_menubar_edit_on_paste_into ) },
 		{ "DuplicateItem" , NULL, N_( "D_uplicate" ), "",
 				/* i18n: tooltip displayed in the status bar when selecting the Duplicate item */
 				N_( "Duplicate the selected item(s)" ),
-				G_CALLBACK( on_duplicate_activated ) },
+				G_CALLBACK( nact_main_menubar_edit_on_duplicate ) },
 		{ "DeleteItem", GTK_STOCK_DELETE, NULL, "Delete",
 				/* i18n: tooltip displayed in the status bar when selecting the Delete item */
 				N_( "Delete the selected item(s)" ),
-				G_CALLBACK( on_delete_activated ) },
+				G_CALLBACK( nact_main_menubar_edit_on_delete ) },
 		{ "ReloadActionsItem", GTK_STOCK_REFRESH, N_( "_Reload the items" ), "F5",
 				/* i18n: tooltip displayed in the status bar when selecting the 'Reload' item */
 				N_( "Cancel your current modifications and reload the initial list of menus and actions" ),
-				G_CALLBACK( on_reload_activated ) },
+				G_CALLBACK( nact_main_menubar_edit_on_reload ) },
 		{ "PreferencesItem", GTK_STOCK_PREFERENCES, NULL, NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the 'Preferences' item */
 				N_( "Edit your preferences" ),
-				G_CALLBACK( on_preferences_activated ) },
+				G_CALLBACK( nact_main_menubar_edit_on_prefererences ) },
 		{ "ExpandAllItem" , NULL, N_( "_Expand all" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the Expand all item */
 				N_( "Entirely expand the items hierarchy" ),
-				G_CALLBACK( on_expand_all_activated ) },
+				G_CALLBACK( nact_main_menubar_view_on_expand_all ) },
 		{ "CollapseAllItem" , NULL, N_( "_Collapse all" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the Collapse all item */
 				N_( "Entirely collapse the items hierarchy" ),
-				G_CALLBACK( on_collapse_all_activated ) },
+				G_CALLBACK( nact_main_menubar_view_on_collapse_all ) },
 
 		{ "ImportItem" , GTK_STOCK_CONVERT, N_( "_Import assistant..." ), "",
 				/* i18n: tooltip displayed in the status bar when selecting the Import item */
@@ -241,19 +213,19 @@ static const GtkToggleActionEntry toolbar_entries[] = {
 		{ "ViewFileToolbarItem", NULL, N_( "_File" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the 'View File toolbar' item */
 				N_( "Display the File toolbar" ),
-				G_CALLBACK( on_view_file_toolbar_activated ), FALSE },
+				G_CALLBACK( nact_main_menubar_view_on_toolbar_file ), FALSE },
 		{ "ViewEditToolbarItem", NULL, N_( "_Edit" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting the 'View Edit toolbar' item */
 				N_( "Display the Edit toolbar" ),
-				G_CALLBACK( on_view_edit_toolbar_activated ), FALSE },
+				G_CALLBACK( nact_main_menubar_view_on_toolbar_edit ), FALSE },
 		{ "ViewToolsToolbarItem", NULL, N_( "_Tools" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting 'View Tools toolbar' item */
 				N_( "Display the Tools toolbar" ),
-				G_CALLBACK( on_view_tools_toolbar_activated ), FALSE },
+				G_CALLBACK( nact_main_menubar_view_on_toolbar_tools ), FALSE },
 		{ "ViewHelpToolbarItem", NULL, N_( "_Help" ), NULL,
 				/* i18n: tooltip displayed in the status bar when selecting 'View Help toolbar' item */
 				N_( "Display the Help toolbar" ),
-				G_CALLBACK( on_view_help_toolbar_activated ), FALSE },
+				G_CALLBACK( nact_main_menubar_view_on_toolbar_help ), FALSE },
 };
 
 /**
@@ -432,33 +404,6 @@ nact_main_menubar_is_level_zero_order_changed( const NactMainWindow *window )
 }
 
 /**
- * Whether the specified object should be relabeled when pasted ?
- * @object: the considered #NAObject-derived object.
- * @pivot: the #NAPivot instance.
- *
- * Returns: %TRUE if the object should be relabeled, %FALSE else.
- */
-gboolean
-nact_main_menubar_is_pasted_object_relabeled( NAObject *object, NAPivot *pivot )
-{
-	static const gchar *thisfn = "nact_main_menubar_is_pasted_object_relabeled";
-	gboolean relabel;
-
-	if( NA_IS_OBJECT_MENU( object )){
-		relabel = na_iprefs_read_bool( NA_IPREFS( pivot ), IPREFS_RELABEL_MENUS, FALSE );
-	} else if( NA_IS_OBJECT_ACTION( object )){
-		relabel = na_iprefs_read_bool( NA_IPREFS( pivot ), IPREFS_RELABEL_ACTIONS, FALSE );
-	} else if( NA_IS_OBJECT_PROFILE( object )){
-		relabel = na_iprefs_read_bool( NA_IPREFS( pivot ), IPREFS_RELABEL_PROFILES, FALSE );
-	} else {
-		g_warning( "%s: unknown object type at %p", thisfn, ( void * ) object );
-		g_return_val_if_reached( FALSE );
-	}
-
-	return( relabel );
-}
-
-/**
  * nact_main_menubar_open_popup:
  * @window: this #NactMainWindow window.
  * @event: the mouse event.
@@ -587,905 +532,33 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_main_menubar_on_update_sensitivities";
 	NactApplication *application;
-	NAUpdater *updater;
-	gboolean is_level_zero_writable;
-	gboolean has_writable_providers;
-	gboolean has_modified_items;
-	GList *selected_items, *is;
-	NAObject *first_parent;
-	gboolean is_first_parent_writable;
-	gboolean new_item_enabled;
-	gboolean new_profile_enabled;
-	NAObject *selected_action;
-	NAObject *parent_item;
 	MenubarIndicatorsStruct *mis;
-	gboolean is_clipboard_empty;
-	gint count_selected;
-	gboolean are_parents_writable;
-	NAObject *selected_item;
-	gboolean cut_enabled;
-	gboolean copy_enabled;
-	gboolean paste_enabled;
-	gboolean paste_into_enabled;
-	gboolean duplicate_enabled;
-	gboolean delete_enabled;
-	gint count_list;
 
 	g_debug( "%s: window=%p, user_data=%p", thisfn, ( void * ) window, ( void * ) user_data );
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
 
-	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-	is_level_zero_writable = na_pivot_is_level_zero_writable( NA_PIVOT( updater ));
-
-	has_writable_providers = nact_window_has_writable_providers( NACT_WINDOW( window ));
-	g_debug( "%s: has_writable_providers=%s", thisfn, has_writable_providers ? "True":"False" );
-
-	has_modified_items = nact_main_window_has_modified_items( window );
-	g_debug( "%s: has_modified_items=%s", thisfn, has_modified_items ? "True":"False" );
-
-	selected_items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
-	first_parent = selected_items && g_list_length( selected_items )
-			? ( NAObject * ) na_object_get_parent( selected_items->data )
-			: NULL;
-	is_first_parent_writable = first_parent
-			? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( first_parent ), NULL )
-			: is_level_zero_writable;
-
 	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
-	is_clipboard_empty = ( mis->clipboard_menus + mis->clipboard_actions + mis->clipboard_profiles == 0 );
-	count_selected = selected_items ? g_list_length( selected_items ) : 0;
-	g_debug( "%s: count_selected=%d", thisfn, count_selected );
-
-	/* new menu / new action
-	 * new item will be inserted just before beginning of selection
-	 * parent of the first selected row must be writable
-	 * we must have at least one writable provider
-	 */
-	new_item_enabled = is_first_parent_writable && has_writable_providers;
-	nact_main_menubar_enable_item( window, "NewMenuItem", new_item_enabled );
-	nact_main_menubar_enable_item( window, "NewActionItem", new_item_enabled );
-
-	/* new profile enabled if selection is relative to only one writable action
-	 * i.e. contains profile(s) of the same action, or only contains one action
-	 * action must be writable
-	 */
-	new_profile_enabled = TRUE;
-	selected_action = NULL;
-	for( is = selected_items ; is ; is = is->next ){
-
-		if( NA_IS_OBJECT_MENU( is->data )){
-			new_profile_enabled = FALSE;
-			break;
-
-		} else if( NA_IS_OBJECT_ACTION( is->data )){
-			if( !selected_action ){
-				selected_action = NA_OBJECT( is->data );
-			} else if( selected_action != is->data ){
-				new_profile_enabled = FALSE;
-				break;
-			}
-
-		} else if( NA_IS_OBJECT_PROFILE( is->data )){
-			parent_item = NA_OBJECT( na_object_get_parent( is->data ));
-			if( !selected_action ){
-				selected_action = parent_item;
-			} else if( selected_action != parent_item ){
-				new_profile_enabled = FALSE;
-				break;
-			}
-		}
-	}
-	nact_main_menubar_enable_item( window, "NewProfileItem",
-			new_profile_enabled &&
-			selected_action != NULL &&
-			nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( selected_action ), NULL ));
-
-	/* save enabled if at least one item has been modified
-	 * or level-zero has been resorted and is writable
-	 */
-	nact_main_menubar_enable_item( window, "SaveItem",
-			has_modified_items || ( mis->level_zero_order_changed && is_level_zero_writable ));
-
-	/* quit always enabled */
-
-	/* cut requires a non-empty selection
-	 * and that all parents are writable (as implies a delete operation)
-	 */
-	cut_enabled = mis->treeview_has_focus || mis->popup_handler;
-	cut_enabled &= count_selected > 0;
-	are_parents_writable = TRUE;
-	for( is = selected_items ; is ; is = is->next ){
-		parent_item = ( NAObject * ) na_object_get_parent( is->data );
-		if( parent_item ){
-			if( !na_updater_is_item_writable( updater, NA_OBJECT_ITEM( parent_item ), NULL )){
-				are_parents_writable = FALSE;
-				break;
-			}
-		} else if( !is_level_zero_writable ){
-			are_parents_writable = FALSE;
-			break;
-		}
-	}
-	cut_enabled &= are_parents_writable;
-	nact_main_menubar_enable_item( window, "CutItem", cut_enabled );
-
-	/* copy only requires a non-empty selection */
-	copy_enabled = mis->treeview_has_focus || mis->popup_handler;
-	copy_enabled &= count_selected > 0;
-	nact_main_menubar_enable_item( window, "CopyItem", copy_enabled );
-
-	/* paste enabled if
-	 * - clipboard is not empty
-	 * - current selection is not multiple
-	 * - if clipboard contains only profiles,
-	 *   then current selection must be a profile or an action
-	 *   and the action must be writable
-	 * - if clipboard contains actions or menus,
-	 *   then current selection (if any) must be a menu or an action
-	 *   and its parent must be writable
-	 */
-	paste_enabled = mis->treeview_has_focus || mis->popup_handler;
-	paste_enabled &= !is_clipboard_empty;
-	paste_enabled &= count_selected <= 1;
-	if( mis->clipboard_profiles ){
-		paste_enabled &= count_selected == 1;
-		if( paste_enabled ){
-			selected_action = NA_OBJECT(
-					NA_IS_OBJECT_PROFILE( selected_items->data )
-							? na_object_get_parent( selected_items->data )
-							: selected_items->data );
-			paste_enabled &= NA_IS_OBJECT_ACTION( selected_action );
-			paste_enabled &= na_updater_is_item_writable( updater, NA_OBJECT_ITEM( selected_action ), NULL );
-		}
-	} else {
-		paste_enabled &= has_writable_providers;
-		if( count_selected ){
-			selected_item = NA_OBJECT( selected_items->data );
-			paste_enabled &= NA_IS_OBJECT_ITEM( selected_item );
-			if( paste_enabled ){
-				parent_item = ( NAObject * ) na_object_get_parent( selected_item );
-				paste_enabled &= parent_item
-						? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( parent_item ), NULL )
-						: is_level_zero_writable;
-			}
-		} else {
-			paste_enabled &= is_level_zero_writable;
-		}
-	}
-	nact_main_menubar_enable_item( window, "PasteItem", paste_enabled );
-
-	/* paste into enabled if
-	 * - clipboard is not empty
-	 * - current selection is not multiple
-	 * - if clipboard contains only profiles,
-	 *   then current selection must be an action
-	 *   and the action must be writable
-	 * - if clipboard contains actions or menus,
-	 *   then current selection (if any) must be a menu
-	 *   and its parent must be writable
-	 */
-	paste_into_enabled = mis->treeview_has_focus || mis->popup_handler;
-	paste_into_enabled &= !is_clipboard_empty;
-	paste_into_enabled &= count_selected <= 1;
-	if( mis->clipboard_profiles ){
-		paste_into_enabled &= count_selected == 1;
-		if( paste_into_enabled ){
-			selected_action = NA_OBJECT( selected_items->data );
-			paste_into_enabled &= NA_IS_OBJECT_ACTION( selected_action );
-			paste_into_enabled &= nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( selected_action ), NULL );
-		}
-	} else {
-		paste_into_enabled &= has_writable_providers;
-		if( count_selected ){
-			selected_item = NA_OBJECT( selected_items->data );
-			paste_into_enabled &= NA_IS_OBJECT_MENU( selected_item );
-			if( paste_into_enabled ){
-				parent_item = ( NAObject * ) na_object_get_parent( selected_item );
-				paste_into_enabled &= parent_item
-						? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( parent_item ), NULL )
-						: is_level_zero_writable;
-			}
-		} else {
-			paste_into_enabled &= is_level_zero_writable;
-		}
-	}
-	nact_main_menubar_enable_item( window, "PasteIntoItem", paste_into_enabled );
-
-	/* duplicate items will be duplicated besides each one
-	 * selection must be non-empty
-	 * each parent must be writable
-	 * -> so this is the same than cut
-	 */
-	duplicate_enabled = cut_enabled;
-	nact_main_menubar_enable_item( window, "DuplicateItem", duplicate_enabled );
-
-	/* delete is same that cut
-	 * but items themselves must be writable (because physically deleted)
-	 * this will be checked on delete activated
-	 */
-	delete_enabled = cut_enabled;
-	nact_main_menubar_enable_item( window, "DeleteItem", delete_enabled );
-
-	/* reload items always enabled */
-
-	/* preferences always enabled */
-
-	/* expand all/collapse all requires at least one item in the list */
-	count_list = mis->list_menus + mis->list_actions + mis->list_profiles;
-	nact_main_menubar_enable_item( window, "ExpandAllItem", count_list > 0 );
-	nact_main_menubar_enable_item( window, "CollapseAllItem", count_list > 0 );
-
-	nact_main_menubar_tools_on_update_sensitivities( window, user_data );
-	nact_main_menubar_maintainer_on_update_sensitivities( window, user_data );
-	nact_main_menubar_help_on_update_sensitivities( window, user_data );
-
-	na_object_unref_selected_items( selected_items );
-}
-
-static void
-on_new_menu_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	NAObjectMenu *menu;
-	GList *items;
-
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	menu = na_object_menu_new_with_defaults();
-	na_object_check_status( menu );
-	items = g_list_prepend( NULL, menu );
-	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-	na_object_unref_items( items );
-}
-
-static void
-on_new_action_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	NAObjectAction *action;
-	GList *items;
-
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	action = na_object_action_new_with_defaults();
-	na_object_check_status( action );
-	items = g_list_prepend( NULL, action );
-	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-	na_object_unref_items( items );
-}
-
-static void
-on_new_profile_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	NAObjectAction *action;
-	NAObjectProfile *profile;
-	gchar *name;
-	GList *items;
-
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	g_object_get(
-			G_OBJECT( window ),
-			TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
-			NULL );
-
-	profile = na_object_profile_new_with_defaults();
-	na_object_set_label( profile, _( "New profile" ));
-
-	name = na_object_action_get_new_profile_name( action );
-	na_object_set_id( profile, name );
-	g_free( name );
-
-	/*na_object_attach_profile( action, profile );*/
-
-	na_object_check_status( profile );
-
-	items = g_list_prepend( NULL, profile );
-	nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-	na_object_unref_items( items );
-}
-
-/*
- * saving is not only saving modified items, but also saving hierarchy
- * (and order if alpha order is not set)
- */
-static void
-on_save_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_on_save_activated";
-
-	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	nact_main_menubar_save_items( window );
-}
-
-/*
- * saving is not only saving modified items, but also saving hierarchy
- * (and order if alpha order is not set)
- */
-void
-nact_main_menubar_save_items( NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_save_items";
-	GList *items, *it;
-	NactApplication *application;
-	NAUpdater *updater;
-	MenubarIndicatorsStruct *mis;
-
-	g_debug( "%s: window=%p", thisfn, ( void * ) window );
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	/* remove deleted items
-	 * so that new actions with same id do not risk to be deleted later
-	 */
-	nact_main_window_remove_deleted( window );
-
-	/* always write the level zero list of items
-	 * and reset the corresponding modification flag
-	 */
-	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-	items = nact_iactions_list_bis_get_items( NACT_IACTIONS_LIST( window ));
-	na_pivot_write_level_zero( NA_PIVOT( updater ), items );
-
-	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
-	mis->level_zero_order_changed = FALSE;
-
-	/* recursively save the modified items
-	 * check is useless here if item was not modified, but not very costly
-	 * above all, it is less costly to check the status here, than to check
-	 * recursively each and every modified item
-	 */
-	for( it = items ; it ; it = it->next ){
-		save_item( window, updater, NA_OBJECT_ITEM( it->data ));
-		na_object_check_status( it->data );
-	}
-	g_list_free( items );
-
-	/* get ride of notification messages of IOProviders
-	 */
-	na_ipivot_consumer_delay_notify( NA_IPIVOT_CONSUMER( window ));
-}
-
-/*
- * iterates here on each and every row stored in the tree
- * - do not deal with profiles as they are directly managed by their
- *   action parent
- * - do not deal with not modified, or not valid, items, but allow
- *   for save their subitems
- */
-static void
-save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item )
-{
-	static const gchar *thisfn = "nact_main_menubar_save_item";
-	NAObjectItem *origin;
-	NAObjectItem *dup_pivot;
-	GList *subitems, *it;
-	NAObjectItem *parent;
-	gint pos;
-	NAIOProvider *provider_before;
-	NAIOProvider *provider_after;
-
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-	g_return_if_fail( NA_IS_UPDATER( updater ));
-	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
-
-	if( NA_IS_OBJECT_MENU( item )){
-		subitems = na_object_get_items( item );
-		for( it = subitems ; it ; it = it->next ){
-			save_item( window, updater, NA_OBJECT_ITEM( it->data ));
-		}
-	}
-
-	provider_before = na_object_get_provider( item );
-
-	if( na_object_is_modified( item ) &&
-		nact_window_save_item( NACT_WINDOW( window ), item )){
-
-			if( NA_IS_OBJECT_ACTION( item )){
-				na_object_reset_last_allocated( item );
-			}
-
-			/* now that the NAObjectItem has been (non recursively) saved,
-			 * we have to update NAPivot so that the next na_object_check_status()
-			 * will show us that this treeview item is no more modified
-			 */
-			origin = ( NAObjectItem * ) na_object_get_origin( item );
-			g_debug( "%s: origin=%p", thisfn, ( void * ) origin );
-
-			parent = NULL;
-			pos = -1;
-
-			if( origin ){
-				parent = na_object_get_parent( origin );
-				if( parent ){
-					pos = na_object_get_position( parent, origin );
-				}
-				na_updater_remove_item( updater, NA_OBJECT( origin ));
-			}
-
-			dup_pivot = NA_OBJECT_ITEM( na_object_duplicate( item ));
-			na_object_reset_origin( item, dup_pivot );
-			na_object_set_parent( dup_pivot, parent );
-			if( parent ){
-				if( pos == -1 ){
-					na_object_append_item( parent, dup_pivot );
-				} else {
-					na_object_insert_at( parent, dup_pivot, pos );
-				}
-			} else {
-				na_updater_append_item( updater, dup_pivot );
-			}
-
-			nact_iactions_list_bis_remove_modified( NACT_IACTIONS_LIST( window ), item );
-
-			provider_after = na_object_get_provider( item );
-			if( provider_after != provider_before ){
-				g_signal_emit_by_name( window, TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED, item );
-			}
-	}
-}
-
-static void
-on_quit_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_on_quit_activated";
-	gboolean has_modified;
-
-	g_debug( "%s: item=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ) || gtk_action == NULL );
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	has_modified = nact_main_window_has_modified_items( window );
-	if( !has_modified || nact_window_warn_modified( NACT_WINDOW( window ))){
-		g_object_unref( window );
-	}
-}
-
-/*
- * cuts the visible selection
- * - (tree) get new refs on selected items
- * - (main) add selected items to main list of deleted,
- *          moving newref from list_from_tree to main_list_of_deleted
- * - (menu) install in clipboard a copy of selected objects
- * - (tree) remove selected items, unreffing objects
- */
-static void
-on_cut_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_on_cut_activated";
-	NactApplication *application;
-	NAUpdater *updater;
-	GList *items;
-	NactClipboard *clipboard;
-	GList *to_delete;
-	GSList *non_deletables;
-
-	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
-
-	non_deletables = NULL;
-	to_delete = get_deletables( updater, items, &non_deletables );
-
-	if( non_deletables ){
-		gchar *second = na_core_utils_slist_join_at_end( non_deletables, "\n" );
-		base_window_error_dlg(
-				BASE_WINDOW( window ),
-				GTK_MESSAGE_INFO,
-				_( "Not all items have been cut as following ones are not modifiable:" ),
-				second );
-		g_free( second );
-		na_core_utils_slist_free( non_deletables );
-	}
-
-	if( to_delete ){
-		nact_main_window_move_to_deleted( window, to_delete );
-		clipboard = nact_main_window_get_clipboard( window );
-		nact_clipboard_primary_set( clipboard, to_delete, CLIPBOARD_MODE_CUT );
-		update_clipboard_counters( window );
-		nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( window ), to_delete, TRUE );
-	}
-
-	na_object_unref_selected_items( items );
-}
-
-/*
- * copies the visible selection
- * - (tree) get new refs on selected items
- * - (menu) install in clipboard a copy of selected objects
- *          renumbering actions/menus id to ensure unicity at paste time
- * - (menu) release refs on selected items
- * - (menu) refresh actions sensitivy (as selection doesn't change)
- */
-static void
-on_copy_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_on_copy_activated";
-	GList *items;
-	NactClipboard *clipboard;
-
-	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
-	clipboard = nact_main_window_get_clipboard( window );
-	nact_clipboard_primary_set( clipboard, items, CLIPBOARD_MODE_COPY );
-	update_clipboard_counters( window );
-	na_object_unref_selected_items( items );
-
-	g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
-}
-
-/*
- * pastes the current content of the clipboard at the current position
- * (same path, same level)
- * - (menu) get from clipboard a copy of installed items
- *          the clipboard will return a new copy
- *          and renumber its own data for allowing a new paste
- * - (tree) insert new items, the tree store will ref them
- *          attaching each item to its parent
- *          recursively checking edition status of the topmost parent
- *          selecting the first item at end
- * - (menu) unreffing the copy got from clipboard
- */
-static void
-on_paste_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_on_paste_activated";
-	GList *items;
-
-	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
-
-	items = prepare_for_paste( window );
-	if( items ){
-		nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
-		na_object_unref_items( items );
-	}
-}
-
-/*
- * pastes the current content of the clipboard as the first child of
- * currently selected item
- * - (menu) get from clipboard a copy of installed items
- *          the clipboard will return a new copy
- *          and renumber its own data for allowing a new paste
- * - (tree) insert new items, the tree store will ref them
- *          attaching each item to its parent
- *          recursively checking edition status of the topmost parent
- *          selecting the first item at end
- * - (menu) unreffing the copy got from clipboard
- */
-static void
-on_paste_into_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_on_paste_into_activated";
-	GList *items;
-
-	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
-
-	items = prepare_for_paste( window );
-	if( items ){
-		nact_iactions_list_bis_insert_into( NACT_IACTIONS_LIST( window ), items );
-		na_object_unref_items( items );
-	}
-}
-
-static GList *
-prepare_for_paste( NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_prepare_for_paste";
-	GList *items, *it;
-	NactClipboard *clipboard;
-	NAObjectAction *action;
-	gboolean relabel;
-	gboolean renumber;
-	NactApplication *application;
-	NAUpdater *updater;
 
 	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-
-	clipboard = nact_main_window_get_clipboard( window );
-	items = nact_clipboard_primary_get( clipboard, &renumber );
-	action = NULL;
+	mis->updater = nact_application_get_updater( application );
+	mis->is_level_zero_writable = na_pivot_is_level_zero_writable( NA_PIVOT( mis->updater ));
 
-	/* if pasted items are profiles, then setup the target action
-	 */
-	for( it = items ; it ; it = it->next ){
-
-		if( NA_IS_OBJECT_PROFILE( it->data )){
-			if( !action ){
-				g_object_get( G_OBJECT( window ), TAB_UPDATABLE_PROP_EDITED_ACTION, &action, NULL );
-				g_return_val_if_fail( NA_IS_OBJECT_ACTION( action ), NULL );
-			}
-		}
+	mis->has_writable_providers = nact_window_has_writable_providers( NACT_WINDOW( window ));
+	g_debug( "%s: has_writable_providers=%s", thisfn, mis->has_writable_providers ? "True":"False" );
 
-		relabel = nact_main_menubar_is_pasted_object_relabeled( NA_OBJECT( it->data ), NA_PIVOT( updater ));
-		na_object_prepare_for_paste( it->data, relabel, renumber, action );
-		na_object_check_status( it->data );
-	}
-
-	g_debug( "%s: action=%p (%s)",
-			thisfn, ( void * ) action, action ? G_OBJECT_TYPE_NAME( action ): "(null)" );
-
-	return( items );
-}
-
-/*
- * duplicate is just as paste, with the difference that content comes
- * from the current selection, instead of coming from the clipboard
- *
- * this is nonetheless a bit more complicated because when we duplicate
- * some items (e.g. a multiple selection), we expect to see the new
- * items just besides the original ones...
- */
-static void
-on_duplicate_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_on_duplicate_activated";
-	NactApplication *application;
-	NAUpdater *updater;
-	NAObjectAction *action;
-	GList *items, *it;
-	GList *dup;
-	NAObject *obj;
-	gboolean relabel;
-
-	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-
-	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
-	for( it = items ; it ; it = it->next ){
-		obj = NA_OBJECT( na_object_duplicate( it->data ));
-		action = NULL;
-
-		/* duplicating a profile
-		 * as we insert in sibling mode, the parent doesn't change
-		 */
-		if( NA_IS_OBJECT_PROFILE( obj )){
-			action = NA_OBJECT_ACTION( na_object_get_parent( it->data ));
-		}
-
-		relabel = nact_main_menubar_is_pasted_object_relabeled( obj, NA_PIVOT( updater ));
-		na_object_prepare_for_paste( obj, relabel, TRUE, action );
-		na_object_set_origin( obj, NULL );
-		na_object_check_status( obj );
-		dup = g_list_prepend( NULL, obj );
-		nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), dup, it->data );
-		na_object_unref_items( dup );
-	}
-
-	na_object_unref_selected_items( items );
-}
-
-/*
- * deletes the visible selection
- * - (tree) get new refs on selected items
- * - (tree) remove selected items, unreffing objects
- * - (main) add selected items to main list of deleted,
- *          moving newref from list_from_tree to main_list_of_deleted
- * - (tree) select next row (if any, or previous if any, or none)
- *
- * note that we get from selection a list of trees, but we don't have
- * yet ensured that each element of this tree is actually deletable
- * each branch of this list must be recursively deletable in order
- * this branch itself be deleted
- */
-static void
-on_delete_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	static const gchar *thisfn = "nact_main_menubar_on_delete_activated";
-	NactApplication *application;
-	NAUpdater *updater;
-	GList *items;
-	GList *to_delete;
-	GSList *non_deletables;
-
-	g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
-	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
-	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
-
-	application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
-	updater = nact_application_get_updater( application );
-	items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
-
-	non_deletables = NULL;
-	to_delete = get_deletables( updater, items, &non_deletables );
-
-	if( non_deletables ){
-		gchar *second = na_core_utils_slist_join_at_end( non_deletables, "\n" );
-		base_window_error_dlg(
-				BASE_WINDOW( window ),
-				GTK_MESSAGE_INFO,
-				_( "Not all items have been deleted as following ones are not modifiable:" ),
-				second );
-		g_free( second );
-		na_core_utils_slist_free( non_deletables );
-	}
-
-	if( to_delete ){
-		nact_main_window_move_to_deleted( window, to_delete );
-		nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( window ), to_delete, TRUE );
-	}
-
-	na_object_unref_selected_items( items );
-}
-
-static GList *
-get_deletables( NAUpdater *updater, GList *selected, GSList **non_deletables )
-{
-	GList *to_delete;
-	GList *it;
-	GList *subitems;
-	GSList *sub_deletables;
-	gint reason;
-
-	to_delete = NULL;
-	for( it = selected ; it ; it = it->next ){
-
-		if( !na_updater_is_item_writable( updater, NA_OBJECT_ITEM( it->data ), &reason )){
-			*non_deletables = g_slist_prepend(
-					*non_deletables, add_non_deletable_msg( NA_OBJECT_ITEM( it->data ), reason ));
-			continue;
-		}
-
-		if( NA_IS_OBJECT_MENU( it->data )){
-			subitems = na_object_get_items( it->data );
-			sub_deletables = get_deletables_rec( updater, subitems );
-
-			if( sub_deletables ){
-				*non_deletables = g_slist_concat( *non_deletables, sub_deletables );
-				continue;
-			}
-		}
-
-		to_delete = g_list_prepend( to_delete, na_object_ref( it->data ));
-	}
-
-	return( to_delete );
-}
-
-static GSList *
-get_deletables_rec( NAUpdater *updater, GList *tree )
-{
-	GSList *msgs;
-	GList *it;
-	GList *subitems;
-	gint reason;
-
-	msgs = NULL;
-	for( it = tree ; it ; it = it->next ){
-
-		if( !na_updater_is_item_writable( updater, NA_OBJECT_ITEM( it->data ), &reason )){
-			msgs = g_slist_prepend(
-					msgs, add_non_deletable_msg( NA_OBJECT_ITEM( it->data ), reason ));
-			continue;
-		}
-
-		if( NA_IS_OBJECT_MENU( it->data )){
-			subitems = na_object_get_items( it->data );
-			msgs = g_slist_concat( msgs, get_deletables_rec( updater, subitems ));
-		}
-	}
-
-	return( msgs );
-}
-
-static gchar *
-add_non_deletable_msg( const NAObjectItem *item, gint reason )
-{
-	gchar *msg;
-	gchar *label;
-	gchar *reason_str;
-
-	label = na_object_get_label( item );
-	reason_str = na_io_provider_get_readonly_tooltip( reason );
-
-	msg = g_strdup_printf( "%s: %s", label, reason_str );
-
-	g_free( reason_str );
-	g_free( label );
-
-	return( msg );
-}
-
-/*
- * as we are coming from cut or copy to clipboard, report selection
- * counters to clipboard ones
- */
-static void
-update_clipboard_counters( NactMainWindow *window )
-{
-	MenubarIndicatorsStruct *mis;
-
-	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
-
-	mis->clipboard_menus = mis->selected_menus;
-	mis->clipboard_actions = mis->selected_actions;
-	mis->clipboard_profiles = mis->selected_profiles;
-
-	g_debug( "nact_main_menubar_update_clipboard_counters: menus=%d, actions=%d, profiles=%d",
-			mis->clipboard_menus, mis->clipboard_actions, mis->clipboard_profiles );
-
-	g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
-}
-
-static void
-on_reload_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	nact_main_window_reload( window );
-}
-
-static void
-on_preferences_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	nact_preferences_editor_run( BASE_WINDOW( window ));
-}
-
-static void
-on_expand_all_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	nact_iactions_list_expand_all( NACT_IACTIONS_LIST( window ));
-}
-
-static void
-on_collapse_all_activated( GtkAction *gtk_action, NactMainWindow *window )
-{
-	nact_iactions_list_collapse_all( NACT_IACTIONS_LIST( window ));
-}
-
-static void
-on_view_file_toolbar_activated( GtkToggleAction *action, NactMainWindow *window )
-{
-	/*on_view_toolbar_activated( action, window, MENUBAR_IPREFS_FILE_TOOLBAR, "/ui/FileToolbar", MENUBAR_FILE_TOOLBAR_POS );*/
-	on_view_toolbar_activated( action, window, MAIN_TOOLBAR_FILE_ID );
-}
-
-static void
-on_view_edit_toolbar_activated( GtkToggleAction *action, NactMainWindow *window )
-{
-	/*on_view_toolbar_activated( action, window, MENUBAR_IPREFS_EDIT_TOOLBAR, "/ui/EditToolbar", MENUBAR_EDIT_TOOLBAR_POS );*/
-	on_view_toolbar_activated( action, window, MAIN_TOOLBAR_EDIT_ID );
-}
-
-static void
-on_view_tools_toolbar_activated( GtkToggleAction *action, NactMainWindow *window )
-{
-	/*on_view_toolbar_activated( action, window, MENUBAR_IPREFS_TOOLS_TOOLBAR, "/ui/ToolsToolbar", MENUBAR_TOOLS_TOOLBAR_POS );*/
-	on_view_toolbar_activated( action, window, MAIN_TOOLBAR_TOOLS_ID );
-}
-
-static void
-on_view_help_toolbar_activated( GtkToggleAction *action, NactMainWindow *window )
-{
-	/*on_view_toolbar_activated( action, window, MENUBAR_IPREFS_HELP_TOOLBAR, "/ui/HelpToolbar", MENUBAR_HELP_TOOLBAR_POS );*/
-	on_view_toolbar_activated( action, window, MAIN_TOOLBAR_HELP_ID );
-}
-
-static void
-on_view_toolbar_activated( GtkToggleAction *action, NactMainWindow *window, int toolbar_id )
-{
-	gboolean is_active;
-	GtkUIManager *ui_manager;
+	mis->selected_items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
+	mis->count_selected = mis->selected_items ? g_list_length( mis->selected_items ) : 0;
+	g_debug( "%s: count_selected=%d", thisfn, mis->count_selected );
 
-	is_active = gtk_toggle_action_get_active( action );
-	ui_manager = ( GtkUIManager * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_UI_MANAGER );
+	nact_main_menubar_file_on_update_sensitivities( window, user_data, mis );
+	nact_main_menubar_edit_on_update_sensitivities( window, user_data, mis );
+	nact_main_menubar_view_on_update_sensitivities( window, user_data, mis );
+	nact_main_menubar_tools_on_update_sensitivities( window, user_data, mis );
+	nact_main_menubar_maintainer_on_update_sensitivities( window, user_data, mis );
+	nact_main_menubar_help_on_update_sensitivities( window, user_data, mis );
 
-	nact_main_toolbar_activate( window, toolbar_id, ui_manager, is_active );
+	na_object_unref_selected_items( mis->selected_items );
+	mis->selected_items = NULL;
 }
 
 /**
@@ -1515,7 +588,7 @@ on_delete_event( GtkWidget *toplevel, GdkEvent *event, NactMainWindow *window )
 	g_debug( "%s: toplevel=%p, event=%p, window=%p",
 			thisfn, ( void * ) toplevel, ( void * ) event, ( void * ) window );
 
-	on_quit_activated( NULL, window );
+	nact_main_menubar_file_on_quit( NULL, window );
 
 	return( TRUE );
 }
diff --git a/src/nact/nact-main-menubar.h b/src/nact/nact-main-menubar.h
index 417685f..cf48e3f 100644
--- a/src/nact/nact-main-menubar.h
+++ b/src/nact/nact-main-menubar.h
@@ -39,7 +39,7 @@
 
 #include <api/na-object.h>
 
-#include <core/na-pivot.h>
+#include <core/na-updater.h>
 
 #include "nact-main-window.h"
 
@@ -49,31 +49,38 @@ G_BEGIN_DECLS
  * interface ; it is then used to update action sensitivities
  */
 typedef struct {
-	gint     selected_menus;
-	gint     selected_actions;
-	gint     selected_profiles;
-	gint     clipboard_menus;
-	gint     clipboard_actions;
-	gint     clipboard_profiles;
-	gint     list_menus;
-	gint     list_actions;
-	gint     list_profiles;
-	gboolean is_modified;
-	gboolean have_exportables;
-	gboolean treeview_has_focus;
-	gboolean level_zero_order_changed;
-	gulong   popup_handler;
+	gint       selected_menus;
+	gint       selected_actions;
+	gint       selected_profiles;
+	gint       clipboard_menus;
+	gint       clipboard_actions;
+	gint       clipboard_profiles;
+	gint       list_menus;
+	gint       list_actions;
+	gint       list_profiles;
+	gboolean   is_modified;
+	gboolean   have_exportables;
+	gboolean   treeview_has_focus;
+	gboolean   level_zero_order_changed;
+	gulong     popup_handler;
+
+	/* set by the nact_main_menubar_on_update_sensitivities() function itself
+	 */
+	gboolean   is_level_zero_writable;
+	gboolean   has_writable_providers;
+	guint      count_selected;
+	GList     *selected_items;
+	NAUpdater *updater;
 }
 	MenubarIndicatorsStruct;
 
-#define MENUBAR_PROP_INDICATORS			"nact-menubar-indicators"
+#define MENUBAR_PROP_INDICATORS				"nact-menubar-indicators"
+#define MENUBAR_PROP_UI_MANAGER				"nact-menubar-ui-manager"
 
 void     nact_main_menubar_runtime_init( NactMainWindow *window );
 void     nact_main_menubar_dispose( NactMainWindow *window );
 gboolean nact_main_menubar_is_level_zero_order_changed( const NactMainWindow *window );
-gboolean nact_main_menubar_is_pasted_object_relabeled( NAObject *object, NAPivot *pivot );
 void     nact_main_menubar_open_popup( NactMainWindow *window, GdkEventButton *event );
-void     nact_main_menubar_save_items( NactMainWindow *window );
 void     nact_main_menubar_enable_item( NactMainWindow *window, const gchar *name, gboolean enabled );
 
 G_END_DECLS
diff --git a/src/nact/nact-tree-model-dnd.c b/src/nact/nact-tree-model-dnd.c
index 10574f3..8784598 100644
--- a/src/nact/nact-tree-model-dnd.c
+++ b/src/nact/nact-tree-model-dnd.c
@@ -47,7 +47,7 @@
 #include "nact-clipboard.h"
 #include "nact-iactions-list.h"
 #include "nact-iprefs.h"
-#include "nact-main-menubar.h"
+#include "nact-main-menubar-edit.h"
 #include "nact-main-statusbar.h"
 #include "nact-main-window.h"
 #include "nact-tree-model.h"
@@ -563,7 +563,7 @@ drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selecti
 					g_list_free( deletable );
 				}
 
-				relabel = nact_main_menubar_is_pasted_object_relabeled( inserted, NA_PIVOT( updater ));
+				relabel = nact_main_menubar_edit_is_pasted_object_relabeled( inserted, NA_PIVOT( updater ));
 				na_object_prepare_for_paste( inserted, relabel, copy_data, parent );
 				object_list = g_list_prepend( object_list, inserted );
 				g_debug( "%s: dropped=%s", thisfn, na_object_get_label( inserted ));



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