summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--components/text/nautilus-text-view.c5
-rw-r--r--libnautilus-extensions/nautilus-gconf-extensions.c80
-rw-r--r--libnautilus-extensions/nautilus-gconf-extensions.h38
-rw-r--r--libnautilus-extensions/nautilus-gdk-font-extensions.c10
-rw-r--r--libnautilus-extensions/nautilus-preferences.c138
-rw-r--r--libnautilus-private/nautilus-gconf-extensions.c80
-rw-r--r--libnautilus-private/nautilus-gconf-extensions.h38
-rw-r--r--libnautilus-private/nautilus-gdk-font-extensions.c10
-rw-r--r--libnautilus-private/nautilus-preferences.c138
10 files changed, 440 insertions, 134 deletions
diff --git a/ChangeLog b/ChangeLog
index d65b436f7..89b7e76ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2001-03-30 Ramiro Estrugo <ramiro@eazel.com>
+
+ reviewed by: John Sullivan <sullivan@eazel.com>
+
+ * components/text/nautilus-text-view.c: (merge_bonobo_menu_items):
+ Add a FIXME for a bug.
+
+ * libnautilus-extensions/nautilus-gconf-extensions.h:
+ * libnautilus-extensions/nautilus-gconf-extensions.c:
+ (nautilus_gconf_get_value), (nautilus_gconf_value_is_equal),
+ (nautilus_gconf_value_free): New convenience functions for using
+ GConf values directly.
+
+ * libnautilus-extensions/nautilus-gdk-font-extensions.c:
+ Remove a FIXME for a bug i fixed recently.
+
+ * libnautilus-extensions/nautilus-preferences.c:
+ (preferences_callback_entry_invoke_function),
+ (preferences_entry_invoke_callbacks_if_needed),
+ (preferences_something_changed_notice),
+ (preferences_global_table_check_changes_function),
+ (preferences_entry_update_cached_value),
+ (preferences_entry_ensure_gconf_connection),
+ (preferences_callback_entry_free_func), (preferences_entry_free),
+ (preferences_global_table_insert):
+ Fix bug 5875 - Preference callbacks should only trigger when
+ values change.
+ The problem was twofold. First, when the user level changed, we
+ would invoke all callbacks regardless of whether the value had
+ changed or not. Second, when a GConf value changed notice
+ triggered, we would invoke the corresponding Nautilus preference
+ callback regardless of whether the value according to Nautilus
+ changed or not.
+ The fact that Nautilus preferences have a visibility attribute
+ means that even if the GConf value changes, they may have a
+ different value (a default due to high visibility for example)
+
2001-03-30 John Sullivan <sullivan@eazel.com>
* libnautilus-extensions/nautilus-preferences.c:
diff --git a/components/text/nautilus-text-view.c b/components/text/nautilus-text-view.c
index 1a06590f1..b00b6a2c7 100644
--- a/components/text/nautilus-text-view.c
+++ b/components/text/nautilus-text-view.c
@@ -769,6 +769,11 @@ merge_bonobo_menu_items (BonoboControl *control, gboolean state, gpointer user_d
* See nautilus-text-view-ui.xml. Need to query system for
* available fonts instead of hard coding the font list
*/
+
+ /* FIXME bugzilla.eazel.com 7907:
+ * The "GTK System Font" string is hard coded in many places.
+ * Please see nautilus-text-view-ui.xml.
+ */
nautilus_view_set_up_ui (NAUTILUS_VIEW (text_view),
DATADIR,
"nautilus-text-view-ui.xml",
diff --git a/libnautilus-extensions/nautilus-gconf-extensions.c b/libnautilus-extensions/nautilus-gconf-extensions.c
index 15b92e229..65ec1845d 100644
--- a/libnautilus-extensions/nautilus-gconf-extensions.c
+++ b/libnautilus-extensions/nautilus-gconf-extensions.c
@@ -27,6 +27,8 @@
#include "nautilus-glib-extensions.h"
#include "nautilus-stock-dialogs.h"
+#include "nautilus-string.h"
+
#include <gconf/gconf-client.h>
#include <gconf/gconf.h>
#include <libgnome/gnome-i18n.h>
@@ -318,3 +320,81 @@ nautilus_gconf_suggest_sync (void)
gconf_client_suggest_sync (client, &error);
nautilus_gconf_handle_error (&error);
}
+
+GConfValue*
+nautilus_gconf_get_value (const char *key)
+{
+ GConfValue *value = NULL;
+ GConfClient *client;
+ GError *error = NULL;
+
+ g_return_val_if_fail (key != NULL, NULL);
+
+ client = nautilus_gconf_client_get_global ();
+ g_return_val_if_fail (client != NULL, NULL);
+
+ value = gconf_client_get (client, key, &error);
+
+ if (nautilus_gconf_handle_error (&error)) {
+ if (value != NULL) {
+ gconf_value_free (value);
+ value = NULL;
+ }
+ }
+
+ return value;
+}
+
+gboolean
+nautilus_gconf_value_is_equal (const GConfValue *a,
+ const GConfValue *b)
+{
+ if (a == NULL && b == NULL) {
+ return TRUE;
+ }
+
+ if (a == NULL || b == NULL) {
+ return FALSE;
+ }
+
+ if (a->type != b->type) {
+ return FALSE;
+ }
+
+ switch (a->type) {
+ case GCONF_VALUE_STRING:
+ return nautilus_str_is_equal (a->d.string_data, b->d.string_data);
+ break;
+
+ case GCONF_VALUE_INT:
+ return a->d.int_data == b->d.int_data;
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ return a->d.float_data == b->d.float_data;
+ break;
+
+ case GCONF_VALUE_BOOL:
+ return a->d.bool_data == b->d.bool_data;
+ break;
+
+ case GCONF_VALUE_LIST:
+ /* FIXME */
+ g_assert (0);
+ return FALSE;
+ default:
+ }
+
+ g_assert_not_reached ();
+ return FALSE;
+}
+
+void
+nautilus_gconf_value_free (GConfValue *value)
+{
+ if (value == NULL) {
+ return;
+ }
+
+ gconf_value_free (value);
+}
diff --git a/libnautilus-extensions/nautilus-gconf-extensions.h b/libnautilus-extensions/nautilus-gconf-extensions.h
index a9393feb4..7c566b8e3 100644
--- a/libnautilus-extensions/nautilus-gconf-extensions.h
+++ b/libnautilus-extensions/nautilus-gconf-extensions.h
@@ -31,23 +31,27 @@
BEGIN_GNOME_DECLS
-GConfClient *nautilus_gconf_client_get_global (void);
-gboolean nautilus_gconf_handle_error (GError **error);
-void nautilus_gconf_set_boolean (const char *key,
- gboolean boolean_value);
-gboolean nautilus_gconf_get_boolean (const char *key);
-int nautilus_gconf_get_integer (const char *key);
-void nautilus_gconf_set_integer (const char *key,
- int int_value);
-char * nautilus_gconf_get_string (const char *key);
-void nautilus_gconf_set_string (const char *key,
- const char *string_value);
-GList * nautilus_gconf_get_string_list (const char *key);
-void nautilus_gconf_set_string_list (const char *key,
- GList *string_list_value);
-gboolean nautilus_gconf_is_default (const char *key);
-gboolean nautilus_gconf_monitor_directory (const char *directory);
-void nautilus_gconf_suggest_sync (void);
+GConfClient *nautilus_gconf_client_get_global (void);
+gboolean nautilus_gconf_handle_error (GError **error);
+void nautilus_gconf_set_boolean (const char *key,
+ gboolean boolean_value);
+gboolean nautilus_gconf_get_boolean (const char *key);
+int nautilus_gconf_get_integer (const char *key);
+void nautilus_gconf_set_integer (const char *key,
+ int int_value);
+char * nautilus_gconf_get_string (const char *key);
+void nautilus_gconf_set_string (const char *key,
+ const char *string_value);
+GList * nautilus_gconf_get_string_list (const char *key);
+void nautilus_gconf_set_string_list (const char *key,
+ GList *string_list_value);
+gboolean nautilus_gconf_is_default (const char *key);
+gboolean nautilus_gconf_monitor_directory (const char *directory);
+void nautilus_gconf_suggest_sync (void);
+GConfValue* nautilus_gconf_get_value (const char *key);
+gboolean nautilus_gconf_value_is_equal (const GConfValue *a,
+ const GConfValue *b);
+void nautilus_gconf_value_free (GConfValue *value);
END_GNOME_DECLS
diff --git a/libnautilus-extensions/nautilus-gdk-font-extensions.c b/libnautilus-extensions/nautilus-gdk-font-extensions.c
index c3e3a4784..43c60efe8 100644
--- a/libnautilus-extensions/nautilus-gdk-font-extensions.c
+++ b/libnautilus-extensions/nautilus-gdk-font-extensions.c
@@ -1062,16 +1062,6 @@ unref_fixed_font (void)
gdk_font_unref (fixed_font);
}
-
-/* FIXME bugzilla.eazel.com 7204:
- * Instead of picking fixed, we could create a temporary GtkStyle
- * and fetch the default font from there. That way we wash our
- * hands on the matter and let gtk be the one to pick the fallback
- * font. One tricky aspect of this strategy is where to put such
- * a call since this file contains on gdk_font stuff. Perhaps
- * nautilus-gtk-extensions.[ch] ?
- */
-
/**
* nautilus_gdk_font_get_fixed
*
diff --git a/libnautilus-extensions/nautilus-preferences.c b/libnautilus-extensions/nautilus-preferences.c
index a2aa70f77..3eea6df57 100644
--- a/libnautilus-extensions/nautilus-preferences.c
+++ b/libnautilus-extensions/nautilus-preferences.c
@@ -70,6 +70,7 @@ typedef struct {
GList *auto_storage_list;
int gconf_connection_id;
NautilusEnumeration *enumeration;
+ GConfValue *cached_value;
} PreferencesEntry;
/*
@@ -129,6 +130,7 @@ static void preferences_global_table_check_changes_function (gpointer
static GHashTable *preferences_global_table_get_global (void);
static void preferences_callback_entry_free (PreferencesCallbackEntry *callback_entry);
static int preferences_user_level_check_range (int user_level);
+static void preferences_entry_update_auto_storage (PreferencesEntry *entry);
static int user_level_changed_connection_id = -1;
static GHashTable *global_table = NULL;
@@ -747,10 +749,10 @@ nautilus_preferences_default_get_string_list (const char *name,
**/
static void
preferences_callback_entry_invoke_function (gpointer data,
- gpointer callback_data)
+ gpointer callback_data)
{
PreferencesCallbackEntry *callback_entry;
-
+
g_return_if_fail (data != NULL);
callback_entry = data;
@@ -758,6 +760,56 @@ preferences_callback_entry_invoke_function (gpointer data,
(* callback_entry->callback) (callback_entry->callback_data);
}
+/**
+ * preferences_entry_invoke_callbacks_if_needed
+ *
+ * @entry: A PreferencesEntry
+ *
+ * This function checks the cached value in the entry with the current
+ * value of the preference. If the value has changed, then callbacks
+ * are invoked and auto storage updated.
+ *
+ * We need this check because even though the GConf value of a preference
+ * could indeed have changed, its representation on the Nautilus side
+ * of things could still be the same. The best example of this is
+ * user level changes, where the value of the preference on the Nautilus
+ * end of things is determined by visibility.
+ **/
+static void
+preferences_entry_invoke_callbacks_if_needed (PreferencesEntry *entry)
+{
+ GConfValue *new_value;
+ char *getter_key;
+
+ g_return_if_fail (entry != NULL);
+
+ getter_key = preferences_key_make_for_getter (entry->name);
+ new_value = nautilus_gconf_get_value (getter_key);
+ g_free (getter_key);
+
+ /* If the values are the same, then we dont need to invoke any callbacks */
+ if (nautilus_gconf_value_is_equal (entry->cached_value, new_value)) {
+ nautilus_gconf_value_free (new_value);
+ return;
+ }
+
+ /* Update the auto storage preferences */
+ if (entry->auto_storage_list != NULL) {
+ preferences_entry_update_auto_storage (entry);
+ }
+
+ /* Store the new cached value */
+ nautilus_gconf_value_free (entry->cached_value);
+ entry->cached_value = new_value;
+
+ /* Invoke callbacks for this entry if any */
+ if (entry->callback_list != NULL) {
+ g_list_foreach (entry->callback_list,
+ preferences_callback_entry_invoke_function,
+ NULL);
+ }
+}
+
static void
update_auto_string (gpointer data, gpointer callback_data)
{
@@ -820,26 +872,11 @@ preferences_something_changed_notice (GConfClient *client,
GConfEntry *entry,
gpointer notice_data)
{
- PreferencesEntry *preferences_entry;
-
g_return_if_fail (entry != NULL);
g_return_if_fail (entry->key != NULL);
g_return_if_fail (notice_data != NULL);
-
- preferences_entry = notice_data;
- if (preferences_entry->auto_storage_list != NULL) {
- preferences_entry_update_auto_storage (preferences_entry);
- }
-
- /* FIXME bugzilla.eazel.com 5875:
- * We need to make sure that the value has actually changed before
- * invoking the callbacks.
- */
- /* Invoke callbacks for this entry */
- g_list_foreach (preferences_entry->callback_list,
- preferences_callback_entry_invoke_function,
- NULL);
+ preferences_entry_invoke_callbacks_if_needed (notice_data);
}
static void
@@ -861,22 +898,21 @@ preferences_global_table_check_changes_function (gpointer key,
return;
}
- /* FIXME: We need to make sure that the value changed before
- * invoking the callbacks.
- */
-#if 0
- int user_level;
- int visible_user_level;
- user_level = nautilus_preferences_get_user_level ();
- visible_user_level = nautilus_preferences_get_visible_user_level (entry->name);
-#endif
-
- /* Invoke callbacks for this entry */
- if (entry->callback_list) {
- g_list_foreach (entry->callback_list,
- preferences_callback_entry_invoke_function,
- NULL);
- }
+ preferences_entry_invoke_callbacks_if_needed (entry);
+}
+
+static void
+preferences_entry_update_cached_value (PreferencesEntry *entry)
+{
+ char *getter_key;
+
+ g_return_if_fail (entry != NULL);
+
+ nautilus_gconf_value_free (entry->cached_value);
+
+ getter_key = preferences_key_make_for_getter (entry->name);
+ entry->cached_value = nautilus_gconf_get_value (getter_key);
+ g_free (getter_key);
}
static void
@@ -920,16 +956,25 @@ preferences_entry_ensure_gconf_connection (PreferencesEntry *entry)
error = NULL;
entry->gconf_connection_id = gconf_client_notify_add (client,
- key,
- preferences_something_changed_notice,
- entry,
- NULL,
- &error);
+ key,
+ preferences_something_changed_notice,
+ entry,
+ NULL,
+ &error);
if (nautilus_gconf_handle_error (&error)) {
entry->gconf_connection_id = 0;
}
g_free (key);
+
+ /* Update the cached value.
+ * From now onwards the cached value will be updated
+ * each time preferences_something_changed_notice() triggers
+ * so that it can be later compared with new values to
+ * determine if the gconf value is different from the
+ * Nautilus value.
+ */
+ preferences_entry_update_cached_value (entry);
}
/**
@@ -1129,7 +1174,7 @@ preferences_callback_entry_free (PreferencesCallbackEntry *callback_entry)
**/
static void
preferences_callback_entry_free_func (gpointer data,
- gpointer callback_data)
+ gpointer callback_data)
{
g_return_if_fail (data != NULL);
@@ -1168,6 +1213,7 @@ preferences_entry_free (PreferencesEntry *entry)
g_free (entry->name);
g_free (entry->description);
+ nautilus_gconf_value_free (entry->cached_value);
nautilus_enumeration_free (entry->enumeration);
g_free (entry);
@@ -1240,6 +1286,18 @@ preferences_global_table_insert (const char *name)
g_return_val_if_fail (entry == preferences_global_table_lookup (name), NULL);
+ /* Update the cached value for the first time.
+ *
+ * We need to do this because checks for value changes
+ * happen not only as a result of callbacks triggering, but
+ * also as a result of user_level changes. When a user level
+ * changes, all the preferences entries are iterated to invoke
+ * callbacks for those that changed as a result.
+ *
+ * See preferences_global_table_check_changes_function().
+ */
+ preferences_entry_update_cached_value (entry);
+
return entry;
}
diff --git a/libnautilus-private/nautilus-gconf-extensions.c b/libnautilus-private/nautilus-gconf-extensions.c
index 15b92e229..65ec1845d 100644
--- a/libnautilus-private/nautilus-gconf-extensions.c
+++ b/libnautilus-private/nautilus-gconf-extensions.c
@@ -27,6 +27,8 @@
#include "nautilus-glib-extensions.h"
#include "nautilus-stock-dialogs.h"
+#include "nautilus-string.h"
+
#include <gconf/gconf-client.h>
#include <gconf/gconf.h>
#include <libgnome/gnome-i18n.h>
@@ -318,3 +320,81 @@ nautilus_gconf_suggest_sync (void)
gconf_client_suggest_sync (client, &error);
nautilus_gconf_handle_error (&error);
}
+
+GConfValue*
+nautilus_gconf_get_value (const char *key)
+{
+ GConfValue *value = NULL;
+ GConfClient *client;
+ GError *error = NULL;
+
+ g_return_val_if_fail (key != NULL, NULL);
+
+ client = nautilus_gconf_client_get_global ();
+ g_return_val_if_fail (client != NULL, NULL);
+
+ value = gconf_client_get (client, key, &error);
+
+ if (nautilus_gconf_handle_error (&error)) {
+ if (value != NULL) {
+ gconf_value_free (value);
+ value = NULL;
+ }
+ }
+
+ return value;
+}
+
+gboolean
+nautilus_gconf_value_is_equal (const GConfValue *a,
+ const GConfValue *b)
+{
+ if (a == NULL && b == NULL) {
+ return TRUE;
+ }
+
+ if (a == NULL || b == NULL) {
+ return FALSE;
+ }
+
+ if (a->type != b->type) {
+ return FALSE;
+ }
+
+ switch (a->type) {
+ case GCONF_VALUE_STRING:
+ return nautilus_str_is_equal (a->d.string_data, b->d.string_data);
+ break;
+
+ case GCONF_VALUE_INT:
+ return a->d.int_data == b->d.int_data;
+ break;
+
+ case GCONF_VALUE_FLOAT:
+ return a->d.float_data == b->d.float_data;
+ break;
+
+ case GCONF_VALUE_BOOL:
+ return a->d.bool_data == b->d.bool_data;
+ break;
+
+ case GCONF_VALUE_LIST:
+ /* FIXME */
+ g_assert (0);
+ return FALSE;
+ default:
+ }
+
+ g_assert_not_reached ();
+ return FALSE;
+}
+
+void
+nautilus_gconf_value_free (GConfValue *value)
+{
+ if (value == NULL) {
+ return;
+ }
+
+ gconf_value_free (value);
+}
diff --git a/libnautilus-private/nautilus-gconf-extensions.h b/libnautilus-private/nautilus-gconf-extensions.h
index a9393feb4..7c566b8e3 100644
--- a/libnautilus-private/nautilus-gconf-extensions.h
+++ b/libnautilus-private/nautilus-gconf-extensions.h
@@ -31,23 +31,27 @@
BEGIN_GNOME_DECLS
-GConfClient *nautilus_gconf_client_get_global (void);
-gboolean nautilus_gconf_handle_error (GError **error);
-void nautilus_gconf_set_boolean (const char *key,
- gboolean boolean_value);
-gboolean nautilus_gconf_get_boolean (const char *key);
-int nautilus_gconf_get_integer (const char *key);
-void nautilus_gconf_set_integer (const char *key,
- int int_value);
-char * nautilus_gconf_get_string (const char *key);
-void nautilus_gconf_set_string (const char *key,
- const char *string_value);
-GList * nautilus_gconf_get_string_list (const char *key);
-void nautilus_gconf_set_string_list (const char *key,
- GList *string_list_value);
-gboolean nautilus_gconf_is_default (const char *key);
-gboolean nautilus_gconf_monitor_directory (const char *directory);
-void nautilus_gconf_suggest_sync (void);
+GConfClient *nautilus_gconf_client_get_global (void);
+gboolean nautilus_gconf_handle_error (GError **error);
+void nautilus_gconf_set_boolean (const char *key,
+ gboolean boolean_value);
+gboolean nautilus_gconf_get_boolean (const char *key);
+int nautilus_gconf_get_integer (const char *key);
+void nautilus_gconf_set_integer (const char *key,
+ int int_value);
+char * nautilus_gconf_get_string (const char *key);
+void nautilus_gconf_set_string (const char *key,
+ const char *string_value);
+GList * nautilus_gconf_get_string_list (const char *key);
+void nautilus_gconf_set_string_list (const char *key,
+ GList *string_list_value);
+gboolean nautilus_gconf_is_default (const char *key);
+gboolean nautilus_gconf_monitor_directory (const char *directory);
+void nautilus_gconf_suggest_sync (void);
+GConfValue* nautilus_gconf_get_value (const char *key);
+gboolean nautilus_gconf_value_is_equal (const GConfValue *a,
+ const GConfValue *b);
+void nautilus_gconf_value_free (GConfValue *value);
END_GNOME_DECLS
diff --git a/libnautilus-private/nautilus-gdk-font-extensions.c b/libnautilus-private/nautilus-gdk-font-extensions.c
index c3e3a4784..43c60efe8 100644
--- a/libnautilus-private/nautilus-gdk-font-extensions.c
+++ b/libnautilus-private/nautilus-gdk-font-extensions.c
@@ -1062,16 +1062,6 @@ unref_fixed_font (void)
gdk_font_unref (fixed_font);
}
-
-/* FIXME bugzilla.eazel.com 7204:
- * Instead of picking fixed, we could create a temporary GtkStyle
- * and fetch the default font from there. That way we wash our
- * hands on the matter and let gtk be the one to pick the fallback
- * font. One tricky aspect of this strategy is where to put such
- * a call since this file contains on gdk_font stuff. Perhaps
- * nautilus-gtk-extensions.[ch] ?
- */
-
/**
* nautilus_gdk_font_get_fixed
*
diff --git a/libnautilus-private/nautilus-preferences.c b/libnautilus-private/nautilus-preferences.c
index a2aa70f77..3eea6df57 100644
--- a/libnautilus-private/nautilus-preferences.c
+++ b/libnautilus-private/nautilus-preferences.c
@@ -70,6 +70,7 @@ typedef struct {
GList *auto_storage_list;
int gconf_connection_id;
NautilusEnumeration *enumeration;
+ GConfValue *cached_value;
} PreferencesEntry;
/*
@@ -129,6 +130,7 @@ static void preferences_global_table_check_changes_function (gpointer
static GHashTable *preferences_global_table_get_global (void);
static void preferences_callback_entry_free (PreferencesCallbackEntry *callback_entry);
static int preferences_user_level_check_range (int user_level);
+static void preferences_entry_update_auto_storage (PreferencesEntry *entry);
static int user_level_changed_connection_id = -1;
static GHashTable *global_table = NULL;
@@ -747,10 +749,10 @@ nautilus_preferences_default_get_string_list (const char *name,
**/
static void
preferences_callback_entry_invoke_function (gpointer data,
- gpointer callback_data)
+ gpointer callback_data)
{
PreferencesCallbackEntry *callback_entry;
-
+
g_return_if_fail (data != NULL);
callback_entry = data;
@@ -758,6 +760,56 @@ preferences_callback_entry_invoke_function (gpointer data,
(* callback_entry->callback) (callback_entry->callback_data);
}
+/**
+ * preferences_entry_invoke_callbacks_if_needed
+ *
+ * @entry: A PreferencesEntry
+ *
+ * This function checks the cached value in the entry with the current
+ * value of the preference. If the value has changed, then callbacks
+ * are invoked and auto storage updated.
+ *
+ * We need this check because even though the GConf value of a preference
+ * could indeed have changed, its representation on the Nautilus side
+ * of things could still be the same. The best example of this is
+ * user level changes, where the value of the preference on the Nautilus
+ * end of things is determined by visibility.
+ **/
+static void
+preferences_entry_invoke_callbacks_if_needed (PreferencesEntry *entry)
+{
+ GConfValue *new_value;
+ char *getter_key;
+
+ g_return_if_fail (entry != NULL);
+
+ getter_key = preferences_key_make_for_getter (entry->name);
+ new_value = nautilus_gconf_get_value (getter_key);
+ g_free (getter_key);
+
+ /* If the values are the same, then we dont need to invoke any callbacks */
+ if (nautilus_gconf_value_is_equal (entry->cached_value, new_value)) {
+ nautilus_gconf_value_free (new_value);
+ return;
+ }
+
+ /* Update the auto storage preferences */
+ if (entry->auto_storage_list != NULL) {
+ preferences_entry_update_auto_storage (entry);
+ }
+
+ /* Store the new cached value */
+ nautilus_gconf_value_free (entry->cached_value);
+ entry->cached_value = new_value;
+
+ /* Invoke callbacks for this entry if any */
+ if (entry->callback_list != NULL) {
+ g_list_foreach (entry->callback_list,
+ preferences_callback_entry_invoke_function,
+ NULL);
+ }
+}
+
static void
update_auto_string (gpointer data, gpointer callback_data)
{
@@ -820,26 +872,11 @@ preferences_something_changed_notice (GConfClient *client,
GConfEntry *entry,
gpointer notice_data)
{
- PreferencesEntry *preferences_entry;
-
g_return_if_fail (entry != NULL);
g_return_if_fail (entry->key != NULL);
g_return_if_fail (notice_data != NULL);
-
- preferences_entry = notice_data;
- if (preferences_entry->auto_storage_list != NULL) {
- preferences_entry_update_auto_storage (preferences_entry);
- }
-
- /* FIXME bugzilla.eazel.com 5875:
- * We need to make sure that the value has actually changed before
- * invoking the callbacks.
- */
- /* Invoke callbacks for this entry */
- g_list_foreach (preferences_entry->callback_list,
- preferences_callback_entry_invoke_function,
- NULL);
+ preferences_entry_invoke_callbacks_if_needed (notice_data);
}
static void
@@ -861,22 +898,21 @@ preferences_global_table_check_changes_function (gpointer key,
return;
}
- /* FIXME: We need to make sure that the value changed before
- * invoking the callbacks.
- */
-#if 0
- int user_level;
- int visible_user_level;
- user_level = nautilus_preferences_get_user_level ();
- visible_user_level = nautilus_preferences_get_visible_user_level (entry->name);
-#endif
-
- /* Invoke callbacks for this entry */
- if (entry->callback_list) {
- g_list_foreach (entry->callback_list,
- preferences_callback_entry_invoke_function,
- NULL);
- }
+ preferences_entry_invoke_callbacks_if_needed (entry);
+}
+
+static void
+preferences_entry_update_cached_value (PreferencesEntry *entry)
+{
+ char *getter_key;
+
+ g_return_if_fail (entry != NULL);
+
+ nautilus_gconf_value_free (entry->cached_value);
+
+ getter_key = preferences_key_make_for_getter (entry->name);
+ entry->cached_value = nautilus_gconf_get_value (getter_key);
+ g_free (getter_key);
}
static void
@@ -920,16 +956,25 @@ preferences_entry_ensure_gconf_connection (PreferencesEntry *entry)
error = NULL;
entry->gconf_connection_id = gconf_client_notify_add (client,
- key,
- preferences_something_changed_notice,
- entry,
- NULL,
- &error);
+ key,
+ preferences_something_changed_notice,
+ entry,
+ NULL,
+ &error);
if (nautilus_gconf_handle_error (&error)) {
entry->gconf_connection_id = 0;
}
g_free (key);
+
+ /* Update the cached value.
+ * From now onwards the cached value will be updated
+ * each time preferences_something_changed_notice() triggers
+ * so that it can be later compared with new values to
+ * determine if the gconf value is different from the
+ * Nautilus value.
+ */
+ preferences_entry_update_cached_value (entry);
}
/**
@@ -1129,7 +1174,7 @@ preferences_callback_entry_free (PreferencesCallbackEntry *callback_entry)
**/
static void
preferences_callback_entry_free_func (gpointer data,
- gpointer callback_data)
+ gpointer callback_data)
{
g_return_if_fail (data != NULL);
@@ -1168,6 +1213,7 @@ preferences_entry_free (PreferencesEntry *entry)
g_free (entry->name);
g_free (entry->description);
+ nautilus_gconf_value_free (entry->cached_value);
nautilus_enumeration_free (entry->enumeration);
g_free (entry);
@@ -1240,6 +1286,18 @@ preferences_global_table_insert (const char *name)
g_return_val_if_fail (entry == preferences_global_table_lookup (name), NULL);
+ /* Update the cached value for the first time.
+ *
+ * We need to do this because checks for value changes
+ * happen not only as a result of callbacks triggering, but
+ * also as a result of user_level changes. When a user level
+ * changes, all the preferences entries are iterated to invoke
+ * callbacks for those that changed as a result.
+ *
+ * See preferences_global_table_check_changes_function().
+ */
+ preferences_entry_update_cached_value (entry);
+
return entry;
}