medit/moo/mooutils/mooprefs.c
2011-09-10 23:51:30 -07:00

1221 lines
26 KiB
C

/*
* mooprefs.c
*
* Copyright (C) 2004-2010 by Yevgen Muntyan <emuntyan@users.sourceforge.net>
*
* This file is part of medit. medit is free software; you can
* redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mooutils/mooprefs.h"
#include "marshals.h"
#include "mooutils/moomarkup.h"
#include "mooutils/mooutils-fs.h"
#include "mooutils/mooutils-misc.h"
#include "mooutils/mooutils-gobject.h"
#include "mooutils/mootype-macros.h"
#include <string.h>
#include <errno.h>
#include <gobject/gvaluecollector.h>
#include <glib/gregex.h>
#define MOO_PREFS_ELEMENT "moo-prefs"
#define PROP_VERSION "version"
#define MOO_PREFS_VERSION "1.0"
#define PREFS_ROOT "Prefs"
#undef MOO_PREFS_DEBUG_READWRITE
#define MOO_PREFS_SYS -1
typedef struct
{
GHashTable *data; /* char* -> Item* */
MooMarkupDoc *xml_rc;
MooMarkupDoc *xml_state;
gboolean rc_modified;
} PrefsStore;
typedef struct {
GType type;
GValue value;
GValue default_value;
guint prefs_kind : 1;
guint overridden : 1;
} PrefsItem;
static PrefsItem *prefs_get_item (const char *key);
static PrefsItem *item_new (GType type,
const GValue *value,
const GValue *default_value,
MooPrefsKind prefs_kind);
static void item_free (PrefsItem *item);
static gboolean item_set_type (PrefsItem *item,
GType type);
static gboolean item_set (PrefsItem *item,
const GValue *value);
static gboolean item_set_default (PrefsItem *item,
const GValue *value);
static void moo_prefs_set_modified (gboolean modified);
static PrefsStore *
prefs_instance (void)
{
static PrefsStore prefs;
if (G_UNLIKELY (!prefs.data))
prefs.data =
g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) item_free);
return &prefs;
}
char *
moo_prefs_make_key (const char *first_comp,
...)
{
char *key;
va_list var_args;
g_return_val_if_fail (first_comp != NULL, NULL);
va_start (var_args, first_comp);
key = moo_prefs_make_keyv (first_comp, var_args);
va_end (var_args);
return key;
}
char *
moo_prefs_make_keyv (const char *first_comp,
va_list var_args)
{
const char *comp;
GString *key = NULL;
g_return_val_if_fail (first_comp != NULL, NULL);
comp = first_comp;
while (comp)
{
if (!key)
{
key = g_string_new (comp);
}
else
{
g_string_append_c (key, '/');
g_string_append (key, comp);
}
comp = va_arg (var_args, const char*);
}
return g_string_free (key, FALSE);
}
static MooMarkupDoc *
create_markup_doc (void)
{
MooMarkupDoc *doc = moo_markup_doc_new ("Prefs");
MooMarkupNode *root = moo_markup_create_root_element (doc, MOO_PREFS_ELEMENT);
moo_markup_set_prop (root, PROP_VERSION, MOO_PREFS_VERSION);
return doc;
}
MooMarkupNode *
moo_prefs_get_markup (MooPrefsKind prefs_kind)
{
PrefsStore *prefs = prefs_instance ();
if (!prefs->xml_rc)
prefs->xml_rc = create_markup_doc ();
if (!prefs->xml_state)
prefs->xml_state = create_markup_doc ();
switch (prefs_kind)
{
case MOO_PREFS_RC:
return moo_markup_get_root_element (prefs->xml_rc, MOO_PREFS_ELEMENT);
case MOO_PREFS_STATE:
return moo_markup_get_root_element (prefs->xml_state, MOO_PREFS_ELEMENT);
}
g_return_val_if_reached (NULL);
}
void
moo_prefs_create_key (const char *key,
MooPrefsKind prefs_kind,
GType value_type,
...)
{
va_list args;
GValue default_value;
char *error = NULL;
g_return_if_fail (key != NULL);
g_return_if_fail (prefs_kind < 2);
g_return_if_fail (_moo_value_type_supported (value_type));
default_value.g_type = 0;
g_value_init (&default_value, value_type);
va_start (args, value_type);
G_VALUE_COLLECT (&default_value, args, 0, &error);
va_end (args);
if (error)
{
g_warning ("could not read value: %s", error);
g_free (error);
return;
}
moo_prefs_new_key (key, value_type, &default_value, prefs_kind);
g_value_unset (&default_value);
}
GType
moo_prefs_get_key_type (const char *key)
{
PrefsItem *item = prefs_get_item (key);
g_return_val_if_fail (item != NULL, G_TYPE_NONE);
return item->type;
}
gboolean
moo_prefs_key_registered (const char *key)
{
g_return_val_if_fail (key != NULL, FALSE);
return prefs_get_item (key) != NULL;
}
const GValue *
moo_prefs_get (const char *key)
{
const GValue *val;
PrefsItem *item;
g_return_val_if_fail (key != NULL, NULL);
item = prefs_get_item (key);
val = item ? &item->value : NULL;
if (!item)
g_warning ("key '%s' not registered", key);
return val;
}
const GValue *
moo_prefs_get_default (const char *key)
{
PrefsItem *item;
g_return_val_if_fail (key != NULL, NULL);
item = prefs_get_item (key);
g_return_val_if_fail (item != NULL, NULL);
return &item->default_value;
}
void
moo_prefs_set (const char *key,
const GValue *value)
{
PrefsItem *item;
g_return_if_fail (key != NULL);
g_return_if_fail (G_IS_VALUE (value));
item = prefs_get_item (key);
if (!item)
{
g_warning ("key '%s' not registered", key);
return;
}
if (item_set (item, value))
if (item->prefs_kind == MOO_PREFS_RC)
moo_prefs_set_modified (TRUE);
}
void
moo_prefs_set_default (const char *key,
const GValue *value)
{
PrefsItem *item;
g_return_if_fail (key != NULL);
g_return_if_fail (G_IS_VALUE (value));
item = prefs_get_item (key);
g_return_if_fail (item != NULL);
item_set_default (item, value);
}
static void
moo_prefs_set_modified (gboolean modified)
{
PrefsStore *prefs = prefs_instance ();
prefs->rc_modified = modified;
}
static void
prepend_key (const char *key,
PrefsItem *item,
gpointer pdata)
{
struct {
GSList *list;
MooPrefsKind prefs_kind;
} *data = pdata;
if (data->prefs_kind == item->prefs_kind)
data->list = g_slist_prepend (data->list, g_strdup (key));
}
GSList *
moo_prefs_list_keys (MooPrefsKind prefs_kind)
{
PrefsStore *prefs = prefs_instance ();
struct {
GSList *list;
MooPrefsKind prefs_kind;
} data;
data.list = NULL;
data.prefs_kind = prefs_kind;
g_hash_table_foreach (prefs->data, (GHFunc) prepend_key, &data);
return g_slist_sort (data.list, (GCompareFunc) strcmp);
}
/***************************************************************************/
/* Prefs
*/
void
moo_prefs_new_key (const char *key,
GType value_type,
const GValue *default_value,
MooPrefsKind prefs_kind)
{
PrefsItem *item;
PrefsStore *prefs;
g_return_if_fail (key && key[0]);
g_return_if_fail (g_utf8_validate (key, -1, NULL));
g_return_if_fail (G_IS_VALUE (default_value));
g_return_if_fail (G_VALUE_TYPE (default_value) == value_type);
switch (value_type)
{
case G_TYPE_STRING:
case G_TYPE_BOOLEAN:
case G_TYPE_INT:
break;
default:
g_warning ("bad type '%s'", g_type_name (value_type));
return;
}
prefs = prefs_instance ();
item = prefs_get_item (key);
if (!item)
{
item = item_new (value_type, default_value, default_value, prefs_kind);
g_hash_table_insert (prefs->data, g_strdup (key), item);
}
else
{
item_set_type (item, value_type);
if (!item->overridden)
item_set_default (item, default_value);
if (!item->overridden &&
item->prefs_kind == MOO_PREFS_RC &&
item->prefs_kind != prefs_kind)
moo_prefs_set_modified (TRUE);
item->prefs_kind = prefs_kind;
}
}
static void
prefs_new_key_from_string (const char *key,
const char *type,
const char *value,
int prefs_kind)
{
PrefsItem *item;
GValue string_val = { 0 };
GValue real_val = { 0 };
GType value_type;
g_return_if_fail (key && key[0]);
g_return_if_fail (type && type[0]);
g_return_if_fail (g_utf8_validate (key, -1, NULL));
if (strcmp (type, "bool") == 0)
value_type = G_TYPE_BOOLEAN;
else if (strcmp (type, "int") == 0)
value_type = G_TYPE_INT;
else if (strcmp (type, "string") == 0)
value_type = G_TYPE_STRING;
else
{
g_critical ("unknown value type '%s'", type);
return;
}
g_value_init (&string_val, G_TYPE_STRING);
g_value_set_string (&string_val, value);
g_value_init (&real_val, value_type);
_moo_value_convert (&string_val, &real_val);
item = prefs_get_item (key);
if (!item)
{
GValue default_val = { 0 };
g_value_init (&default_val, value_type);
if (prefs_kind == MOO_PREFS_SYS)
g_value_copy (&real_val, &default_val);
moo_prefs_new_key (key, value_type, &default_val,
prefs_kind == MOO_PREFS_SYS ? MOO_PREFS_RC : prefs_kind);
item = prefs_get_item (key);
g_value_unset (&default_val);
}
item_set (item, &real_val);
if (prefs_kind == MOO_PREFS_SYS)
item->overridden = TRUE;
g_value_unset (&real_val);
g_value_unset (&string_val);
}
void
moo_prefs_delete_key (const char *key)
{
PrefsItem *item;
PrefsStore *prefs;
g_return_if_fail (key != NULL);
item = prefs_get_item (key);
if (!item)
return;
if (item->prefs_kind == MOO_PREFS_RC)
moo_prefs_set_modified (TRUE);
prefs = prefs_instance ();
g_hash_table_remove (prefs->data, key);
}
static PrefsItem*
prefs_get_item (const char *key)
{
PrefsStore *prefs = prefs_instance ();
g_return_val_if_fail (key != NULL, NULL);
return g_hash_table_lookup (prefs->data, key);
}
/***************************************************************************/
/* PrefsItem
*/
static PrefsItem*
item_new (GType type,
const GValue *value,
const GValue *default_value,
MooPrefsKind prefs_kind)
{
PrefsItem *item;
g_return_val_if_fail (_moo_value_type_supported (type), NULL);
g_return_val_if_fail (value && default_value, NULL);
g_return_val_if_fail (G_VALUE_TYPE (value) == type, NULL);
g_return_val_if_fail (G_VALUE_TYPE (default_value) == type, NULL);
item = g_new0 (PrefsItem, 1);
item->type = type;
item->prefs_kind = prefs_kind;
g_value_init (&item->value, type);
g_value_copy (value, &item->value);
g_value_init (&item->default_value, type);
g_value_copy (default_value, &item->default_value);
return item;
}
static gboolean
item_set_type (PrefsItem *item,
GType type)
{
g_return_val_if_fail (item != NULL, FALSE);
g_return_val_if_fail (_moo_value_type_supported (type), FALSE);
if (type != item->type)
{
g_critical ("oops");
item->type = type;
_moo_value_change_type (&item->value, type);
_moo_value_change_type (&item->default_value, type);
return TRUE;
}
return FALSE;
}
static void
item_free (PrefsItem *item)
{
if (item)
{
item->type = 0;
g_value_unset (&item->value);
g_value_unset (&item->default_value);
g_free (item);
}
}
static gboolean
item_set (PrefsItem *item,
const GValue *value)
{
g_return_val_if_fail (item != NULL, FALSE);
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (item->type == G_VALUE_TYPE (value), FALSE);
if (!_moo_value_equal (value, &item->value))
{
g_value_copy (value, &item->value);
return TRUE;
}
return FALSE;
}
static gboolean
item_set_default (PrefsItem *item,
const GValue *value)
{
g_return_val_if_fail (item != NULL, FALSE);
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (item->type == G_VALUE_TYPE (value), FALSE);
if (!_moo_value_equal (value, &item->default_value))
{
g_value_copy (value, &item->default_value);
return TRUE;
}
return FALSE;
}
/***************************************************************************/
/* Loading abd saving
*/
static void
process_item (MooMarkupElement *elm,
int prefs_kind)
{
const char *name;
const char *type;
if (strcmp (elm->name, "item") != 0)
{
g_critical ("bad element '%s'", elm->name);
return;
}
name = moo_markup_get_prop (MOO_MARKUP_NODE (elm), "name");
type = moo_markup_get_prop (MOO_MARKUP_NODE (elm), "type");
g_return_if_fail (name && *name && type && *type);
prefs_new_key_from_string (name, type, elm->content, prefs_kind);
#ifdef MOO_PREFS_DEBUG_READWRITE
g_print ("key: '%s', type: '%s', val: '%s'\n", name, type, elm->content);
#endif
}
static gboolean
load_file (const char *file,
int prefs_kind,
GError **error)
{
MooMarkupDoc *xml;
MooMarkupNode *root;
PrefsStore *prefs;
MooMarkupDoc **target = NULL;
const char *version;
prefs = prefs_instance ();
switch (prefs_kind)
{
case MOO_PREFS_RC:
target = &prefs->xml_rc;
break;
case MOO_PREFS_STATE:
target = &prefs->xml_state;
break;
case MOO_PREFS_SYS:
target = NULL;
break;
default:
g_assert_not_reached ();
}
if (!g_file_test (file, G_FILE_TEST_EXISTS))
return TRUE;
xml = moo_markup_parse_file (file, error);
if (!xml)
return FALSE;
root = moo_markup_get_root_element (xml, MOO_PREFS_ELEMENT);
if (!root)
{
g_warning ("element '%s' missing in file %s", MOO_PREFS_ELEMENT, file);
moo_markup_doc_unref (xml);
return FALSE;
}
version = moo_markup_get_prop (root, PROP_VERSION);
if (!version || strcmp (version, MOO_PREFS_VERSION) != 0)
{
g_warning ("invalid version '%s'in file %s", version, file);
moo_markup_doc_unref (xml);
return FALSE;
}
if (target)
{
if (*target)
{
g_warning ("implement me");
moo_markup_doc_unref (*target);
}
*target = moo_markup_doc_ref (xml);
}
if (prefs_kind != MOO_PREFS_STATE)
{
_moo_markup_set_track_modified (xml, TRUE);
_moo_markup_set_modified (xml, FALSE);
}
root = moo_markup_get_element (root, PREFS_ROOT);
if (root)
{
MooMarkupNode *child;
for (child = root->children; child != NULL; child = child->next)
if (child->type == MOO_MARKUP_ELEMENT_NODE)
process_item (MOO_MARKUP_ELEMENT (child), prefs_kind);
}
moo_markup_doc_unref (xml);
return TRUE;
}
gboolean
moo_prefs_load (char **sys_files,
const char *file_rc,
const char *file_state,
GError **error)
{
moo_prefs_set_modified (FALSE);
for (; sys_files && *sys_files; ++sys_files)
if (!load_file (*sys_files, MOO_PREFS_SYS, error))
return FALSE;
if (file_rc && !load_file (file_rc, MOO_PREFS_RC, error))
return FALSE;
if (file_state && !load_file (file_state, MOO_PREFS_STATE, error))
return FALSE;
return TRUE;
}
typedef struct {
GPtrArray *keys;
MooPrefsKind prefs_kind;
} CollectItemsData;
static void
collect_item (const char *key,
PrefsItem *item,
CollectItemsData *data)
{
g_return_if_fail (key && *key && item);
g_return_if_fail (_moo_value_type_supported (item->type));
if (item->prefs_kind != data->prefs_kind)
return;
if (_moo_value_equal (&item->value, &item->default_value))
{
#ifdef MOO_PREFS_DEBUG_READWRITE
g_print ("skipping '%s'\n", key);
#endif
return;
}
g_ptr_array_add (data->keys, (gpointer) key);
}
static void
write_item (const char *key,
MooMarkupNode *root)
{
const char *string = NULL;
const char *type;
MooMarkupNode *elm;
PrefsItem *item;
item = prefs_get_item (key);
g_return_if_fail (item != NULL);
string = _moo_value_convert_to_string (&item->value);
if (!string)
string = "";
switch (item->type)
{
case G_TYPE_INT:
type = "int";
break;
case G_TYPE_STRING:
type = "string";
break;
case G_TYPE_BOOLEAN:
type = "bool";
break;
default:
g_return_if_reached ();
}
elm = moo_markup_create_text_element (root, "item", string);
moo_markup_set_prop (elm, "name", key);
moo_markup_set_prop (elm, "type", type);
#ifdef MOO_PREFS_DEBUG_READWRITE
g_print ("writing key: '%s', type: '%s', val: '%s'\n", key, type, string);
#endif
}
static int
compare_strings (gconstpointer a, gconstpointer b)
{
return strcmp (*(char**)a, *(char**)b);
}
static void
sync_xml (MooPrefsKind prefs_kind)
{
PrefsStore *prefs = prefs_instance ();
MooMarkupDoc *xml;
MooMarkupDoc **xml_ptr = NULL;
MooMarkupNode *root;
CollectItemsData data;
switch (prefs_kind)
{
case MOO_PREFS_RC:
xml_ptr = &prefs->xml_rc;
break;
case MOO_PREFS_STATE:
xml_ptr = &prefs->xml_state;
break;
default:
g_return_if_reached ();
break;
}
if (!*xml_ptr)
*xml_ptr = create_markup_doc ();
xml = *xml_ptr;
root = moo_markup_get_element (MOO_MARKUP_NODE (xml), MOO_PREFS_ELEMENT "/" PREFS_ROOT);
if (root)
moo_markup_delete_node (root);
data.prefs_kind = prefs_kind;
data.keys = g_ptr_array_new ();
g_hash_table_foreach (prefs->data,
(GHFunc) collect_item,
&data);
if (data.keys->len > 0)
{
guint i;
g_ptr_array_sort (data.keys, compare_strings);
root = moo_markup_create_element (MOO_MARKUP_NODE (xml),
MOO_PREFS_ELEMENT "/" PREFS_ROOT);
for (i = 0; i < data.keys->len; ++i)
write_item (data.keys->pdata[i], root);
}
g_ptr_array_free (data.keys, TRUE);
}
static gboolean
check_modified (MooPrefsKind prefs_kind)
{
PrefsStore *prefs = prefs_instance ();
MooMarkupDoc *xml = prefs->xml_rc;
if (prefs_kind != MOO_PREFS_RC)
return TRUE;
if (xml && _moo_markup_get_modified (xml))
return TRUE;
else
return prefs->rc_modified;
}
static gboolean
save_file (const char *file,
MooPrefsKind prefs_kind,
GError **error)
{
MooMarkupDoc *xml = NULL;
MooMarkupNode *node;
gboolean empty;
PrefsStore *prefs = prefs_instance ();
MooFileWriter *writer;
if (!check_modified (prefs_kind))
return TRUE;
sync_xml (prefs_kind);
switch (prefs_kind)
{
case MOO_PREFS_RC:
xml = prefs->xml_rc;
break;
case MOO_PREFS_STATE:
xml = prefs->xml_state;
break;
}
g_return_val_if_fail (xml != NULL, FALSE);
empty = TRUE;
for (node = xml->children; empty && node != NULL; node = node->next)
if (MOO_MARKUP_IS_ELEMENT (node))
empty = FALSE;
if (empty)
{
if (g_file_test (file, G_FILE_TEST_EXISTS))
if (_moo_unlink (file))
g_critical ("%s", g_strerror (errno));
return TRUE;
}
if ((writer = moo_config_writer_new (file, FALSE, error)))
{
moo_markup_write_pretty (xml, writer, 2);
return moo_file_writer_close (writer, error);
}
return FALSE;
}
gboolean
moo_prefs_save (const char *file_rc,
const char *file_state,
GError **error)
{
PrefsStore *prefs = prefs_instance ();
g_return_val_if_fail (file_rc != NULL, FALSE);
g_return_val_if_fail (file_state != NULL, FALSE);
if (save_file (file_rc, MOO_PREFS_RC, error))
{
if (prefs->xml_rc)
_moo_markup_set_modified (prefs->xml_rc, FALSE);
moo_prefs_set_modified (FALSE);
}
else
{
return FALSE;
}
return save_file (file_state, MOO_PREFS_STATE, error);
}
/***************************************************************************/
/* Helpers
*/
/**
* moo_prefs_new_key_bool:
*
* @key: (type const-utf8)
* @default_val: (default FALSE):
*/
void
moo_prefs_new_key_bool (const char *key,
gboolean default_val)
{
GValue val;
g_return_if_fail (key != NULL);
val.g_type = 0;
g_value_init (&val, G_TYPE_BOOLEAN);
g_value_set_boolean (&val, default_val);
moo_prefs_new_key (key, G_TYPE_BOOLEAN, &val, MOO_PREFS_RC);
}
/**
* moo_prefs_new_key_int:
*
* @key: (type const-utf8)
* @default_val: (default 0):
*/
void
moo_prefs_new_key_int (const char *key,
int default_val)
{
GValue val;
g_return_if_fail (key != NULL);
val.g_type = 0;
g_value_init (&val, G_TYPE_INT);
g_value_set_int (&val, default_val);
moo_prefs_new_key (key, G_TYPE_INT, &val, MOO_PREFS_RC);
}
/**
* moo_prefs_new_key_string:
*
* @key: (type const-utf8)
* @default_val: (type const-cstring) (allow-none) (default NULL):
**/
void
moo_prefs_new_key_string (const char *key,
const char *default_val)
{
static GValue val;
g_return_if_fail (key != NULL);
val.g_type = 0;
g_value_init (&val, G_TYPE_STRING);
g_value_set_static_string (&val, default_val);
moo_prefs_new_key (key, G_TYPE_STRING, &val, MOO_PREFS_RC);
g_value_unset (&val);
}
/**
* moo_prefs_get_string:
*
* @key: (type const-utf8)
*
* Returns: (type const-cstring)
*/
const char *
moo_prefs_get_string (const char *key)
{
const GValue *val;
val = moo_prefs_get (key);
g_return_val_if_fail (val != NULL, NULL);
return g_value_get_string (val);
}
/**
* moo_prefs_get_filename:
*
* @key: (type const-utf8)
*
* Returns: (type const-filename)
*/
const char *
moo_prefs_get_filename (const char *key)
{
const char *utf8_val;
static char *val = NULL;
GError *error = NULL;
utf8_val = moo_prefs_get_string (key);
if (!utf8_val)
return NULL;
g_free (val);
val = g_filename_from_utf8 (utf8_val, -1, NULL, NULL, &error);
if (!val)
{
g_warning ("could not convert '%s' to filename encoding: %s",
utf8_val, moo_error_message (error));
g_error_free (error);
}
return val;
}
/**
* moo_prefs_get_file:
*
* @key: (type const-utf8)
*
* Returns: (transfer full):
*/
GFile *
moo_prefs_get_file (const char *key)
{
const char *uri = moo_prefs_get_string (key);
return uri ? g_file_new_for_uri (uri) : NULL;
}
/**
* moo_prefs_get_bool:
*
* @key: (type const-utf8)
*/
gboolean
moo_prefs_get_bool (const char *key)
{
const GValue *value;
g_return_val_if_fail (key != NULL, FALSE);
value = moo_prefs_get (key);
g_return_val_if_fail (value != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN, FALSE);
return g_value_get_boolean (value);
}
/**
* moo_prefs_get_int:
*
* @key: (type const-utf8)
*/
int
moo_prefs_get_int (const char *key)
{
const GValue *value;
g_return_val_if_fail (key != NULL, 0);
value = moo_prefs_get (key);
g_return_val_if_fail (value != NULL, 0);
g_return_val_if_fail (G_VALUE_TYPE (value) == G_TYPE_INT, 0);
return g_value_get_int (value);
}
/**
* moo_prefs_set_string:
*
* @key: (type const-utf8)
* @val: (type const-cstring) (allow-none)
*/
void
moo_prefs_set_string (const char *key,
const char *val)
{
GValue gval;
g_return_if_fail (key != NULL);
gval.g_type = 0;
g_value_init (&gval, G_TYPE_STRING);
g_value_set_static_string (&gval, val);
moo_prefs_set (key, &gval);
g_value_unset (&gval);
}
/**
* moo_prefs_set_filename:
*
* @key: (type const-utf8)
* @val: (type const-filename) (allow-none)
*/
void
moo_prefs_set_filename (const char *key,
const char *val)
{
char *utf8_val;
g_return_if_fail (key != NULL);
if (!val)
{
moo_prefs_set_string (key, NULL);
return;
}
utf8_val = g_filename_display_name (val);
if (!utf8_val)
{
g_warning ("could not convert '%s' to utf8", val);
return;
}
moo_prefs_set_string (key, utf8_val);
g_free (utf8_val);
}
/**
* moo_prefs_set_file:
*
* @key: (type const-utf8)
* @val: (allow-none)
*/
void
moo_prefs_set_file (const char *key,
GFile *val)
{
char *uri;
g_return_if_fail (key != NULL);
if (!val)
{
moo_prefs_set_string (key, NULL);
return;
}
uri = g_file_get_uri (val);
moo_prefs_set_string (key, uri);
g_free (uri);
}
/**
* moo_prefs_set_int:
*
* @key: (type const-utf8)
* @val:
*/
void
moo_prefs_set_int (const char *key,
int val)
{
GValue gval = { 0 };
g_return_if_fail (key != NULL);
g_value_init (&gval, G_TYPE_INT);
g_value_set_int (&gval, val);
moo_prefs_set (key, &gval);
g_value_unset (&gval);
}
/**
* moo_prefs_set_bool:
*
* @key: (type const-utf8)
* @val:
*/
void
moo_prefs_set_bool (const char *key,
gboolean val)
{
GValue gval = { 0 };
g_return_if_fail (key != NULL);
g_value_init (&gval, G_TYPE_BOOLEAN);
g_value_set_boolean (&gval, val);
moo_prefs_set (key, &gval);
g_value_unset (&gval);
}