diff options
Diffstat (limited to 'src/mateconf-utils.c')
-rw-r--r-- | src/mateconf-utils.c | 862 |
1 files changed, 862 insertions, 0 deletions
diff --git a/src/mateconf-utils.c b/src/mateconf-utils.c new file mode 100644 index 0000000..f851200 --- /dev/null +++ b/src/mateconf-utils.c @@ -0,0 +1,862 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* + * File-Roller + * + * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. + */ + +/* eel-mateconf-extensions.c - Stuff to make MateConf easier to use. + + Copyright (C) 2000, 2001 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo <[email protected]> +*/ + +/* Modified by Paolo Bacchilega <[email protected]> for File Roller. */ + +#include <config.h> +#include <string.h> +#include <errno.h> + +#include <mateconf/mateconf-client.h> +#include <mateconf/mateconf.h> +#include "mateconf-utils.h" +#include "gtk-utils.h" +#include "fr-error.h" + +static MateConfClient *global_mateconf_client = NULL; + + +void +eel_global_client_free (void) +{ + if (global_mateconf_client == NULL) { + return; + } + + g_object_unref (global_mateconf_client); + global_mateconf_client = NULL; +} + + +MateConfClient * +eel_mateconf_client_get_global (void) +{ + /* Initialize mateconf if needed */ + if (!mateconf_is_initialized ()) { + char *argv[] = { "eel-preferences", NULL }; + GError *error = NULL; + + if (!mateconf_init (1, argv, &error)) { + if (eel_mateconf_handle_error (&error)) { + return NULL; + } + } + } + + if (global_mateconf_client == NULL) + global_mateconf_client = mateconf_client_get_default (); + + return global_mateconf_client; +} + + +gboolean +eel_mateconf_handle_error (GError **error) +{ + static gboolean shown_dialog = FALSE; + + g_return_val_if_fail (error != NULL, FALSE); + + if (*error != NULL) { + g_warning ("MateConf error:\n %s", (*error)->message); + if (! shown_dialog) { + GtkWidget *d; + shown_dialog = TRUE; + d = _gtk_error_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + NULL, + "MateConf error", + "MateConf error: %s\n" + "All further errors " + "shown only on terminal", + (*error)->message); + g_signal_connect (d, "response", + G_CALLBACK (gtk_widget_destroy), + NULL); + + gtk_widget_show (d); + } + + g_error_free (*error); + *error = NULL; + + return TRUE; + } + + return FALSE; +} + + +static gboolean +check_type (const char *key, + MateConfValue *val, + MateConfValueType t, + GError **err) +{ + if (val->type != t) { + g_set_error (err, + FR_ERROR, + errno, + "Type mismatch for key %s", + key); + return FALSE; + } else + return TRUE; +} + + +void +eel_mateconf_set_boolean (const char *key, + gboolean boolean_value) +{ + MateConfClient *client; + GError *error = NULL; + + g_return_if_fail (key != NULL); + + client = eel_mateconf_client_get_global (); + g_return_if_fail (client != NULL); + + mateconf_client_set_bool (client, key, boolean_value, &error); + eel_mateconf_handle_error (&error); +} + + +gboolean +eel_mateconf_get_boolean (const char *key, + gboolean def) +{ + GError *error = NULL; + gboolean result = def; + MateConfClient *client; + MateConfValue *val; + + g_return_val_if_fail (key != NULL, def); + + client = eel_mateconf_client_get_global (); + g_return_val_if_fail (client != NULL, def); + + val = mateconf_client_get (client, key, &error); + + if (val != NULL) { + if (check_type (key, val, MATECONF_VALUE_BOOL, &error)) + result = mateconf_value_get_bool (val); + else + eel_mateconf_handle_error (&error); + mateconf_value_free (val); + + } else if (error != NULL) + eel_mateconf_handle_error (&error); + + return result; +} + + +void +eel_mateconf_set_integer (const char *key, + int int_value) +{ + MateConfClient *client; + GError *error = NULL; + + g_return_if_fail (key != NULL); + + client = eel_mateconf_client_get_global (); + g_return_if_fail (client != NULL); + + mateconf_client_set_int (client, key, int_value, &error); + eel_mateconf_handle_error (&error); +} + + +int +eel_mateconf_get_integer (const char *key, + int def) +{ + GError *error = NULL; + int result = def; + MateConfClient *client; + MateConfValue *val; + + g_return_val_if_fail (key != NULL, def); + + client = eel_mateconf_client_get_global (); + g_return_val_if_fail (client != NULL, def); + + val = mateconf_client_get (client, key, &error); + + if (val != NULL) { + if (check_type (key, val, MATECONF_VALUE_INT, &error)) + result = mateconf_value_get_int (val); + else + eel_mateconf_handle_error (&error); + mateconf_value_free (val); + + } else if (error != NULL) + eel_mateconf_handle_error (&error); + + return result; +} + + +void +eel_mateconf_set_float (const char *key, + float float_value) +{ + MateConfClient *client; + GError *error = NULL; + + g_return_if_fail (key != NULL); + + client = eel_mateconf_client_get_global (); + g_return_if_fail (client != NULL); + + mateconf_client_set_float (client, key, float_value, &error); + eel_mateconf_handle_error (&error); +} + + +float +eel_mateconf_get_float (const char *key, + float def) +{ + GError *error = NULL; + float result = def; + MateConfClient *client; + MateConfValue *val; + + g_return_val_if_fail (key != NULL, def); + + client = eel_mateconf_client_get_global (); + g_return_val_if_fail (client != NULL, def); + + val = mateconf_client_get (client, key, &error); + + if (val != NULL) { + if (check_type (key, val, MATECONF_VALUE_FLOAT, &error)) + result = mateconf_value_get_float (val); + else + eel_mateconf_handle_error (&error); + mateconf_value_free (val); + + } else if (error != NULL) + eel_mateconf_handle_error (&error); + + return result; +} + + +void +eel_mateconf_set_string (const char *key, + const char *string_value) +{ + MateConfClient *client; + GError *error = NULL; + + g_return_if_fail (key != NULL); + + client = eel_mateconf_client_get_global (); + g_return_if_fail (client != NULL); + + mateconf_client_set_string (client, key, string_value, &error); + eel_mateconf_handle_error (&error); +} + + +char * +eel_mateconf_get_string (const char *key, + const char *def) +{ + GError *error = NULL; + char *result; + MateConfClient *client; + char *val; + + if (def != NULL) + result = g_strdup (def); + else + result = NULL; + + g_return_val_if_fail (key != NULL, result); + + client = eel_mateconf_client_get_global (); + g_return_val_if_fail (client != NULL, result); + + val = mateconf_client_get_string (client, key, &error); + + if (val != NULL) { + g_return_val_if_fail (error == NULL, result); + g_free (result); + result = g_strdup (val); + g_free (val); + } else if (error != NULL) + eel_mateconf_handle_error (&error); + + return result; +} + + +void +eel_mateconf_set_locale_string (const char *key, + const char *string_value) +{ + char *utf8; + + utf8 = g_locale_to_utf8 (string_value, -1, 0, 0, 0); + + if (utf8 != NULL) { + eel_mateconf_set_string (key, utf8); + g_free (utf8); + } +} + + +char * +eel_mateconf_get_locale_string (const char *key, + const char *def) +{ + char *utf8; + char *result; + + utf8 = eel_mateconf_get_string (key, def); + + if (utf8 == NULL) + return NULL; + + result = g_locale_from_utf8 (utf8, -1, 0, 0, 0); + g_free (utf8); + + return result; +} + + +void +eel_mateconf_set_string_list (const char *key, + const GSList *slist) +{ + MateConfClient *client; + GError *error; + + g_return_if_fail (key != NULL); + + client = eel_mateconf_client_get_global (); + g_return_if_fail (client != NULL); + + error = NULL; + mateconf_client_set_list (client, key, MATECONF_VALUE_STRING, + /* Need cast cause of MateConf api bug */ + (GSList *) slist, + &error); + eel_mateconf_handle_error (&error); +} + + +GSList * +eel_mateconf_get_string_list (const char *key) +{ + GSList *slist; + MateConfClient *client; + GError *error; + + g_return_val_if_fail (key != NULL, NULL); + + client = eel_mateconf_client_get_global (); + g_return_val_if_fail (client != NULL, NULL); + + error = NULL; + slist = mateconf_client_get_list (client, key, MATECONF_VALUE_STRING, &error); + if (eel_mateconf_handle_error (&error)) { + slist = NULL; + } + + return slist; +} + + +GSList * +eel_mateconf_get_locale_string_list (const char *key) +{ + GSList *utf8_slist, *slist, *scan; + + utf8_slist = eel_mateconf_get_string_list (key); + + slist = NULL; + for (scan = utf8_slist; scan; scan = scan->next) { + char *utf8 = scan->data; + char *locale = g_locale_from_utf8 (utf8, -1, 0, 0, 0); + slist = g_slist_prepend (slist, locale); + } + + g_slist_foreach (utf8_slist, (GFunc) g_free, NULL); + g_slist_free (utf8_slist); + + return g_slist_reverse (slist); +} + + +void +eel_mateconf_set_locale_string_list (const char *key, + const GSList *string_list_value) +{ + GSList *utf8_slist; + const GSList *scan; + + utf8_slist = NULL; + for (scan = string_list_value; scan; scan = scan->next) { + char *locale = scan->data; + char *utf8 = g_locale_to_utf8 (locale, -1, 0, 0, 0); + utf8_slist = g_slist_prepend (utf8_slist, utf8); + } + + utf8_slist = g_slist_reverse (utf8_slist); + + eel_mateconf_set_string_list (key, utf8_slist); + + g_slist_foreach (utf8_slist, (GFunc) g_free, NULL); + g_slist_free (utf8_slist); +} + + +gboolean +eel_mateconf_is_default (const char *key) +{ + gboolean result; + MateConfValue *value; + GError *error = NULL; + + g_return_val_if_fail (key != NULL, FALSE); + + value = mateconf_client_get_without_default (eel_mateconf_client_get_global (), key, &error); + + if (eel_mateconf_handle_error (&error)) { + if (value != NULL) { + mateconf_value_free (value); + } + return FALSE; + } + + result = (value == NULL); + eel_mateconf_value_free (value); + return result; +} + + +gboolean +eel_mateconf_monitor_add (const char *directory) +{ + GError *error = NULL; + MateConfClient *client; + + g_return_val_if_fail (directory != NULL, FALSE); + + client = mateconf_client_get_default (); + g_return_val_if_fail (client != NULL, FALSE); + + mateconf_client_add_dir (client, + directory, + MATECONF_CLIENT_PRELOAD_NONE, + &error); + + if (eel_mateconf_handle_error (&error)) { + return FALSE; + } + + return TRUE; +} + + +gboolean +eel_mateconf_monitor_remove (const char *directory) +{ + GError *error = NULL; + MateConfClient *client; + + if (directory == NULL) { + return FALSE; + } + + client = mateconf_client_get_default (); + g_return_val_if_fail (client != NULL, FALSE); + + mateconf_client_remove_dir (client, + directory, + &error); + + if (eel_mateconf_handle_error (&error)) { + return FALSE; + } + + return TRUE; +} + + +void +eel_mateconf_preload_cache (const char *directory, + MateConfClientPreloadType preload_type) +{ + GError *error = NULL; + MateConfClient *client; + + if (directory == NULL) { + return; + } + + client = mateconf_client_get_default (); + g_return_if_fail (client != NULL); + + mateconf_client_preload (client, + directory, + preload_type, + &error); + + eel_mateconf_handle_error (&error); +} + + +void +eel_mateconf_suggest_sync (void) +{ + MateConfClient *client; + GError *error = NULL; + + client = eel_mateconf_client_get_global (); + g_return_if_fail (client != NULL); + + mateconf_client_suggest_sync (client, &error); + eel_mateconf_handle_error (&error); +} + + +MateConfValue* +eel_mateconf_get_value (const char *key) +{ + MateConfValue *value = NULL; + MateConfClient *client; + GError *error = NULL; + + g_return_val_if_fail (key != NULL, NULL); + + client = eel_mateconf_client_get_global (); + g_return_val_if_fail (client != NULL, NULL); + + value = mateconf_client_get (client, key, &error); + + if (eel_mateconf_handle_error (&error)) { + if (value != NULL) { + mateconf_value_free (value); + value = NULL; + } + } + + return value; +} + + +MateConfValue* +eel_mateconf_get_default_value (const char *key) +{ + MateConfValue *value = NULL; + MateConfClient *client; + GError *error = NULL; + + g_return_val_if_fail (key != NULL, NULL); + + client = eel_mateconf_client_get_global (); + g_return_val_if_fail (client != NULL, NULL); + + value = mateconf_client_get_default_from_schema (client, key, &error); + + if (eel_mateconf_handle_error (&error)) { + if (value != NULL) { + mateconf_value_free (value); + value = NULL; + } + } + + return value; +} + + +static int +eel_strcmp (const char *string_a, const char *string_b) +{ + /* FIXME bugzilla.eazel.com 5450: Maybe we need to make this + * treat 'NULL < ""', or have a flavor that does that. If we + * didn't have code that already relies on 'NULL == ""', I + * would change it right now. + */ + return strcmp (string_a == NULL ? "" : string_a, + string_b == NULL ? "" : string_b); +} + + +static gboolean +eel_str_is_equal (const char *string_a, const char *string_b) +{ + /* FIXME bugzilla.eazel.com 5450: Maybe we need to make this + * treat 'NULL != ""', or have a flavor that does that. If we + * didn't have code that already relies on 'NULL == ""', I + * would change it right now. + */ + return eel_strcmp (string_a, string_b) == 0; +} + + +static gboolean +simple_value_is_equal (const MateConfValue *a, + const MateConfValue *b) +{ + g_return_val_if_fail (a != NULL, FALSE); + g_return_val_if_fail (b != NULL, FALSE); + + switch (a->type) { + case MATECONF_VALUE_STRING: + return eel_str_is_equal (mateconf_value_get_string (a), + mateconf_value_get_string (b)); + break; + + case MATECONF_VALUE_INT: + return mateconf_value_get_int (a) == + mateconf_value_get_int (b); + break; + + case MATECONF_VALUE_FLOAT: + return mateconf_value_get_float (a) == + mateconf_value_get_float (b); + break; + + case MATECONF_VALUE_BOOL: + return mateconf_value_get_bool (a) == + mateconf_value_get_bool (b); + break; + default: + g_assert_not_reached (); + break; + } + + return FALSE; +} + + +gboolean +eel_mateconf_value_is_equal (const MateConfValue *a, + const MateConfValue *b) +{ + GSList *node_a; + GSList *node_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 MATECONF_VALUE_STRING: + case MATECONF_VALUE_INT: + case MATECONF_VALUE_FLOAT: + case MATECONF_VALUE_BOOL: + return simple_value_is_equal (a, b); + break; + + case MATECONF_VALUE_LIST: + if (mateconf_value_get_list_type (a) != + mateconf_value_get_list_type (b)) { + return FALSE; + } + + node_a = mateconf_value_get_list (a); + node_b = mateconf_value_get_list (b); + + if (node_a == NULL && node_b == NULL) { + return TRUE; + } + + if (g_slist_length (node_a) != + g_slist_length (node_b)) { + return FALSE; + } + + for (; + node_a != NULL && node_b != NULL; + node_a = node_a->next, node_b = node_b->next) { + g_assert (node_a->data != NULL); + g_assert (node_b->data != NULL); + if (!simple_value_is_equal (node_a->data, node_b->data)) { + return FALSE; + } + } + + return TRUE; + default: + /* FIXME: pair ? */ + g_assert (0); + break; + } + + g_assert_not_reached (); + return FALSE; +} + + +void +eel_mateconf_value_free (MateConfValue *value) +{ + if (value == NULL) { + return; + } + + mateconf_value_free (value); +} + + +guint +eel_mateconf_notification_add (const char *key, + MateConfClientNotifyFunc notification_callback, + gpointer callback_data) +{ + guint notification_id; + MateConfClient *client; + GError *error = NULL; + + g_return_val_if_fail (key != NULL, EEL_MATECONF_UNDEFINED_CONNECTION); + g_return_val_if_fail (notification_callback != NULL, EEL_MATECONF_UNDEFINED_CONNECTION); + + client = eel_mateconf_client_get_global (); + g_return_val_if_fail (client != NULL, EEL_MATECONF_UNDEFINED_CONNECTION); + + notification_id = mateconf_client_notify_add (client, + key, + notification_callback, + callback_data, + NULL, + &error); + + if (eel_mateconf_handle_error (&error)) { + if (notification_id != EEL_MATECONF_UNDEFINED_CONNECTION) { + mateconf_client_notify_remove (client, notification_id); + notification_id = EEL_MATECONF_UNDEFINED_CONNECTION; + } + } + + return notification_id; +} + + +void +eel_mateconf_notification_remove (guint notification_id) +{ + MateConfClient *client; + + if (notification_id == EEL_MATECONF_UNDEFINED_CONNECTION) { + return; + } + + client = eel_mateconf_client_get_global (); + g_return_if_fail (client != NULL); + + mateconf_client_notify_remove (client, notification_id); +} + + +GSList * +eel_mateconf_value_get_string_list (const MateConfValue *value) +{ + GSList *result; + const GSList *slist; + const GSList *node; + const char *string; + const MateConfValue *next_value; + + if (value == NULL) { + return NULL; + } + + g_return_val_if_fail (value->type == MATECONF_VALUE_LIST, NULL); + g_return_val_if_fail (mateconf_value_get_list_type (value) == MATECONF_VALUE_STRING, NULL); + + slist = mateconf_value_get_list (value); + result = NULL; + for (node = slist; node != NULL; node = node->next) { + next_value = node->data; + g_return_val_if_fail (next_value != NULL, NULL); + g_return_val_if_fail (next_value->type == MATECONF_VALUE_STRING, NULL); + string = mateconf_value_get_string (next_value); + result = g_slist_append (result, g_strdup (string)); + } + return result; +} + + +void +eel_mateconf_value_set_string_list (MateConfValue *value, + const GSList *string_list) +{ + const GSList *node; + MateConfValue *next_value; + GSList *value_list; + + g_return_if_fail (value->type == MATECONF_VALUE_LIST); + g_return_if_fail (mateconf_value_get_list_type (value) == MATECONF_VALUE_STRING); + + value_list = NULL; + for (node = string_list; node != NULL; node = node->next) { + next_value = mateconf_value_new (MATECONF_VALUE_STRING); + mateconf_value_set_string (next_value, node->data); + value_list = g_slist_append (value_list, next_value); + } + + mateconf_value_set_list (value, value_list); + + for (node = value_list; node != NULL; node = node->next) { + mateconf_value_free (node->data); + } + g_slist_free (value_list); +} |