[nautilus-actions] Global review of the notification systems
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Global review of the notification systems
- Date: Mon, 24 Jan 2011 22:35:37 +0000 (UTC)
commit d1ae2196a1b5c81ba5cbdbb0a662c6dcc7d0b71f
Author: Pierre Wieser <pwieser trychlos org>
Date: Mon Jan 24 23:34:05 2011 +0100
Global review of the notification systems
+ NAPivot always acts as a summarizing relay for items changes from i/o providers
+ NASettings always enables a pre-key callback preregistration system
+ NASettings now also have its own signal notification system, only distinguishing between
runtime and user preferences.
ChangeLog | 7 ++
src/core/na-pivot.c | 25 +++--
src/core/na-pivot.h | 55 +++++------
src/core/na-settings.c | 270 ++++++++++++++++++++++++++++++------------------
src/core/na-settings.h | 29 +++++-
5 files changed, 243 insertions(+), 143 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index fa00b09..cb28065 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2011-01-24 Pierre Wieser <pwieser trychlos org>
+ * src/core/na-pivot.c:
+ * src/core/na-pivot.h: Review the notification system.
+
+ * src/core/na-settings.c:
+ * src/core/na-settings.h:
+ Add a signal notification to the existing callback pregistration system.
+
* data/gconf-schemas/nautilus-actions-prefs.schemas.in:
* docs/des-ema/des-ema-0.15:
* docs/nact/C/nact-conditions.xml:
diff --git a/src/core/na-pivot.c b/src/core/na-pivot.c
index f246db8..93a2df7 100644
--- a/src/core/na-pivot.c
+++ b/src/core/na-pivot.c
@@ -117,7 +117,7 @@ static NAObjectItem *get_item_from_tree( const NAPivot *pivot, GList *tree, cons
static void free_consumers( GList *list );
/* NAIIOProvider management */
-static void on_item_changed_timeout( NAPivot *pivot );
+static void on_items_changed_timeout( NAPivot *pivot );
GType
na_pivot_get_type( void )
@@ -186,7 +186,7 @@ class_init( NAPivotClass *klass )
/*
* NAPivot::pivot-items-changed:
*
- * This signal is sent by NAPivot ath the end of a burst of modifications
+ * This signal is sent by NAPivot at the end of a burst of modifications
* as signaled by i/o providers.
*
* The signal is registered without any default handler.
@@ -228,7 +228,7 @@ instance_init( GTypeInstance *instance, gpointer klass )
/* initialize timeout parameters for 'item-changed' handler
*/
self->private->change_timeout.timeout = st_burst_timeout;
- self->private->change_timeout.handler = ( NATimeoutFunc ) on_item_changed_timeout;
+ self->private->change_timeout.handler = ( NATimeoutFunc ) on_items_changed_timeout;
self->private->change_timeout.user_data = self;
self->private->change_timeout.source_id = 0;
}
@@ -619,9 +619,13 @@ na_pivot_set_new_items( NAPivot *pivot, GList *items )
*
* This handler is trigerred by #NAIIOProvider providers when an action
* is changed in their underlying storage subsystems.
+ *
+ * The NAIIOProvider is supposed to have itself already summarized
+ * a minima its own burst of notifications.
+ *
* We don't care of updating our internal list with each and every
* atomic modification; instead we wait for the end of notifications
- * serie, and then reload the whole list of actions
+ * serie, and then signal our consumers.
*/
void
na_pivot_on_item_changed_handler( NAIIOProvider *provider, NAPivot *pivot )
@@ -645,16 +649,18 @@ na_pivot_on_item_changed_handler( NAIIOProvider *provider, NAPivot *pivot )
* this is up to NAPivot to send now its summarized signal
*/
static void
-on_item_changed_timeout( NAPivot *pivot )
+on_items_changed_timeout( NAPivot *pivot )
{
- static const gchar *thisfn = "na_pivot_on_item_changed_timeout";
- GList *ic;
+ static const gchar *thisfn = "na_pivot_on_items_changed_timeout";
g_return_if_fail( NA_IS_PIVOT( pivot ));
g_debug( "%s: emitting %s signal", thisfn, PIVOT_SIGNAL_ITEMS_CHANGED );
g_signal_emit_by_name(( gpointer ) pivot, PIVOT_SIGNAL_ITEMS_CHANGED );
+#if 0
+ GList *ic;
+
/* this has to be deprecated.. or not ?? */
g_debug( "%s: triggering NAIPivotConsumer interfaces", thisfn );
if( pivot->private->automatic_reload ){
@@ -663,6 +669,7 @@ on_item_changed_timeout( NAPivot *pivot )
for( ic = pivot->private->consumers ; ic ; ic = ic->next ){
na_ipivot_consumer_notify_of_items_changed( NA_IPIVOT_CONSUMER( ic->data ));
}
+#endif
}
/*
@@ -727,13 +734,13 @@ na_pivot_get_settings( const NAPivot *pivot )
* na_pivot_set_automatic_reload:
* @pivot: this #NAPivot instance.
* @reload: whether this #NAPivot instance should automatically reload
- * its list of actions when I/O providers advertize it of a
+ * its list of actions when I/O providers advertise it of a
* modification.
*
* Sets the automatic reload flag.
*
* Note that even if the #NAPivot instance is not authorized to
- * automatically reload its list of actions when it is advertized of
+ * automatically reload its list of actions when it is advertised of
* a modification by one of the I/O providers, it always sends an
* ad-hoc notification to its consumers.
*/
diff --git a/src/core/na-pivot.h b/src/core/na-pivot.h
index d81bbf4..fcc8ce8 100644
--- a/src/core/na-pivot.h
+++ b/src/core/na-pivot.h
@@ -42,41 +42,35 @@
*
* With this newly allocated #NAPivot object, the consuming program
* is then able to ask for loading the items.
- * na_pivot_load_items( pivot, PIVOT_LOADABLE_SET );
+ * na_pivot_set_loadable( pivot, PIVOT_LOADABLE_SET );
+ * na_pivot_load_items( pivot );
*
* Notification system.
*
- * Each I/O storage provider should monitor modifications/deletions of
- * actions, and advertize this #NAPivot, which itself will then
- * advertise any registered consumers.
+ * The NAPivot object acts as a sort of "summarizing relay" for notification
+ * messages sent by I/O storage providers:
*
- * This notification system is so a double-stage one :
+ * - When an I/O storage subsystem detects a change on an item it manages,
+ * action or menu, it is first supposed to do its best effort in order
+ * to summarize its notifications messages;
*
- * 1. When an I/O storage subsystem detects a change on an action, it
- * should call the na_iio_provider_item_changed() function, which
- * itself will emit the "io-provider-item-changed" signal.
+ * - At the end of this first stage of summarization, the I/O provider
+ * should call the na_iio_provider_item_changed() function, which
+ * itself will emit the "io-provider-item-changed" signal.
+ * This is done so that an external I/O provider does not have to know
+ * anything with the signal name, but has only to take care of calling
+ * a function of the NAIIOProvider API.
*
- * All these signals are catched by na_pivot_on_item_changed_handler()
+ * - The emitted signal is catched by na_pivot_on_item_changed_handler(),
+ * which was connected when the I/O provider plugin was associated with
+ * the NAIOProvider object.
*
- * notify #NAPivot of this change. The user data associated with the
- * message is the internal id of the #NAObjectItem-derived modified
- * object.
+ * - The NAPivot object receives these notifications originating from all
+ * loaded I/O providers, itself summarizes them, and only then notify its
+ * consumers with only one message for a whole set of modifications.
*
- * When this signal is received, #NAPivot updates accordingly the
- * list of actions it maintains.
- *
- * It is up to the I/O storage provider to decide if it sends a
- * message for each and every one detected modification, or if it
- * sends only one message for a whole, maybe coherent, set of
- * updates.
- *
- * 2. When #NAPivot has successfully updated its list of actions, it
- * notifies its consumers so they update themselves.
- *
- * Note that #NAPivot tries to factorize notification messages, and
- * to notify its consumers only once even if it has itself received
- * many elementary notifications from the underlying I/O storage
- * subsystems.
+ * It is eventually up to the consumer to connect to this signal, and
+ * choose itself whether to reload items or not.
*/
#include <api/na-iio-provider.h>
@@ -120,9 +114,10 @@ GType na_pivot_get_type( void );
/* signals
*
- * NAPivot acts as a 'summarizing' proxy for signals emitted by the NAIIOProvider
- * providers when they detect a modification of their underlying items storage
- * subsystems.
+ * NAPivot acts as a 'summarizing' proxy for signals emitted by the
+ * NAIIOProvider providers when they detect a modification in 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.
*/
diff --git a/src/core/na-settings.c b/src/core/na-settings.c
index be295f1..7000f25 100644
--- a/src/core/na-settings.c
+++ b/src/core/na-settings.c
@@ -62,23 +62,13 @@ typedef struct {
}
KeyFile;
-/* The configuration content is handled as a GList of NAKeyValue structs.
- * This list is loaded at initialization time, and then compared each
- * time our file monitors signal us that a change has occured.
- */
-typedef struct {
- gchar *group;
- gchar *key;
- gboolean mandatory;
- NABoxed *boxed;
-}
- KeyValue;
-
/* Each consumer may register a callback function which will be triggered
* when a key is modified.
- * The monitored key may be a real key of the file, but also be a composite
- * key (e.g. NA_IPREFS_IO_PROVIDERS_READ_STATUS monitors the 'readable'
- * key of all i/o providers).
+ *
+ * The monitored key usually is the real key read in the file;
+ * as a special case, composite keys are defined:
+ * - NA_IPREFS_IO_PROVIDERS_READ_STATUS monitors the 'readable' key for all i/o providers
+ *
* Note that we actually monitor the _user_view_ of the configuration:
* e.g. if a key has a mandatory value in global conf, then the same
* key in user conf will just be ignored.
@@ -107,69 +97,91 @@ struct _NASettingsPrivate {
typedef struct {
const gchar *key;
const gchar *group;
+ gboolean runtime; /* whether the key participates to the 'runtime-change' signal */
guint type;
const gchar *default_value;
}
KeyDef;
static const KeyDef st_def_keys[] = {
- { NA_IPREFS_ADMIN_PREFERENCES_LOCKED, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_ADMIN_IO_PROVIDERS_LOCKED, GROUP_RUNTIME, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_ASSISTANT_ESC_CONFIRM, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "true" },
- { NA_IPREFS_ASSISTANT_ESC_QUIT, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "true" },
- { NA_IPREFS_CAPABILITY_ADD_CAPABILITY_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_COMMAND_CHOOSER_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_COMMAND_CHOOSER_URI, GROUP_NACT, NA_BOXED_TYPE_STRING, "file:///bin" },
- { NA_IPREFS_COMMAND_LEGEND_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_WORKING_DIR_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_WORKING_DIR_URI, GROUP_NACT, NA_BOXED_TYPE_STRING, "file:///" },
- { NA_IPREFS_SHOW_IF_RUNNING_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_SHOW_IF_RUNNING_URI, GROUP_NACT, NA_BOXED_TYPE_STRING, "file:///bin" },
- { NA_IPREFS_TRY_EXEC_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_TRY_EXEC_URI, GROUP_NACT, NA_BOXED_TYPE_STRING, "file:///bin" },
- { NA_IPREFS_EXPORT_ASK_USER_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_EXPORT_ASK_USER_LAST_FORMAT, GROUP_NACT, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_EXPORT_FORMAT },
- { NA_IPREFS_EXPORT_ASK_USER_KEEP_LAST_CHOICE, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_EXPORT_ASSISTANT_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_EXPORT_ASSISTANT_URI, GROUP_NACT, NA_BOXED_TYPE_STRING, "file:///tmp" },
- { NA_IPREFS_EXPORT_PREFERRED_FORMAT, GROUP_NACT, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_EXPORT_FORMAT },
- { NA_IPREFS_FOLDER_CHOOSER_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_FOLDER_CHOOSER_URI, GROUP_NACT, NA_BOXED_TYPE_STRING, "file:///" },
- { NA_IPREFS_IMPORT_ASK_USER_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_IMPORT_ASK_USER_LAST_MODE, GROUP_NACT, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_IMPORT_MODE },
- { NA_IPREFS_IMPORT_ASSISTANT_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_IMPORT_ASSISTANT_URI, GROUP_NACT, NA_BOXED_TYPE_STRING, "file:///tmp" },
- { NA_IPREFS_IMPORT_ASK_USER_KEEP_LAST_CHOICE, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_IMPORT_PREFERRED_MODE, GROUP_NACT, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_IMPORT_MODE },
- { NA_IPREFS_IO_PROVIDERS_WRITE_ORDER, GROUP_NACT, NA_BOXED_TYPE_STRING_LIST, "" },
- { NA_IPREFS_ICON_CHOOSER_URI, GROUP_NACT, NA_BOXED_TYPE_STRING, "file:///" },
- { NA_IPREFS_ICON_CHOOSER_PANED, GROUP_NACT, NA_BOXED_TYPE_UINT, "200" },
- { NA_IPREFS_ICON_CHOOSER_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_ITEMS_ADD_ABOUT_ITEM, GROUP_RUNTIME, NA_BOXED_TYPE_BOOLEAN, "true" },
- { NA_IPREFS_ITEMS_CREATE_ROOT_MENU, GROUP_RUNTIME, NA_BOXED_TYPE_BOOLEAN, "true" },
- { NA_IPREFS_ITEMS_LEVEL_ZERO_ORDER, GROUP_RUNTIME, NA_BOXED_TYPE_STRING_LIST, "" },
- { NA_IPREFS_ITEMS_LIST_ORDER_MODE, GROUP_RUNTIME, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_LIST_ORDER_MODE },
- { NA_IPREFS_MAIN_PANED, GROUP_NACT, NA_BOXED_TYPE_UINT, "200" },
- { NA_IPREFS_MAIN_SAVE_AUTO, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_MAIN_SAVE_PERIOD, GROUP_NACT, NA_BOXED_TYPE_UINT, "5" },
- { NA_IPREFS_MAIN_TOOLBAR_EDIT_DISPLAY, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "true" },
- { NA_IPREFS_MAIN_TOOLBAR_FILE_DISPLAY, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "true" },
- { NA_IPREFS_MAIN_TOOLBAR_HELP_DISPLAY, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "true" },
- { NA_IPREFS_MAIN_TOOLBAR_TOOLS_DISPLAY, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_MAIN_WINDOW_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_PREFERENCES_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_RELABEL_DUPLICATE_ACTION, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_RELABEL_DUPLICATE_MENU, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_RELABEL_DUPLICATE_PROFILE, GROUP_NACT, NA_BOXED_TYPE_BOOLEAN, "false" },
- { NA_IPREFS_SCHEME_ADD_SCHEME_WSP, GROUP_NACT, NA_BOXED_TYPE_UINT_LIST, "" },
- { NA_IPREFS_SCHEME_DEFAULT_LIST, GROUP_NACT, NA_BOXED_TYPE_STRING_LIST, "" },
- { NA_IPREFS_IO_PROVIDER_READABLE, NA_IPREFS_IO_PROVIDER_GROUP, NA_BOXED_TYPE_BOOLEAN, "true" },
- { NA_IPREFS_IO_PROVIDER_WRITABLE, NA_IPREFS_IO_PROVIDER_GROUP, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_ADMIN_PREFERENCES_LOCKED, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_ADMIN_IO_PROVIDERS_LOCKED, GROUP_RUNTIME, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_ASSISTANT_ESC_CONFIRM, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_ASSISTANT_ESC_QUIT, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_CAPABILITY_ADD_CAPABILITY_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_COMMAND_CHOOSER_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_COMMAND_CHOOSER_URI, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, "file:///bin" },
+ { NA_IPREFS_COMMAND_LEGEND_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_WORKING_DIR_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_WORKING_DIR_URI, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, "file:///" },
+ { NA_IPREFS_SHOW_IF_RUNNING_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_SHOW_IF_RUNNING_URI, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, "file:///bin" },
+ { NA_IPREFS_TRY_EXEC_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_TRY_EXEC_URI, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, "file:///bin" },
+ { NA_IPREFS_EXPORT_ASK_USER_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_EXPORT_ASK_USER_LAST_FORMAT, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_EXPORT_FORMAT },
+ { NA_IPREFS_EXPORT_ASK_USER_KEEP_LAST_CHOICE, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_EXPORT_ASSISTANT_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_EXPORT_ASSISTANT_URI, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, "file:///tmp" },
+ { NA_IPREFS_EXPORT_PREFERRED_FORMAT, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_EXPORT_FORMAT },
+ { NA_IPREFS_FOLDER_CHOOSER_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_FOLDER_CHOOSER_URI, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, "file:///" },
+ { NA_IPREFS_IMPORT_ASK_USER_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_IMPORT_ASK_USER_LAST_MODE, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_IMPORT_MODE },
+ { NA_IPREFS_IMPORT_ASSISTANT_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_IMPORT_ASSISTANT_URI, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, "file:///tmp" },
+ { NA_IPREFS_IMPORT_ASK_USER_KEEP_LAST_CHOICE, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_IMPORT_PREFERRED_MODE, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_IMPORT_MODE },
+ { NA_IPREFS_IO_PROVIDERS_WRITE_ORDER, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING_LIST, "" },
+ { NA_IPREFS_ICON_CHOOSER_URI, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING, "file:///" },
+ { NA_IPREFS_ICON_CHOOSER_PANED, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT, "200" },
+ { NA_IPREFS_ICON_CHOOSER_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_ITEMS_ADD_ABOUT_ITEM, GROUP_RUNTIME, TRUE, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_ITEMS_CREATE_ROOT_MENU, GROUP_RUNTIME, TRUE, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_ITEMS_LEVEL_ZERO_ORDER, GROUP_RUNTIME, TRUE, NA_BOXED_TYPE_STRING_LIST, "" },
+ { NA_IPREFS_ITEMS_LIST_ORDER_MODE, GROUP_RUNTIME, TRUE, NA_BOXED_TYPE_STRING, NA_IPREFS_DEFAULT_LIST_ORDER_MODE },
+ { NA_IPREFS_MAIN_PANED, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT, "200" },
+ { NA_IPREFS_MAIN_SAVE_AUTO, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_MAIN_SAVE_PERIOD, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT, "5" },
+ { NA_IPREFS_MAIN_TOOLBAR_EDIT_DISPLAY, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_MAIN_TOOLBAR_FILE_DISPLAY, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_MAIN_TOOLBAR_HELP_DISPLAY, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_MAIN_TOOLBAR_TOOLS_DISPLAY, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_MAIN_WINDOW_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_PREFERENCES_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_RELABEL_DUPLICATE_ACTION, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_RELABEL_DUPLICATE_MENU, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_RELABEL_DUPLICATE_PROFILE, GROUP_NACT, FALSE, NA_BOXED_TYPE_BOOLEAN, "false" },
+ { NA_IPREFS_SCHEME_ADD_SCHEME_WSP, GROUP_NACT, FALSE, NA_BOXED_TYPE_UINT_LIST, "" },
+ { NA_IPREFS_SCHEME_DEFAULT_LIST, GROUP_NACT, FALSE, NA_BOXED_TYPE_STRING_LIST, "" },
+ { NA_IPREFS_IO_PROVIDER_READABLE, NA_IPREFS_IO_PROVIDER_GROUP, TRUE, NA_BOXED_TYPE_BOOLEAN, "true" },
+ { NA_IPREFS_IO_PROVIDER_WRITABLE, NA_IPREFS_IO_PROVIDER_GROUP, FALSE, NA_BOXED_TYPE_BOOLEAN, "true" },
{ 0 }
};
-static GObjectClass *st_parent_class = NULL;
-static gint st_burst_timeout = 100; /* burst timeout in msec */
+/* The configuration content is handled as a GList of KeyValue structs.
+ * This list is loaded at initialization time, and then compared each
+ * time our file monitors signal us that a change has occured.
+ */
+typedef struct {
+ const KeyDef *def;
+ const gchar *group;
+ gboolean mandatory;
+ NABoxed *boxed;
+}
+ KeyValue;
+
+/* signals
+ */
+enum {
+ RUNTIME_CHANGE,
+ UI_CHANGE,
+ LAST_SIGNAL
+};
+
+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( NASettingsClass *klass );
@@ -245,6 +257,46 @@ class_init( NASettingsClass *klass )
object_class->finalize = instance_finalize;
klass->private = g_new0( NASettingsClassPrivate, 1 );
+
+ /*
+ * NASettings::settings-runtime-change:
+ *
+ * This signal is sent by NASettings at the end of a burst of
+ * modifications which may affect the way the file manager displays
+ * its context menus.
+ *
+ * The signal is registered without any default handler.
+ */
+ st_signals[ RUNTIME_CHANGE ] = g_signal_new(
+ SETTINGS_SIGNAL_RUNTIME_CHANGE,
+ NA_SETTINGS_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 );
+
+ /*
+ * NASettings::settings-ui-change:
+ *
+ * This signal is sent by NASettings at the end of a burst of
+ * modifications which only affect the behavior of the NACT
+ * configuration tool.
+ *
+ * The signal is registered without any default handler.
+ */
+ st_signals[ UI_CHANGE ] = g_signal_new(
+ SETTINGS_SIGNAL_UI_CHANGE,
+ NA_SETTINGS_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
@@ -882,7 +934,6 @@ content_diff( GList *old, GList *new )
GList *diffs, *io, *in;
KeyValue *kold, *knew, *kdiff;
gboolean found;
- KeyDef *key_def;
diffs = NULL;
@@ -891,13 +942,13 @@ content_diff( GList *old, GList *new )
found = FALSE;
for( in = new ; in && !found ; in = in->next ){
knew = ( KeyValue * ) in->data;
- if( !strcmp( kold->group, knew->group ) && !strcmp( kold->key, knew->key )){
+ if( !strcmp( kold->group, knew->group ) && ( gpointer ) kold->def == ( gpointer ) knew->def ){
found = TRUE;
if( na_boxed_compare( kold->boxed, knew->boxed ) != 0 ){
/* a key has been modified */
kdiff = g_new0( KeyValue, 1 );
kdiff->group = g_strdup( knew->group );
- kdiff->key = g_strdup( knew->key );
+ kdiff->def = knew->def;
kdiff->mandatory = knew->mandatory;
kdiff->boxed = na_boxed_copy( knew->boxed );
diffs = g_list_prepend( diffs, kdiff );
@@ -905,16 +956,13 @@ content_diff( GList *old, GList *new )
}
}
if( !found ){
- key_def = get_key_def( kold->key );
- if( key_def ){
- /* a key has disappeared */
- kdiff = g_new0( KeyValue, 1 );
- kdiff->group = g_strdup( kold->group );
- kdiff->key = g_strdup( kold->key );
- kdiff->mandatory = FALSE;
- kdiff->boxed = na_boxed_new_from_string( key_def->type, key_def->default_value );
- diffs = g_list_prepend( diffs, kdiff );
- }
+ /* a key has disappeared */
+ kdiff = g_new0( KeyValue, 1 );
+ kdiff->group = g_strdup( kold->group );
+ kdiff->def = kold->def;
+ kdiff->mandatory = FALSE;
+ kdiff->boxed = na_boxed_new_from_string( kold->def->type, kold->def->default_value );
+ diffs = g_list_prepend( diffs, kdiff );
}
}
@@ -923,21 +971,18 @@ content_diff( GList *old, GList *new )
found = FALSE;
for( io = old ; io && !found ; io = io->next ){
kold = ( KeyValue * ) io->data;
- if( !strcmp( kold->group, knew->group ) && !strcmp( kold->key, knew->key )){
+ if( !strcmp( kold->group, knew->group ) && ( gpointer ) kold->def == ( gpointer ) knew->def ){
found = TRUE;
}
}
if( !found ){
- key_def = get_key_def( knew->key );
- if( key_def ){
- /* a key is new */
- kdiff = g_new0( KeyValue, 1 );
- kdiff->group = g_strdup( knew->group );
- kdiff->key = g_strdup( knew->key );
- kdiff->mandatory = knew->mandatory;
- kdiff->boxed = na_boxed_copy( knew->boxed );
- diffs = g_list_prepend( diffs, kdiff );
- }
+ /* a key is new */
+ kdiff = g_new0( KeyValue, 1 );
+ kdiff->group = g_strdup( knew->group );
+ kdiff->def = knew->def;
+ kdiff->mandatory = knew->mandatory;
+ kdiff->boxed = na_boxed_copy( knew->boxed );
+ diffs = g_list_prepend( diffs, kdiff );
}
}
@@ -1085,23 +1130,31 @@ on_keyfile_changed_timeout( NASettings *settings )
GList *new_content;
GList *modifs;
GList *ic, *im;
- gchar *value;
- Consumer *consumer;
KeyValue *changed;
+ Consumer *consumer;
gchar *group_prefix, *key;
+ gboolean runtime_change, ui_change;
+#ifdef NA_MAINTAINER_MODE
+ gchar *value;
+#endif
/* last individual notification is older that the st_burst_timeout
* we may so suppose that the burst is terminated
*/
new_content = content_load( settings );
modifs = content_diff( settings->private->content, new_content );
+#ifdef NA_MAINTAINER_MODE
g_debug( "%s: %d found update(s)", thisfn, g_list_length( modifs ));
for( im = modifs ; im ; im = im->next ){
changed = ( KeyValue * ) im->data;
value = na_boxed_get_string( changed->boxed );
- g_debug( "%s: key=%s, value=%s", thisfn, changed->key, value );
+ g_debug( "%s: key=%s, value=%s", thisfn, changed->def->key, value );
g_free( value );
}
+#endif
+
+ runtime_change = FALSE;
+ ui_change = FALSE;
for( ic = settings->private->consumers ; ic ; ic = ic->next ){
consumer = ( Consumer * ) ic->data;
@@ -1116,14 +1169,28 @@ on_keyfile_changed_timeout( NASettings *settings )
for( im = modifs ; im ; im = im->next ){
changed = ( KeyValue * ) im->data;
- if(( !group_prefix || g_str_has_prefix( changed->group, group_prefix )) && !strcmp( changed->key, key )){
- ( *( NASettingsKeyCallback ) consumer->callback )( changed->group, changed->key, na_boxed_get_pointer( changed->boxed ), changed->mandatory, consumer->user_data );
+ if(( !group_prefix || g_str_has_prefix( changed->group, group_prefix )) && !strcmp( changed->def->key, key )){
+ ( *( NASettingsKeyCallback ) consumer->callback )( changed->group, changed->def->key, na_boxed_get_pointer( changed->boxed ), changed->mandatory, consumer->user_data );
+ }
+
+ if( changed->def->runtime ){
+ runtime_change = TRUE;
+ } else {
+ ui_change = FALSE;
}
}
g_free( group_prefix );
}
+ if( runtime_change ){
+ g_signal_emit_by_name(( gpointer ) settings, SETTINGS_SIGNAL_RUNTIME_CHANGE );
+ }
+
+ if( ui_change ){
+ g_signal_emit_by_name(( gpointer ) settings, SETTINGS_SIGNAL_UI_CHANGE );
+ }
+
g_list_foreach( settings->private->content, ( GFunc ) release_key_value, NULL );
g_list_free( settings->private->content );
settings->private->content = new_content;
@@ -1141,7 +1208,7 @@ peek_key_value_from_content( GList *content, const gchar *group, const gchar *ke
found = NULL;
for( ic = content ; ic && !found ; ic = ic->next ){
value = ( KeyValue * ) ic->data;
- if( !strcmp( value->group, group ) && !strcmp( value->key, key )){
+ if( !strcmp( value->group, group ) && !strcmp( value->def->key, key )){
found = value;
}
}
@@ -1227,7 +1294,7 @@ read_key_value_from_key_file( GKeyFile *key_file, const gchar *group, const gcha
} else {
value = g_new0( KeyValue, 1 );
value->group = g_strdup( group );
- value->key = g_strdup( key );
+ value->def = key_def;
switch( key_def->type ){
case NA_BOXED_TYPE_STRING:
case NA_BOXED_TYPE_UINT:
@@ -1288,8 +1355,7 @@ release_key_file( KeyFile *key_file )
static void
release_key_value( KeyValue *value )
{
- g_free( value->group );
- g_free( value->key );
+ g_free(( gpointer ) value->group );
na_boxed_free( value->boxed );
g_free( value );
}
diff --git a/src/core/na-settings.h b/src/core/na-settings.h
index 65bc05e..c825fe8 100644
--- a/src/core/na-settings.h
+++ b/src/core/na-settings.h
@@ -43,12 +43,23 @@
* - a per-user configuration.
*
* The configuration is implemented as keyed files:
- * - global configuration is sysconfdir/nautilus-actions.conf
+ * - global configuration is sysconfdir/xdg/nautilus-actions.conf
* - per-user configuration is HOME/.config/nautilus-actions.conf
*
- * Each setting has so its own read-only attribute, whether it
+ * Each setting may so have its own read-only attribute, whether it
* has been read from the global configuration or from the
* per-user one.
+ *
+ * NASettings class implements two notification systems:
+ *
+ * a) a per-key system, which relies on a callback pre-registration;
+ * see na_settings_register_key_callback() function;
+ * b) a per-usage system, which relies on the usage of the changed
+ * key; see signal descriptions.
+ *
+ * The consumer of change notifications will choose the most accurate
+ * system for its needs, e.g. whether it requires to have an exact list
+ * of modified keys, or not.
*/
#include <glib-object.h>
@@ -149,6 +160,20 @@ GType na_settings_get_type( void );
#define NA_IPREFS_DEFAULT_IMPORT_MODE "NoImport"
#define NA_IPREFS_DEFAULT_LIST_ORDER_MODE "AscendingOrder"
+/* signals
+ *
+ * NASettings monitors, and so is able to send messages about, two sort
+ * of changes:
+ * - runtime preferences change, which group all changes which may have
+ * an effect on the display in file manager context menus;
+ * - user interface preferences change, which have only an effect on the
+ * NACT configuration tool
+ *
+ * These two signals are a summarization of individual changes.
+ */
+#define SETTINGS_SIGNAL_RUNTIME_CHANGE "settings-runtime-change"
+#define SETTINGS_SIGNAL_UI_CHANGE "settings-ui-change"
+
typedef void ( *NASettingsKeyCallback )( const gchar *group, const gchar *key, gconstpointer new_value, gboolean mandatory, void *user_data );
NASettings *na_settings_new ( void );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]