diff options
Diffstat (limited to 'nautilus-widgets/nautilus-preferences.c')
-rw-r--r-- | nautilus-widgets/nautilus-preferences.c | 516 |
1 files changed, 200 insertions, 316 deletions
diff --git a/nautilus-widgets/nautilus-preferences.c b/nautilus-widgets/nautilus-preferences.c index b117c5896..6bb4703fb 100644 --- a/nautilus-widgets/nautilus-preferences.c +++ b/nautilus-widgets/nautilus-preferences.c @@ -35,6 +35,8 @@ #include <gconf/gconf.h> #include <gconf/gconf-client.h> +#include <gtk/gtksignal.h> + static const char PREFERENCES_GCONF_PATH[] = "/nautilus"; /* @@ -45,9 +47,9 @@ static const char PREFERENCES_GCONF_PATH[] = "/nautilus"; * (a string). The hash value is a pointer of the following struct: */ typedef struct { - NautilusPreference *preference; GList *callback_list; - int gconf_connection; + int gconf_connections[3]; + char *name; } PreferencesHashNode; /* @@ -72,20 +74,21 @@ typedef struct { typedef struct { GHashTable *preference_table; GConfClient *gconf_client; + guint old_user_level; + } PreferencesGlobalData; -static PreferencesGlobalData GLOBAL = { NULL, NULL }; +static PreferencesGlobalData GLOBAL = { NULL, NULL, 0 }; /* PreferencesHashNode functions */ -static PreferencesHashNode * preferences_hash_node_alloc (char *name, - char *description, - NautilusPreferenceType type, - gconstpointer default_value, - gpointer data); +static PreferencesHashNode * preferences_hash_node_alloc (const char *name); static void preferences_hash_node_free (PreferencesHashNode *node); static void preferences_hash_node_free_func (gpointer key, gpointer value, gpointer callback_data); +static void preferences_hash_node_check_changes_func (gpointer key, + gpointer value, + gpointer callback_data); @@ -108,17 +111,8 @@ static void preferences_hash_node_remove_callback ( /* Private stuff */ static PreferencesHashNode * preferences_hash_node_lookup (const char *name); -static PreferencesHashNode * preferences_hash_node_lookup_with_registration (const char *pref_name, - NautilusPreferenceType pref_type, - gconstpointer default_value); -static void preferences_register (char *name, - char *description, - NautilusPreferenceType type, - gconstpointer default_value, - gpointer data); -static void set_default_value_if_needed (const char *name, - NautilusPreferenceType type, - gconstpointer default_value); +static PreferencesHashNode * preferences_hash_node_lookup_with_registration (const char *pref_name); +static void preferences_register (const char *name); /* Gconf callbacks */ static void preferences_gconf_callback (GConfClient *client, @@ -129,7 +123,6 @@ static void preferences_gconf_callback ( gpointer user_data); static gboolean preferences_initialize_if_needed (void); - /** * preferences_hash_node_alloc * @@ -139,11 +132,7 @@ static gboolean preferences_initialize_if_needed ( * Return value: A newly allocated node. **/ static PreferencesHashNode * -preferences_hash_node_alloc (char *name, - char *description, - NautilusPreferenceType type, - gconstpointer default_value, - gpointer data) +preferences_hash_node_alloc (const char *name) { PreferencesHashNode * node; @@ -151,19 +140,13 @@ preferences_hash_node_alloc (char *name, node = g_new (PreferencesHashNode, 1); - node->preference = NAUTILUS_PREFERENCE (nautilus_preference_new_from_type (name, type)); - - g_assert (node->preference != NULL); - - if (description) { - nautilus_preference_set_description (node->preference, description); - } - - set_default_value_if_needed (name, type, default_value); + node->name = g_strdup(name); node->callback_list = NULL; - node->gconf_connection = 0; + node->gconf_connections[0] = 0; + node->gconf_connections[1] = 0; + node->gconf_connections[2] = 0; return node; } @@ -177,28 +160,30 @@ preferences_hash_node_alloc (char *name, static void preferences_hash_node_free (PreferencesHashNode *node) { - g_assert (node != NULL); + guint i; - g_assert (node->preference != NULL); + g_assert (node != NULL); /* Remove the gconf notification if its still lingering */ - if (node->gconf_connection != 0) + for (i = 0; i < 3; i++) { - gconf_client_notify_remove (GLOBAL.gconf_client, - node->gconf_connection); - - node->gconf_connection = 0; + if (node->gconf_connections[i] != 0) + { + gconf_client_notify_remove (GLOBAL.gconf_client, + node->gconf_connections[i]); + + node->gconf_connections[i] = 0; + } } nautilus_g_list_free_deep_custom (node->callback_list, preferneces_callback_node_free_func, NULL); - gtk_object_unref (GTK_OBJECT (node->preference)); - node->preference = NULL; - node->callback_list = NULL; + g_free (node->name); + g_free (node); } @@ -217,6 +202,7 @@ preferences_hash_node_add_callback (PreferencesHashNode *node, gpointer callback_data) { PreferencesCallbackNode *preferneces_callback_node; + guint i; g_assert (node != NULL); @@ -236,27 +222,26 @@ preferences_hash_node_add_callback (PreferencesHashNode *node, * Otherwise, we would invoke the installed callbacks more than once * per registered callback. */ - if (node->gconf_connection == 0) { - char *name = nautilus_preference_get_name (node->preference); - - g_assert (name != NULL); - - /* - * Ref the preference here, cause we use for the gconf callback data. - * See preferences_hash_node_remove_callback() to make sure the ref is balanced. - */ - g_assert (node->preference != NULL); - gtk_object_ref (GTK_OBJECT (node->preference)); - - g_assert (node->gconf_connection == 0); - - node->gconf_connection = gconf_client_notify_add (GLOBAL.gconf_client, - name, - preferences_gconf_callback, - node->preference, - NULL, - NULL); - g_free (name); + for (i = 0; i < 3; i++) + { + if (node->gconf_connections[i] == 0) { + char *key; + g_assert (key); + g_assert (node->name != NULL); + g_assert (node->gconf_connections[i] == 0); + + key = nautilus_user_level_manager_make_gconf_key (node->name, i); + g_assert (key); + + node->gconf_connections[i] = gconf_client_notify_add (GLOBAL.gconf_client, + key, + preferences_gconf_callback, + node, + NULL, + NULL); + + g_free (key); + } } } @@ -304,19 +289,17 @@ preferences_hash_node_remove_callback (PreferencesHashNode *node, * notification as well. */ if (node->callback_list == NULL) { - g_assert (node->gconf_connection != 0); - - gconf_client_notify_remove (GLOBAL.gconf_client, - node->gconf_connection); - - node->gconf_connection = 0; - - /* - * Unref the preference here to balance the ref added in - * preferences_hash_node_add_callback(). - */ - g_assert (node->preference != NULL); - gtk_object_unref (GTK_OBJECT (node->preference)); + guint i; + + for (i = 0; i < 3; i++) + { + g_assert (node->gconf_connections[i] != 0); + + gconf_client_notify_remove (GLOBAL.gconf_client, + node->gconf_connections[i]); + + node->gconf_connections[i] = 0; + } } } @@ -339,6 +322,34 @@ preferences_hash_node_free_func (gpointer key, preferences_hash_node_free ((PreferencesHashNode *) value); } +static void +preferences_hash_node_check_changes_func (gpointer key, + gpointer value, + gpointer user_data) +{ + PreferencesHashNode *node; + guint old_user_level; + guint new_user_level; + + g_assert (value != NULL); + + node = (PreferencesHashNode *) value; + old_user_level = (guint) user_data; + new_user_level = nautilus_user_level_manager_get_user_level (); + + /* FIXME: This is currently only works for keys, it doenst work with whole namespaces */ + if (!nautilus_user_level_manager_compare_preference_between_user_levels (node->name, + old_user_level, + new_user_level)) { + /* Invoke callbacks for this node */ + if (node->callback_list) { + g_list_foreach (node->callback_list, + preferneces_callback_node_invoke_func, + (gpointer) NULL); + } + } +} + /** * preferneces_callback_node_alloc * @@ -416,33 +427,21 @@ preferneces_callback_node_invoke_func (gpointer data, gpointer callback_data) { PreferencesCallbackNode *callback_node; - char *preference_name; callback_node = (PreferencesCallbackNode *) data; g_assert (callback_node != NULL); g_assert (callback_node->callback_proc != NULL); - preference_name = nautilus_preference_get_name (callback_node->hash_node->preference); - - g_assert (preference_name != NULL); - (* callback_node->callback_proc) (callback_node->callback_data); - - g_free (preference_name); } static void -preferences_register (char *name, - char *description, - NautilusPreferenceType type, - gconstpointer default_value, - gpointer data) +preferences_register (const char *name) { PreferencesHashNode *node; g_return_if_fail (name != NULL); - g_return_if_fail (description != NULL); preferences_initialize_if_needed (); @@ -453,73 +452,9 @@ preferences_register (char *name, return; } - node = preferences_hash_node_alloc (name, description, type, default_value, data); + node = preferences_hash_node_alloc (name); g_hash_table_insert (GLOBAL.preference_table, (gpointer) name, (gpointer) node); - - g_assert (node->preference != NULL); -} - -/** - * set_default_value_if_needed - * - * This function will ask gconf for a value. If - * - * The value is not found in the user's database: - * It will be added to the database using the given default value. - * - * The value is found in the user's database: - * Nothing. - * - * @name: The name of the preference. - * @type: The type of preference. - * @default_value: The default_value to use. - **/ -static void -set_default_value_if_needed (const char *name, - NautilusPreferenceType type, - gconstpointer default_value) -{ - GConfValue *value = NULL; - - g_return_if_fail (name != NULL); - - preferences_initialize_if_needed (); - - /* Find out if the preference exists at all */ - value = gconf_client_get_without_default (GLOBAL.gconf_client, - name, - NULL); - - /* The value does not exist, so create one */ - if (!value) { - switch (type) - { - case NAUTILUS_PREFERENCE_STRING: - /* Gconf will not grok NULL strings, so for this case dont do it. */ - if (default_value) { - value = gconf_value_new (GCONF_VALUE_STRING); - gconf_value_set_string (value, (const char *) default_value); - } - break; - case NAUTILUS_PREFERENCE_BOOLEAN: - value = gconf_value_new (GCONF_VALUE_BOOL); - gconf_value_set_bool (value, GPOINTER_TO_INT (default_value)); - break; - case NAUTILUS_PREFERENCE_ENUM: - value = gconf_value_new (GCONF_VALUE_INT); - gconf_value_set_int (value, GPOINTER_TO_INT (default_value)); - break; - } - - if (value) { - gconf_client_set (GLOBAL.gconf_client, name, value, NULL); - } - } - - if (value) { - gconf_value_destroy (value); - } } static PreferencesHashNode * @@ -537,9 +472,7 @@ preferences_hash_node_lookup (const char *name) } static PreferencesHashNode * -preferences_hash_node_lookup_with_registration (const char *name, - NautilusPreferenceType type, - gconstpointer default_value) +preferences_hash_node_lookup_with_registration (const char *name) { PreferencesHashNode * node; @@ -550,11 +483,7 @@ preferences_hash_node_lookup_with_registration (const char *name, node = preferences_hash_node_lookup (name); if (!node) { - preferences_register (g_strdup (name), - "Unspecified Description", - type, - default_value, - (gpointer) NULL); + preferences_register (name); node = preferences_hash_node_lookup (name); } @@ -573,17 +502,15 @@ preferences_gconf_callback (GConfClient *client, gpointer user_data) { PreferencesHashNode *node; - NautilusPreference *expected_preference; + const char *expected_name; char *expected_key; - g_assert (key != NULL); - - preferences_initialize_if_needed (); + g_return_if_fail (user_data != NULL); - g_assert (user_data != NULL); - g_assert (NAUTILUS_IS_PREFERENCE (user_data)); + node = (PreferencesHashNode *) user_data; - expected_preference = NAUTILUS_PREFERENCE (user_data); + expected_name = node->name; + g_assert (expected_name != NULL); /* * This gconf notification was installed with an expected key in mind. @@ -603,22 +530,31 @@ preferences_gconf_callback (GConfClient *client, * So we can use this mechanism to keep track of changes within a whole * namespace by comparing the expected_key to the given key. */ - expected_key = nautilus_preference_get_name (expected_preference); - - g_assert (expected_key != NULL); + expected_key = nautilus_user_level_manager_make_current_gconf_key (expected_name); if (strcmp (key, expected_key) != 0) { + /* The prefix should be the same */ - g_assert (strncmp (key, expected_key, strlen (expected_key)) == 0); + if (strncmp (key, expected_key, strlen (expected_key)) != 0) { + + /* FIXME: This is triggering the first time the beast runs + * without an existing ~/.gconf directory. + */ +#if 0 + g_warning ("preferences_gconf_callback: Wrong prefix! This indicates a bug.\n"); +#endif + g_free (expected_key); + return; + } + key = expected_key; } - + g_assert (key != NULL); - node = preferences_hash_node_lookup (key); + node = preferences_hash_node_lookup (expected_name); g_assert (node != NULL); - g_assert (node->preference != NULL); gconf_client_suggest_sync (GLOBAL.gconf_client, NULL); @@ -632,6 +568,21 @@ preferences_gconf_callback (GConfClient *client, g_free (expected_key); } +static void +user_level_changed_callback (GtkObject *user_level_manager, + gpointer user_data) +{ + guint new_user_level; + + new_user_level = nautilus_user_level_manager_get_user_level (); + + g_hash_table_foreach (GLOBAL.preference_table, + preferences_hash_node_check_changes_func, + (gpointer) GLOBAL.old_user_level); + + GLOBAL.old_user_level = new_user_level; +} + static gboolean preferences_initialize_if_needed (void) { @@ -674,139 +625,21 @@ preferences_initialize_if_needed (void) g_assert (GLOBAL.gconf_client != NULL); + GLOBAL.old_user_level = nautilus_user_level_manager_get_user_level (); + + /* Register to find out about user level changes */ + gtk_signal_connect (GTK_OBJECT (nautilus_user_level_manager_get ()), + "user_level_changed", + user_level_changed_callback, + NULL); + return TRUE; } + /* * Public functions */ - - -/** - * nautilus_preferences_find_preference - * - * Search for a named preference in the given preferences and return it. - * @preferences: The preferences to search - * - * Return value: A referenced pointer to the preference object that corresponds - * to the given preference name. The caller should gtk_object_unref() the return - * value of this function. - **/ -NautilusPreference * -nautilus_preferences_find_preference (const char *name) -{ - PreferencesHashNode *node; - - g_return_val_if_fail (name != NULL, NULL); - - preferences_initialize_if_needed (); - - node = preferences_hash_node_lookup (name); - - g_assert (node != NULL); - - gtk_object_ref (GTK_OBJECT (node->preference)); - - return node->preference; -} - -void -nautilus_preferences_set_info (const char *name, - const char *description, - NautilusPreferenceType type, - gconstpointer default_value) -{ - PreferencesHashNode *node; - - g_return_if_fail (name != NULL); - - preferences_initialize_if_needed (); - - node = preferences_hash_node_lookup_with_registration (name, type, default_value); - - g_assert (node != NULL); - g_assert (node->preference != NULL); - - if (description) { - nautilus_preference_set_description (node->preference, description); - } - - set_default_value_if_needed (name, type, default_value); -} - -void -nautilus_preferences_enum_add_entry (const char *name, - const char *entry_name, - const char *entry_description, - int entry_value) -{ - PreferencesHashNode *node; - - g_return_if_fail (name != NULL); - - preferences_initialize_if_needed (); - - node = preferences_hash_node_lookup_with_registration (name, NAUTILUS_PREFERENCE_ENUM, NULL); - - g_assert (node != NULL); - g_assert (node->preference != NULL); - - g_assert (nautilus_preference_get_preference_type (node->preference) == NAUTILUS_PREFERENCE_ENUM); - - nautilus_preference_enum_add_entry (node->preference, - entry_name, - entry_description, - entry_value); -} - -gboolean -nautilus_preferences_add_boolean_callback (const char *name, - NautilusPreferencesCallback callback_proc, - gpointer callback_data) -{ - PreferencesHashNode *node; - - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (callback_proc != NULL, FALSE); - - preferences_initialize_if_needed (); - - node = preferences_hash_node_lookup_with_registration (name, NAUTILUS_PREFERENCE_BOOLEAN, NULL); - - if (node == NULL) { - g_warning ("trying to add a callback for an unregistered preference"); - return FALSE; - } - - preferences_hash_node_add_callback (node, callback_proc, callback_data); - - return TRUE; -} - -gboolean -nautilus_preferences_add_enum_callback (const char *name, - NautilusPreferencesCallback callback_proc, - gpointer callback_data) -{ - PreferencesHashNode *node; - - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (callback_proc != NULL, FALSE); - - preferences_initialize_if_needed (); - - node = preferences_hash_node_lookup_with_registration (name, NAUTILUS_PREFERENCE_ENUM, NULL); - - if (node == NULL) { - g_warning ("trying to add a callback for an unregistered preference"); - return FALSE; - } - - preferences_hash_node_add_callback (node, callback_proc, callback_data); - - return TRUE; -} - gboolean nautilus_preferences_add_callback (const char *name, NautilusPreferencesCallback callback_proc, @@ -819,7 +652,7 @@ nautilus_preferences_add_callback (const char *name, preferences_initialize_if_needed (); - node = preferences_hash_node_lookup_with_registration (name, NAUTILUS_PREFERENCE_STRING, NULL); + node = preferences_hash_node_lookup_with_registration (name); if (node == NULL) { g_warning ("trying to add a callback for an unregistered preference"); @@ -856,33 +689,51 @@ void nautilus_preferences_set_boolean (const char *name, gboolean boolean_value) { + char *key; + gboolean gconf_result; g_return_if_fail (name != NULL); preferences_initialize_if_needed (); + key = nautilus_user_level_manager_make_current_gconf_key (name); + g_assert (key != NULL); + /* Make sure the preference value is indeed different */ - if (gconf_client_get_bool (GLOBAL.gconf_client, name, NULL) == boolean_value) { + if (gconf_client_get_bool (GLOBAL.gconf_client, key, NULL) == boolean_value) { + g_free (key); return; } - gconf_result = gconf_client_set_bool (GLOBAL.gconf_client, name, boolean_value, NULL); + gconf_result = gconf_client_set_bool (GLOBAL.gconf_client, key, boolean_value, NULL); g_assert (gconf_result); gconf_client_suggest_sync (GLOBAL.gconf_client, NULL); + + g_free (key); } gboolean nautilus_preferences_get_boolean (const char *name, gboolean default_value) { + gboolean result; + char *key; + g_return_val_if_fail (name != NULL, FALSE); preferences_initialize_if_needed (); - return gconf_client_get_bool (GLOBAL.gconf_client, name, NULL); + key = nautilus_user_level_manager_make_current_gconf_key (name); + g_assert (key != NULL); + + result = gconf_client_get_bool (GLOBAL.gconf_client, key, NULL); + + g_free (key); + + return result; } void @@ -890,32 +741,47 @@ nautilus_preferences_set_enum (const char *name, int enum_value) { gboolean gconf_result; + char *key; g_return_if_fail (name != NULL); preferences_initialize_if_needed (); + key = nautilus_user_level_manager_make_current_gconf_key (name); + g_assert (key != NULL); + /* Make sure the preference value is indeed different */ - if (gconf_client_get_int (GLOBAL.gconf_client, name, NULL) == enum_value) { + if (gconf_client_get_int (GLOBAL.gconf_client, key, NULL) == enum_value) { + g_free (key); return; } - gconf_result = gconf_client_set_int (GLOBAL.gconf_client, name, enum_value, NULL); + gconf_result = gconf_client_set_int (GLOBAL.gconf_client, key, enum_value, NULL); g_assert (gconf_result); gconf_client_suggest_sync (GLOBAL.gconf_client, NULL); + + g_free (key); } int nautilus_preferences_get_enum (const char *name, int default_value) { + int result; + char *key; + g_return_val_if_fail (name != NULL, FALSE); preferences_initialize_if_needed (); - return gconf_client_get_int (GLOBAL.gconf_client, name, NULL); + key = nautilus_user_level_manager_make_current_gconf_key (name); + g_assert (key != NULL); + + result = gconf_client_get_int (GLOBAL.gconf_client, key, NULL); + + return result; } void @@ -923,14 +789,18 @@ nautilus_preferences_set (const char *name, const char *value) { gboolean gconf_result; + char *key; g_return_if_fail (name != NULL); preferences_initialize_if_needed (); + key = nautilus_user_level_manager_make_current_gconf_key (name); + g_assert (key != NULL); + /* Make sure the preference value is indeed different */ if (value) { - char *current_value = gconf_client_get_string (GLOBAL.gconf_client, name, NULL); + char *current_value = gconf_client_get_string (GLOBAL.gconf_client, key, NULL); int result = nautilus_strcmp (current_value, value); if (current_value) { @@ -938,15 +808,18 @@ nautilus_preferences_set (const char *name, } if (result == 0) { + g_free (key); return; } } - gconf_result = gconf_client_set_string (GLOBAL.gconf_client, name, value, NULL); + gconf_result = gconf_client_set_string (GLOBAL.gconf_client, key, value, NULL); g_assert (gconf_result); gconf_client_suggest_sync (GLOBAL.gconf_client, NULL); + + g_free (key); } char * @@ -954,16 +827,22 @@ nautilus_preferences_get (const char *name, const char *default_value) { gchar *value = NULL; + char *key; g_return_val_if_fail (name != NULL, FALSE); preferences_initialize_if_needed (); - value = gconf_client_get_string (GLOBAL.gconf_client, name, NULL); + key = nautilus_user_level_manager_make_current_gconf_key (name); + g_assert (key != NULL); + + value = gconf_client_get_string (GLOBAL.gconf_client, key, NULL); if (!value && default_value) { value = g_strdup (default_value); } + + g_free (key); return value; } @@ -974,6 +853,10 @@ nautilus_preferences_shutdown (void) if (GLOBAL.preference_table == NULL && GLOBAL.gconf_client == NULL) { return; } + + gtk_signal_disconnect_by_func (GTK_OBJECT (nautilus_user_level_manager_get ()), + user_level_changed_callback, + NULL); if (GLOBAL.preference_table != NULL) { g_hash_table_foreach (GLOBAL.preference_table, @@ -990,5 +873,6 @@ nautilus_preferences_shutdown (void) GLOBAL.gconf_client = NULL; } + } |