[nautilus-actions] Replace GConf preferences monitoring with NASettings



commit ef73ef8a621460e6e75e9c81fdd128cde85c4e60
Author: Pierre Wieser <pwieser trychlos org>
Date:   Mon Jan 10 21:10:50 2011 +0100

    Replace GConf preferences monitoring with NASettings

 ChangeLog                          |   11 +++
 src/core/na-pivot.c                |  166 ++++++++++++++++++++++++-----------
 src/core/na-pivot.h                |   31 +++++---
 src/core/na-settings.c             |  129 ++++++++++++++++++++--------
 src/core/na-settings.h             |   12 ++-
 src/plugin-menu/nautilus-actions.c |   87 ++++++++++++-------
 6 files changed, 297 insertions(+), 139 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 95b4925..c28ac75 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -35,6 +35,17 @@
 
 2011-01-10 Pierre Wieser <pwieser trychlos org>
 
+	* src/core/na-pivot.c:
+	* src/core/na-pivot.h:
+	Replace GConf preferences monitoring with NASettings.
+	Define new PIVOT_SIGNAL_ITEMS_CHANGED signal.
+
+	* src/core/na-settings.c:
+	* src/core/na-settings.h
+	(na_settings_register_key_callback,
+	na_settings_register_global_callback, na_settings_get_boolean):
+	New functions.
+
 	* src/api/na-iio-provider.h:
 	* src/core/na-io-provider.h: IIO_PROVIDER_SIGNAL_ITEM_CHANGED signal
 	definition is moved (and renamed) from public API to internal one.
diff --git a/src/core/na-pivot.c b/src/core/na-pivot.c
index ef11a6d..f883444 100644
--- a/src/core/na-pivot.c
+++ b/src/core/na-pivot.c
@@ -60,10 +60,6 @@ struct _NAPivotPrivate {
 	 */
 	GList      *modules;
 
-	/* The NASettings object
-	 */
-	NASettings *settings;
-
 	/* list of instances to be notified of configuration updates
 	 * these are called 'consumers' of NAPivot
 	 */
@@ -82,9 +78,9 @@ struct _NAPivotPrivate {
 	GTimeVal    last_event;
 	guint       event_source_id;
 
-	/* list of monitoring objects on runtime preferences
+	/* the preferences management
 	 */
-	GList      *monitors;
+	NASettings *settings;
 };
 
 /* NAPivot properties
@@ -93,9 +89,16 @@ enum {
 	NAPIVOT_PROP_TREE_ID = 1,
 };
 
+/* signals
+ */
+enum {
+	ITEMS_CHANGED,
+	LAST_SIGNAL
+};
 
-static GObjectClass *st_parent_class = NULL;
-static gint          st_burst_timeout = 100;		/* burst timeout in msec */
+static GObjectClass *st_parent_class           = NULL;
+static gint          st_burst_timeout          = 100;		/* burst timeout in msec */
+static gint          st_signals[ LAST_SIGNAL ] = { 0 };
 
 static GType         register_type( void );
 static void          class_init( NAPivotClass *klass );
@@ -117,8 +120,8 @@ static void          free_consumers( GList *list );
 static gboolean      on_item_changed_timeout( NAPivot *pivot );
 static gulong        time_val_diff( const GTimeVal *recent, const GTimeVal *old );
 
+#if 0
 /* NAGConf runtime preferences management */
-static void          monitor_runtime_preferences( NAPivot *pivot );
 static void          on_io_provider_prefs_changed( GConfClient *client, guint cnxn_id, GConfEntry *entry, NAPivot *pivot );
 static void          on_mandatory_prefs_changed( GConfClient *client, guint cnxn_id, GConfEntry *entry, NAPivot *pivot );
 static void          on_preferences_change( GConfClient *client, guint cnxn_id, GConfEntry *entry, NAPivot *pivot );
@@ -126,6 +129,12 @@ static void          display_order_changed( NAPivot *pivot );
 static void          create_root_menu_changed( NAPivot *pivot );
 static void          display_about_changed( NAPivot *pivot );
 static void          autosave_changed( NAPivot *pivot );
+#endif
+/* NASettings monitoring */
+static void          monitor_runtime_preferences( NAPivot *pivot );
+static void          on_io_provider_read_status_changed( gpointer newvalue, NAPivot *pivot );
+static void          on_io_providers_read_order_changed( gpointer newvalue, NAPivot *pivot );
+static void          on_items_level_zero_order_changed( gpointer newvalue, NAPivot *pivot );
 
 GType
 na_pivot_get_type( void )
@@ -198,6 +207,25 @@ class_init( NAPivotClass *klass )
 	g_object_class_install_property( object_class, NAPIVOT_PROP_TREE_ID, spec );
 
 	klass->private = g_new0( NAPivotClassPrivate, 1 );
+
+	/*
+	 * NAPivot::pivot-items-changed:
+	 *
+	 * This signal is sent by NAPivot ath the end of a burst of modifications
+	 * as signaled by i/o providers.
+	 *
+	 * The signal is registered without any default handler.
+	 */
+	st_signals[ ITEMS_CHANGED ] = g_signal_new(
+				PIVOT_SIGNAL_ITEMS_CHANGED,
+				NA_PIVOT_TYPE,
+				G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+				0,									/* class offset */
+				NULL,								/* accumulator */
+				NULL,								/* accumulator data */
+				g_cclosure_marshal_VOID__VOID,
+				G_TYPE_NONE,
+				0 );
 }
 
 static void
@@ -221,7 +249,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self->private->tree = NULL;
 	self->private->automatic_reload = FALSE;
 	self->private->event_source_id = 0;
-	self->private->monitors = NULL;
 }
 
 static void
@@ -325,9 +352,6 @@ instance_dispose( GObject *object )
 		na_object_unref_items( self->private->tree );
 		self->private->tree = NULL;
 
-		/* release the GConf monitoring */
-		na_gconf_monitor_release_monitors( self->private->monitors );
-
 		/* release the I/O Provider objects */
 		na_io_provider_terminate();
 
@@ -380,8 +404,6 @@ na_pivot_new( void )
 
 	pivot = g_object_new( NA_PIVOT_TYPE, NULL );
 
-	pivot->private->settings = na_settings_new();
-
 	return( pivot );
 }
 
@@ -405,7 +427,7 @@ na_pivot_dump( const NAPivot *pivot )
 		g_debug( "%s:        consumers=%p (%d elts)", thisfn, ( void * ) pivot->private->consumers, g_list_length( pivot->private->consumers ));
 		g_debug( "%s:             tree=%p (%d elts)", thisfn, ( void * ) pivot->private->tree, g_list_length( pivot->private->tree ));
 		g_debug( "%s: automatic_reload=%s", thisfn, pivot->private->automatic_reload ? "True":"False" );
-		g_debug( "%s:         monitors=%p (%d elts)", thisfn, ( void * ) pivot->private->monitors, g_list_length( pivot->private->monitors ));
+		/*g_debug( "%s:         monitors=%p (%d elts)", thisfn, ( void * ) pivot->private->monitors, g_list_length( pivot->private->monitors ));*/
 
 		for( it = pivot->private->tree, i = 0 ; it ; it = it->next ){
 			g_debug( "%s:     [%d]: %p", thisfn, i++, it->data );
@@ -663,17 +685,20 @@ on_item_changed_timeout( NAPivot *pivot )
 	 * this is up to NAPivot to send now its summarized signal
 	 * last, destroy this timeout
 	 */
-	g_debug( "%s: triggering NAIPivotConsumer interfaces", thisfn );
+	g_debug( "%s: emitting %s signal", thisfn, PIVOT_SIGNAL_ITEMS_CHANGED );
+	g_signal_emit_by_name(( gpointer ) pivot, PIVOT_SIGNAL_ITEMS_CHANGED );
 
+	/* this has to be deprecated */
+	g_debug( "%s: triggering NAIPivotConsumer interfaces", thisfn );
 	if( pivot->private->automatic_reload ){
 		na_pivot_load_items( pivot );
 	}
-
 	for( ic = pivot->private->consumers ; ic ; ic = ic->next ){
 		na_ipivot_consumer_notify_of_items_changed( NA_IPIVOT_CONSUMER( ic->data ));
 	}
 
 	pivot->private->event_source_id = 0;
+
 	return( FALSE );
 }
 
@@ -777,23 +802,29 @@ free_consumers( GList *consumers )
 }
 
 /*
- * na_pivot_register:
- * @settings: this #NAPivot instance.
- * @key: the key to be monitored.
- * @callback: the function to be called when the value of the key changes.
- * @user_data: data to be passed to the @callback function.
+ * na_pivot_get_settings:
+ * @pivot: this #NAPivot instance.
  *
- * Registers a new consumer of the monitoring of the @key.
+ * Returns: a pointer (not a reference) to the common #NASettings object.
+ * This pointer is owned by @pivot, and should not be released by the caller.
  *
  * Since: 3.1.0
  */
-void
-na_pivot_register( NAPivot *pivot, const gchar *key, GCallback callback, gpointer user_data )
+NASettings *
+na_pivot_get_settings( NAPivot *pivot )
 {
-	g_return_if_fail( NA_IS_PIVOT( pivot ));
+	NASettings *settings;
+
+	g_return_val_if_fail( NA_IS_PIVOT( pivot ), NULL );
+
+	settings = NULL;
 
 	if( !pivot->private->dispose_has_run ){
+
+		settings = pivot->private->settings;
 	}
+
+	return( settings );
 }
 
 /*
@@ -952,39 +983,39 @@ static void
 monitor_runtime_preferences( NAPivot *pivot )
 {
 	static const gchar *thisfn = "na_pivot_monitor_runtime_preferences";
-	GList *list = NULL;
-	gchar *path;
 
 	g_return_if_fail( NA_IS_PIVOT( pivot ));
 	g_return_if_fail( !pivot->private->dispose_has_run );
 
 	g_debug( "%s: pivot=%p", thisfn, ( void * ) pivot );
 
-	list = g_list_prepend( list,
-			na_gconf_monitor_new(
-					IPREFS_GCONF_PREFS_PATH,
-					( GConfClientNotifyFunc ) on_preferences_change,
-					pivot ));
-
-	path = gconf_concat_dir_and_key( IPREFS_GCONF_BASEDIR, "mandatory" );
-	list = g_list_prepend( list,
-			na_gconf_monitor_new(
-					path,
-					( GConfClientNotifyFunc ) on_mandatory_prefs_changed,
-					pivot ));
-	g_free( path );
-
-	path = gconf_concat_dir_and_key( IPREFS_GCONF_BASEDIR, "io-providers" );
-	list = g_list_prepend( list,
-			na_gconf_monitor_new(
-					path,
-					( GConfClientNotifyFunc ) on_io_provider_prefs_changed,
-					pivot ));
-	g_free( path );
-
-	pivot->private->monitors = list;
+	/* this is the new behavior (since 3.1.0)
+	 * NASettings take itself care of maintaining the list of registered callbacks
+	 */
+	pivot->private->settings = na_settings_new();
+
+	/* monitor the modifications of the readability status of the i/o providers
+	 * this use a fake key as this actually monitor the 'readable' key of
+	 * all known i/o providers
+	 */
+	na_settings_register_key_callback( pivot->private->settings,
+			NA_SETTINGS_RUNTIME_IO_PROVIDER_READ_STATUS,
+			G_CALLBACK( on_io_provider_read_status_changed ), pivot );
+
+	/* monitor the modification of the read order of the i/o providers
+	 */
+	na_settings_register_key_callback( pivot->private->settings,
+			NA_SETTINGS_RUNTIME_IO_PROVIDERS_READ_ORDER,
+			G_CALLBACK( on_io_providers_read_order_changed ), pivot );
+
+	/* monitor the modification of the level-zero order
+	 */
+	na_settings_register_key_callback( pivot->private->settings,
+			NA_SETTINGS_RUNTIME_ITEMS_LEVEL_ZERO_ORDER,
+			G_CALLBACK( on_items_level_zero_order_changed ), pivot );
 }
 
+#if 0
 static void
 on_io_provider_prefs_changed( GConfClient *client, guint cnxn_id, GConfEntry *entry, NAPivot *pivot )
 {
@@ -1131,3 +1162,34 @@ autosave_changed( NAPivot *pivot )
 		}
 	}
 }
+#endif
+
+static void
+on_io_provider_read_status_changed( gpointer newvalue, NAPivot *pivot )
+{
+	g_return_if_fail( NA_IS_PIVOT( pivot ));
+
+	if( !pivot->private->dispose_has_run ){
+
+	}
+}
+
+static void
+on_io_providers_read_order_changed( gpointer newvalue, NAPivot *pivot )
+{
+	g_return_if_fail( NA_IS_PIVOT( pivot ));
+
+	if( !pivot->private->dispose_has_run ){
+
+	}
+}
+
+static void
+on_items_level_zero_order_changed( gpointer newvalue, NAPivot *pivot )
+{
+	g_return_if_fail( NA_IS_PIVOT( pivot ));
+
+	if( !pivot->private->dispose_has_run ){
+
+	}
+}
diff --git a/src/core/na-pivot.h b/src/core/na-pivot.h
index ed2e9c4..690e1ca 100644
--- a/src/core/na-pivot.h
+++ b/src/core/na-pivot.h
@@ -125,21 +125,20 @@ enum {
 	PIVOT_LOAD_ALL      = 0xff
 };
 
-#define NA_PIVOT_RUNTIME_ITEMS_LIST_CHANGED		"na-pivot-runtime-items-list-changed"
-
-NAPivot      *na_pivot_new( void );
+NAPivot      *na_pivot_new ( void );
 void          na_pivot_dump( const NAPivot *pivot );
 
-/* providers management of any NAIxxxxProvider interface
+/* Management of the NAIxxxxProvider interfaces
+ * As of 2.30, these are NAIIOProvider, NAIImporter, NAIExporter
  */
-GList        *na_pivot_get_providers( const NAPivot *pivot, GType type );
+GList        *na_pivot_get_providers ( const NAPivot *pivot, GType type );
 void          na_pivot_free_providers( GList *providers );
 
-/* menus/actions items management
+/* Items, menus and actions, management
  */
-NAObjectItem *na_pivot_get_item( const NAPivot *pivot, const gchar *id );
-GList        *na_pivot_get_items( const NAPivot *pivot );
-void          na_pivot_load_items( NAPivot *pivot );
+NAObjectItem *na_pivot_get_item     ( const NAPivot *pivot, const gchar *id );
+GList        *na_pivot_get_items    ( const NAPivot *pivot );
+void          na_pivot_load_items   ( NAPivot *pivot );
 void          na_pivot_set_new_items( NAPivot *pivot, GList *tree );
 
 void          na_pivot_item_changed_handler( NAIIOProvider *provider, const gchar *id, NAPivot *pivot  );
@@ -147,11 +146,21 @@ void          na_pivot_item_changed_handler( NAIIOProvider *provider, const gcha
 gboolean      na_pivot_write_level_zero( const NAPivot *pivot, GList *items, GSList **messages );
 
 /* NAIPivotConsumer interface management
- * Monitoring and preferences management
+ * to be deprecated
  */
 void          na_pivot_register_consumer( NAPivot *pivot, const NAIPivotConsumer *consumer );
+
+/*
+ * Monitoring and preferences management
+ *
+ * NAPivot acts as a proxy for signals emitted by the NAIIOProvider providers
+ * when they detect a modification of their underlying items storage subsystems.
+ * As several to many signals may be emitted when such a modification occurs,
+ * NAPivot summarizes all these signals in an only one 'items-changed' event.
+ */
+#define PIVOT_SIGNAL_ITEMS_CHANGED				"pivot-items-changed"
+
 NASettings   *na_pivot_get_settings     ( NAPivot *pivot );
-void          na_pivot_register         ( NAPivot *pivot, const gchar *key, GCallback callback, gpointer user_data );
 
 /* NAPivot properties and configuration
  */
diff --git a/src/core/na-settings.c b/src/core/na-settings.c
index 2bdd55c..0575adf 100644
--- a/src/core/na-settings.c
+++ b/src/core/na-settings.c
@@ -33,6 +33,7 @@
 #endif
 
 #include <gio/gio.h>
+#include <string.h>
 
 #include <api/na-data-types.h>
 
@@ -75,6 +76,8 @@ static const KeyDef st_def_keys[] = {
 		{ 0 }
 };
 
+typedef void ( *global_fn )( gboolean global, void *user_data );
+
 typedef struct {
 	gchar    *key;
 	GCallback callback;
@@ -90,6 +93,7 @@ static void      instance_init( GTypeInstance *instance, gpointer klass );
 static void      instance_dispose( GObject *object );
 static void      instance_finalize( GObject *object );
 
+static KeyDef   *get_key_def( const gchar *key );
 static GKeyFile *initialize_settings( NASettings* settings, const gchar *dir, GFileMonitor **monitor, gulong *handler );
 static void      on_conf_changed( GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, NASettings *settings );
 static void      release_consumer( Consumer *consumer );
@@ -268,7 +272,7 @@ na_settings_new( void )
 }
 
 /**
- * na_settings_register:
+ * na_settings_register_key_callback:
  * @settings: this #NASettings instance.
  * @key: the key to be monitored.
  * @callback: the function to be called when the value of the key changes.
@@ -279,7 +283,7 @@ na_settings_new( void )
  * Since: 3.1.0
  */
 void
-na_settings_register( NASettings *settings, const gchar *key, GCallback callback, gpointer user_data )
+na_settings_register_key_callback( NASettings *settings, const gchar *key, GCallback callback, gpointer user_data )
 {
 	g_return_if_fail( NA_IS_SETTINGS( settings ));
 
@@ -296,7 +300,7 @@ na_settings_register( NASettings *settings, const gchar *key, GCallback callback
 }
 
 /**
- * na_settings_register_global:
+ * na_settings_register_global_callback:
  * @settings: this #NASettings instance.
  * @callback: the function to be called when the value of the key changes.
  * @user_data: data to be passed to the @callback function.
@@ -306,7 +310,7 @@ na_settings_register( NASettings *settings, const gchar *key, GCallback callback
  * Since: 3.1.0
  */
 void
-na_settings_register_global( NASettings *settings, GCallback callback, gpointer user_data )
+na_settings_register_global_callback( NASettings *settings, GCallback callback, gpointer user_data )
 {
 	g_return_if_fail( NA_IS_SETTINGS( settings ));
 
@@ -342,7 +346,11 @@ na_settings_register_global( NASettings *settings, GCallback callback, gpointer
 gboolean
 na_settings_get_boolean( NASettings *settings, const gchar *key, gboolean *found, gboolean *global )
 {
+	static const gchar *thisfn = "na_settings_get_boolean";
 	gboolean value;
+	KeyDef *key_def;
+	GError *error;
+	gboolean has_entry;
 
 	g_return_val_if_fail( NA_IS_SETTINGS( settings ), FALSE );
 
@@ -355,49 +363,67 @@ na_settings_get_boolean( NASettings *settings, const gchar *key, gboolean *found
 	}
 
 	if( !settings->private->dispose_has_run ){
-
+		error = NULL;
+		has_entry = TRUE;
+		key_def = get_key_def( key );
+
+		if( key_def ){
+			value = g_key_file_get_boolean( settings->private->global_conf, key_def->group, key, &error );
+			if( error ){
+				has_entry = FALSE;
+				if( error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND ){
+					g_warning( "%s: (global) %s", thisfn, error->message );
+				}
+				g_error_free( error );
+				error = NULL;
+
+			} else {
+				if( found ){
+					*found = TRUE;
+				}
+				if( global ){
+					*global = TRUE;
+				}
+			}
+			if( !has_entry ){
+				value = g_key_file_get_boolean( settings->private->user_conf, key_def->group, key, &error );
+				if( error ){
+					if( error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND ){
+						g_warning( "%s: (user) %s", thisfn, error->message );
+					}
+					g_error_free( error );
+					error = NULL;
+				} else {
+					has_entry = TRUE;
+					if( found ){
+						*found = TRUE;
+					}
+				}
+			}
+			if( !has_entry ){
+				value = ( strcmp( key_def->default_value, "true" ) == 0 );
+			}
+		}
 	}
 
 	return( value );
 }
 
-/**
- * na_settings_get_value:
- * @settings: this #NASettings instance.
- * @key: the key whose value is to be returned.
- * @found: if not %NULL, a pointer to a gboolean in which we will store
- *  whether the searched @key has been found (%TRUE), or if the returned
- *  value comes from default (%FALSE).
- * @global: if not %NULL, a pointer to a gboolean in which we will store
- *  whether the returned value has been readen from global preferences
- *  (%TRUE), or from the user preferences (%FALSE). Global preferences
- *  are usually read-only. When the @key has not been found, @global
- *  is set to %FALSE.
- *
- * Returns: the value of the key, of its default value if not found.
- *
- * Since: 3.1.0
- */
-gpointer
-na_settings_get_value( NASettings *settings, const gchar *key, gboolean *found, gboolean *global )
+static KeyDef *
+get_key_def( const gchar *key )
 {
-	gpointer value;
-
-	g_return_val_if_fail( NA_IS_SETTINGS( settings ), NULL );
-
-	value = NULL;
-	if( found ){
-		*found = FALSE;
-	}
-	if( global ){
-		*global = FALSE;
-	}
-
-	if( !settings->private->dispose_has_run ){
+	KeyDef *found = NULL;
+	KeyDef *idef;
 
+	idef = ( KeyDef * ) st_def_keys;
+	while( idef && !found ){
+		if( !strcmp( idef->key, key )){
+			found = idef;
+		}
+		idef++;
 	}
 
-	return( value );
+	return( found );
 }
 
 /*
@@ -439,11 +465,38 @@ initialize_settings( NASettings* settings, const gchar *dir, GFileMonitor **moni
 	return( key_file );
 }
 
+/*
+ * one of the two monitored configuration files have changed on the disk
+ * we do not try to identify which keys have actually change
+ * instead we trigger each registered consumer for the 'global' event
+ */
 static void
 on_conf_changed( GFileMonitor *monitor,
 		GFile *file, GFile *other_file, GFileMonitorEvent event_type, NASettings *settings )
 {
+	GList *ic;
+	Consumer *consumer;
+	gchar *path;
+	GFile *prefix;
+	gboolean global;
+
 	g_return_if_fail( NA_IS_SETTINGS( settings ));
+
+	if( !settings->private->dispose_has_run ){
+
+		path = g_build_filename( SYSCONFDIR, "xdg", NULL );
+		prefix = g_file_new_for_path( path );
+		global = g_file_has_prefix( file, prefix );
+		g_object_unref( prefix );
+		g_free( path );
+
+		for( ic = settings->private->consumers ; ic ; ic = ic->next ){
+			consumer = ( Consumer * ) ic->data;
+			if( !consumer->key ){
+				( *( global_fn ) consumer->callback )( global, consumer->user_data );
+			}
+		}
+	}
 }
 
 /*
diff --git a/src/core/na-settings.h b/src/core/na-settings.h
index d0866e8..c679f6c 100644
--- a/src/core/na-settings.h
+++ b/src/core/na-settings.h
@@ -81,16 +81,18 @@ typedef struct {
 
 GType na_settings_get_type( void );
 
+#define NA_SETTINGS_RUNTIME_IO_PROVIDER_READ_STATUS		"io-provider-read-status-fake-key"
+#define NA_SETTINGS_RUNTIME_IO_PROVIDERS_READ_ORDER		"io-providers-read-order"
 #define NA_SETTINGS_RUNTIME_ITEMS_ADD_ABOUT_ITEM		"items-add-about-item"
 #define NA_SETTINGS_RUNTIME_ITEMS_CREATE_ROOT_MENU		"items-create-root-menu"
+#define NA_SETTINGS_RUNTIME_ITEMS_LEVEL_ZERO_ORDER		"items-level-zero-order"
 
-NASettings *na_settings_new            ( void );
+NASettings *na_settings_new                     ( void );
 
-void        na_settings_register       ( NASettings *settings, const gchar *key, GCallback callback, gpointer user_data );
-void        na_settings_register_global( NASettings *settings, GCallback callback, gpointer user_data );
+void        na_settings_register_key_callback   ( NASettings *settings, const gchar *key, GCallback callback, gpointer user_data );
+void        na_settings_register_global_callback( NASettings *settings, GCallback callback, gpointer user_data );
 
-gboolean    na_settings_get_boolean    ( NASettings *settings, const gchar *key, gboolean *found, gboolean *global );
-gpointer    na_settings_get_value      ( NASettings *settings, const gchar *key, gboolean *found, gboolean *global );
+gboolean    na_settings_get_boolean             ( NASettings *settings, const gchar *key, gboolean *found, gboolean *global );
 
 G_END_DECLS
 
diff --git a/src/plugin-menu/nautilus-actions.c b/src/plugin-menu/nautilus-actions.c
index a612911..b39ac50 100644
--- a/src/plugin-menu/nautilus-actions.c
+++ b/src/plugin-menu/nautilus-actions.c
@@ -71,6 +71,7 @@ struct NautilusActionsClassPrivate {
 struct NautilusActionsPrivate {
 	gboolean dispose_has_run;
 	NAPivot *pivot;
+	gulong   items_changed_handler;
 	gboolean items_add_about_item;
 	gboolean items_create_root_menu;
 };
@@ -110,10 +111,10 @@ static GList            *create_root_menu( NautilusActions *plugin, GList *nauti
 static GList            *add_about_item( NautilusActions *plugin, GList *nautilus_menu );
 static void              execute_about( NautilusMenuItem *item, NautilusActions *plugin );
 
-static void              on_items_list_changed( NautilusActions *plugin );
+static void              on_pivot_items_changed_handler( NAPivot *pivot, NautilusActions *plugin );
 static void              on_items_add_about_item_changed( gpointer newvalue, NautilusActions *plugin );
 static void              on_items_create_root_menu_changed( gpointer newvalue, NautilusActions *plugin );
-static void              on_global_settings_changed( NautilusActions *plugin, gboolean global );
+static void              on_global_settings_changed( gboolean global, NautilusActions *plugin );
 
 GType
 nautilus_actions_get_type( void )
@@ -151,9 +152,10 @@ nautilus_actions_register_type( GTypeModule *module )
 		NULL
 	};
 
-	g_debug( "%s: module=%p", thisfn, ( void * ) module );
 	g_assert( st_actions_type == 0 );
 
+	g_debug( "%s: module=%p", thisfn, ( void * ) module );
+
 	st_actions_type = g_type_module_register_type( module, G_TYPE_OBJECT, "NautilusActions", &info, 0 );
 
 	g_type_module_add_interface( module, st_actions_type, NAUTILUS_TYPE_MENU_PROVIDER, &menu_provider_iface_info );
@@ -185,17 +187,15 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	static const gchar *thisfn = "nautilus_actions_instance_init";
 	NautilusActions *self;
 
-	g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) instance, ( void * ) klass );
 	g_return_if_fail( NAUTILUS_IS_ACTIONS( instance ));
-	g_return_if_fail( NA_IS_IPIVOT_CONSUMER( instance ));
+
+	g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) instance, ( void * ) klass );
 
 	self = NAUTILUS_ACTIONS( instance );
 
 	self->private = g_new0( NautilusActionsPrivate, 1 );
 
 	self->private->dispose_has_run = FALSE;
-
-	na_ipivot_consumer_allow_notify( NA_IPIVOT_CONSUMER( instance ), TRUE, 0 );
 }
 
 static void
@@ -205,14 +205,12 @@ instance_constructed( GObject *object )
 	NautilusActions *self;
 	NASettings *settings;
 
-	g_debug( "%s: object=%p", thisfn, ( void * ) object );
-
 	g_return_if_fail( NAUTILUS_IS_ACTIONS( object ));
-	g_return_if_fail( NA_IS_IPIVOT_CONSUMER( object ));
 
 	self = NAUTILUS_ACTIONS( object );
 
 	if( !self->private->dispose_has_run ){
+		g_debug( "%s: object=%p", thisfn, ( void * ) object );
 
 		self->private->pivot = na_pivot_new();
 
@@ -222,29 +220,35 @@ instance_constructed( GObject *object )
 		na_pivot_set_loadable( self->private->pivot, !PIVOT_LOAD_DISABLED & !PIVOT_LOAD_INVALID );
 		na_pivot_load_items( self->private->pivot );
 
-		/* register against NAPivot to be notified of modifications
-		 *  of items list
+		/* register against NAPivot to be notified of items changes
 		 */
-		na_pivot_register( self->private->pivot,
-				NA_PIVOT_RUNTIME_ITEMS_LIST_CHANGED,
-				( GCallback ) on_items_list_changed, self );
+		self->private->items_changed_handler =
+				g_signal_connect(
+						self->private->pivot,
+						PIVOT_SIGNAL_ITEMS_CHANGED,
+						G_CALLBACK( on_pivot_items_changed_handler ), self );
 
 		/* register against NASettings to be notified of changes on
 		 *  our runtime preferences
 		 */
 		settings = na_pivot_get_settings( self->private->pivot );
 		self->private->items_add_about_item = na_settings_get_boolean( settings, NA_SETTINGS_RUNTIME_ITEMS_ADD_ABOUT_ITEM, NULL, NULL );
-		na_settings_register( settings,
+		/*self->private->items_add_about_item = na_settings_get_boolean( settings, NA_SETTINGS_RUNTIME_ITEMS_ADD_ABOUT_ITEM, &found, &global );
+		g_debug( "%s: add_about_item=%s, found=%s, global=%s", thisfn,
+				self->private->items_add_about_item ? "True":"False",
+				found ? "True":"False",
+				global ? "True":"False" );*/
+		na_settings_register_key_callback( settings,
 				NA_SETTINGS_RUNTIME_ITEMS_ADD_ABOUT_ITEM,
-				( GCallback ) on_items_add_about_item_changed, self );
+				G_CALLBACK( on_items_add_about_item_changed ), self );
 
 		self->private->items_create_root_menu = na_settings_get_boolean( settings, NA_SETTINGS_RUNTIME_ITEMS_CREATE_ROOT_MENU, NULL, NULL );
-		na_settings_register( settings,
+		na_settings_register_key_callback( settings,
 				NA_SETTINGS_RUNTIME_ITEMS_CREATE_ROOT_MENU,
-				( GCallback ) on_items_create_root_menu_changed, self );
+				G_CALLBACK( on_items_create_root_menu_changed ), self );
 
-		na_settings_register_global( settings,
-				( GCallback ) on_global_settings_changed, self );
+		na_settings_register_global_callback( settings,
+				G_CALLBACK( on_global_settings_changed ), self );
 
 		/* chain up to the parent class */
 		if( G_OBJECT_CLASS( st_parent_class )->constructed ){
@@ -267,6 +271,9 @@ instance_dispose( GObject *object )
 
 		self->private->dispose_has_run = TRUE;
 
+		if( self->private->items_changed_handler ){
+			g_signal_handler_disconnect( self->private->pivot, self->private->items_changed_handler );
+		}
 		g_object_unref( self->private->pivot );
 
 		/* chain up to the parent class */
@@ -988,23 +995,16 @@ execute_about( NautilusMenuItem *item, NautilusActions *plugin )
 }
 
 /*
- * this is a composite callback which is called when:
- * - the content of an action or a menu is modified
- * - the i/o providers read order is changed
- * - the 'readable' status of a i/o provider is changed
- * - the level-zero order is modified
- *
- * if pivot is in automatic reload mode, then it already has reloaded
- * the items tree in the new environment
+ * signal emitted by NAPivot at the end of a burst of 'item-changed' signals
+ * from i/o providers
  */
 static void
-on_items_list_changed( NautilusActions *plugin )
+on_pivot_items_changed_handler( NAPivot *pivot, NautilusActions *plugin )
 {
+	g_return_if_fail( NA_IS_PIVOT( pivot ));
 	g_return_if_fail( NAUTILUS_IS_ACTIONS( plugin ));
 
 	if( !plugin->private->dispose_has_run ){
-
-		nautilus_menu_provider_emit_items_updated_signal( NAUTILUS_MENU_PROVIDER( plugin ));
 	}
 }
 
@@ -1042,11 +1042,32 @@ on_items_create_root_menu_changed( gpointer newvalue, NautilusActions *plugin )
 	}
 }
 
+/*
+ * this is called when one of the configuration files have been changed
+ *
+ * as NAPivot is also registered for this same event, then it reloads itself
+ * and will send a 'on_items_list_changed' event. which itself triggers
+ * the nautilus_menu_provider_emit_items_updated_signal() function.
+ *
+ * so just reload here the preferences we are monitoring
+ */
 static void
-on_global_settings_changed( NautilusActions *plugin, gboolean global )
+on_global_settings_changed( gboolean global, NautilusActions *plugin )
 {
+	NAPivot *pivot;
+	NASettings *settings;
+
 	g_return_if_fail( NAUTILUS_IS_ACTIONS( plugin ));
 
 	if( !plugin->private->dispose_has_run ){
+
+		g_debug( "nautilus_actions_on_global_settings_changed: global=%s, plugin=%p",
+				global ? "True":"False", ( void * ) plugin );
+
+		pivot = plugin->private->pivot;
+		settings = na_pivot_get_settings( pivot );
+
+		plugin->private->items_add_about_item = na_settings_get_boolean( settings, NA_SETTINGS_RUNTIME_ITEMS_ADD_ABOUT_ITEM, NULL, NULL );
+		plugin->private->items_create_root_menu = na_settings_get_boolean( settings, NA_SETTINGS_RUNTIME_ITEMS_CREATE_ROOT_MENU, NULL, NULL );
 	}
 }



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