[nautilus-actions] Complete writability status of GConf IO Provider



commit 38788b3efea4b1b04f735137e07b8954144612ec
Author: Pierre Wieser <pwieser trychlos org>
Date:   Wed Nov 25 22:25:21 2009 +0100

    Complete writability status of GConf IO Provider

 ChangeLog                                       |    9 ++
 nautilus-actions/io-provider-gconf/nagp-read.c  |   49 +++++++++--
 nautilus-actions/io-provider-gconf/nagp-write.c |  111 ++++++++---------------
 nautilus-actions/io-provider-gconf/nagp-write.h |    2 -
 4 files changed, 88 insertions(+), 83 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0bdba23..5e1a8ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,15 @@
 	(na_object_action_is_readonly): Renamed to na_object_item_is_readonly.
 	(na_object_action_set_readonly): Renamed to na_object_item_set_readonly.
 
+	* nautilus-actions/io-provider-gconf/nagp-read.c
+	(read_object_item_properties): Set the 'read-only' flag for the object.
+
+	* nautilus-actions/io-provider-gconf/nagp-write.c
+	(nagp_iio_provider_is_writable): Set the writability status of the
+	object.
+	(nagp_iio_provider_is_willing_to_write): Set the writability status of
+	the provider.
+
 	* nautilus-actions/io-provider-desktop/egg-desktop-file.c:
 	* nautilus-actions/io-provider-desktop/egg-desktop-file.h:
 	New files.
diff --git a/nautilus-actions/io-provider-gconf/nagp-read.c b/nautilus-actions/io-provider-gconf/nagp-read.c
index f5776fa..89a7958 100644
--- a/nautilus-actions/io-provider-gconf/nagp-read.c
+++ b/nautilus-actions/io-provider-gconf/nagp-read.c
@@ -53,6 +53,7 @@ static void           read_item_menu( NagpGConfProvider *provider, const gchar *
 static void           read_item_menu_properties( NagpGConfProvider *provider, GSList *entries, NAObjectMenu *menu );
 static void           read_object_item_properties( NagpGConfProvider *provider, GSList *entries, NAObjectItem *item );
 
+static gboolean       is_key_writable( NagpGConfProvider *gconf, const gchar *key );
 static GSList        *get_subdirs( GConfClient *gconf, const gchar *path );
 static void           free_subdirs( GSList *subdirs );
 static gboolean       has_entry( GConfClient *gconf, const gchar *path, const gchar *entry );
@@ -213,8 +214,6 @@ read_item_action( NagpGConfProvider *provider, const gchar *path, NAObjectAction
 	free_gslist( order );
 	free_subdirs( list_profiles );
 	na_gconf_utils_free_entries( entries );
-
-	/*na_object_action_set_readonly( action, !nagp_key_is_writable( provider, path ));*/
 }
 
 /*
@@ -397,6 +396,10 @@ read_item_menu_properties( NagpGConfProvider *provider, GSList *entries, NAObjec
 
 /*
  * set the properties into the NAObjectItem
+ *
+ * The NAObjectItem is set to 'read-only' if at least one the entries is
+ * not writable ; in other words, a writable NAObjectItem has all its
+ * entries writable.
  */
 static void
 read_object_item_properties( NagpGConfProvider *provider, GSList *entries, NAObjectItem *item )
@@ -405,6 +408,10 @@ read_object_item_properties( NagpGConfProvider *provider, GSList *entries, NAObj
 	gchar *id, *label, *tooltip, *icon;
 	gboolean enabled;
 	GSList *subitems;
+	GSList *ie;
+	GConfEntry *gconf_entry;
+	const gchar *key;
+	gboolean writable;
 
 	if( !na_gconf_utils_get_string_from_entries( entries, OBJECT_ITEM_LABEL_ENTRY, &label )){
 		id = na_object_get_id( item );
@@ -433,9 +440,39 @@ read_object_item_properties( NagpGConfProvider *provider, GSList *entries, NAObj
 		na_object_item_set_items_string_list( item, subitems );
 		free_gslist( subitems );
 	}
+
+	writable = TRUE;
+	for( ie = entries ; ie && writable ; ie = ie->next ){
+		gconf_entry = ( GConfEntry * ) ie->data;
+		key = gconf_entry_get_key( gconf_entry );
+		writable = is_key_writable( provider, key );
+	}
+	na_object_set_readonly( item, !writable );
+}
+
+/*
+ * key must be an existing entry (not a dir) to get a relevant return
+ * value ; else we get FALSE
+ */
+static gboolean
+is_key_writable( NagpGConfProvider *gconf, const gchar *key )
+{
+	static const gchar *thisfn = "nagp_read_is_key_writable";
+	GError *error = NULL;
+	gboolean is_writable;
+
+	is_writable = gconf_client_key_is_writable( gconf->private->gconf, key, &error );
+	if( error ){
+		g_warning( "%s: gconf_client_key_is_writable: %s", thisfn, error->message );
+		g_error_free( error );
+		error = NULL;
+		is_writable = FALSE;
+	}
+
+	return( is_writable );
 }
 
-/**
+/*
  * get_subdirs:
  * @gconf: a  #GConfClient instance.
  * @path: a full path to be readen.
@@ -465,7 +502,7 @@ get_subdirs( GConfClient *gconf, const gchar *path )
 	return( list_subdirs );
 }
 
-/**
+/*
  * free_subdirs:
  * @subdirs: a list of subdirs as returned by get_subdirs().
  *
@@ -477,7 +514,7 @@ free_subdirs( GSList *subdirs )
 	free_gslist( subdirs );
 }
 
-/**
+/*
  * na_gconf_utils_have_subdir:
  * @gconf: a  #GConfClient instance.
  * @path: a full path to be readen.
@@ -498,7 +535,7 @@ na_gconf_utils_have_subdir( GConfClient *gconf, const gchar *path )
 	return( have_subdir );
 }*/
 
-/**
+/*
  * has_entry:
  * @gconf: a  #GConfClient instance.
  * @path: the full path of a key.
diff --git a/nautilus-actions/io-provider-gconf/nagp-write.c b/nautilus-actions/io-provider-gconf/nagp-write.c
index aa388bc..38e7d3a 100644
--- a/nautilus-actions/io-provider-gconf/nagp-write.c
+++ b/nautilus-actions/io-provider-gconf/nagp-write.c
@@ -49,46 +49,76 @@ static gboolean       write_list( NagpGConfProvider *gconf, const gchar *uuid, c
 static void           free_gslist( GSList *list );
 
 /*
- * always returns TRUE because user _should_ be able to write its own
- * configurations into ~/.gconf
+ * Rationale: gconf reads its storage path in /etc/gconf/2/path ;
+ * there is there a 'xml:readwrite:$(HOME)/.gconf' line, but I do not
+ * known any way to get it programatically, so an admin may have set a
+ * readwrite space elsewhere..
+ *
+ * So, I try to write a 'foo' key somewhere: if it is ok, then the
+ * provider is supposed willing to write...
  */
 gboolean
 nagp_iio_provider_is_willing_to_write( const NAIIOProvider *provider )
 {
 	static const gchar *thisfn = "nagp_iio_provider_is_willing_to_write";
+	static const gchar *path = "/apps/no-nautilus-actions";
 	NagpGConfProvider *self;
 	gboolean willing_to = FALSE;
+	gchar *key;
 
 	g_debug( "%s: provider=%p", thisfn, ( void * ) provider );
 	g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider ), FALSE );
 	g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider ), FALSE );
 	self = NAGP_GCONF_PROVIDER( provider );
 
-	/* TODO: nagp_gconf_provider_iio_provider_is_willing_to_write */
 	if( !self->private->dispose_has_run ){
-		willing_to = TRUE;
+
+		key = gconf_concat_dir_and_key( path, thisfn );
+
+		if( !na_gconf_utils_write_string( self->private->gconf, key, "1", NULL )){
+			willing_to = FALSE;
+
+		} else if( !gconf_client_recursive_unset( self->private->gconf, path, 0, NULL )){
+			willing_to = FALSE;
+
+		} else {
+			willing_to = TRUE;
+		}
+
+		g_free( key );
 	}
 
 	return( willing_to );
 }
 
 /*
+ * Though the provider writability has already been checked by the
+ * program, we can only returns TRUE if the provider is willing to write.
+ * We so have to re-check it here.
  *
+ * If the provider is set, we are able to use the 'read-only' flag of
+ * the object. Else, we returns the provider itself writability status.
  */
 gboolean
 nagp_iio_provider_is_writable( const NAIIOProvider *provider, const NAObjectItem *item )
 {
 	NagpGConfProvider *self;
 	gboolean willing_to = FALSE;
+	NAIIOProvider *origin;
 
 	g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider ), FALSE );
 	g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider ), FALSE );
 	g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), FALSE );
 	self = NAGP_GCONF_PROVIDER( provider );
 
-	/* TODO: nagp_gconf_provider_iio_provider_is_writable */
 	if( !self->private->dispose_has_run ){
-		willing_to = TRUE;
+
+		origin = na_object_get_provider( item );
+		if( origin ){
+			willing_to = !na_object_is_readonly( item );
+		} else {
+			willing_to = nagp_iio_provider_is_willing_to_write( provider );
+		}
 	}
 
 	return( willing_to );
@@ -276,75 +306,6 @@ nagp_iio_provider_delete_item( const NAIIOProvider *provider, const NAObjectItem
 	return( ret );
 }
 
-/*
- * gconf_client_key_is_writable doesn't work as I expect: it returns
- * FALSE without error for our keys !
- * So I have to actually try a fake write to the key to get the real
- * writability status...
- *
- * TODO: having a NAPivot as Nautilus extension and another NAPivot in
- * the UI leads to a sort of notification loop: extension's pivot is
- * not aware of UI's one, and so get notifications from GConf, reloads
- * the list of actions, retrying to test the writability.
- * In the meanwhile, UI's pivot has reauthorized notifications, and is
- * notified of extension's pivot tests, and so on......
- *
- * -> Nautilus extension's pivot should not test for writability, as it
- *    uses actions as read-only, reloading the whole list when one
- *    action is modified ; this can break the loop
- *
- * -> the UI may use the pivot inside of Nautilus extension via a sort
- *    of API, falling back to its own pivot, when the extension is not
- *    present.
- *
- * 2009-11-25 - it appears that gconf_client_key_is_writable() returns
- * - FALSE for an existant dir (provided 'path')
- * - FALSE for a non-existant entry
- * - TRUE for an existant entry
- */
-gboolean
-nagp_key_is_writable( NagpGConfProvider *gconf, const gchar *path )
-{
-	static const gchar *thisfn = "nagp_gconf_provider_key_is_writable";
-	GError *error = NULL;
-	gboolean is_writable;
-	gchar *key;
-
-	g_debug( "%s: gconf=%p, path=%s", thisfn, ( void * ) gconf, path );
-
-	/*remove_gconf_watched_dir( gconf );*/
-
-	key = gconf_concat_dir_and_key( path, "foo" );
-	is_writable = gconf_client_key_is_writable( gconf->private->gconf, key, &error );
-	g_debug( "%s: gconf_client_key_is_writable returns is_writable=%s", thisfn, is_writable ? "True":"False" );
-	if( error ){
-		g_warning( "%s: gconf_client_key_is_writable: %s", thisfn, error->message );
-		g_error_free( error );
-		error = NULL;
-		is_writable = FALSE;
-	}
-	g_free( key );
-
-	/*gboolean ret_try = FALSE;
-	gchar *path_try = g_strdup_printf( "%s/%s", path, "fake_key" );
-	ret_try = gconf_client_set_string( gconf->private->gconf, path_try, "fake_value", &error );
-	if( error ){
-		g_warning( "%s: gconf_client_set_string: %s", thisfn, error->message );
-		g_error_free( error );
-		error = NULL;
-	}
-	if( ret_try ){
-		gconf_client_unset( gconf->private->gconf, path_try, NULL );
-	}
-	g_free( path_try );
-	g_debug( "%s: ret_gconf=%s, ret_try=%s", thisfn, ret_gconf ? "True":"False", ret_try ? "True":"False" );
-
-	install_gconf_watched_dir( gconf );
-	return( ret_try );*/
-
-	return( is_writable );
-}
-
 static gboolean
 write_str( NagpGConfProvider *provider, const gchar *uuid, const gchar *name, const gchar *key, gchar *value, GSList **messages )
 {
diff --git a/nautilus-actions/io-provider-gconf/nagp-write.h b/nautilus-actions/io-provider-gconf/nagp-write.h
index bb626fc..366458b 100644
--- a/nautilus-actions/io-provider-gconf/nagp-write.h
+++ b/nautilus-actions/io-provider-gconf/nagp-write.h
@@ -55,8 +55,6 @@ gboolean nagp_iio_provider_is_willing_to_write( const NAIIOProvider *provider );
 
 gboolean nagp_iio_provider_is_writable( const NAIIOProvider *provider, const NAObjectItem *item );
 
-gboolean nagp_key_is_writable( NagpGConfProvider *gconf, const gchar *path );
-
 guint    nagp_iio_provider_write_item( const NAIIOProvider *provider, const NAObjectItem *item, GSList **message );
 
 guint    nagp_iio_provider_delete_item( const NAIIOProvider *provider, const NAObjectItem *item, GSList **message );



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