summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Sullivan <sullivan@src.gnome.org>2001-03-30 20:52:36 +0000
committerJohn Sullivan <sullivan@src.gnome.org>2001-03-30 20:52:36 +0000
commit3f3dd3bf8515a7ac72a9d318363f362a27763555 (patch)
treebcab9213698ed7750e93bf8fb84e4346fe35721d
parent31128bf3bc63dac98da65f76cb7867342bdde00a (diff)
downloadnautilus-3f3dd3bf8515a7ac72a9d318363f362a27763555.tar.gz
reviewed by: Darin Adler <darin@eazel.com>
Fixed bug 7913 (fm_get_text_attribute_names_preference should cache preference value for speed) Fixed bug 7914 (nautilus_icon_canvas_item_initialize should cache smooth_font for speed) Added a new way to stay up-to-date with the value of a preference: you register a (typically global) variable with a particular preference, and the preferences machinery updates its value automatically whenever the preference changes. This is a replacement for using nautilus_preferences_get (and _get_integer and _get_boolean) repeatedly, and is much more efficient. We might eventually replace all the callers of _get_xxx with calls to this, and remove those calls entirely. I deployed this in the two specific cases Pavel found with profiling (bugs 7913 & 7914) and some more places. I'll deploy it in more places still later. * libnautilus-extensions/nautilus-preferences.h: * libnautilus-extensions/nautilus-preferences.c: (update_auto_string), (update_auto_integer_or_boolean): New helper functions to update an individual auto-storage variable. (preferences_entry_update_auto_storage): New function, updates all auto-storage variables for a particular preference. (preferences_something_changed_notice): update auto-storage variables before calling callbacks. (preferences_entry_ensure_gconf_connection): New function, extracted from preferences_entry_add_callback. (preferences_entry_add_callback): Now calls extracted function. (preferences_entry_add_auto_storage): New function, adds a single auto-storage variable for a given preference. (preferences_entry_check_remove_connection): New function, extracted from preferences_entry_remove_callback. (preferences_entry_remove_callback): Now calls extracted function. (preferences_entry_remove_auto_storage): New function, removes a single auto-storage variable for a given preference. (preferences_entry_free): Free the auto-storage list. (nautilus_preferences_add_auto_string), (nautilus_preferences_add_auto_integer), (nautilus_preferences_add_auto_boolean), (nautilus_preferences_remove_auto_string), (nautilus_preferences_remove_auto_integer), (nautilus_preferences_remove_auto_boolean): Public cover functions for the three basic types of auto-storage variables. (nautilus_preferences_remove_callback): Fixed small bug where this function would unnecessarily add an entry before removing it. * libnautilus-extensions/nautilus-font-factory.c: (nautilus_font_factory_get_font_from_preferences): Reworked to use auto-storage variable. * libnautilus-extensions/nautilus-global-preferences.c: (nautilus_global_preferences_initialize): Set up auto-storage variables for icon view & default smooth font preferences. (global_preferences_get_smooth_font), (global_preferences_get_smooth_bold_font): Changed to take font file name instead of preferences name. (nautilus_global_preferences_get_icon_view_smooth_font), (nautilus_global_preferences_get_default_smooth_font), (nautilus_global_preferences_get_default_smooth_bold_font): Use auto-storage variables. * libnautilus-extensions/nautilus-icon-canvas-item.c: (nautilus_icon_canvas_item_initialize_class): Set up auto-storage variable for click policy preference. (in_single_click_mode): Use auto-storage variable. * libnautilus-extensions/nautilus-icon-factory.c: (should_display_image_file_as_itself): Use auto-storage variable for thumbnail policy. * src/file-manager/fm-icon-text-window.c: (fm_get_text_attribute_names_preference): Use auto-storage variable for icon captions. * src/file-manager/fm-icon-view.c: (should_preview_sound): Use auto-storage variable for sound-preview preference. (fm_icon_view_initialize_class): Set up auto-storage variable for sound-preview preference.
-rw-r--r--ChangeLog87
-rw-r--r--libnautilus-extensions/nautilus-font-factory.c20
-rw-r--r--libnautilus-extensions/nautilus-global-preferences.c30
-rw-r--r--libnautilus-extensions/nautilus-icon-canvas-item.c8
-rw-r--r--libnautilus-extensions/nautilus-icon-factory.c19
-rw-r--r--libnautilus-extensions/nautilus-preferences.c379
-rw-r--r--libnautilus-extensions/nautilus-preferences.h14
-rw-r--r--libnautilus-private/nautilus-font-factory.c20
-rw-r--r--libnautilus-private/nautilus-global-preferences.c30
-rw-r--r--libnautilus-private/nautilus-icon-canvas-item.c8
-rw-r--r--libnautilus-private/nautilus-icon-factory.c19
-rw-r--r--libnautilus-private/nautilus-preferences.c379
-rw-r--r--libnautilus-private/nautilus-preferences.h14
-rw-r--r--src/file-manager/fm-icon-text-window.c50
-rw-r--r--src/file-manager/fm-icon-view.c11
15 files changed, 904 insertions, 184 deletions
diff --git a/ChangeLog b/ChangeLog
index bf43f2d23..385c94ef1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,90 @@
+2001-03-30 John Sullivan <sullivan@eazel.com>
+
+ reviewed by: Darin Adler <darin@eazel.com>
+
+ Fixed bug 7913 (fm_get_text_attribute_names_preference
+ should cache preference value for speed)
+
+ Fixed bug 7914 (nautilus_icon_canvas_item_initialize
+ should cache smooth_font for speed)
+
+ Added a new way to stay up-to-date with the value of a
+ preference: you register a (typically global) variable
+ with a particular preference, and the preferences machinery
+ updates its value automatically whenever the preference
+ changes. This is a replacement for using
+ nautilus_preferences_get (and _get_integer and _get_boolean)
+ repeatedly, and is much more efficient. We might eventually
+ replace all the callers of _get_xxx with calls to this, and
+ remove those calls entirely.
+
+ I deployed this in the two specific cases Pavel found with
+ profiling (bugs 7913 & 7914) and some more places. I'll
+ deploy it in more places still later.
+
+ * libnautilus-extensions/nautilus-preferences.h:
+ * libnautilus-extensions/nautilus-preferences.c:
+ (update_auto_string), (update_auto_integer_or_boolean):
+ New helper functions to update an individual auto-storage variable.
+ (preferences_entry_update_auto_storage): New function, updates
+ all auto-storage variables for a particular preference.
+ (preferences_something_changed_notice): update auto-storage variables
+ before calling callbacks.
+ (preferences_entry_ensure_gconf_connection): New function, extracted
+ from preferences_entry_add_callback.
+ (preferences_entry_add_callback): Now calls extracted function.
+ (preferences_entry_add_auto_storage): New function, adds a single
+ auto-storage variable for a given preference.
+ (preferences_entry_check_remove_connection): New function, extracted
+ from preferences_entry_remove_callback.
+ (preferences_entry_remove_callback): Now calls extracted function.
+ (preferences_entry_remove_auto_storage): New function, removes a single
+ auto-storage variable for a given preference.
+ (preferences_entry_free): Free the auto-storage list.
+ (nautilus_preferences_add_auto_string),
+ (nautilus_preferences_add_auto_integer),
+ (nautilus_preferences_add_auto_boolean),
+ (nautilus_preferences_remove_auto_string),
+ (nautilus_preferences_remove_auto_integer),
+ (nautilus_preferences_remove_auto_boolean): Public cover functions
+ for the three basic types of auto-storage variables.
+ (nautilus_preferences_remove_callback): Fixed small bug where this
+ function would unnecessarily add an entry before removing it.
+
+ * libnautilus-extensions/nautilus-font-factory.c:
+ (nautilus_font_factory_get_font_from_preferences):
+ Reworked to use auto-storage variable.
+
+ * libnautilus-extensions/nautilus-global-preferences.c:
+ (nautilus_global_preferences_initialize): Set up auto-storage
+ variables for icon view & default smooth font preferences.
+ (global_preferences_get_smooth_font),
+ (global_preferences_get_smooth_bold_font): Changed to take
+ font file name instead of preferences name.
+ (nautilus_global_preferences_get_icon_view_smooth_font),
+ (nautilus_global_preferences_get_default_smooth_font),
+ (nautilus_global_preferences_get_default_smooth_bold_font):
+ Use auto-storage variables.
+
+ * libnautilus-extensions/nautilus-icon-canvas-item.c:
+ (nautilus_icon_canvas_item_initialize_class): Set up
+ auto-storage variable for click policy preference.
+ (in_single_click_mode): Use auto-storage variable.
+
+ * libnautilus-extensions/nautilus-icon-factory.c:
+ (should_display_image_file_as_itself): Use auto-storage
+ variable for thumbnail policy.
+
+ * src/file-manager/fm-icon-text-window.c:
+ (fm_get_text_attribute_names_preference): Use auto-storage
+ variable for icon captions.
+
+ * src/file-manager/fm-icon-view.c:
+ (should_preview_sound): Use auto-storage variable for
+ sound-preview preference.
+ (fm_icon_view_initialize_class): Set up auto-storage variable
+ for sound-preview preference.
+
2001-03-29 Darin Adler <darin@eazel.com>
reviewed by: Pavel Cisler <pavel@eazel.com>
diff --git a/libnautilus-extensions/nautilus-font-factory.c b/libnautilus-extensions/nautilus-font-factory.c
index c6c894cef..09abdb6e6 100644
--- a/libnautilus-extensions/nautilus-font-factory.c
+++ b/libnautilus-extensions/nautilus-font-factory.c
@@ -273,12 +273,20 @@ nautilus_font_factory_get_font_by_family (const char *family,
GdkFont *
nautilus_font_factory_get_font_from_preferences (guint size_in_pixels)
{
- char *family;
- GdkFont *font;
+ static gboolean icon_view_font_auto_value_registered;
+ static const char *icon_view_font_auto_value;
- family = nautilus_preferences_get (NAUTILUS_PREFERENCES_ICON_VIEW_FONT);
- font = nautilus_font_factory_get_font_by_family (family, size_in_pixels);
- g_free (family);
+ /* Can't initialize this in initialize_class, because no font factory
+ * instance may yet exist when this is called.
+ */
+ if (!icon_view_font_auto_value_registered) {
+ nautilus_preferences_add_auto_string (NAUTILUS_PREFERENCES_ICON_VIEW_FONT,
+ &icon_view_font_auto_value);
+ icon_view_font_auto_value_registered = TRUE;
+ }
- return font;
+ /* FIXME: We hardwire icon view font here, but some callers probably
+ * expect default font instead.
+ */
+ return nautilus_font_factory_get_font_by_family (icon_view_font_auto_value, size_in_pixels);
}
diff --git a/libnautilus-extensions/nautilus-global-preferences.c b/libnautilus-extensions/nautilus-global-preferences.c
index a1d69d4ab..b205a19f9 100644
--- a/libnautilus-extensions/nautilus-global-preferences.c
+++ b/libnautilus-extensions/nautilus-global-preferences.c
@@ -81,6 +81,8 @@ static GtkWidget *global_preferences_populate_pane (Nautilu
const PreferenceDialogItem *preference_dialog_item);
static GtkWidget *global_prefs_dialog = NULL;
+static const char *default_smooth_font_auto_value;
+static const char *icon_view_smooth_font_auto_value;
/* An enumeration used for installing type specific preferences defaults. */
typedef enum
@@ -1563,33 +1565,25 @@ nautilus_global_preferences_set_dialog_title (const char *title)
}
static NautilusScalableFont *
-global_preferences_get_smooth_font (const char *preference_name)
+global_preferences_get_smooth_font (const char *smooth_font_file_name)
{
NautilusScalableFont *smooth_font;
- char *smooth_font_file_name;
- g_return_val_if_fail (preference_name != NULL, NULL);
-
- smooth_font_file_name = nautilus_preferences_get (preference_name);
-
- smooth_font = (smooth_font_file_name && g_file_exists (smooth_font_file_name)) ?
+ smooth_font = (smooth_font_file_name != NULL && g_file_exists (smooth_font_file_name)) ?
nautilus_scalable_font_new (smooth_font_file_name) :
nautilus_scalable_font_get_default_font ();
- g_free (smooth_font_file_name);
g_assert (NAUTILUS_IS_SCALABLE_FONT (smooth_font));
return smooth_font;
}
static NautilusScalableFont *
-global_preferences_get_smooth_bold_font (const char *preference_name)
+global_preferences_get_smooth_bold_font (const char *file_name)
{
NautilusScalableFont *plain_font;
NautilusScalableFont *bold_font;
- g_return_val_if_fail (preference_name != NULL, NULL);
-
- plain_font = global_preferences_get_smooth_font (preference_name);
+ plain_font = global_preferences_get_smooth_font (file_name);
g_assert (NAUTILUS_IS_SCALABLE_FONT (plain_font));
bold_font = nautilus_scalable_font_make_bold (plain_font);
@@ -1613,7 +1607,7 @@ global_preferences_get_smooth_bold_font (const char *preference_name)
NautilusScalableFont *
nautilus_global_preferences_get_icon_view_smooth_font (void)
{
- return global_preferences_get_smooth_font (NAUTILUS_PREFERENCES_ICON_VIEW_SMOOTH_FONT);
+ return global_preferences_get_smooth_font (icon_view_smooth_font_auto_value);
}
/**
@@ -1625,7 +1619,7 @@ nautilus_global_preferences_get_icon_view_smooth_font (void)
NautilusScalableFont *
nautilus_global_preferences_get_default_smooth_font (void)
{
- return global_preferences_get_smooth_font (NAUTILUS_PREFERENCES_DEFAULT_SMOOTH_FONT);
+ return global_preferences_get_smooth_font (default_smooth_font_auto_value);
}
/**
@@ -1639,7 +1633,7 @@ nautilus_global_preferences_get_default_smooth_font (void)
NautilusScalableFont *
nautilus_global_preferences_get_default_smooth_bold_font (void)
{
- return global_preferences_get_smooth_bold_font (NAUTILUS_PREFERENCES_DEFAULT_SMOOTH_FONT);
+ return global_preferences_get_smooth_bold_font (default_smooth_font_auto_value);
}
void
@@ -1655,4 +1649,10 @@ nautilus_global_preferences_initialize (void)
/* Install defaults */
global_preferences_install_defaults ();
+
+ /* Set up storage for values accessed in this file */
+ nautilus_preferences_add_auto_string (NAUTILUS_PREFERENCES_ICON_VIEW_SMOOTH_FONT,
+ &icon_view_smooth_font_auto_value);
+ nautilus_preferences_add_auto_string (NAUTILUS_PREFERENCES_DEFAULT_SMOOTH_FONT,
+ &default_smooth_font_auto_value);
}
diff --git a/libnautilus-extensions/nautilus-icon-canvas-item.c b/libnautilus-extensions/nautilus-icon-canvas-item.c
index 4d3606f15..01a83eb7b 100644
--- a/libnautilus-extensions/nautilus-icon-canvas-item.c
+++ b/libnautilus-extensions/nautilus-icon-canvas-item.c
@@ -147,6 +147,8 @@ static guint32 highlight_background_color = NAUTILUS_RGBA_COLOR_PACK (0x00, 0x00
static guint32 highlight_text_color = NAUTILUS_RGBA_COLOR_PACK (0xFF, 0xFF, 0xFF, 0xFF);
static guint32 highlight_text_info_color = NAUTILUS_RGBA_COLOR_PACK (0xCC, 0xCC, 0xCC, 0xFF);
+static int click_policy_auto_value;
+
/* GtkObject */
static void nautilus_icon_canvas_item_initialize_class (NautilusIconCanvasItemClass *class);
static void nautilus_icon_canvas_item_initialize (NautilusIconCanvasItem *item);
@@ -284,6 +286,9 @@ nautilus_icon_canvas_item_initialize_class (NautilusIconCanvasItemClass *class)
item_class->point = nautilus_icon_canvas_item_point;
item_class->bounds = nautilus_icon_canvas_item_bounds;
item_class->event = nautilus_icon_canvas_item_event;
+
+ nautilus_preferences_add_auto_integer (NAUTILUS_PREFERENCES_CLICK_POLICY,
+ &click_policy_auto_value);
}
/* Object initialization function for the icon item. */
@@ -719,8 +724,7 @@ gnome_icon_underline_text (GnomeIconTextInfo *text_info,
static gboolean
in_single_click_mode ()
{
- /* Perhaps this should be computed elsewhere and passed in. */
- return nautilus_preferences_get_integer (NAUTILUS_PREFERENCES_CLICK_POLICY) == NAUTILUS_CLICK_POLICY_SINGLE;
+ return click_policy_auto_value == NAUTILUS_CLICK_POLICY_SINGLE;
}
/* Keep these for a bit while we work on performance of draw_or_measure_label_text. */
diff --git a/libnautilus-extensions/nautilus-icon-factory.c b/libnautilus-extensions/nautilus-icon-factory.c
index 4bb3cd2ca..009ec9f51 100644
--- a/libnautilus-extensions/nautilus-icon-factory.c
+++ b/libnautilus-extensions/nautilus-icon-factory.c
@@ -1333,15 +1333,18 @@ nautilus_scalable_icon_equal (gconstpointer a,
&& icon_a->aa_mode == icon_b->aa_mode;
}
-
static gboolean
should_display_image_file_as_itself (NautilusFile *file, gboolean anti_aliased)
{
- NautilusSpeedTradeoffValue preference_value;
-
- preference_value = nautilus_preferences_get_integer
- (NAUTILUS_PREFERENCES_SHOW_IMAGE_FILE_THUMBNAILS);
+ static int show_thumbnails_auto_value;
+ static gboolean show_thumbnail_auto_value_registered;
+ if (!show_thumbnail_auto_value_registered) {
+ nautilus_preferences_add_auto_integer (NAUTILUS_PREFERENCES_SHOW_IMAGE_FILE_THUMBNAILS,
+ &show_thumbnails_auto_value);
+ show_thumbnail_auto_value_registered = TRUE;
+ }
+
/* see if there's a proxy thumbnail to indicate that thumbnailing
* failed, in which case we shouldn't use the thumbnail.
*/
@@ -1354,15 +1357,15 @@ should_display_image_file_as_itself (NautilusFile *file, gboolean anti_aliased)
return FALSE;
}
- if (preference_value == NAUTILUS_SPEED_TRADEOFF_ALWAYS) {
+ if (show_thumbnails_auto_value == NAUTILUS_SPEED_TRADEOFF_ALWAYS) {
return TRUE;
}
- if (preference_value == NAUTILUS_SPEED_TRADEOFF_NEVER) {
+ if (show_thumbnails_auto_value == NAUTILUS_SPEED_TRADEOFF_NEVER) {
return FALSE;
}
- g_assert (preference_value == NAUTILUS_SPEED_TRADEOFF_LOCAL_ONLY);
+ g_assert (show_thumbnails_auto_value == NAUTILUS_SPEED_TRADEOFF_LOCAL_ONLY);
return nautilus_file_is_local (file);
}
diff --git a/libnautilus-extensions/nautilus-preferences.c b/libnautilus-extensions/nautilus-preferences.c
index f800cad33..b20d29cf8 100644
--- a/libnautilus-extensions/nautilus-preferences.c
+++ b/libnautilus-extensions/nautilus-preferences.c
@@ -44,6 +44,17 @@
#define DEFAULT_USER_LEVEL NAUTILUS_USER_LEVEL_INTERMEDIATE
+/* An enumeration used for updating auto-storage variables in a type-specific way.
+ * FIXME: there is another enumeration like this in nautilus-global-preferences.c,
+ * used for different purposes but in a related way. Should we combine them?
+ */
+typedef enum
+{
+ PREFERENCE_BOOLEAN = 1,
+ PREFERENCE_INTEGER,
+ PREFERENCE_STRING
+} PreferenceType;
+
/*
* PreferencesEntry:
*
@@ -54,7 +65,9 @@
typedef struct {
char *name;
char *description;
+ PreferenceType type;
GList *callback_list;
+ GList *auto_storage_list;
int gconf_connection_id;
NautilusEnumeration *enumeration;
} PreferencesEntry;
@@ -509,7 +522,7 @@ nautilus_preferences_get (const char *name)
{
char *result;
char *key;
-
+
g_return_val_if_fail (name != NULL, NULL);
key = preferences_key_make_for_getter (name);
@@ -746,6 +759,63 @@ preferences_callback_entry_invoke_function (gpointer data,
}
static void
+update_auto_string (gpointer data, gpointer callback_data)
+{
+ char **storage;
+ const char *value;
+
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (callback_data != NULL);
+
+ storage = (char **)data;
+ value = (const char *)callback_data;
+
+ g_free (*storage);
+ *(char **)storage = g_strdup (value);
+}
+
+static void
+update_auto_integer_or_boolean (gpointer data, gpointer callback_data)
+{
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (callback_data != NULL);
+
+ *(int *)data = GPOINTER_TO_INT (callback_data);
+}
+
+static void
+preferences_entry_update_auto_storage (PreferencesEntry *entry)
+{
+ char *new_string_value;
+ int new_int_value;
+ gboolean new_boolean_value;
+
+ switch (entry->type) {
+ case PREFERENCE_STRING:
+ new_string_value = nautilus_preferences_get (entry->name);
+ g_list_foreach (entry->auto_storage_list,
+ update_auto_string,
+ new_string_value);
+ g_free (new_string_value);
+ break;
+ case PREFERENCE_INTEGER:
+ new_int_value = nautilus_preferences_get_integer (entry->name);
+ g_list_foreach (entry->auto_storage_list,
+ update_auto_integer_or_boolean,
+ GINT_TO_POINTER (new_int_value));
+ break;
+ case PREFERENCE_BOOLEAN:
+ new_boolean_value = nautilus_preferences_get_boolean (entry->name);
+ g_list_foreach (entry->auto_storage_list,
+ update_auto_integer_or_boolean,
+ GINT_TO_POINTER (new_boolean_value));
+ break;
+ default:
+ g_warning ("unexpected preferences type %d in preferences_entry_update_auto_storage", entry->type);
+ }
+}
+
+static void
preferences_something_changed_notice (GConfClient *client,
guint connection_id,
GConfEntry *entry,
@@ -758,17 +828,19 @@ preferences_something_changed_notice (GConfClient *client,
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 */
- if (preferences_entry->callback_list) {
- g_list_foreach (preferences_entry->callback_list,
- preferences_callback_entry_invoke_function,
- NULL);
- }
+ g_list_foreach (preferences_entry->callback_list,
+ preferences_callback_entry_invoke_function,
+ NULL);
}
static void
@@ -823,14 +895,52 @@ preferences_user_level_changed_notice (GConfClient *client,
NULL);
}
+static void
+preferences_entry_ensure_gconf_connection (PreferencesEntry *entry)
+{
+ GError *error;
+ GConfClient *client;
+ char *key;
+
+ /*
+ * We install only one gconf notification for each preference entry.
+ * Otherwise, we would invoke the installed callbacks more than once
+ * per registered callback.
+ */
+ if (entry->gconf_connection_id != 0) {
+ return;
+ }
+
+ g_return_if_fail (entry->name != NULL);
+
+ client = preferences_global_client_get ();
+
+ g_return_if_fail (client != NULL);
+
+ key = preferences_key_make (entry->name);
+
+ error = NULL;
+ entry->gconf_connection_id = gconf_client_notify_add (client,
+ key,
+ preferences_something_changed_notice,
+ entry,
+ NULL,
+ &error);
+ if (nautilus_gconf_handle_error (&error)) {
+ entry->gconf_connection_id = 0;
+ }
+
+ g_free (key);
+}
+
/**
* preferences_entry_add_callback
*
* Add a callback to a pref node. Callbacks are fired whenever
* the pref value changes.
* @preferences_entry: The hash node.
- * @callback: The user supplied callback.
- * @callback_data: The user supplied closure.
+ * @callback: The user-supplied callback.
+ * @callback_data: The user-supplied closure.
**/
static void
preferences_entry_add_callback (PreferencesEntry *entry,
@@ -850,36 +960,56 @@ preferences_entry_add_callback (PreferencesEntry *entry,
entry->callback_list = g_list_append (entry->callback_list, callback_entry);
- /*
- * We install only one gconf notification for each preference entry.
- * Otherwise, we would invoke the installed callbacks more than once
- * per registered callback.
- */
- if (entry->gconf_connection_id == 0) {
- GError *error = NULL;
- GConfClient *client;
- char *key;
-
- g_return_if_fail (entry->name != NULL);
+ preferences_entry_ensure_gconf_connection (entry);
+}
- client = preferences_global_client_get ();
+/**
+ * preferences_entry_add_auto_storage
+ *
+ * Add an auto-storage variable to a pref node. The variable will
+ * be updated to match the pref value whenever the pref
+ * the pref value changes.
+ * @preferences_entry: The hash node.
+ * @storage: The user-supplied location at which to store the value.
+ * @type: Which type of variable this is.
+ **/
+static void
+preferences_entry_add_auto_storage (PreferencesEntry *entry,
+ gpointer storage,
+ PreferenceType type)
+{
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (storage != NULL);
+ g_return_if_fail (entry->type == 0 || entry->type == type);
+ g_return_if_fail (g_list_find (entry->auto_storage_list, storage) == NULL);
- g_return_if_fail (client != NULL);
+ entry->type = type;
+
+ entry->auto_storage_list = g_list_append (entry->auto_storage_list, storage);
- key = preferences_key_make (entry->name);
+ preferences_entry_ensure_gconf_connection (entry);
+}
- entry->gconf_connection_id = gconf_client_notify_add (client,
- key,
- preferences_something_changed_notice,
- entry,
- NULL,
- &error);
- if (nautilus_gconf_handle_error (&error)) {
- entry->gconf_connection_id = 0;
- }
+static void
+preferences_entry_check_remove_connection (PreferencesEntry *entry)
+{
+ GConfClient *client;
+
+ /*
+ * If there are no callbacks or auto-storage variables left in the entry,
+ * remove the gconf notification.
+ */
+ if (entry->callback_list != NULL || entry->auto_storage_list != NULL) {
+ return;
+ }
- g_free (key);
+ client = preferences_global_client_get ();
+
+ if (entry->gconf_connection_id != 0) {
+ gconf_client_notify_remove (client, entry->gconf_connection_id);
}
+
+ entry->gconf_connection_id = 0;
}
/**
@@ -888,8 +1018,8 @@ preferences_entry_add_callback (PreferencesEntry *entry,
* remove a callback from a pref entry. Both the callback and the callback_data must
* match in order for a callback to be removed from the entry.
* @preferences_entry: The hash entry.
- * @callback: The user supplied callback.
- * @callback_data: The user supplied closure.
+ * @callback: The user-supplied callback.
+ * @callback_data: The user-supplied closure.
**/
static void
preferences_entry_remove_callback (PreferencesEntry *entry,
@@ -920,22 +1050,57 @@ preferences_entry_remove_callback (PreferencesEntry *entry,
}
g_list_free (new_list);
-
- /*
- * If there are no callbacks left in the entry, remove the gconf
- * notification as well.
- */
- if (entry->callback_list == NULL) {
- GConfClient *client;
- client = preferences_global_client_get ();
+ preferences_entry_check_remove_connection (entry);
+}
+
+/**
+ * preferences_entry_remove_auto_storage
+ *
+ * remove an auto-storage variable from a pref entry.
+ * @preferences_entry: The hash entry.
+ * @storage: The user-supplied location.
+ **/
+static void
+preferences_entry_remove_auto_storage (PreferencesEntry *entry,
+ gpointer storage)
+{
+ GList *new_list;
+ GList *iterator;
+ gpointer storage_in_entry;
+
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (storage != NULL);
+ g_return_if_fail (entry->auto_storage_list != NULL);
+
+ new_list = g_list_copy (entry->auto_storage_list);
+
+ for (iterator = new_list; iterator != NULL; iterator = iterator->next) {
+ storage_in_entry = iterator->data;
- if (entry->gconf_connection_id != 0) {
- gconf_client_notify_remove (client, entry->gconf_connection_id);
- }
+ g_return_if_fail (storage_in_entry != NULL);
- entry->gconf_connection_id = 0;
+ if (storage_in_entry == storage) {
+ entry->auto_storage_list = g_list_remove (entry->auto_storage_list,
+ storage);
+
+ switch (entry->type) {
+ case PREFERENCE_STRING:
+ update_auto_string (storage, NULL);
+ break;
+ case PREFERENCE_BOOLEAN:
+ case PREFERENCE_INTEGER:
+ update_auto_integer_or_boolean (storage, 0);
+ break;
+ default:
+ g_warning ("unexpected preference type %d in preferences_entry_remove_auto_storage", entry->type);
+ }
+ }
}
+
+ g_list_free (new_list);
+
+ preferences_entry_check_remove_connection (entry);
}
/**
@@ -975,7 +1140,7 @@ preferences_callback_entry_free_func (gpointer data,
/**
* preferences_entry_free
*
- * Free a preference hash node members along with the node itself.
+ * Free a preference hash node's members along with the node itself.
* @preferences_hash_node: The node to free.
**/
static void
@@ -992,11 +1157,13 @@ preferences_entry_free (PreferencesEntry *entry)
gconf_client_notify_remove (client, entry->gconf_connection_id);
entry->gconf_connection_id = 0;
}
-
+
+ g_list_free (entry->auto_storage_list);
nautilus_g_list_free_deep_custom (entry->callback_list,
preferences_callback_entry_free_func,
NULL);
+ entry->auto_storage_list = NULL;
entry->callback_list = NULL;
g_free (entry->name);
@@ -1112,6 +1279,118 @@ nautilus_preferences_add_callback (const char *name,
preferences_entry_add_callback (entry, callback, callback_data);
}
+void
+nautilus_preferences_add_auto_string (const char *name,
+ const char **storage)
+{
+ PreferencesEntry *entry;
+ char *value;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup_or_insert (name);
+ g_assert (entry != NULL);
+
+ preferences_entry_add_auto_storage (entry, storage, PREFERENCE_STRING);
+
+ value = nautilus_preferences_get (entry->name);
+ update_auto_string (storage, value);
+ g_free (value);
+}
+
+void
+nautilus_preferences_add_auto_integer (const char *name,
+ int *storage)
+{
+ PreferencesEntry *entry;
+ int value;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup_or_insert (name);
+ g_assert (entry != NULL);
+
+ preferences_entry_add_auto_storage (entry, storage, PREFERENCE_INTEGER);
+
+ value = nautilus_preferences_get_integer (entry->name);
+ update_auto_integer_or_boolean (storage, GINT_TO_POINTER (value));
+}
+
+void
+nautilus_preferences_add_auto_boolean (const char *name,
+ gboolean *storage)
+{
+ PreferencesEntry *entry;
+ gboolean value;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup_or_insert (name);
+ g_assert (entry != NULL);
+
+ preferences_entry_add_auto_storage (entry, storage, PREFERENCE_BOOLEAN);
+
+ value = nautilus_preferences_get_boolean (entry->name);
+ update_auto_integer_or_boolean (storage, GINT_TO_POINTER (value));
+}
+
+void
+nautilus_preferences_remove_auto_string (const char *name,
+ const char **storage)
+{
+ PreferencesEntry *entry;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup (name);
+ if (entry == NULL) {
+ g_warning ("Trying to remove auto-string for %s without adding it first.", name);
+ return;
+ }
+
+ preferences_entry_remove_auto_storage (entry, storage);
+}
+
+void
+nautilus_preferences_remove_auto_integer (const char *name,
+ int *storage)
+{
+ PreferencesEntry *entry;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup (name);
+ if (entry == NULL) {
+ g_warning ("Trying to remove auto-integer for %s without adding it first.", name);
+ return;
+ }
+
+ preferences_entry_remove_auto_storage (entry, storage);
+}
+
+void
+nautilus_preferences_remove_auto_boolean (const char *name,
+ gboolean *storage)
+{
+ PreferencesEntry *entry;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup (name);
+ if (entry == NULL) {
+ g_warning ("Trying to remove auto-boolean for %s without adding it first.", name);
+ return;
+ }
+
+ preferences_entry_remove_auto_storage (entry, storage);
+}
+
typedef struct
{
char *name;
@@ -1172,10 +1451,10 @@ nautilus_preferences_remove_callback (const char *name,
g_return_if_fail (name != NULL);
g_return_if_fail (callback != NULL);
- entry = preferences_global_table_lookup_or_insert (name);
+ entry = preferences_global_table_lookup (name);
if (entry == NULL) {
- g_warning ("Trying to remove a callback without adding it first.");
+ g_warning ("Trying to remove a callback for %s without adding it first.", name);
return;
}
diff --git a/libnautilus-extensions/nautilus-preferences.h b/libnautilus-extensions/nautilus-preferences.h
index 07a1d7ef2..7f6554d8c 100644
--- a/libnautilus-extensions/nautilus-preferences.h
+++ b/libnautilus-extensions/nautilus-preferences.h
@@ -99,6 +99,20 @@ void nautilus_preferences_remove_callback (const char
NautilusPreferencesCallback callback,
gpointer callback_data);
+/* Variables that are automatically updated (lightweight "callbacks") */
+void nautilus_preferences_add_auto_string (const char *name,
+ const char **storage);
+void nautilus_preferences_add_auto_integer (const char *name,
+ int *storage);
+void nautilus_preferences_add_auto_boolean (const char *name,
+ gboolean *storage);
+void nautilus_preferences_remove_auto_string (const char *name,
+ const char **storage);
+void nautilus_preferences_remove_auto_integer (const char *name,
+ int *storage);
+void nautilus_preferences_remove_auto_boolean (const char *name,
+ int *storage);
+
/* Preferences attributes */
int nautilus_preferences_get_visible_user_level (const char *name);
void nautilus_preferences_set_visible_user_level (const char *name,
diff --git a/libnautilus-private/nautilus-font-factory.c b/libnautilus-private/nautilus-font-factory.c
index c6c894cef..09abdb6e6 100644
--- a/libnautilus-private/nautilus-font-factory.c
+++ b/libnautilus-private/nautilus-font-factory.c
@@ -273,12 +273,20 @@ nautilus_font_factory_get_font_by_family (const char *family,
GdkFont *
nautilus_font_factory_get_font_from_preferences (guint size_in_pixels)
{
- char *family;
- GdkFont *font;
+ static gboolean icon_view_font_auto_value_registered;
+ static const char *icon_view_font_auto_value;
- family = nautilus_preferences_get (NAUTILUS_PREFERENCES_ICON_VIEW_FONT);
- font = nautilus_font_factory_get_font_by_family (family, size_in_pixels);
- g_free (family);
+ /* Can't initialize this in initialize_class, because no font factory
+ * instance may yet exist when this is called.
+ */
+ if (!icon_view_font_auto_value_registered) {
+ nautilus_preferences_add_auto_string (NAUTILUS_PREFERENCES_ICON_VIEW_FONT,
+ &icon_view_font_auto_value);
+ icon_view_font_auto_value_registered = TRUE;
+ }
- return font;
+ /* FIXME: We hardwire icon view font here, but some callers probably
+ * expect default font instead.
+ */
+ return nautilus_font_factory_get_font_by_family (icon_view_font_auto_value, size_in_pixels);
}
diff --git a/libnautilus-private/nautilus-global-preferences.c b/libnautilus-private/nautilus-global-preferences.c
index a1d69d4ab..b205a19f9 100644
--- a/libnautilus-private/nautilus-global-preferences.c
+++ b/libnautilus-private/nautilus-global-preferences.c
@@ -81,6 +81,8 @@ static GtkWidget *global_preferences_populate_pane (Nautilu
const PreferenceDialogItem *preference_dialog_item);
static GtkWidget *global_prefs_dialog = NULL;
+static const char *default_smooth_font_auto_value;
+static const char *icon_view_smooth_font_auto_value;
/* An enumeration used for installing type specific preferences defaults. */
typedef enum
@@ -1563,33 +1565,25 @@ nautilus_global_preferences_set_dialog_title (const char *title)
}
static NautilusScalableFont *
-global_preferences_get_smooth_font (const char *preference_name)
+global_preferences_get_smooth_font (const char *smooth_font_file_name)
{
NautilusScalableFont *smooth_font;
- char *smooth_font_file_name;
- g_return_val_if_fail (preference_name != NULL, NULL);
-
- smooth_font_file_name = nautilus_preferences_get (preference_name);
-
- smooth_font = (smooth_font_file_name && g_file_exists (smooth_font_file_name)) ?
+ smooth_font = (smooth_font_file_name != NULL && g_file_exists (smooth_font_file_name)) ?
nautilus_scalable_font_new (smooth_font_file_name) :
nautilus_scalable_font_get_default_font ();
- g_free (smooth_font_file_name);
g_assert (NAUTILUS_IS_SCALABLE_FONT (smooth_font));
return smooth_font;
}
static NautilusScalableFont *
-global_preferences_get_smooth_bold_font (const char *preference_name)
+global_preferences_get_smooth_bold_font (const char *file_name)
{
NautilusScalableFont *plain_font;
NautilusScalableFont *bold_font;
- g_return_val_if_fail (preference_name != NULL, NULL);
-
- plain_font = global_preferences_get_smooth_font (preference_name);
+ plain_font = global_preferences_get_smooth_font (file_name);
g_assert (NAUTILUS_IS_SCALABLE_FONT (plain_font));
bold_font = nautilus_scalable_font_make_bold (plain_font);
@@ -1613,7 +1607,7 @@ global_preferences_get_smooth_bold_font (const char *preference_name)
NautilusScalableFont *
nautilus_global_preferences_get_icon_view_smooth_font (void)
{
- return global_preferences_get_smooth_font (NAUTILUS_PREFERENCES_ICON_VIEW_SMOOTH_FONT);
+ return global_preferences_get_smooth_font (icon_view_smooth_font_auto_value);
}
/**
@@ -1625,7 +1619,7 @@ nautilus_global_preferences_get_icon_view_smooth_font (void)
NautilusScalableFont *
nautilus_global_preferences_get_default_smooth_font (void)
{
- return global_preferences_get_smooth_font (NAUTILUS_PREFERENCES_DEFAULT_SMOOTH_FONT);
+ return global_preferences_get_smooth_font (default_smooth_font_auto_value);
}
/**
@@ -1639,7 +1633,7 @@ nautilus_global_preferences_get_default_smooth_font (void)
NautilusScalableFont *
nautilus_global_preferences_get_default_smooth_bold_font (void)
{
- return global_preferences_get_smooth_bold_font (NAUTILUS_PREFERENCES_DEFAULT_SMOOTH_FONT);
+ return global_preferences_get_smooth_bold_font (default_smooth_font_auto_value);
}
void
@@ -1655,4 +1649,10 @@ nautilus_global_preferences_initialize (void)
/* Install defaults */
global_preferences_install_defaults ();
+
+ /* Set up storage for values accessed in this file */
+ nautilus_preferences_add_auto_string (NAUTILUS_PREFERENCES_ICON_VIEW_SMOOTH_FONT,
+ &icon_view_smooth_font_auto_value);
+ nautilus_preferences_add_auto_string (NAUTILUS_PREFERENCES_DEFAULT_SMOOTH_FONT,
+ &default_smooth_font_auto_value);
}
diff --git a/libnautilus-private/nautilus-icon-canvas-item.c b/libnautilus-private/nautilus-icon-canvas-item.c
index 4d3606f15..01a83eb7b 100644
--- a/libnautilus-private/nautilus-icon-canvas-item.c
+++ b/libnautilus-private/nautilus-icon-canvas-item.c
@@ -147,6 +147,8 @@ static guint32 highlight_background_color = NAUTILUS_RGBA_COLOR_PACK (0x00, 0x00
static guint32 highlight_text_color = NAUTILUS_RGBA_COLOR_PACK (0xFF, 0xFF, 0xFF, 0xFF);
static guint32 highlight_text_info_color = NAUTILUS_RGBA_COLOR_PACK (0xCC, 0xCC, 0xCC, 0xFF);
+static int click_policy_auto_value;
+
/* GtkObject */
static void nautilus_icon_canvas_item_initialize_class (NautilusIconCanvasItemClass *class);
static void nautilus_icon_canvas_item_initialize (NautilusIconCanvasItem *item);
@@ -284,6 +286,9 @@ nautilus_icon_canvas_item_initialize_class (NautilusIconCanvasItemClass *class)
item_class->point = nautilus_icon_canvas_item_point;
item_class->bounds = nautilus_icon_canvas_item_bounds;
item_class->event = nautilus_icon_canvas_item_event;
+
+ nautilus_preferences_add_auto_integer (NAUTILUS_PREFERENCES_CLICK_POLICY,
+ &click_policy_auto_value);
}
/* Object initialization function for the icon item. */
@@ -719,8 +724,7 @@ gnome_icon_underline_text (GnomeIconTextInfo *text_info,
static gboolean
in_single_click_mode ()
{
- /* Perhaps this should be computed elsewhere and passed in. */
- return nautilus_preferences_get_integer (NAUTILUS_PREFERENCES_CLICK_POLICY) == NAUTILUS_CLICK_POLICY_SINGLE;
+ return click_policy_auto_value == NAUTILUS_CLICK_POLICY_SINGLE;
}
/* Keep these for a bit while we work on performance of draw_or_measure_label_text. */
diff --git a/libnautilus-private/nautilus-icon-factory.c b/libnautilus-private/nautilus-icon-factory.c
index 4bb3cd2ca..009ec9f51 100644
--- a/libnautilus-private/nautilus-icon-factory.c
+++ b/libnautilus-private/nautilus-icon-factory.c
@@ -1333,15 +1333,18 @@ nautilus_scalable_icon_equal (gconstpointer a,
&& icon_a->aa_mode == icon_b->aa_mode;
}
-
static gboolean
should_display_image_file_as_itself (NautilusFile *file, gboolean anti_aliased)
{
- NautilusSpeedTradeoffValue preference_value;
-
- preference_value = nautilus_preferences_get_integer
- (NAUTILUS_PREFERENCES_SHOW_IMAGE_FILE_THUMBNAILS);
+ static int show_thumbnails_auto_value;
+ static gboolean show_thumbnail_auto_value_registered;
+ if (!show_thumbnail_auto_value_registered) {
+ nautilus_preferences_add_auto_integer (NAUTILUS_PREFERENCES_SHOW_IMAGE_FILE_THUMBNAILS,
+ &show_thumbnails_auto_value);
+ show_thumbnail_auto_value_registered = TRUE;
+ }
+
/* see if there's a proxy thumbnail to indicate that thumbnailing
* failed, in which case we shouldn't use the thumbnail.
*/
@@ -1354,15 +1357,15 @@ should_display_image_file_as_itself (NautilusFile *file, gboolean anti_aliased)
return FALSE;
}
- if (preference_value == NAUTILUS_SPEED_TRADEOFF_ALWAYS) {
+ if (show_thumbnails_auto_value == NAUTILUS_SPEED_TRADEOFF_ALWAYS) {
return TRUE;
}
- if (preference_value == NAUTILUS_SPEED_TRADEOFF_NEVER) {
+ if (show_thumbnails_auto_value == NAUTILUS_SPEED_TRADEOFF_NEVER) {
return FALSE;
}
- g_assert (preference_value == NAUTILUS_SPEED_TRADEOFF_LOCAL_ONLY);
+ g_assert (show_thumbnails_auto_value == NAUTILUS_SPEED_TRADEOFF_LOCAL_ONLY);
return nautilus_file_is_local (file);
}
diff --git a/libnautilus-private/nautilus-preferences.c b/libnautilus-private/nautilus-preferences.c
index f800cad33..b20d29cf8 100644
--- a/libnautilus-private/nautilus-preferences.c
+++ b/libnautilus-private/nautilus-preferences.c
@@ -44,6 +44,17 @@
#define DEFAULT_USER_LEVEL NAUTILUS_USER_LEVEL_INTERMEDIATE
+/* An enumeration used for updating auto-storage variables in a type-specific way.
+ * FIXME: there is another enumeration like this in nautilus-global-preferences.c,
+ * used for different purposes but in a related way. Should we combine them?
+ */
+typedef enum
+{
+ PREFERENCE_BOOLEAN = 1,
+ PREFERENCE_INTEGER,
+ PREFERENCE_STRING
+} PreferenceType;
+
/*
* PreferencesEntry:
*
@@ -54,7 +65,9 @@
typedef struct {
char *name;
char *description;
+ PreferenceType type;
GList *callback_list;
+ GList *auto_storage_list;
int gconf_connection_id;
NautilusEnumeration *enumeration;
} PreferencesEntry;
@@ -509,7 +522,7 @@ nautilus_preferences_get (const char *name)
{
char *result;
char *key;
-
+
g_return_val_if_fail (name != NULL, NULL);
key = preferences_key_make_for_getter (name);
@@ -746,6 +759,63 @@ preferences_callback_entry_invoke_function (gpointer data,
}
static void
+update_auto_string (gpointer data, gpointer callback_data)
+{
+ char **storage;
+ const char *value;
+
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (callback_data != NULL);
+
+ storage = (char **)data;
+ value = (const char *)callback_data;
+
+ g_free (*storage);
+ *(char **)storage = g_strdup (value);
+}
+
+static void
+update_auto_integer_or_boolean (gpointer data, gpointer callback_data)
+{
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (callback_data != NULL);
+
+ *(int *)data = GPOINTER_TO_INT (callback_data);
+}
+
+static void
+preferences_entry_update_auto_storage (PreferencesEntry *entry)
+{
+ char *new_string_value;
+ int new_int_value;
+ gboolean new_boolean_value;
+
+ switch (entry->type) {
+ case PREFERENCE_STRING:
+ new_string_value = nautilus_preferences_get (entry->name);
+ g_list_foreach (entry->auto_storage_list,
+ update_auto_string,
+ new_string_value);
+ g_free (new_string_value);
+ break;
+ case PREFERENCE_INTEGER:
+ new_int_value = nautilus_preferences_get_integer (entry->name);
+ g_list_foreach (entry->auto_storage_list,
+ update_auto_integer_or_boolean,
+ GINT_TO_POINTER (new_int_value));
+ break;
+ case PREFERENCE_BOOLEAN:
+ new_boolean_value = nautilus_preferences_get_boolean (entry->name);
+ g_list_foreach (entry->auto_storage_list,
+ update_auto_integer_or_boolean,
+ GINT_TO_POINTER (new_boolean_value));
+ break;
+ default:
+ g_warning ("unexpected preferences type %d in preferences_entry_update_auto_storage", entry->type);
+ }
+}
+
+static void
preferences_something_changed_notice (GConfClient *client,
guint connection_id,
GConfEntry *entry,
@@ -758,17 +828,19 @@ preferences_something_changed_notice (GConfClient *client,
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 */
- if (preferences_entry->callback_list) {
- g_list_foreach (preferences_entry->callback_list,
- preferences_callback_entry_invoke_function,
- NULL);
- }
+ g_list_foreach (preferences_entry->callback_list,
+ preferences_callback_entry_invoke_function,
+ NULL);
}
static void
@@ -823,14 +895,52 @@ preferences_user_level_changed_notice (GConfClient *client,
NULL);
}
+static void
+preferences_entry_ensure_gconf_connection (PreferencesEntry *entry)
+{
+ GError *error;
+ GConfClient *client;
+ char *key;
+
+ /*
+ * We install only one gconf notification for each preference entry.
+ * Otherwise, we would invoke the installed callbacks more than once
+ * per registered callback.
+ */
+ if (entry->gconf_connection_id != 0) {
+ return;
+ }
+
+ g_return_if_fail (entry->name != NULL);
+
+ client = preferences_global_client_get ();
+
+ g_return_if_fail (client != NULL);
+
+ key = preferences_key_make (entry->name);
+
+ error = NULL;
+ entry->gconf_connection_id = gconf_client_notify_add (client,
+ key,
+ preferences_something_changed_notice,
+ entry,
+ NULL,
+ &error);
+ if (nautilus_gconf_handle_error (&error)) {
+ entry->gconf_connection_id = 0;
+ }
+
+ g_free (key);
+}
+
/**
* preferences_entry_add_callback
*
* Add a callback to a pref node. Callbacks are fired whenever
* the pref value changes.
* @preferences_entry: The hash node.
- * @callback: The user supplied callback.
- * @callback_data: The user supplied closure.
+ * @callback: The user-supplied callback.
+ * @callback_data: The user-supplied closure.
**/
static void
preferences_entry_add_callback (PreferencesEntry *entry,
@@ -850,36 +960,56 @@ preferences_entry_add_callback (PreferencesEntry *entry,
entry->callback_list = g_list_append (entry->callback_list, callback_entry);
- /*
- * We install only one gconf notification for each preference entry.
- * Otherwise, we would invoke the installed callbacks more than once
- * per registered callback.
- */
- if (entry->gconf_connection_id == 0) {
- GError *error = NULL;
- GConfClient *client;
- char *key;
-
- g_return_if_fail (entry->name != NULL);
+ preferences_entry_ensure_gconf_connection (entry);
+}
- client = preferences_global_client_get ();
+/**
+ * preferences_entry_add_auto_storage
+ *
+ * Add an auto-storage variable to a pref node. The variable will
+ * be updated to match the pref value whenever the pref
+ * the pref value changes.
+ * @preferences_entry: The hash node.
+ * @storage: The user-supplied location at which to store the value.
+ * @type: Which type of variable this is.
+ **/
+static void
+preferences_entry_add_auto_storage (PreferencesEntry *entry,
+ gpointer storage,
+ PreferenceType type)
+{
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (storage != NULL);
+ g_return_if_fail (entry->type == 0 || entry->type == type);
+ g_return_if_fail (g_list_find (entry->auto_storage_list, storage) == NULL);
- g_return_if_fail (client != NULL);
+ entry->type = type;
+
+ entry->auto_storage_list = g_list_append (entry->auto_storage_list, storage);
- key = preferences_key_make (entry->name);
+ preferences_entry_ensure_gconf_connection (entry);
+}
- entry->gconf_connection_id = gconf_client_notify_add (client,
- key,
- preferences_something_changed_notice,
- entry,
- NULL,
- &error);
- if (nautilus_gconf_handle_error (&error)) {
- entry->gconf_connection_id = 0;
- }
+static void
+preferences_entry_check_remove_connection (PreferencesEntry *entry)
+{
+ GConfClient *client;
+
+ /*
+ * If there are no callbacks or auto-storage variables left in the entry,
+ * remove the gconf notification.
+ */
+ if (entry->callback_list != NULL || entry->auto_storage_list != NULL) {
+ return;
+ }
- g_free (key);
+ client = preferences_global_client_get ();
+
+ if (entry->gconf_connection_id != 0) {
+ gconf_client_notify_remove (client, entry->gconf_connection_id);
}
+
+ entry->gconf_connection_id = 0;
}
/**
@@ -888,8 +1018,8 @@ preferences_entry_add_callback (PreferencesEntry *entry,
* remove a callback from a pref entry. Both the callback and the callback_data must
* match in order for a callback to be removed from the entry.
* @preferences_entry: The hash entry.
- * @callback: The user supplied callback.
- * @callback_data: The user supplied closure.
+ * @callback: The user-supplied callback.
+ * @callback_data: The user-supplied closure.
**/
static void
preferences_entry_remove_callback (PreferencesEntry *entry,
@@ -920,22 +1050,57 @@ preferences_entry_remove_callback (PreferencesEntry *entry,
}
g_list_free (new_list);
-
- /*
- * If there are no callbacks left in the entry, remove the gconf
- * notification as well.
- */
- if (entry->callback_list == NULL) {
- GConfClient *client;
- client = preferences_global_client_get ();
+ preferences_entry_check_remove_connection (entry);
+}
+
+/**
+ * preferences_entry_remove_auto_storage
+ *
+ * remove an auto-storage variable from a pref entry.
+ * @preferences_entry: The hash entry.
+ * @storage: The user-supplied location.
+ **/
+static void
+preferences_entry_remove_auto_storage (PreferencesEntry *entry,
+ gpointer storage)
+{
+ GList *new_list;
+ GList *iterator;
+ gpointer storage_in_entry;
+
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (storage != NULL);
+ g_return_if_fail (entry->auto_storage_list != NULL);
+
+ new_list = g_list_copy (entry->auto_storage_list);
+
+ for (iterator = new_list; iterator != NULL; iterator = iterator->next) {
+ storage_in_entry = iterator->data;
- if (entry->gconf_connection_id != 0) {
- gconf_client_notify_remove (client, entry->gconf_connection_id);
- }
+ g_return_if_fail (storage_in_entry != NULL);
- entry->gconf_connection_id = 0;
+ if (storage_in_entry == storage) {
+ entry->auto_storage_list = g_list_remove (entry->auto_storage_list,
+ storage);
+
+ switch (entry->type) {
+ case PREFERENCE_STRING:
+ update_auto_string (storage, NULL);
+ break;
+ case PREFERENCE_BOOLEAN:
+ case PREFERENCE_INTEGER:
+ update_auto_integer_or_boolean (storage, 0);
+ break;
+ default:
+ g_warning ("unexpected preference type %d in preferences_entry_remove_auto_storage", entry->type);
+ }
+ }
}
+
+ g_list_free (new_list);
+
+ preferences_entry_check_remove_connection (entry);
}
/**
@@ -975,7 +1140,7 @@ preferences_callback_entry_free_func (gpointer data,
/**
* preferences_entry_free
*
- * Free a preference hash node members along with the node itself.
+ * Free a preference hash node's members along with the node itself.
* @preferences_hash_node: The node to free.
**/
static void
@@ -992,11 +1157,13 @@ preferences_entry_free (PreferencesEntry *entry)
gconf_client_notify_remove (client, entry->gconf_connection_id);
entry->gconf_connection_id = 0;
}
-
+
+ g_list_free (entry->auto_storage_list);
nautilus_g_list_free_deep_custom (entry->callback_list,
preferences_callback_entry_free_func,
NULL);
+ entry->auto_storage_list = NULL;
entry->callback_list = NULL;
g_free (entry->name);
@@ -1112,6 +1279,118 @@ nautilus_preferences_add_callback (const char *name,
preferences_entry_add_callback (entry, callback, callback_data);
}
+void
+nautilus_preferences_add_auto_string (const char *name,
+ const char **storage)
+{
+ PreferencesEntry *entry;
+ char *value;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup_or_insert (name);
+ g_assert (entry != NULL);
+
+ preferences_entry_add_auto_storage (entry, storage, PREFERENCE_STRING);
+
+ value = nautilus_preferences_get (entry->name);
+ update_auto_string (storage, value);
+ g_free (value);
+}
+
+void
+nautilus_preferences_add_auto_integer (const char *name,
+ int *storage)
+{
+ PreferencesEntry *entry;
+ int value;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup_or_insert (name);
+ g_assert (entry != NULL);
+
+ preferences_entry_add_auto_storage (entry, storage, PREFERENCE_INTEGER);
+
+ value = nautilus_preferences_get_integer (entry->name);
+ update_auto_integer_or_boolean (storage, GINT_TO_POINTER (value));
+}
+
+void
+nautilus_preferences_add_auto_boolean (const char *name,
+ gboolean *storage)
+{
+ PreferencesEntry *entry;
+ gboolean value;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup_or_insert (name);
+ g_assert (entry != NULL);
+
+ preferences_entry_add_auto_storage (entry, storage, PREFERENCE_BOOLEAN);
+
+ value = nautilus_preferences_get_boolean (entry->name);
+ update_auto_integer_or_boolean (storage, GINT_TO_POINTER (value));
+}
+
+void
+nautilus_preferences_remove_auto_string (const char *name,
+ const char **storage)
+{
+ PreferencesEntry *entry;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup (name);
+ if (entry == NULL) {
+ g_warning ("Trying to remove auto-string for %s without adding it first.", name);
+ return;
+ }
+
+ preferences_entry_remove_auto_storage (entry, storage);
+}
+
+void
+nautilus_preferences_remove_auto_integer (const char *name,
+ int *storage)
+{
+ PreferencesEntry *entry;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup (name);
+ if (entry == NULL) {
+ g_warning ("Trying to remove auto-integer for %s without adding it first.", name);
+ return;
+ }
+
+ preferences_entry_remove_auto_storage (entry, storage);
+}
+
+void
+nautilus_preferences_remove_auto_boolean (const char *name,
+ gboolean *storage)
+{
+ PreferencesEntry *entry;
+
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (storage != NULL);
+
+ entry = preferences_global_table_lookup (name);
+ if (entry == NULL) {
+ g_warning ("Trying to remove auto-boolean for %s without adding it first.", name);
+ return;
+ }
+
+ preferences_entry_remove_auto_storage (entry, storage);
+}
+
typedef struct
{
char *name;
@@ -1172,10 +1451,10 @@ nautilus_preferences_remove_callback (const char *name,
g_return_if_fail (name != NULL);
g_return_if_fail (callback != NULL);
- entry = preferences_global_table_lookup_or_insert (name);
+ entry = preferences_global_table_lookup (name);
if (entry == NULL) {
- g_warning ("Trying to remove a callback without adding it first.");
+ g_warning ("Trying to remove a callback for %s without adding it first.", name);
return;
}
diff --git a/libnautilus-private/nautilus-preferences.h b/libnautilus-private/nautilus-preferences.h
index 07a1d7ef2..7f6554d8c 100644
--- a/libnautilus-private/nautilus-preferences.h
+++ b/libnautilus-private/nautilus-preferences.h
@@ -99,6 +99,20 @@ void nautilus_preferences_remove_callback (const char
NautilusPreferencesCallback callback,
gpointer callback_data);
+/* Variables that are automatically updated (lightweight "callbacks") */
+void nautilus_preferences_add_auto_string (const char *name,
+ const char **storage);
+void nautilus_preferences_add_auto_integer (const char *name,
+ int *storage);
+void nautilus_preferences_add_auto_boolean (const char *name,
+ gboolean *storage);
+void nautilus_preferences_remove_auto_string (const char *name,
+ const char **storage);
+void nautilus_preferences_remove_auto_integer (const char *name,
+ int *storage);
+void nautilus_preferences_remove_auto_boolean (const char *name,
+ int *storage);
+
/* Preferences attributes */
int nautilus_preferences_get_visible_user_level (const char *name);
void nautilus_preferences_set_visible_user_level (const char *name,
diff --git a/src/file-manager/fm-icon-text-window.c b/src/file-manager/fm-icon-text-window.c
index 11468805c..340b17071 100644
--- a/src/file-manager/fm-icon-text-window.c
+++ b/src/file-manager/fm-icon-text-window.c
@@ -367,8 +367,8 @@ static void
fm_icon_text_window_destroy_callback (GtkObject *object,
gpointer user_data)
{
- nautilus_preferences_remove_callback (NAUTILUS_PREFERENCES_ICON_CAPTIONS,
- synch_menus_with_preference,
+ nautilus_preferences_remove_callback (NAUTILUS_PREFERENCES_ICON_CAPTIONS,
+ synch_menus_with_preference,
NULL);
}
@@ -394,27 +394,43 @@ fm_icon_text_window_get_or_create (void)
return GTK_WINDOW (icon_text_window);
}
+/* fm_get_text_attribute_names_preference:
+ *
+ * Get the preference for which caption text should appear
+ * beneath icons. This function validates the raw preference
+ * and returns a default value if the raw preference is
+ * nonsensical.
+ */
char *
fm_get_text_attribute_names_preference (void)
{
- /* FIXME: This string leaks at exit, which matters only if you're
- * using a leak checker.
- */
- static char *icon_captions = NULL;
- char *new_icon_captions;
-
- new_icon_captions = nautilus_preferences_get (NAUTILUS_PREFERENCES_ICON_CAPTIONS);
-
- if (attribute_names_string_is_good (new_icon_captions)) {
- g_free (icon_captions);
- icon_captions = g_strdup (new_icon_captions);
+ static const char *auto_preferences_value;
+ static char *last_checked_value;
+ static gboolean auto_preferences_value_is_registered;
+ static char *captions_as_string;
+
+ /* Register auto-storage value the first time it's asked for */
+ if (!auto_preferences_value_is_registered) {
+ nautilus_preferences_add_auto_string (NAUTILUS_PREFERENCES_ICON_CAPTIONS,
+ &auto_preferences_value);
+ auto_preferences_value_is_registered = TRUE;
}
- g_free (new_icon_captions);
+ /* Validate preferences value the first time we see it */
+ if (last_checked_value == NULL || strcmp (last_checked_value, auto_preferences_value) != 0) {
+ if (attribute_names_string_is_good (auto_preferences_value)) {
+ g_free (captions_as_string);
+ captions_as_string = g_strdup (auto_preferences_value);
+ }
+
+ g_free (last_checked_value);
+ last_checked_value = g_strdup (auto_preferences_value);
+ }
- if (icon_captions == NULL) {
- icon_captions = g_strdup (DEFAULT_ATTRIBUTE_NAMES);
+ /* If the preferences value was bad or nonexistent, use default value */
+ if (captions_as_string == NULL) {
+ captions_as_string = g_strdup (DEFAULT_ATTRIBUTE_NAMES);
}
- return g_strdup (icon_captions);
+ return g_strdup (captions_as_string);
}
diff --git a/src/file-manager/fm-icon-view.c b/src/file-manager/fm-icon-view.c
index de9ac36b7..c317ef1c3 100644
--- a/src/file-manager/fm-icon-view.c
+++ b/src/file-manager/fm-icon-view.c
@@ -150,6 +150,8 @@ static void font_changed_callback (gpointer callback_data);
static void smooth_font_changed_callback (gpointer callback_data);
static void standard_font_size_changed_callback (gpointer callback_data);
+static int preview_sound_auto_value;
+
NAUTILUS_DEFINE_CLASS_BOILERPLATE (FMIconView,
fm_icon_view,
FM_TYPE_DIRECTORY_VIEW)
@@ -1442,11 +1444,7 @@ preview_audio (FMIconView *icon_view, NautilusFile *file, gboolean start_flag)
static gboolean
should_preview_sound (NautilusFile *file) {
- int preview_mode;
-
- preview_mode = nautilus_preferences_get_integer (NAUTILUS_PREFERENCES_PREVIEW_SOUND);
-
- if (preview_mode == NAUTILUS_SPEED_TRADEOFF_NEVER) {
+ if (preview_sound_auto_value == NAUTILUS_SPEED_TRADEOFF_NEVER) {
return FALSE;
}
/* the following is disabled until we can preview remote sounds, which we currently can't do */
@@ -1970,6 +1968,9 @@ fm_icon_view_initialize_class (FMIconViewClass *klass)
klass->get_directory_tighter_layout = fm_icon_view_real_get_directory_tighter_layout;
klass->set_directory_tighter_layout = fm_icon_view_real_set_directory_tighter_layout;
klass->supports_auto_layout = real_supports_auto_layout;
+
+ nautilus_preferences_add_auto_integer (NAUTILUS_PREFERENCES_PREVIEW_SOUND,
+ &preview_sound_auto_value);
}
static void