[nautilus-actions] Check that I/O providers preferences are modifiable



commit da354f7b634dfba41fca7c30451846abbdf0eacc
Author: Pierre <pierre vfedora13 virtuals pwi>
Date:   Mon Jan 17 10:39:59 2011 +0100

    Check that I/O providers preferences are modifiable

 ChangeLog                      |   12 +++
 src/core/na-io-provider.c      |   65 +++++++++++++----
 src/core/na-io-provider.h      |    4 +-
 src/core/na-updater.c          |    2 +-
 src/nact/nact-providers-list.c |  158 ++++++++++++++++++++++++++++++++++------
 5 files changed, 201 insertions(+), 40 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0284f32..8fa558e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,18 @@
 
 2011-01-17 Pierre Wieser <pwieser trychlos org>
 
+	* src/core/na-io-provider.c:
+	* src/core/na-io-provider.h (na_io_provider_is_conf_readable,
+	na_io_provider_is_conf_writable):
+	Returns mandatory flag.
+	List I/O providers in write order.
+
+	* src/core/na-updater.c (na_updater_is_item_writable): Updated accordingly.
+
+	* src/nact/nact-providers-list.c: Do not allow modification of I/O
+	providers readability/writability/write order properties if
+	preferences are locked or properties mandatory.
+
 	* src/core/na-module.c (na_module_release_modules): Release the loaded module.
 
 2011-01-16 Pierre Wieser <pwieser trychlos org>
diff --git a/src/core/na-io-provider.c b/src/core/na-io-provider.c
index 6f90c74..13edbca 100644
--- a/src/core/na-io-provider.c
+++ b/src/core/na-io-provider.c
@@ -84,7 +84,8 @@ static void          dump_providers_list( GList *providers );
 static NAIOProvider *io_provider_new( const NAPivot *pivot, NAIIOProvider *module, const gchar *id );
 static GList        *io_providers_list_add_from_plugins( const NAPivot *pivot, GList *list );
 static GList        *io_providers_list_add_from_prefs( const NAPivot *pivot, GList *objects_list );
-static GList        *io_providers_list_add_object( const NAPivot *pivot, GList *list, NAIIOProvider *module, const gchar *id );
+static GList        *io_providers_list_add_from_write_order( const NAPivot *pivot, GList *objects_list );
+static GList        *io_providers_list_append_object( const NAPivot *pivot, GList *list, NAIIOProvider *module, const gchar *id );
 static gboolean      is_really_writable( const NAIOProvider *provider, const NAPivot *pivot );
 static GList        *load_items_filter_unwanted_items( const NAPivot *pivot, GList *merged, guint loadable_set );
 static GList        *load_items_filter_unwanted_items_rec( GList *merged, guint loadable_set );
@@ -357,7 +358,7 @@ na_io_provider_find_io_provider_by_id( const NAPivot *pivot, const gchar *id )
  * na_io_provider_get_io_providers_list:
  * @pivot: the current #NAPivot instance.
  *
- * Build (if not already done) the unordered list of currently avialable
+ * Build (if not already done) the ordered list of currently avialable
  * NAIOProvider objects.
  *
  * A NAIOProvider object may be created:
@@ -365,7 +366,7 @@ na_io_provider_find_io_provider_by_id( const NAPivot *pivot, const gchar *id )
  *   NAIIOProvider interface;
  * - or because an i/o provider identifier has been found in preferences.
  *
- * The order of objects in this list is not relevant:
+ * The objects in this list must be in write order:
  * - when loading items, items are ordered depending of menus items list
  *   and of level zero defined order;
  * - when writing a new item, there is a 'writable-order' preference.
@@ -381,7 +382,8 @@ na_io_provider_get_io_providers_list( const NAPivot *pivot )
 	g_return_val_if_fail( NA_IS_PIVOT( pivot ), NULL );
 
 	if( !st_io_providers ){
-		st_io_providers = io_providers_list_add_from_plugins( pivot, NULL );
+		st_io_providers = io_providers_list_add_from_write_order( pivot, NULL );
+		st_io_providers = io_providers_list_add_from_plugins( pivot, st_io_providers );
 		st_io_providers = io_providers_list_add_from_prefs( pivot, st_io_providers );
 	}
 
@@ -495,6 +497,8 @@ na_io_provider_is_available( const NAIOProvider *provider )
  * na_io_provider_is_conf_readable:
  * @provider: this #NAIOProvider.
  * @pivot: the #NAPivot application object.
+ * @mandatory: a pointer to a boolean which will be set to %TRUE if the
+ *  preference is mandatory; may be %NULL.
  *
  * Returns: %TRUE is this I/O provider should be read at startup, and so
  * may participate to the global list of menus and actions, %FALSE else.
@@ -506,7 +510,7 @@ na_io_provider_is_available( const NAIOProvider *provider )
  * - whether this flag has been set as mandatory by an admin.
  */
 gboolean
-na_io_provider_is_conf_readable( const NAIOProvider *provider, const NAPivot *pivot )
+na_io_provider_is_conf_readable( const NAIOProvider *provider, const NAPivot *pivot, gboolean *mandatory )
 {
 	gboolean readable;
 	gchar *group;
@@ -520,7 +524,7 @@ na_io_provider_is_conf_readable( const NAIOProvider *provider, const NAPivot *pi
 
 		group = g_strdup_printf( "%s %s", NA_IPREFS_IO_PROVIDER_GROUP, provider->private->id );
 		readable = na_settings_get_boolean_ex(
-				na_pivot_get_settings( pivot ), group, NA_IPREFS_IO_PROVIDER_READABLE, NULL, NULL );
+				na_pivot_get_settings( pivot ), group, NA_IPREFS_IO_PROVIDER_READABLE, NULL, mandatory );
 		g_free( group );
 	}
 
@@ -564,6 +568,8 @@ na_io_provider_is_able_to_write( const NAIOProvider *provider )
  * na_io_provider_is_conf_writable:
  * @provider: this #NAIOProvider.
  * @pivot: the #NAPivot application object.
+ * @mandatory: a pointer to a boolean which will be set to %TRUE if the
+ *  preference is mandatory; may be %NULL.
  *
  * Returns: %TRUE is this I/O provider is candidate to be edited.
  *
@@ -577,7 +583,7 @@ na_io_provider_is_able_to_write( const NAIOProvider *provider )
  * NAIIOProvider module. See also is_willing_to() and is_able_to().
  */
 gboolean
-na_io_provider_is_conf_writable( const NAIOProvider *provider, const NAPivot *pivot )
+na_io_provider_is_conf_writable( const NAIOProvider *provider, const NAPivot *pivot, gboolean *mandatory )
 {
 	gboolean is_writable;
 	gchar *group;
@@ -591,7 +597,7 @@ na_io_provider_is_conf_writable( const NAIOProvider *provider, const NAPivot *pi
 
 		group = g_strdup_printf( "%s %s", NA_IPREFS_IO_PROVIDER_GROUP, provider->private->id );
 		is_writable = na_settings_get_boolean_ex(
-				na_pivot_get_settings( pivot ), group, NA_IPREFS_IO_PROVIDER_WRITABLE, NULL, NULL );
+				na_pivot_get_settings( pivot ), group, NA_IPREFS_IO_PROVIDER_WRITABLE, NULL, mandatory );
 		g_free( group );
 	}
 
@@ -803,7 +809,7 @@ io_providers_list_add_from_plugins( const NAPivot *pivot, GList *objects_list )
 		}
 
 		if( id ){
-			merged = io_providers_list_add_object( pivot, merged, provider_module, id );
+			merged = io_providers_list_append_object( pivot, merged, provider_module, id );
 			g_free( id );
 		}
 	}
@@ -832,7 +838,32 @@ io_providers_list_add_from_prefs( const NAPivot *pivot, GList *objects_list )
 	io_providers = na_iprefs_get_io_providers( pivot );
 	for( it = io_providers ; it ; it = it->next ){
 		id = ( const gchar * ) it->data;
-		merged = io_providers_list_add_object( pivot, merged, NULL, id );
+		merged = io_providers_list_append_object( pivot, merged, NULL, id );
+	}
+	na_core_utils_slist_free( io_providers );
+
+	return( merged );
+}
+
+/*
+ * adding from write-order means we only create NAIOProvider objects
+ * without having any ref to the underlying NAIIOProvider if it exists
+ */
+static GList *
+io_providers_list_add_from_write_order( const NAPivot *pivot, GList *objects_list )
+{
+	GList *merged;
+	NASettings *settings;
+	GSList *io_providers, *it;
+	const gchar *id;
+
+	merged = objects_list;
+	settings = na_pivot_get_settings( pivot );
+	io_providers = na_settings_get_string_list( settings, NA_IPREFS_IO_PROVIDERS_WRITE_ORDER, NULL, NULL );
+
+	for( it = io_providers ; it ; it = it->next ){
+		id = ( const gchar * ) it->data;
+		merged = io_providers_list_append_object( pivot, merged, NULL, id );
 	}
 	na_core_utils_slist_free( io_providers );
 
@@ -844,16 +875,20 @@ io_providers_list_add_from_prefs( const NAPivot *pivot, GList *objects_list )
  * if it does not have been already registered
  */
 static GList *
-io_providers_list_add_object( const NAPivot *pivot, GList *list, NAIIOProvider *module, const gchar *id )
+io_providers_list_append_object( const NAPivot *pivot, GList *list, NAIIOProvider *module, const gchar *id )
 {
 	GList *merged;
 	NAIOProvider *object;
 
 	merged = list;
+	object = peek_provider_by_id( list, id );
 
-	if( !peek_provider_by_id( list, id ) ){
+	if( !object ){
 		object = io_provider_new( pivot, module, id );
-		merged = g_list_prepend( merged, object );
+		merged = g_list_append( merged, object );
+
+	} else if( !object->private->provider && module ){
+		object->private->provider = module;
 	}
 
 	return( merged );
@@ -877,7 +912,7 @@ is_really_writable( const NAIOProvider *provider, const NAPivot *pivot )
 
 	return( na_io_provider_is_willing_to_write( provider ) &&
 			na_io_provider_is_able_to_write( provider ) &&
-			na_io_provider_is_conf_writable( provider, pivot ) &&
+			na_io_provider_is_conf_writable( provider, pivot, NULL ) &&
 			!na_pivot_is_configuration_locked_by_admin( pivot ));
 }
 
@@ -976,7 +1011,7 @@ load_items_get_merged_list( const NAPivot *pivot, guint loadable_set, GSList **m
 
 		if( provider_module &&
 			NA_IIO_PROVIDER_GET_INTERFACE( provider_module )->read_items &&
-			na_io_provider_is_conf_readable( provider_object, pivot )){
+			na_io_provider_is_conf_readable( provider_object, pivot, NULL )){
 
 			items = NA_IIO_PROVIDER_GET_INTERFACE( provider_module )->read_items( provider_module, messages );
 
diff --git a/src/core/na-io-provider.h b/src/core/na-io-provider.h
index ed7afe9..6ea69ce 100644
--- a/src/core/na-io-provider.h
+++ b/src/core/na-io-provider.h
@@ -103,9 +103,9 @@ void          na_io_provider_unref_io_providers_list  ( void );
 gchar        *na_io_provider_get_id             ( const NAIOProvider *provider );
 gchar        *na_io_provider_get_name           ( const NAIOProvider *provider );
 gboolean      na_io_provider_is_available       ( const NAIOProvider *provider );
-gboolean      na_io_provider_is_conf_readable   ( const NAIOProvider *provider, const NAPivot *pivot );
+gboolean      na_io_provider_is_conf_readable   ( const NAIOProvider *provider, const NAPivot *pivot, gboolean *mandatory );
 gboolean      na_io_provider_is_able_to_write   ( const NAIOProvider *provider );
-gboolean      na_io_provider_is_conf_writable   ( const NAIOProvider *provider, const NAPivot *pivot );
+gboolean      na_io_provider_is_conf_writable   ( const NAIOProvider *provider, const NAPivot *pivot, gboolean *mandatory );
 gboolean      na_io_provider_is_willing_to_write( const NAIOProvider *provider );
 
 GList        *na_io_provider_load_items( const NAPivot *pivot, guint loadable_set, GSList **messages );
diff --git a/src/core/na-updater.c b/src/core/na-updater.c
index b7ca518..71b6a7c 100644
--- a/src/core/na-updater.c
+++ b/src/core/na-updater.c
@@ -352,7 +352,7 @@ na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item,
 					if( reason ){
 						*reason = NA_IIO_PROVIDER_STATUS_PROVIDER_LOCKED_BY_ADMIN;
 					}*/
-				} else if( !na_io_provider_is_conf_writable( provider, NA_PIVOT( updater ))){
+				} else if( !na_io_provider_is_conf_writable( provider, NA_PIVOT( updater ), NULL )){
 					writable = FALSE;
 					if( reason ){
 						*reason = NA_IIO_PROVIDER_STATUS_PROVIDER_LOCKED_BY_USER;
diff --git a/src/nact/nact-providers-list.c b/src/nact/nact-providers-list.c
index d64a4a8..ea22373 100644
--- a/src/nact/nact-providers-list.c
+++ b/src/nact/nact-providers-list.c
@@ -49,7 +49,9 @@
  */
 enum {
 	PROVIDER_READABLE_COLUMN = 0,
+	PROVIDER_READABLE_MANDATORY_COLUMN,
 	PROVIDER_WRITABLE_COLUMN,
+	PROVIDER_WRITABLE_MANDATORY_COLUMN,
 	PROVIDER_LIBELLE_COLUMN,
 	PROVIDER_ID_COLUMN,
 	PROVIDER_PROVIDER_COLUMN,
@@ -80,6 +82,7 @@ static void       on_writable_toggled( GtkCellRendererToggle *renderer, gchar *p
 static void       on_up_clicked( GtkButton *button, BaseWindow *window );
 static void       on_down_clicked( GtkButton *button, BaseWindow *window );
 
+static gboolean   are_preferences_locked( BaseWindow *window );
 static void       display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, GtkTreeView *treeview );
 static GtkButton *get_up_button( BaseWindow *window );
 static GtkButton *get_down_button( BaseWindow *window );
@@ -104,18 +107,26 @@ nact_providers_list_create_model( GtkTreeView *treeview )
 	g_debug( "%s: treeview=%p", thisfn, ( void * ) treeview );
 	g_return_if_fail( GTK_IS_TREE_VIEW( treeview ));
 
-	model = gtk_list_store_new( PROVIDER_N_COLUMN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_OBJECT );
+	model = gtk_list_store_new( PROVIDER_N_COLUMN,
+			G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_OBJECT );
 	gtk_tree_view_set_model( treeview, GTK_TREE_MODEL( model ));
 	g_object_unref( model );
 
+	/* readable */
 	toggled_cell = gtk_cell_renderer_toggle_new();
 	column = gtk_tree_view_column_new_with_attributes(
-			_( "To be read" ),
+			_( "Readable" ),
 			toggled_cell,
 			"active", PROVIDER_READABLE_COLUMN,
 			NULL );
 	gtk_tree_view_append_column( treeview, column );
 
+	/* readable mandatory */
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_append_column( treeview, column );
+	gtk_tree_view_column_set_visible( column, FALSE );
+
+	/* writable */
 	toggled_cell = gtk_cell_renderer_toggle_new();
 	column = gtk_tree_view_column_new_with_attributes(
 			_( "Writable" ),
@@ -124,6 +135,12 @@ nact_providers_list_create_model( GtkTreeView *treeview )
 			NULL );
 	gtk_tree_view_append_column( treeview, column );
 
+	/* writable mandatory */
+	column = gtk_tree_view_column_new();
+	gtk_tree_view_append_column( treeview, column );
+	gtk_tree_view_column_set_visible( column, FALSE );
+
+	/* label */
 	text_cell = gtk_cell_renderer_text_new();
 	column = gtk_tree_view_column_new_with_attributes(
 			_( "I/O Provider" ),
@@ -133,12 +150,12 @@ nact_providers_list_create_model( GtkTreeView *treeview )
 	gtk_tree_view_column_set_cell_data_func( column, text_cell, ( GtkTreeCellDataFunc ) display_label, treeview, NULL );
 	gtk_tree_view_append_column( treeview, column );
 
-	/* PROVIDER_ID_COLUMN */
+	/* id */
 	column = gtk_tree_view_column_new();
 	gtk_tree_view_append_column( treeview, column );
 	gtk_tree_view_column_set_visible( column, FALSE );
 
-	/* PROVIDER_PROVIDER_COLUMN */
+	/* provider */
 	column = gtk_tree_view_column_new();
 	gtk_tree_view_append_column( treeview, column );
 	gtk_tree_view_column_set_visible( column, FALSE );
@@ -177,6 +194,7 @@ nact_providers_list_init_view( GtkTreeView *treeview, BaseWindow *window )
 static void
 init_view_setup_providers( GtkTreeView *treeview, BaseWindow *window )
 {
+	static const gchar *thisfn = "nact_providers_list_init_view_setup_providers";
 	NactApplication *application;
 	NAUpdater *updater;
 	GtkListStore *model;
@@ -184,6 +202,9 @@ init_view_setup_providers( GtkTreeView *treeview, BaseWindow *window )
 	const GList *iter;
 	GtkTreeIter row;
 	gchar *id, *libelle;
+	gboolean readable, readable_mandatory;
+	gboolean writable, writable_mandatory;
+	NAIOProvider *provider;
 
 	model = GTK_LIST_STORE( gtk_tree_view_get_model( treeview ));
 
@@ -192,29 +213,36 @@ init_view_setup_providers( GtkTreeView *treeview, BaseWindow *window )
 	providers = na_io_provider_get_io_providers_list( NA_PIVOT( updater ));
 
 	for( iter = providers ; iter ; iter = iter->next ){
+		provider = NA_IO_PROVIDER( iter->data );
+		id = na_io_provider_get_id( provider );
+		libelle = na_io_provider_get_name( provider );
+		readable = na_io_provider_is_conf_readable( provider, NA_PIVOT( updater ), &readable_mandatory );
+		writable = na_io_provider_is_conf_writable( provider, NA_PIVOT( updater ), &writable_mandatory );
 
-		gtk_list_store_append( model, &row );
-
-		id = na_io_provider_get_id( NA_IO_PROVIDER( iter->data ));
-		libelle = na_io_provider_get_name( NA_IO_PROVIDER( iter->data ));
+		g_debug( "%s: id=%s, readable=%s (mandatory=%s), writable=%s (mandatory=%s)",
+				thisfn, id,
+				readable ? "True":"False", readable_mandatory ? "True":"False",
+				writable ? "True":"False", writable_mandatory ? "True":"False" );
 
 		if( !libelle || !g_utf8_strlen( libelle, -1 )){
-
 			g_free( libelle );
-			if( na_io_provider_is_available( NA_IO_PROVIDER( iter->data ))){
 
+			if( na_io_provider_is_available( provider )){
 				/* i18n: default name when the I/O providers doesn't provide one */
 				libelle = g_strdup_printf( "<%s: %s>", id, _( "no name" ));
-			} else {
 
+			} else {
 				/* i18n: name displayed when the corresponding I/O provider is unavailable at runtime */
 				libelle = g_strdup_printf( "<%s: %s>", id, _( "unavailable I/O provider" ));
 			}
 		}
 
+		gtk_list_store_append( model, &row );
 		gtk_list_store_set( model, &row,
-				PROVIDER_READABLE_COLUMN, na_io_provider_is_conf_readable( NA_IO_PROVIDER( iter->data ), NA_PIVOT( updater )),
-				PROVIDER_WRITABLE_COLUMN, na_io_provider_is_conf_writable( NA_IO_PROVIDER( iter->data ), NA_PIVOT( updater )),
+				PROVIDER_READABLE_COLUMN, readable,
+				PROVIDER_READABLE_MANDATORY_COLUMN, readable_mandatory,
+				PROVIDER_WRITABLE_COLUMN, writable,
+				PROVIDER_WRITABLE_MANDATORY_COLUMN, writable_mandatory,
 				PROVIDER_LIBELLE_COLUMN, libelle,
 				PROVIDER_ID_COLUMN, id,
 				PROVIDER_PROVIDER_COLUMN, iter->data,
@@ -373,6 +401,11 @@ nact_providers_list_dispose( BaseWindow *window )
 	gtk_list_store_clear( GTK_LIST_STORE( model ));
 }
 
+/*
+ * may up/down if:
+ * - preferences are not locked
+ * - i/o providers order is not mandatory
+ */
 static void
 on_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
 {
@@ -381,16 +414,29 @@ on_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
 	GtkButton *button;
 	GtkTreePath *path;
 	gboolean may_up, may_down;
+	gboolean preferences_locked, order_mandatory;
+	GSList *write_order;
+	NactApplication *application;
+	NAUpdater *updater;
+	NASettings *settings;
 
 	may_up = FALSE;
 	may_down = FALSE;
 
-	if( gtk_tree_selection_get_selected( selection, &model, &iter )){
-		path = gtk_tree_model_get_path( model, &iter );
-		may_up = gtk_tree_path_prev( path );
-		gtk_tree_path_free( path );
+	application = NACT_APPLICATION( base_window_get_application( window ));
+	updater = nact_application_get_updater( application );
+	settings = na_pivot_get_settings( NA_PIVOT( updater ));
+	preferences_locked = na_settings_get_boolean( settings, NA_IPREFS_ADMIN_PREFERENCES_LOCKED, NULL, NULL );
+	write_order = na_settings_get_string_list( settings, NA_IPREFS_IO_PROVIDERS_WRITE_ORDER, NULL, &order_mandatory );
+
+	if( !preferences_locked &&
+		!order_mandatory &&
+		gtk_tree_selection_get_selected( selection, &model, &iter )){
 
-		may_down = gtk_tree_model_iter_next( model, &iter );
+			path = gtk_tree_model_get_path( model, &iter );
+			may_up = gtk_tree_path_prev( path );
+			gtk_tree_path_free( path );
+			may_down = gtk_tree_model_iter_next( model, &iter );
 	}
 
 	button = get_up_button( window );
@@ -400,21 +446,47 @@ on_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
 	gtk_widget_set_sensitive( GTK_WIDGET( button ), may_down );
 }
 
+/*
+ * may toggle if
+ * - preferences are not locked
+ * - readable status is not mandatory
+ */
 static void
 on_readable_toggled( GtkCellRendererToggle *renderer, gchar *path_string, BaseWindow *window )
 {
+	static const gchar *thisfn = "nact_providers_list_on_readable_toggled";
 	GtkTreeView *treeview;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	gboolean state;
+	gboolean readable_mandatory;
+	gchar *id;
 
 	if( !st_on_selection_change ){
 
 		treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW ));
 		model = gtk_tree_view_get_model( treeview );
 		if( gtk_tree_model_get_iter_from_string( model, &iter, path_string )){
-			gtk_tree_model_get( model, &iter, PROVIDER_READABLE_COLUMN, &state, -1 );
-			gtk_list_store_set( GTK_LIST_STORE( model ), &iter, PROVIDER_READABLE_COLUMN, !state, -1 );
+			gtk_tree_model_get( model, &iter,
+					PROVIDER_READABLE_COLUMN, &state,
+					PROVIDER_ID_COLUMN, &id,
+					PROVIDER_READABLE_MANDATORY_COLUMN, &readable_mandatory,
+					-1 );
+
+			g_debug( "%s: id=%s, readable=%s (mandatory=%s)", thisfn, id,
+					state ? "True":"False", readable_mandatory ? "True":"False" );
+
+			if( readable_mandatory || are_preferences_locked( window )){
+				g_signal_handlers_block_by_func(( gpointer ) renderer, on_readable_toggled, window );
+				state = gtk_cell_renderer_toggle_get_active( renderer );
+				gtk_cell_renderer_toggle_set_active( renderer, !state );
+				g_signal_handlers_unblock_by_func(( gpointer ) renderer, on_readable_toggled, window );
+
+			} else {
+				gtk_list_store_set( GTK_LIST_STORE( model ), &iter, PROVIDER_READABLE_COLUMN, !state, -1 );
+			}
+
+			g_free( id );
 		}
 	}
 }
@@ -422,22 +494,48 @@ on_readable_toggled( GtkCellRendererToggle *renderer, gchar *path_string, BaseWi
 static void
 on_writable_toggled( GtkCellRendererToggle *renderer, gchar *path_string, BaseWindow *window )
 {
+	static const gchar *thisfn = "nact_providers_list_on_writable_toggled";
 	GtkTreeView *treeview;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	gboolean state;
+	gboolean writable_mandatory;
+	gchar *id;
 
 	if( !st_on_selection_change ){
 
 		treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW ));
 		model = gtk_tree_view_get_model( treeview );
 		if( gtk_tree_model_get_iter_from_string( model, &iter, path_string )){
-			gtk_tree_model_get( model, &iter, PROVIDER_WRITABLE_COLUMN, &state, -1 );
-			gtk_list_store_set( GTK_LIST_STORE( model ), &iter, PROVIDER_WRITABLE_COLUMN, !state, -1 );
+			gtk_tree_model_get( model, &iter,
+					PROVIDER_WRITABLE_COLUMN, &state,
+					PROVIDER_ID_COLUMN, &id,
+					PROVIDER_WRITABLE_MANDATORY_COLUMN, &writable_mandatory,
+					-1 );
+
+			g_debug( "%s: id=%s, writable=%s (mandatory=%s)", thisfn, id,
+					state ? "True":"False", writable_mandatory ? "True":"False" );
+
+			if( writable_mandatory || are_preferences_locked( window )){
+				g_signal_handlers_block_by_func(( gpointer ) renderer, on_writable_toggled, window );
+				state = gtk_cell_renderer_toggle_get_active( renderer );
+				gtk_cell_renderer_toggle_set_active( renderer, !state );
+				g_signal_handlers_unblock_by_func(( gpointer ) renderer, on_writable_toggled, window );
+
+			} else {
+				gtk_list_store_set( GTK_LIST_STORE( model ), &iter, PROVIDER_WRITABLE_COLUMN, !state, -1 );
+			}
+
+			g_free( id );
 		}
 	}
 }
 
+/*
+ * may up/down if:
+ * - preferences are not locked
+ * - i/o providers order is not mandatory
+ */
 static void
 on_up_clicked( GtkButton *button, BaseWindow *window )
 {
@@ -488,6 +586,22 @@ on_down_clicked( GtkButton *button, BaseWindow *window )
 	}
 }
 
+static gboolean
+are_preferences_locked( BaseWindow *window )
+{
+	NactApplication *application;
+	NAUpdater *updater;
+	NASettings *settings;
+	gboolean are_locked;
+
+	application = NACT_APPLICATION( base_window_get_application( window ));
+	updater = nact_application_get_updater( application );
+	settings = na_pivot_get_settings( NA_PIVOT( updater ));
+	are_locked = na_settings_get_boolean( settings, NA_IPREFS_ADMIN_PREFERENCES_LOCKED, NULL, NULL );
+
+	return( are_locked );
+}
+
 /*
  * unavailable provider: italic grey
  */



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