[nautilus-actions] Manage read-only items in the UI



commit 3a40c61a85ce43a8a05a5cbbfa5c990e02af0dbb
Author: Pierre Wieser <pwieser trychlos org>
Date:   Tue Dec 15 19:05:51 2009 +0100

    Manage read-only items in the UI

 ChangeLog                                          |   19 ++
 TODO                                               |    3 +-
 nautilus-actions/nact/Makefile.am                  |    2 +
 nautilus-actions/nact/nact-gtk-utils.c             |   85 +++++++
 nautilus-actions/nact/nact-gtk-utils.h             |   48 ++++
 nautilus-actions/nact/nact-iaction-tab.c           |  259 ++++++++++++++------
 nautilus-actions/nact/nact-iactions-list.c         |    6 +-
 nautilus-actions/nact/nact-iadvanced-tab.c         |  132 +++++++---
 nautilus-actions/nact/nact-ibackground-tab.c       |   83 +++++--
 nautilus-actions/nact/nact-icommand-tab.c          |   90 ++++---
 nautilus-actions/nact/nact-iconditions-tab.c       |  136 ++++++++---
 nautilus-actions/nact/nact-main-tab.h              |    2 +
 nautilus-actions/nact/nact-main-window.c           |   54 ++++-
 .../nact/nautilus-actions-config-tool.ui           |   20 +-
 14 files changed, 712 insertions(+), 227 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 2ab2440..7817134 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2009-12-15 Pierre Wieser <pwieser trychlos org>
+
+	* nautilus-actions/nact/nact-gtk-utils.c:
+	* nautilus-actions/nact/nact-gtk-utils.h: New files.
+
+	* nautilus-actions/nact/Makefile.am: Updated accordingly.
+
+	* nautilus-actions/nact/nact-main-tab.h:
+	* nautilus-actions/nact/nact-main-window.c:
+	Define TAB_UPDATABLE_PROP_READONLY_ITEM and
+	TAB_UPDATABLE_PROP_WRITABLE_PROVIDER new properties.
+
+	* nautilus-actions/nact/nact-iaction-tab.c:
+	* nautilus-actions/nact/nact-iadvanced-tab.c:
+	* nautilus-actions/nact/nact-ibackground-tab.c:
+	* nautilus-actions/nact/nact-icommand-tab.c:
+	* nautilus-actions/nact/nact-iconditions-tab.c:
+	Manage read-only items.
+
 2009-12-13 Pierre Wieser <pwieser trychlos org>
 
 	* nautilus-actions/api/na-api.h (na_api_module_get_version):
diff --git a/TODO b/TODO
index ac079b2..51b50bd 100644
--- a/TODO
+++ b/TODO
@@ -99,5 +99,4 @@
 
 - desktop provider: fix default toolbar label
 
-- readonly_item or locked_provider:
-  all entry/button fields should be readonly
+- setup tree-model dnd code when item or parent is readonly
diff --git a/nautilus-actions/nact/Makefile.am b/nautilus-actions/nact/Makefile.am
index f68a117..3a9cf52 100644
--- a/nautilus-actions/nact/Makefile.am
+++ b/nautilus-actions/nact/Makefile.am
@@ -84,6 +84,8 @@ nautilus_actions_config_tool_SOURCES = \
 	nact-clipboard.h											\
 	nact-confirm-logout.c										\
 	nact-confirm-logout.h										\
+	nact-gtk-utils.c											\
+	nact-gtk-utils.h											\
 	nact-iactions-list.c										\
 	nact-iactions-list.h										\
 	nact-iaction-tab.c											\
diff --git a/nautilus-actions/nact/nact-gtk-utils.c b/nautilus-actions/nact/nact-gtk-utils.c
new file mode 100644
index 0000000..42df3f6
--- /dev/null
+++ b/nautilus-actions/nact/nact-gtk-utils.c
@@ -0,0 +1,85 @@
+/*
+ * 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 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.h>
+
+#include "nact-gtk-utils.h"
+
+/**
+ * nact_gtk_utils_set_editable:
+ * @widget: the #GtkWdiget.
+ * @editable: whether the @widget is editable or not.
+ *
+ * Try to set a visual indication of whether the @widget is editable or not.
+ */
+void
+nact_gtk_utils_set_editable( GtkObject *widget, gboolean editable )
+{
+	GList *renderers, *irender;
+
+	if( GTK_IS_ENTRY( widget )){
+		gtk_editable_set_editable( GTK_EDITABLE( widget ), editable );
+		/* removing the frame leads to a disturbing modification of the
+		 * height of the control */
+		/*g_object_set( G_OBJECT( widget ), "has-frame", editable, NULL );*/
+		/* this prevents the caret to be displayed when we click in the entry */
+		g_object_set( G_OBJECT( widget ), "can-focus", editable, NULL );
+
+	} else if( GTK_IS_TOGGLE_BUTTON( widget )){
+		/* transforms to a quasi standard GtkButton */
+		/*g_object_set( G_OBJECT( widget ), "draw-indicator", editable, NULL );*/
+		/* this at least prevent the keyboard focus to go to the button
+		 * (which is better than nothing) */
+		g_object_set( G_OBJECT( widget ), "can-focus", editable, NULL );
+
+	} else if( GTK_IS_BUTTON( widget )){
+		gtk_widget_set_sensitive( GTK_WIDGET( widget ), editable );
+
+	} else if( GTK_IS_COMBO_BOX_ENTRY( widget )){
+		/* idem as GtkEntry */
+		gtk_editable_set_editable( GTK_EDITABLE( gtk_bin_get_child( GTK_BIN( widget ))), editable );
+		g_object_set( G_OBJECT( gtk_bin_get_child( GTK_BIN( widget ))), "can-focus", editable, NULL );
+		/* disable the listbox button itself */
+		gtk_combo_box_set_button_sensitivity( GTK_COMBO_BOX( widget ), editable ? GTK_SENSITIVITY_ON : GTK_SENSITIVITY_OFF );
+
+	} else if( GTK_IS_TREE_VIEW_COLUMN( widget )){
+		renderers = gtk_tree_view_column_get_cell_renderers( GTK_TREE_VIEW_COLUMN( widget ));
+		for( irender = renderers ; irender ; irender = irender->next ){
+			if( GTK_IS_CELL_RENDERER_TEXT( irender->data )){
+				g_object_set( G_OBJECT( irender->data ), "editable", editable, "editable-set", TRUE, NULL );
+			}
+		}
+		g_list_free( renderers );
+	}
+}
diff --git a/nautilus-actions/nact/nact-gtk-utils.h b/nautilus-actions/nact/nact-gtk-utils.h
new file mode 100644
index 0000000..4d6c7c3
--- /dev/null
+++ b/nautilus-actions/nact/nact-gtk-utils.h
@@ -0,0 +1,48 @@
+/*
+ * 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 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_GTK_UTILS_H__
+#define __NACT_GTK_UTILS_H__
+
+/**
+ * SECTION: nact_gtk_utils
+ * @short_description: Gtk helper functions.
+ * @include: nact/nact-gtk-utils.h
+ */
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+void nact_gtk_utils_set_editable( GtkObject *widget, gboolean editable );
+
+G_END_DECLS
+
+#endif /* __NACT_GTK_UTILS_H__ */
diff --git a/nautilus-actions/nact/nact-iaction-tab.c b/nautilus-actions/nact/nact-iaction-tab.c
index 4e6c50f..f3413b2 100644
--- a/nautilus-actions/nact/nact-iaction-tab.c
+++ b/nautilus-actions/nact/nact-iaction-tab.c
@@ -42,6 +42,7 @@
 #include "base-window.h"
 #include "nact-application.h"
 #include "nact-main-statusbar.h"
+#include "nact-gtk-utils.h"
 #include "nact-iactions-list.h"
 #include "nact-main-tab.h"
 #include "nact-iaction-tab.h"
@@ -66,6 +67,7 @@ enum {
 
 static gboolean st_initialized = FALSE;
 static gboolean st_finalized = FALSE;
+static gboolean st_on_selection_change = FALSE;
 
 static GType         register_type( void );
 static void          interface_base_init( NactIActionTabInterface *klass );
@@ -103,6 +105,8 @@ static void          release_icon_combobox( NactIActionTab *instance );
 static GtkButton    *get_enabled_button( NactIActionTab *instance );
 static void          on_enabled_toggled( GtkToggleButton *button, NactIActionTab *instance );
 
+static void          on_readonly_toggled( GtkToggleButton *button, NactIActionTab *instance );
+
 GType
 nact_iaction_tab_get_type( void )
 {
@@ -284,6 +288,13 @@ nact_iaction_tab_runtime_init_toplevel( NactIActionTab *instance )
 				G_OBJECT( enabled_button ),
 				"toggled",
 				G_CALLBACK( on_enabled_toggled ));
+
+		button = base_window_get_widget( BASE_WINDOW( instance ), "ActionReadonlyButton" );
+		base_window_signal_connect(
+				BASE_WINDOW( instance ),
+				G_OBJECT( button ),
+				"toggled",
+				G_CALLBACK( on_readonly_toggled ));
 	}
 }
 
@@ -376,6 +387,7 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 	GtkToggleButton *toggle;
 	NAIIOProvider *provider;
 	gboolean readonly;
+	gboolean readonly_item, writable_provider;
 
 	g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
 	g_return_if_fail( BASE_IS_WINDOW( instance ));
@@ -385,10 +397,13 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 
 		application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( instance )));
 		pivot = nact_application_get_pivot( application );
+		st_on_selection_change = TRUE;
 
 		g_object_get(
 				G_OBJECT( instance ),
 				TAB_UPDATABLE_PROP_EDITED_ACTION, &item,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
 				NULL );
 
 		g_return_if_fail( !item || NA_IS_OBJECT_ITEM( item ));
@@ -404,18 +419,20 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 				( NA_IS_OBJECT_ACTION( item ) && na_object_action_is_target_background( NA_OBJECT_ACTION( item ))) ||
 				( NA_IS_OBJECT_MENU( item ))));
 
-		target_toolbar = (item && (
+		target_toolbar = ( item && (
 				( NA_IS_OBJECT_ACTION( item ) && na_object_action_is_target_toolbar( NA_OBJECT_ACTION( item )))));
 
-		readonly = item ? na_object_is_readonly( item ) : FALSE;
+		readonly = readonly_item || !writable_provider;
 
 		toggle = GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "ActionTargetSelectionButton" ));
 		gtk_toggle_button_set_active( toggle, target_selection );
-		gtk_widget_set_sensitive( GTK_WIDGET( toggle ), item && NA_IS_OBJECT_ACTION( item ) && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( toggle ), item && NA_IS_OBJECT_ACTION( item ));
+		nact_gtk_utils_set_editable( GTK_OBJECT( toggle ), !readonly );
 
 		toggle = GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "ActionTargetBackgroundButton" ));
 		gtk_toggle_button_set_active( toggle, target_background );
-		gtk_widget_set_sensitive( GTK_WIDGET( toggle ), item && NA_IS_OBJECT_ACTION( item ) && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( toggle ), item && NA_IS_OBJECT_ACTION( item ));
+		nact_gtk_utils_set_editable( GTK_OBJECT( toggle ), !readonly );
 
 		enable_label = ( item && ( NA_IS_OBJECT_MENU( item ) || target_selection || target_background ));
 		label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionMenuLabelEntry" );
@@ -425,37 +442,44 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 			check_for_label( instance, GTK_ENTRY( label_widget ), label );
 		}
 		g_free( label );
-		gtk_widget_set_sensitive( label_widget, enable_label && !readonly );
+		gtk_widget_set_sensitive( label_widget, enable_label );
+		nact_gtk_utils_set_editable( GTK_OBJECT( label_widget ), !readonly );
 
 		toggle = GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "ActionTargetToolbarButton" ));
 		gtk_toggle_button_set_active( toggle, target_toolbar );
-		gtk_widget_set_sensitive( GTK_WIDGET( toggle ), item && NA_IS_OBJECT_ACTION( item ) && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( toggle ), item && NA_IS_OBJECT_ACTION( item ));
+		nact_gtk_utils_set_editable( GTK_OBJECT( toggle ), !readonly );
 
 		toggle = GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "ToolbarSameLabelButton" ));
 		same_label = item && NA_IS_OBJECT_ACTION( item ) ? na_object_action_toolbar_use_same_label( NA_OBJECT_ACTION( item )) : FALSE;
 		gtk_toggle_button_set_active( toggle, same_label );
 		toolbar_same_label_set_sensitive( instance, item );
+		nact_gtk_utils_set_editable( GTK_OBJECT( toggle ), !readonly );
 
 		label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionIconLabelEntry" );
 		label = item && NA_IS_OBJECT_ACTION( item ) ? na_object_action_toolbar_get_label( NA_OBJECT_ACTION( item )) : g_strdup( "" );
 		gtk_entry_set_text( GTK_ENTRY( label_widget ), label );
 		g_free( label );
 		toolbar_label_set_sensitive( instance, item );
+		nact_gtk_utils_set_editable( GTK_OBJECT( label_widget ), !readonly );
 
 		tooltip_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionTooltipEntry" );
 		tooltip = item ? na_object_get_tooltip( item ) : g_strdup( "" );
 		gtk_entry_set_text( GTK_ENTRY( tooltip_widget ), tooltip );
 		g_free( tooltip );
-		gtk_widget_set_sensitive( tooltip_widget, item && !readonly );
+		gtk_widget_set_sensitive( tooltip_widget, item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( tooltip_widget ), !readonly );
 
 		icon_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionIconComboBoxEntry" );
 		icon = item ? na_object_get_icon( item ) : g_strdup( "" );
 		gtk_entry_set_text( GTK_ENTRY( GTK_BIN( icon_widget )->child ), icon );
 		g_free( icon );
-		gtk_widget_set_sensitive( icon_widget, item && !readonly );
+		gtk_widget_set_sensitive( icon_widget, item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( icon_widget ), !readonly );
 
 		icon_button = GTK_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "ActionIconBrowseButton" ));
-		gtk_widget_set_sensitive( GTK_WIDGET( icon_button ), item && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( icon_button ), item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( icon_button ), !readonly );
 
 		title_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionPropertiesTitle" );
 		if( item && NA_IS_OBJECT_MENU( item )){
@@ -467,17 +491,22 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 		enabled_button = get_enabled_button( instance );
 		enabled_item = item ? na_object_is_enabled( NA_OBJECT_ITEM( item )) : FALSE;
 		gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( enabled_button ), enabled_item );
-		gtk_widget_set_sensitive( GTK_WIDGET( enabled_button ), item && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( enabled_button ), item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( enabled_button ), !readonly );
 
+		/* read-only toggle only indicates the writability status of this item
+		 * _not_ the writability status of the provider
+		 */
 		readonly_button = GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "ActionReadonlyButton" ));
-		gtk_toggle_button_set_active( readonly_button, readonly );
-		gtk_widget_set_sensitive( GTK_WIDGET( readonly_button ), FALSE );
+		gtk_toggle_button_set_active( readonly_button, readonly_item );
+		gtk_widget_set_sensitive( GTK_WIDGET( readonly_button ), item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( readonly_button ), FALSE );
 
 		label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionItemID" );
 		label = item ? na_object_get_id( item ) : g_strdup( "" );
 		gtk_label_set_text( GTK_LABEL( label_widget ), label );
 		g_free( label );
-		gtk_widget_set_sensitive( label_widget, item && !readonly );
+		gtk_widget_set_sensitive( label_widget, item != NULL );
 
 		label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionItemProvider" );
 		label = NULL;
@@ -492,7 +521,9 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
 		}
 		gtk_label_set_text( GTK_LABEL( label_widget ), label );
 		g_free( label );
-		gtk_widget_set_sensitive( label_widget, item && !readonly );
+		gtk_widget_set_sensitive( label_widget, item != NULL );
+
+		st_on_selection_change = FALSE;
 	}
 }
 
@@ -502,21 +533,38 @@ on_target_selection_toggled( GtkToggleButton *button, NactIActionTab *instance )
 	static const gchar *thisfn = "nact_iaction_tab_on_target_selection_toggled";
 	NAObjectAction *action;
 	gboolean is_target;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
+	if( !st_on_selection_change ){
+		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
-			NULL );
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+				NULL );
+
+		g_debug( "%s: item=%p (%s), readonly_item=%s, writable_provider=%s",
+				thisfn, ( void * ) action, action ? G_OBJECT_TYPE_NAME( action ) : "(null)",
+				readonly_item ? "True":"False", writable_provider ? "True":"False" );
+
+		if( action && NA_IS_OBJECT_ACTION( action )){
 
-	if( action && NA_IS_OBJECT_ACTION( action )){
+			is_target = gtk_toggle_button_get_active( button );
 
-		is_target = gtk_toggle_button_get_active( button );
-		na_object_action_set_target_selection( action, is_target );
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) button, on_target_selection_toggled, instance );
+				gtk_toggle_button_set_active( button, !is_target );
+				g_signal_handlers_unblock_by_func(( gpointer ) button, on_target_selection_toggled, instance );
 
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ENABLE_TAB, action );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, action, FALSE );
+			} else {
+				na_object_action_set_target_selection( action, is_target );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ENABLE_TAB, action );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, action, FALSE );
+			}
+		}
 	}
 }
 
@@ -526,21 +574,34 @@ on_target_background_toggled( GtkToggleButton *button, NactIActionTab *instance
 	static const gchar *thisfn = "nact_iaction_tab_on_target_background_toggled";
 	NAObjectAction *action;
 	gboolean is_target;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
+	if( !st_on_selection_change ){
+		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
-			NULL );
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+				NULL );
+
+		if( action && NA_IS_OBJECT_ACTION( action )){
 
-	if( action && NA_IS_OBJECT_ACTION( action )){
+			is_target = gtk_toggle_button_get_active( button );
 
-		is_target = gtk_toggle_button_get_active( button );
-		na_object_action_set_target_background( action, is_target );
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) button, on_target_background_toggled, instance );
+				gtk_toggle_button_set_active( button, !is_target );
+				g_signal_handlers_unblock_by_func(( gpointer ) button, on_target_background_toggled, instance );
 
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ENABLE_TAB, action );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, action, FALSE );
+			} else {
+				na_object_action_set_target_background( action, is_target );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ENABLE_TAB, action );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, action, FALSE );
+			}
+		}
 	}
 }
 
@@ -627,48 +688,75 @@ on_target_toolbar_toggled( GtkToggleButton *button, NactIActionTab *instance )
 	static const gchar *thisfn = "nact_iaction_tab_on_target_toolbar_toggled";
 	NAObjectAction *action;
 	gboolean is_target;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
+	if( !st_on_selection_change ){
+		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
-			NULL );
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+				NULL );
 
-	if( action && NA_IS_OBJECT_ACTION( action )){
+		if( action && NA_IS_OBJECT_ACTION( action )){
 
-		is_target = gtk_toggle_button_get_active( button );
-		na_object_action_set_target_toolbar( action, is_target );
+			is_target = gtk_toggle_button_get_active( button );
 
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ENABLE_TAB, action );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, action, FALSE );
-	}
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) button, on_target_toolbar_toggled, instance );
+				gtk_toggle_button_set_active( button, !is_target );
+				g_signal_handlers_unblock_by_func(( gpointer ) button, on_target_toolbar_toggled, instance );
 
-	toolbar_same_label_set_sensitive( instance, NA_OBJECT_ITEM( action ));
-	toolbar_label_set_sensitive( instance, NA_OBJECT_ITEM( action ));
+			} else {
+				na_object_action_set_target_toolbar( action, is_target );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ENABLE_TAB, action );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, action, FALSE );
+				toolbar_same_label_set_sensitive( instance, NA_OBJECT_ITEM( action ));
+				toolbar_label_set_sensitive( instance, NA_OBJECT_ITEM( action ));
+			}
+		}
+	}
 }
 
 static void
 on_toolbar_same_label_toggled( GtkToggleButton *button, NactIActionTab *instance )
 {
+	static const gchar *thisfn = "nact_iaction_tab_on_toolbar_same_label_toggled";
 	NAObjectItem *edited;
 	gboolean same_label;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_ACTION, &edited,
-			NULL );
+	if( !st_on_selection_change ){
+		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
 
-	if( edited && NA_IS_OBJECT_ACTION( edited )){
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_ACTION, &edited,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+				NULL );
 
-		same_label = gtk_toggle_button_get_active( button );
-		na_object_action_toolbar_set_same_label( NA_OBJECT_ACTION( edited ), same_label );
+		if( edited && NA_IS_OBJECT_ACTION( edited )){
 
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
-	}
+			same_label = gtk_toggle_button_get_active( button );
+
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) button, on_toolbar_same_label_toggled, instance );
+				gtk_toggle_button_set_active( button, !same_label );
+				g_signal_handlers_unblock_by_func(( gpointer ) button, on_toolbar_same_label_toggled, instance );
 
-	toolbar_same_label_set_sensitive( instance, NA_OBJECT_ITEM( edited ));
-	toolbar_label_set_sensitive( instance, NA_OBJECT_ITEM( edited ));
+			} else {
+				na_object_action_toolbar_set_same_label( NA_OBJECT_ACTION( edited ), same_label );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+				toolbar_same_label_set_sensitive( instance, NA_OBJECT_ITEM( edited ));
+				toolbar_label_set_sensitive( instance, NA_OBJECT_ITEM( edited ));
+			}
+		}
+	}
 }
 
 static void
@@ -709,14 +797,12 @@ toolbar_label_set_sensitive( NactIActionTab *instance, NAObjectItem *item )
 {
 	gboolean is_action;
 	gboolean same_label;
-	gboolean readonly;
 	GtkWidget *label_widget;
 
 	is_action = item && NA_IS_OBJECT_ACTION( item );
-	readonly = item ? na_object_is_readonly( item ) : FALSE;
 	same_label = is_action ? na_object_action_toolbar_use_same_label( NA_OBJECT_ACTION( item )) : FALSE;
 	label_widget = base_window_get_widget( BASE_WINDOW( instance ), "ActionIconLabelEntry" );
-	gtk_widget_set_sensitive( label_widget, is_action && !same_label && !readonly );
+	gtk_widget_set_sensitive( label_widget, is_action && !same_label );
 }
 
 static void
@@ -945,17 +1031,52 @@ get_enabled_button( NactIActionTab *instance )
 static void
 on_enabled_toggled( GtkToggleButton *button, NactIActionTab *instance )
 {
+	static const gchar *thisfn = "nact_iaction_tab_on_enabled_toggled";
 	NAObjectItem *edited;
 	gboolean enabled;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_ACTION, &edited,
-			NULL );
+	if( !st_on_selection_change ){
+		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
 
-	if( edited && NA_IS_OBJECT_ITEM( edited )){
-		enabled = gtk_toggle_button_get_active( button );
-		na_object_item_set_enabled( edited, enabled );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_ACTION, &edited,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+				NULL );
+
+		if( edited && NA_IS_OBJECT_ITEM( edited )){
+
+			enabled = gtk_toggle_button_get_active( button );
+
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) button, on_enabled_toggled, instance );
+				gtk_toggle_button_set_active( button, !enabled );
+				g_signal_handlers_unblock_by_func(( gpointer ) button, on_enabled_toggled, instance );
+
+			} else {
+				na_object_item_set_enabled( edited, enabled );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+			}
+		}
+	}
+}
+
+static void
+on_readonly_toggled( GtkToggleButton *button, NactIActionTab *instance )
+{
+	static const gchar *thisfn = "nact_iaction_tab_on_readonly_toggled";
+	gboolean active;
+
+	if( !st_on_selection_change ){
+		g_debug( "%s: button=%p, instance=%p", thisfn, ( void * ) button, ( void * ) instance );
+
+		active = gtk_toggle_button_get_active( button );
+
+		g_signal_handlers_block_by_func(( gpointer ) button, on_readonly_toggled, instance );
+		gtk_toggle_button_set_active( button, !active );
+		g_signal_handlers_unblock_by_func(( gpointer ) button, on_readonly_toggled, instance );
 	}
 }
diff --git a/nautilus-actions/nact/nact-iactions-list.c b/nautilus-actions/nact/nact-iactions-list.c
index a054139..8ae2b0a 100644
--- a/nautilus-actions/nact/nact-iactions-list.c
+++ b/nautilus-actions/nact/nact-iactions-list.c
@@ -1658,12 +1658,12 @@ display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *m
 		if( modified ){
 			g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
 		}
+
 		if( !valid ){
 			g_object_set( cell, "foreground", "Red", "foreground-set", TRUE, NULL );
 		}
-		if( writable_provider && !readonly_item ){
-			g_object_set( cell, "editable", TRUE, NULL );
-		}
+
+		g_object_set( cell, "editable", writable_provider && !readonly_item, NULL );
 	}
 
 	g_object_set( cell, "text", label, NULL );
diff --git a/nautilus-actions/nact/nact-iadvanced-tab.c b/nautilus-actions/nact/nact-iadvanced-tab.c
index 3077b40..92238ed 100644
--- a/nautilus-actions/nact/nact-iadvanced-tab.c
+++ b/nautilus-actions/nact/nact-iadvanced-tab.c
@@ -42,6 +42,7 @@
 
 #include "base-window.h"
 #include "base-iprefs.h"
+#include "nact-gtk-utils.h"
 #include "nact-main-tab.h"
 #include "nact-iadvanced-tab.h"
 
@@ -62,6 +63,7 @@ enum {
 
 static gboolean st_initialized = FALSE;
 static gboolean st_finalized = FALSE;
+static gboolean st_on_selection_change = FALSE;
 
 static GType         register_type( void );
 static void          interface_base_init( NactIAdvancedTabInterface *klass );
@@ -212,7 +214,6 @@ initial_load_create_schemes_selection_list( NactIAdvancedTab *instance )
 		gtk_tree_view_append_column( listview, column );
 
 		text_cell = gtk_cell_renderer_text_new();
-		g_object_set( G_OBJECT( text_cell ), "editable", TRUE, NULL );
 		column = gtk_tree_view_column_new_with_attributes(
 				"scheme-code",
 				text_cell,
@@ -221,7 +222,6 @@ initial_load_create_schemes_selection_list( NactIAdvancedTab *instance )
 		gtk_tree_view_append_column( listview, column );
 
 		text_cell = gtk_cell_renderer_text_new();
-		g_object_set( G_OBJECT( text_cell ), "editable", TRUE, NULL );
 		column = gtk_tree_view_column_new_with_attributes(
 				"scheme-description",
 				text_cell,
@@ -422,14 +422,18 @@ on_tab_updatable_selection_changed( NactIAdvancedTab *instance, gint count_selec
 	gboolean enable_tab;
 	GSList *schemes;
 	GtkTreeModel *scheme_model;
-	gboolean readonly;
+	gboolean readonly_item;
+	gboolean writable_provider;
 	GtkWidget *widget;
+	GtkTreeViewColumn *column;
 
 	g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
 	g_return_if_fail( NACT_IS_IADVANCED_TAB( instance ));
 
 	if( st_initialized && !st_finalized ){
 
+		st_on_selection_change = TRUE;
+
 		scheme_model = get_schemes_tree_model( instance );
 		gtk_tree_model_foreach( scheme_model, ( GtkTreeModelForeachFunc ) reset_schemes_list, NULL );
 
@@ -437,10 +441,10 @@ on_tab_updatable_selection_changed( NactIAdvancedTab *instance, gint count_selec
 				G_OBJECT( instance ),
 				TAB_UPDATABLE_PROP_EDITED_ACTION, &item,
 				TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
 				NULL );
 
-		readonly = item ? na_object_is_readonly( item ) : FALSE;
-
 		enable_tab = tab_set_sensitive( instance );
 
 		if( profile ){
@@ -449,13 +453,23 @@ on_tab_updatable_selection_changed( NactIAdvancedTab *instance, gint count_selec
 		}
 
 		widget = GTK_WIDGET( get_schemes_tree_view( instance ));
-		gtk_widget_set_sensitive( widget, item && !readonly );
+		gtk_widget_set_sensitive( widget, item != NULL );
+
+		column = gtk_tree_view_get_column( GTK_TREE_VIEW( widget ), SCHEMES_KEYWORD_COLUMN );
+		nact_gtk_utils_set_editable( GTK_OBJECT( column ), writable_provider && !readonly_item );
+
+		column = gtk_tree_view_get_column( GTK_TREE_VIEW( widget ), SCHEMES_DESC_COLUMN );
+		nact_gtk_utils_set_editable( GTK_OBJECT( column ), writable_provider && !readonly_item );
 
 		widget = base_window_get_widget( BASE_WINDOW( instance ), "AddSchemeButton" );
-		gtk_widget_set_sensitive( widget, item && !readonly );
+		gtk_widget_set_sensitive( widget, item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( widget ), writable_provider && !readonly_item );
 
 		widget = base_window_get_widget( BASE_WINDOW( instance ), "RemoveSchemeButton" );
-		gtk_widget_set_sensitive( widget, item && !readonly );
+		gtk_widget_set_sensitive( widget, item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( widget ), writable_provider && !readonly_item );
+
+		st_on_selection_change = FALSE;
 	}
 }
 
@@ -495,21 +509,34 @@ tab_set_sensitive( NactIAdvancedTab *instance )
 static gboolean
 on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactIAdvancedTab *instance )
 {
-	gboolean stop = FALSE;
+	gboolean stop;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	if( event->keyval == GDK_F2 ){
-		inline_edition( instance );
-		stop = TRUE;
-	}
+	stop = FALSE;
 
-	if( event->keyval == GDK_Insert || event->keyval == GDK_KP_Insert ){
-		insert_new_row( instance );
-		stop = TRUE;
-	}
+	g_object_get(
+			G_OBJECT( instance ),
+			TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+			TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+			NULL );
+
+	if( writable_provider && !readonly_item ){
+
+		if( event->keyval == GDK_F2 ){
+			inline_edition( instance );
+			stop = TRUE;
+		}
+
+		if( event->keyval == GDK_Insert || event->keyval == GDK_KP_Insert ){
+			insert_new_row( instance );
+			stop = TRUE;
+		}
 
-	if( event->keyval == GDK_Delete || event->keyval == GDK_KP_Delete ){
-		delete_row( instance );
-		stop = TRUE;
+		if( event->keyval == GDK_Delete || event->keyval == GDK_KP_Delete ){
+			delete_row( instance );
+			stop = TRUE;
+		}
 	}
 
 	return( stop );
@@ -787,14 +814,25 @@ on_scheme_list_selection_changed( GtkTreeSelection *selection, NactIAdvancedTab
 	/*static const gchar *thisfn = "nact_iadvanced_tab_on_scheme_list_selection_changed";
 	g_debug( "%s: selection=%p, user_data=%p", thisfn, selection, user_data );*/
 
+	gboolean readonly_item;
+	gboolean writable_provider;
 	GtkButton *button;
 
-	button = get_remove_button( instance );
+	g_object_get(
+			G_OBJECT( instance ),
+			TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+			TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+			NULL );
+
+	if( writable_provider && !readonly_item ){
 
-	if( gtk_tree_selection_count_selected_rows( selection )){
-		gtk_widget_set_sensitive( GTK_WIDGET( button ), TRUE );
-	} else {
-		gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE );
+		button = get_remove_button( instance );
+
+		if( gtk_tree_selection_count_selected_rows( selection )){
+			gtk_widget_set_sensitive( GTK_WIDGET( button ), TRUE );
+		} else {
+			gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE );
+		}
 	}
 }
 
@@ -810,31 +848,43 @@ on_scheme_selection_toggled( GtkCellRendererToggle *renderer, gchar *path, NactI
 	GtkTreePath *tree_path;
 	gboolean state;
 	gchar *scheme;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
-			NULL );
+	if( !st_on_selection_change ){
 
-	if( edited ){
-		model = get_schemes_tree_model( instance );
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+				NULL );
 
-		tree_path = gtk_tree_path_new_from_string( path );
-		gtk_tree_model_get_iter( model, &iter, tree_path );
-		gtk_tree_path_free( tree_path );
+		if( edited ){
+			model = get_schemes_tree_model( instance );
 
-		gtk_tree_model_get( model, &iter, SCHEMES_CHECKBOX_COLUMN, &state, SCHEMES_KEYWORD_COLUMN, &scheme, -1 );
+			tree_path = gtk_tree_path_new_from_string( path );
+			gtk_tree_model_get_iter( model, &iter, tree_path );
+			gtk_tree_path_free( tree_path );
 
-		/* gtk_tree_model_get: returns the previous state
-		g_debug( "%s: gtk_tree_model_get returns keyword=%s state=%s", thisfn, scheme, state ? "True":"False" );*/
+			gtk_tree_model_get( model, &iter, SCHEMES_CHECKBOX_COLUMN, &state, SCHEMES_KEYWORD_COLUMN, &scheme, -1 );
 
-		gtk_list_store_set( GTK_LIST_STORE( model ), &iter, SCHEMES_CHECKBOX_COLUMN, !state, -1 );
+			/* gtk_tree_model_get: returns the previous state
+			g_debug( "%s: gtk_tree_model_get returns keyword=%s state=%s", thisfn, scheme, state ? "True":"False" );*/
 
-		na_object_profile_set_scheme( edited, scheme, !state );
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) renderer, on_scheme_selection_toggled, instance );
+				gtk_cell_renderer_toggle_set_active( renderer, state );
+				g_signal_handlers_unblock_by_func(( gpointer ) renderer, on_scheme_selection_toggled, instance );
 
-		g_free( scheme );
+			} else {
+				gtk_list_store_set( GTK_LIST_STORE( model ), &iter, SCHEMES_CHECKBOX_COLUMN, !state, -1 );
+				na_object_profile_set_scheme( edited, scheme, !state );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+			}
 
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+			g_free( scheme );
+		}
 	}
 }
 
diff --git a/nautilus-actions/nact/nact-ibackground-tab.c b/nautilus-actions/nact/nact-ibackground-tab.c
index deede06..b58f86f 100644
--- a/nautilus-actions/nact/nact-ibackground-tab.c
+++ b/nautilus-actions/nact/nact-ibackground-tab.c
@@ -44,6 +44,7 @@
 
 #include "base-iprefs.h"
 #include "base-window.h"
+#include "nact-gtk-utils.h"
 #include "nact-application.h"
 #include "nact-main-tab.h"
 #include "nact-ibackground-tab.h"
@@ -66,6 +67,7 @@ enum {
 
 static gboolean st_initialized = FALSE;
 static gboolean st_finalized = FALSE;
+static gboolean st_on_selection_change = FALSE;
 
 static GType        register_type( void );
 static void         interface_base_init( NactIBackgroundTabInterface *klass );
@@ -181,7 +183,6 @@ nact_ibackground_tab_initial_load_toplevel( NactIBackgroundTab *instance )
 		g_object_unref( model );
 
 		text_cell = gtk_cell_renderer_text_new();
-		g_object_set( G_OBJECT( text_cell ), "editable", TRUE, NULL );
 		column = gtk_tree_view_column_new_with_attributes(
 				"folder-uri",
 				text_cell,
@@ -290,8 +291,12 @@ on_tab_updatable_selection_changed( NactIBackgroundTab *instance, gint count_sel
 {
 	static const gchar *thisfn = "nact_ibackground_tab_on_tab_updatable_selection_changed";
 	NAObjectItem *item;
+	NAObjectProfile *profile;
 	gboolean enable_tab;
-	gboolean readonly;
+	gboolean readonly_item;
+	gboolean writable_provider;
+	GtkTreeView *treeview;
+	GtkTreeViewColumn *column;
 	GtkWidget *widget;
 
 	g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
@@ -299,31 +304,40 @@ on_tab_updatable_selection_changed( NactIBackgroundTab *instance, gint count_sel
 
 	if( st_initialized && !st_finalized ){
 
+		st_on_selection_change = TRUE;
+
 		reset_folders( instance );
 
 		g_object_get(
 				G_OBJECT( instance ),
 				TAB_UPDATABLE_PROP_EDITED_ACTION, &item,
+				TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
 				NULL );
 
 		g_return_if_fail( !item || NA_IS_OBJECT_ITEM( item ));
 
-		readonly = item ? na_object_is_readonly( item ) : FALSE;
-
 		enable_tab = tab_set_sensitive( instance );
 
 		if( item && NA_IS_OBJECT_ACTION( item )){
 			setup_folders( instance );
 		}
 
-		widget = base_window_get_widget( BASE_WINDOW( instance ), "FoldersTreeView" );
-		gtk_widget_set_sensitive( widget, item && !readonly );
+		treeview = GTK_TREE_VIEW( base_window_get_widget( BASE_WINDOW( instance ), "FoldersTreeView" ));
+		gtk_widget_set_sensitive( GTK_WIDGET( treeview ), profile != NULL );
+		column = gtk_tree_view_get_column( treeview, BACKGROUND_URI_COLUMN );
+		nact_gtk_utils_set_editable( GTK_OBJECT( column ), writable_provider && !readonly_item );
 
 		widget = base_window_get_widget( BASE_WINDOW( instance ), "AddFolderButton" );
-		gtk_widget_set_sensitive( widget, item && !readonly );
+		gtk_widget_set_sensitive( widget, profile != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( widget ), writable_provider && !readonly_item );
 
 		widget = base_window_get_widget( BASE_WINDOW( instance ), "RemoveFolderButton" );
-		gtk_widget_set_sensitive( widget, item && !readonly );
+		gtk_widget_set_sensitive( widget, profile != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( widget ), writable_provider && !readonly_item );
+
+		st_on_selection_change = FALSE;
 	}
 }
 
@@ -365,21 +379,34 @@ tab_set_sensitive( NactIBackgroundTab *instance )
 static gboolean
 on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactIBackgroundTab *instance )
 {
-	gboolean stop = FALSE;
+	gboolean stop;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	if( event->keyval == GDK_F2 ){
-		inline_edition( instance );
-		stop = TRUE;
-	}
+	stop = FALSE;
 
-	if( event->keyval == GDK_Insert || event->keyval == GDK_KP_Insert ){
-		insert_new_row( instance );
-		stop = TRUE;
-	}
+	g_object_get(
+			G_OBJECT( instance ),
+			TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+			TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+			NULL );
+
+	if( writable_provider && !readonly_item ){
 
-	if( event->keyval == GDK_Delete || event->keyval == GDK_KP_Delete ){
-		delete_row( instance );
-		stop = TRUE;
+		if( event->keyval == GDK_F2 ){
+			inline_edition( instance );
+			stop = TRUE;
+		}
+
+		if( event->keyval == GDK_Insert || event->keyval == GDK_KP_Insert ){
+			insert_new_row( instance );
+			stop = TRUE;
+		}
+
+		if( event->keyval == GDK_Delete || event->keyval == GDK_KP_Delete ){
+			delete_row( instance );
+			stop = TRUE;
+		}
 	}
 
 	return( stop );
@@ -537,7 +564,7 @@ on_add_folder_clicked( GtkButton *button, NactIBackgroundTab *instance )
 	toplevel = base_window_get_toplevel( BASE_WINDOW( instance ));
 
 	/* i18n: title of the FileChoose dialog when selecting an URI which
-	 * will be comparent to Nautilus 'current_folder'
+	 * will be compare to Nautilus 'current_folder'
 	 */
 	dialog = gtk_file_chooser_dialog_new( _( "Select a folder" ),
 			toplevel,
@@ -579,11 +606,21 @@ on_folder_uri_edited( GtkCellRendererText *renderer, const gchar *path, const gc
 static void
 on_folders_selection_changed( GtkTreeSelection *selection, NactIBackgroundTab *instance )
 {
+	gboolean readonly_item;
+	gboolean writable_provider;
 	GtkWidget *button;
 
-	button = base_window_get_widget( BASE_WINDOW( instance ), "RemoveFolderButton");
+	g_object_get(
+			G_OBJECT( instance ),
+			TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+			TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+			NULL );
 
-	gtk_widget_set_sensitive( button, gtk_tree_selection_count_selected_rows( selection ) > 0 );
+	if( writable_provider && !readonly_item ){
+
+		button = base_window_get_widget( BASE_WINDOW( instance ), "RemoveFolderButton");
+		gtk_widget_set_sensitive( button, gtk_tree_selection_count_selected_rows( selection ) > 0 );
+	}
 }
 
 static void
diff --git a/nautilus-actions/nact/nact-icommand-tab.c b/nautilus-actions/nact/nact-icommand-tab.c
index 9afe39f..83f9909 100644
--- a/nautilus-actions/nact/nact-icommand-tab.c
+++ b/nautilus-actions/nact/nact-icommand-tab.c
@@ -45,6 +45,7 @@
 #include "base-iprefs.h"
 #include "nact-application.h"
 #include "nact-main-statusbar.h"
+#include "nact-gtk-utils.h"
 #include "nact-iactions-list.h"
 #include "nact-main-tab.h"
 #include "nact-icommand-tab.h"
@@ -70,6 +71,7 @@ struct NactICommandTabInterfacePrivate {
 
 static gboolean st_initialized = FALSE;
 static gboolean st_finalized = FALSE;
+static gboolean st_on_selection_change = FALSE;
 
 static GType      register_type( void );
 static void       interface_base_init( NactICommandTabInterface *klass );
@@ -319,7 +321,8 @@ on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_select
 	gboolean enable_tab;
 	GtkWidget *label_entry, *path_entry, *parameters_entry;
 	gchar *label, *path, *parameters;
-	gboolean readonly;
+	gboolean readonly_item;
+	gboolean writable_provider;
 	GtkButton *path_button;
 	GtkButton *legend_button;
 
@@ -328,40 +331,48 @@ on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_select
 
 	if( st_initialized && !st_finalized ){
 
+		st_on_selection_change = TRUE;
+
 		g_object_get(
 				G_OBJECT( instance ),
 				TAB_UPDATABLE_PROP_EDITED_ACTION, &item,
 				TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
 				NULL );
 
 		enable_tab = tab_set_sensitive( instance );
 
-		readonly = item ? na_object_is_readonly( item ) : FALSE;
-
 		label_entry = get_label_entry( instance );
 		label = profile ? na_object_get_label( profile ) : g_strdup( "" );
 		gtk_entry_set_text( GTK_ENTRY( label_entry ), label );
 		check_for_label( instance, GTK_ENTRY( label_entry ), label );
 		g_free( label );
-		gtk_widget_set_sensitive( label_entry, profile && !readonly );
+		gtk_widget_set_sensitive( label_entry, profile != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( label_entry ), writable_provider && !readonly_item );
 
 		path_entry = get_path_entry( instance );
 		path = profile ? na_object_profile_get_path( profile ) : g_strdup( "" );
 		gtk_entry_set_text( GTK_ENTRY( path_entry ), path );
 		g_free( path );
-		gtk_widget_set_sensitive( path_entry, profile && !readonly );
+		gtk_widget_set_sensitive( path_entry, profile != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( path_entry ), writable_provider && !readonly_item );
 
 		path_button = get_path_button( instance );
-		gtk_widget_set_sensitive( GTK_WIDGET( path_button ), profile && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( path_button ), profile != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( path_button ), writable_provider && !readonly_item );
 
 		parameters_entry = get_parameters_entry( instance );
 		parameters = profile ? na_object_profile_get_parameters( profile ) : g_strdup( "" );
 		gtk_entry_set_text( GTK_ENTRY( parameters_entry ), parameters );
 		g_free( parameters );
-		gtk_widget_set_sensitive( parameters_entry, profile && !readonly );
+		gtk_widget_set_sensitive( parameters_entry, profile != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( parameters_entry ), writable_provider && !readonly_item );
 
 		legend_button = get_legend_button( instance );
-		gtk_widget_set_sensitive( GTK_WIDGET( legend_button ), profile && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( legend_button ), profile != NULL );
+
+		st_on_selection_change = FALSE;
 	}
 }
 
@@ -496,16 +507,19 @@ on_label_changed( GtkEntry *entry, NactICommandTab *instance )
 	NAObjectProfile *edited;
 	const gchar *label;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
-			NULL );
+	if( !st_on_selection_change ){
 
-	if( edited ){
-		label = gtk_entry_get_text( entry );
-		na_object_set_label( edited, label );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, TRUE );
-		check_for_label( instance, entry, label );
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
+				NULL );
+
+		if( edited ){
+			label = gtk_entry_get_text( entry );
+			na_object_set_label( edited, label );
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, TRUE );
+			check_for_label( instance, entry, label );
+		}
 	}
 }
 
@@ -525,17 +539,20 @@ on_parameters_changed( GtkEntry *entry, NactICommandTab *instance )
 {
 	NAObjectProfile *edited;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
-			NULL );
+	if( !st_on_selection_change ){
 
-	if( edited ){
-		na_object_profile_set_parameters( edited, gtk_entry_get_text( entry ));
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
-	}
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
+				NULL );
 
-	update_example_label( instance, edited );
+		if( edited ){
+
+			na_object_profile_set_parameters( edited, gtk_entry_get_text( entry ));
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+			update_example_label( instance, edited );
+		}
+	}
 }
 
 static void
@@ -598,17 +615,20 @@ on_path_changed( GtkEntry *entry, NactICommandTab *instance )
 {
 	NAObjectProfile *edited;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
-			NULL );
+	if( !st_on_selection_change ){
 
-	if( edited ){
-		na_object_profile_set_path( edited, gtk_entry_get_text( entry ));
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
-	}
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
+				NULL );
+
+		if( edited ){
 
-	update_example_label( instance, edited );
+			na_object_profile_set_path( edited, gtk_entry_get_text( entry ));
+			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+			update_example_label( instance, edited );
+		}
+	}
 }
 
 /*
diff --git a/nautilus-actions/nact/nact-iconditions-tab.c b/nautilus-actions/nact/nact-iconditions-tab.c
index 8bfe311..9b5d26c 100644
--- a/nautilus-actions/nact/nact-iconditions-tab.c
+++ b/nautilus-actions/nact/nact-iconditions-tab.c
@@ -42,6 +42,7 @@
 #include "base-iprefs.h"
 #include "nact-main-window.h"
 #include "nact-main-tab.h"
+#include "nact-gtk-utils.h"
 #include "nact-iconditions-tab.h"
 
 /* private interface data
@@ -52,6 +53,7 @@ struct NactIConditionsTabInterfacePrivate {
 
 static gboolean st_initialized = FALSE;
 static gboolean st_finalized = FALSE;
+static gboolean st_on_selection_change = FALSE;
 
 static GType      register_type( void );
 static void       interface_base_init( NactIConditionsTabInterface *klass );
@@ -309,21 +311,24 @@ on_tab_updatable_selection_changed( NactIConditionsTab *instance, gint count_sel
 	gboolean isfile, isdir;
 	GtkButton *multiple_button;
 	gboolean multiple;
-	gboolean readonly;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
 	g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
 	g_return_if_fail( NACT_IS_ICONDITIONS_TAB( instance ));
 
 	if( st_initialized && !st_finalized ){
 
+		st_on_selection_change = TRUE;
+
 		g_object_get(
 				G_OBJECT( instance ),
 				TAB_UPDATABLE_PROP_EDITED_ACTION, &item,
 				TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
 				NULL );
 
-		readonly = item ? na_object_is_readonly( item ) : FALSE;
-
 		enable_tab = tab_set_sensitive( instance );
 
 		basenames_widget = get_basenames_entry( instance );
@@ -332,12 +337,14 @@ on_tab_updatable_selection_changed( NactIConditionsTab *instance, gint count_sel
 		gtk_entry_set_text( GTK_ENTRY( basenames_widget ), basenames_text );
 		g_free( basenames_text );
 		na_utils_free_string_list( basenames );
-		gtk_widget_set_sensitive( basenames_widget, item && !readonly );
+		gtk_widget_set_sensitive( basenames_widget, item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( basenames_widget ), writable_provider && !readonly_item );
 
 		matchcase_button = get_matchcase_button( instance );
 		matchcase = profile ? na_object_profile_get_matchcase( profile ) : FALSE;
 		gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( matchcase_button ), matchcase );
-		gtk_widget_set_sensitive( GTK_WIDGET( matchcase_button ), item && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( matchcase_button ), item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( matchcase_button ), writable_provider && !readonly_item );
 
 		mimetypes_widget = get_mimetypes_entry( instance );
 		mimetypes = profile ? na_object_profile_get_mimetypes( profile ) : NULL;
@@ -345,16 +352,20 @@ on_tab_updatable_selection_changed( NactIConditionsTab *instance, gint count_sel
 		gtk_entry_set_text( GTK_ENTRY( mimetypes_widget ), mimetypes_text );
 		g_free( mimetypes_text );
 		na_utils_free_string_list( mimetypes );
-		gtk_widget_set_sensitive( mimetypes_widget, item && !readonly );
+		gtk_widget_set_sensitive( mimetypes_widget, item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( mimetypes_widget ), writable_provider && !readonly_item );
 
 		isfile = profile ? na_object_profile_get_is_file( profile ) : FALSE;
 		isdir = profile ? na_object_profile_get_is_dir( profile ) : FALSE;
-		set_isfiledir( instance, isfile, isdir, readonly );
+		set_isfiledir( instance, isfile, isdir, writable_provider && !readonly_item );
 
 		multiple_button = get_multiple_button( instance );
 		multiple = profile ? na_object_profile_get_multiple( profile ) : FALSE;
 		gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( multiple_button ), multiple );
-		gtk_widget_set_sensitive( GTK_WIDGET( multiple_button ), item && !readonly );
+		gtk_widget_set_sensitive( GTK_WIDGET( multiple_button ), item != NULL );
+		nact_gtk_utils_set_editable( GTK_OBJECT( multiple_button ), writable_provider && !readonly_item );
+
+		st_on_selection_change = FALSE;
 	}
 }
 
@@ -467,18 +478,34 @@ on_isfiledir_toggled( GtkToggleButton *button, NactIConditionsTab *instance )
 	/*static const gchar *thisfn = "nact_iconditions_tab_on_isfiledir_toggled";*/
 	NAObjectProfile *edited;
 	gboolean isfile, isdir;
-
-	if( gtk_toggle_button_get_active( button )){
-
-		g_object_get(
-				G_OBJECT( instance ),
-				TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
-				NULL );
-
-		if( edited ){
-			nact_iconditions_tab_get_isfiledir( instance, &isfile, &isdir );
-			na_object_profile_set_isfiledir( edited, isfile, isdir );
-			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+	gboolean readonly_item;
+	gboolean writable_provider;
+
+	if( !st_on_selection_change ){
+
+		if( gtk_toggle_button_get_active( button )){
+
+			g_object_get(
+					G_OBJECT( instance ),
+					TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
+					TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+					TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+					NULL );
+
+			g_return_if_fail( NA_IS_OBJECT_PROFILE( edited ));
+
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) button, on_isfiledir_toggled, instance );
+				isfile = na_object_profile_get_is_file( edited );
+				isdir = na_object_profile_get_is_dir( edited );
+				set_isfiledir( instance, isfile, isdir, readonly_item || !writable_provider );
+				g_signal_handlers_unblock_by_func(( gpointer ) button, on_isfiledir_toggled, instance );
+
+			} else if( gtk_toggle_button_get_active( button )){
+				nact_iconditions_tab_get_isfiledir( instance, &isfile, &isdir );
+				na_object_profile_set_isfiledir( edited, isfile, isdir );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+			}
 		}
 	}
 }
@@ -488,16 +515,32 @@ on_matchcase_toggled( GtkToggleButton *button, NactIConditionsTab *instance )
 {
 	NAObjectProfile *edited;
 	gboolean matchcase;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
-			NULL );
+	if( !st_on_selection_change ){
 
-	if( edited ){
-		matchcase = gtk_toggle_button_get_active( button );
-		na_object_profile_set_matchcase( edited, matchcase );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+				NULL );
+
+		if( edited ){
+
+			matchcase = gtk_toggle_button_get_active( button );
+
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) button, on_matchcase_toggled, instance );
+				gtk_toggle_button_set_active( button, !matchcase );
+				g_signal_handlers_unblock_by_func(( gpointer ) button, on_matchcase_toggled, instance );
+
+			} else {
+				na_object_profile_set_matchcase( edited, matchcase );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+			}
+		}
 	}
 }
 
@@ -527,16 +570,31 @@ on_multiple_toggled( GtkToggleButton *button, NactIConditionsTab *instance )
 {
 	NAObjectProfile *edited;
 	gboolean multiple;
+	gboolean readonly_item;
+	gboolean writable_provider;
 
-	g_object_get(
-			G_OBJECT( instance ),
-			TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
-			NULL );
+	if( !st_on_selection_change ){
 
-	if( edited ){
-		multiple = gtk_toggle_button_get_active( button );
-		na_object_profile_set_multiple( edited, multiple );
-		g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+		g_object_get(
+				G_OBJECT( instance ),
+				TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
+				TAB_UPDATABLE_PROP_READONLY_ITEM, &readonly_item,
+				TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, &writable_provider,
+				NULL );
+
+		if( edited ){
+			multiple = gtk_toggle_button_get_active( button );
+
+			if( readonly_item || !writable_provider ){
+				g_signal_handlers_block_by_func(( gpointer ) button, on_multiple_toggled, instance );
+				gtk_toggle_button_set_active( button, !multiple );
+				g_signal_handlers_unblock_by_func(( gpointer ) button, on_multiple_toggled, instance );
+
+			} else {
+				na_object_profile_set_multiple( edited, multiple );
+				g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
+			}
+		}
 	}
 }
 
@@ -561,7 +619,7 @@ set_isfiledir( NactIConditionsTab *instance, gboolean isfile, gboolean isdir, gb
 		gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( dirs_button ), TRUE );
 	}
 
-	gtk_widget_set_sensitive( GTK_WIDGET( both_button ), !readonly );
-	gtk_widget_set_sensitive( GTK_WIDGET( file_button ), !readonly );
-	gtk_widget_set_sensitive( GTK_WIDGET( dirs_button ), !readonly );
+	nact_gtk_utils_set_editable( GTK_OBJECT( both_button ), !readonly );
+	nact_gtk_utils_set_editable( GTK_OBJECT( file_button ), !readonly );
+	nact_gtk_utils_set_editable( GTK_OBJECT( dirs_button ), !readonly );
 }
diff --git a/nautilus-actions/nact/nact-main-tab.h b/nautilus-actions/nact/nact-main-tab.h
index 11f9c55..d3ae9d4 100644
--- a/nautilus-actions/nact/nact-main-tab.h
+++ b/nautilus-actions/nact/nact-main-tab.h
@@ -46,6 +46,8 @@
 #define TAB_UPDATABLE_PROP_EDITED_ACTION				"nact-tab-updatable-edited-action"
 #define TAB_UPDATABLE_PROP_EDITED_PROFILE				"nact-tab-updatable-edited-profile"
 #define TAB_UPDATABLE_PROP_SELECTED_ROW					"nact-tab-updatable-selected-row"
+#define TAB_UPDATABLE_PROP_READONLY_ITEM				"nact-tab-updatable-readonly-item"
+#define TAB_UPDATABLE_PROP_WRITABLE_PROVIDER			"nact-tab-updatable-writable-provider"
 
 /* signals
  */
diff --git a/nautilus-actions/nact/nact-main-window.c b/nautilus-actions/nact/nact-main-window.c
index 38c5753..5ab50b7 100644
--- a/nautilus-actions/nact/nact-main-window.c
+++ b/nautilus-actions/nact/nact-main-window.c
@@ -81,6 +81,8 @@ struct NactMainWindowPrivate {
 	 * Can be null, and this implies that edited_profile is also null.
 	 */
 	NAObjectItem    *edited_item;
+	gboolean         readonly_item;
+	gboolean         writable_provider;
 
 	/**
 	 * Currently edited profile.
@@ -108,11 +110,14 @@ struct NactMainWindowPrivate {
 };
 
 /* action properties
+ * these are set when selection changes as an optimization try
  */
 enum {
 	PROP_EDITED_ITEM = 1,
 	PROP_EDITED_PROFILE,
-	PROP_SELECTED_ROW
+	PROP_SELECTED_ROW,
+	PROP_READONLY_ITEM,
+	PROP_WRITABLE_PROVIDER
 };
 
 /* signals
@@ -320,6 +325,20 @@ class_init( NactMainWindowClass *klass )
 			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
 	g_object_class_install_property( object_class, PROP_SELECTED_ROW, spec );
 
+	spec = g_param_spec_boolean(
+			TAB_UPDATABLE_PROP_READONLY_ITEM,
+			"Read-only item ?",
+			"Whether the item itself is read-only", FALSE,
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_READONLY_ITEM, spec );
+
+	spec = g_param_spec_boolean(
+			TAB_UPDATABLE_PROP_WRITABLE_PROVIDER,
+			"Writable provider",
+			"Whether the provider of the item is writable", TRUE,
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_WRITABLE_PROVIDER, spec );
+
 	klass->private = g_new0( NactMainWindowClassPrivate, 1 );
 
 	base_class = BASE_WINDOW_CLASS( klass );
@@ -572,10 +591,18 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 				g_value_set_pointer( value, self->private->edited_profile );
 				break;
 
-			case PROP_SELECTED_ROW	:
+			case PROP_SELECTED_ROW:
 				g_value_set_pointer( value, self->private->selected_row );
 				break;
 
+			case PROP_READONLY_ITEM:
+				g_value_set_boolean( value, self->private->readonly_item );
+				break;
+
+			case PROP_WRITABLE_PROVIDER:
+				g_value_set_boolean( value, self->private->writable_provider );
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
 				break;
@@ -606,6 +633,14 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 				self->private->selected_row = g_value_get_pointer( value );
 				break;
 
+			case PROP_READONLY_ITEM:
+				self->private->readonly_item = g_value_get_boolean( value );
+				break;
+
+			case PROP_WRITABLE_PROVIDER:
+				self->private->writable_provider = g_value_get_boolean( value );
+				break;
+
 			default:
 				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
 				break;
@@ -1099,6 +1134,9 @@ on_iactions_list_selection_changed( NactIActionsList *instance, GSList *selected
 			G_OBJECT( window ),
 			TAB_UPDATABLE_PROP_EDITED_ACTION, window->private->edited_item,
 			TAB_UPDATABLE_PROP_EDITED_PROFILE, window->private->edited_profile,
+			TAB_UPDATABLE_PROP_SELECTED_ROW, window->private->selected_row,
+			TAB_UPDATABLE_PROP_READONLY_ITEM, window->private->readonly_item,
+			TAB_UPDATABLE_PROP_WRITABLE_PROVIDER, window->private->writable_provider,
 			NULL );
 
 	setup_dialog_title( window );
@@ -1132,8 +1170,12 @@ set_current_object_item( NactMainWindow *window, GSList *selected_items )
 	 */
 	window->private->edited_profile = NULL;
 
-	if( window->private->edited_item &&
-		NA_IS_OBJECT_ACTION( window->private->edited_item )){
+	if( window->private->edited_item ){
+
+		window->private->readonly_item = na_object_is_readonly( window->private->edited_item );
+		window->private->writable_provider = nact_window_is_writable_provider( NACT_WINDOW( window ), window->private->edited_item );
+
+		if( NA_IS_OBJECT_ACTION( window->private->edited_item )){
 
 			count_profiles = na_object_get_items_count( NA_OBJECT_ACTION( window->private->edited_item ));
 			/*g_return_if_fail( count_profiles >= 1 );*/
@@ -1142,6 +1184,7 @@ set_current_object_item( NactMainWindow *window, GSList *selected_items )
 				profiles = na_object_get_items_list( window->private->edited_item );
 				window->private->edited_profile = NA_OBJECT_PROFILE( profiles->data );
 			}
+		}
 	}
 
 	set_current_profile( window, FALSE, selected_items );
@@ -1156,8 +1199,11 @@ set_current_profile( NactMainWindow *window, gboolean set_action, GSList *select
 			thisfn, ( void * ) window, set_action ? "True":"False", ( void * ) selected_items );
 
 	if( window->private->edited_profile && set_action ){
+
 		NAObjectAction *action = NA_OBJECT_ACTION( na_object_get_parent( window->private->edited_profile ));
 		window->private->edited_item = NA_OBJECT_ITEM( action );
+		window->private->readonly_item = na_object_is_readonly( window->private->edited_item );
+		window->private->writable_provider = nact_window_is_writable_provider( NACT_WINDOW( window ), window->private->edited_item );
 	}
 }
 
diff --git a/nautilus-actions/nact/nautilus-actions-config-tool.ui b/nautilus-actions/nact/nautilus-actions-config-tool.ui
index dafd747..28b33ff 100644
--- a/nautilus-actions/nact/nautilus-actions-config-tool.ui
+++ b/nautilus-actions/nact/nautilus-actions-config-tool.ui
@@ -859,7 +859,6 @@ Defining several profiles lets you have several commands, each applying with a d
                                     <child>
                                       <object class="GtkButton" id="RemoveFolderButton">
                                         <property name="visible">True</property>
-                                        <property name="sensitive">False</property>
                                         <property name="can_focus">True</property>
                                         <property name="receives_default">True</property>
                                         <property name="tooltip_text" translatable="yes">Click to remove the selected folder URI.</property>
@@ -902,7 +901,7 @@ Defining several profiles lets you have several commands, each applying with a d
                     <child type="tab">
                       <object class="GtkLabel" id="label15">
                         <property name="visible">True</property>
-                        <property name="tooltip_text" translatable="yes">This advanced tab lets you precisely choose on which schemes the selection will apply.</property>
+                        <property name="tooltip_text" translatable="yes">This tab lets you precisely choose in which folders this profile will apply.</property>
                         <property name="label" translatable="yes">_Folders</property>
                         <property name="use_underline">True</property>
                       </object>
@@ -1222,7 +1221,6 @@ Defining several profiles lets you have several commands, each applying with a d
                                     <child>
                                       <object class="GtkButton" id="RemoveSchemeButton">
                                         <property name="visible">True</property>
-                                        <property name="sensitive">False</property>
                                         <property name="can_focus">True</property>
                                         <property name="receives_default">True</property>
                                         <property name="tooltip_text" translatable="yes">Click to remove the selected scheme.</property>
@@ -1324,9 +1322,9 @@ Defining several profiles lets you have several commands, each applying with a d
           <object class="GtkFileChooserWidget" id="ImportFileChooser">
             <property name="visible">True</property>
             <property name="local_only">False</property>
-            <property name="preview_widget_active">False</property>
             <property name="use_preview_label">False</property>
             <property name="select_multiple">True</property>
+            <property name="preview_widget_active">False</property>
           </object>
           <packing>
             <property name="position">0</property>
@@ -2912,24 +2910,24 @@ Be warned: this mode may be dangerous. You will not be prompted another time.</p
   </object>
   <object class="GtkSizeGroup" id="CommandLabelSizeGroup">
     <widgets>
-      <widget name="ProfileLabelLabel"/>
-      <widget name="CommandPathLabel"/>
       <widget name="CommandParametersLabel"/>
+      <widget name="CommandPathLabel"/>
+      <widget name="ProfileLabelLabel"/>
     </widgets>
   </object>
   <object class="GtkSizeGroup" id="CommandButtonSizeGroup">
     <widgets>
-      <widget name="CommandPathButton"/>
       <widget name="CommandLegendButton"/>
+      <widget name="CommandPathButton"/>
     </widgets>
   </object>
   <object class="GtkSizeGroup" id="ActionLabelSizeGroup">
     <widgets>
-      <widget name="ActionIconLabelLabel"/>
-      <widget name="ActionMenuLabelLabel"/>
-      <widget name="ActionIdLabel"/>
-      <widget name="ActionTooltipLabel"/>
       <widget name="ActionIconLabel"/>
+      <widget name="ActionTooltipLabel"/>
+      <widget name="ActionIdLabel"/>
+      <widget name="ActionMenuLabelLabel"/>
+      <widget name="ActionIconLabelLabel"/>
     </widgets>
   </object>
 </interface>



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