2
* Copyright (C) 2009-2010 Nick Schermer <nick@xfce.org>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundatoin; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License along
15
* with this program; if not, write to the Free Software Foundatoin, Inc.,
16
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31
#include <xfconf/xfconf.h>
32
#include <libxfce4util/libxfce4util.h>
33
#include <migrate/migrate-default.h>
34
#include <libxfce4panel/xfce-panel-macros.h>
40
XfconfChannel *channel;
49
migrate_default_gtype_from_string (const gchar *type)
51
if (strcmp (type, "string") == 0)
53
else if (strcmp (type, "uint") == 0)
55
else if (strcmp (type, "int") == 0)
57
else if (strcmp (type, "double") == 0)
59
else if (strcmp (type, "bool") == 0)
60
return G_TYPE_BOOLEAN;
61
else if (strcmp (type, "array") == 0)
63
else if (strcmp (type, "empty") == 0)
66
return G_TYPE_INVALID;
72
migrate_default_set_value (GValue *value,
75
switch (G_VALUE_TYPE (value))
78
g_value_set_string (value, string);
82
g_value_set_uint (value, strtol (string, NULL, 0));
86
g_value_set_int (value, strtoul (string, NULL, 0));
90
g_value_set_double (value, g_ascii_strtod (string, NULL));
94
g_value_set_boolean (value, strcmp (string, "true") == 0);
103
migrate_default_property_path (ConfigParser *parser)
108
path = g_string_new (NULL);
110
for (li = parser->path; li != NULL; li = li->next)
112
g_string_append_c (path, '/');
113
g_string_append (path, (const gchar *) li->data);
116
return g_string_free (path, FALSE);
122
migrate_default_start_element_handler (GMarkupParseContext *context,
123
const gchar *element_name,
124
const gchar **attribute_names,
125
const gchar **attribute_values,
129
ConfigParser *parser = user_data;
131
const gchar *channel_name;
132
const gchar *prop_name, *prop_value, *prop_type;
135
GValue value = { 0, };
136
const gchar *value_value, *value_type;
139
if (strcmp (element_name, "channel") == 0)
143
if (G_LIKELY (attribute_names != NULL))
145
for (i = 0; attribute_names[i] != NULL; i++)
147
if (strcmp (attribute_names[i], "name") == 0)
149
channel_name = attribute_values[i];
151
/* this is an xfce4-panel workaround to make it work
152
* with the custom channel names */
153
channel_name = XFCE_PANEL_CHANNEL_NAME;
158
if (channel_name != NULL)
160
/* open the xfconf channel */
161
parser->channel = xfconf_channel_new (channel_name);
165
g_set_error_literal (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
166
"The channel element has no name attribute");
169
else if (strcmp (element_name, "property") == 0)
175
if (G_LIKELY (attribute_names != NULL))
177
for (i = 0; attribute_names[i] != NULL; i++)
179
if (strcmp (attribute_names[i], "name") == 0)
180
prop_name = attribute_values[i];
181
else if (strcmp (attribute_names[i], "value") == 0)
182
prop_value = attribute_values[i];
183
else if (strcmp (attribute_names[i], "type") == 0)
184
prop_type = attribute_values[i];
188
if (prop_name != NULL && prop_type != NULL)
190
type = migrate_default_gtype_from_string (prop_type);
192
parser->path = g_slist_append (parser->path, g_strdup (prop_name));
194
if (type == G_TYPE_INVALID)
196
g_set_error (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
197
"Property \"%s\" has invalid type \"%s\"",
198
prop_name, prop_type);
200
if (type == G_TYPE_BOXED)
202
parser->array = g_ptr_array_new ();
204
else if (type != G_TYPE_NONE && prop_value != NULL)
206
g_value_init (&value, type);
207
migrate_default_set_value (&value, prop_value);
209
prop_path = migrate_default_property_path (parser);
210
xfconf_channel_set_property (parser->channel, prop_path, &value);
213
g_value_unset (&value);
218
g_set_error (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
219
"Found property without name (%s), type (%s) or value (%s)",
220
prop_name, prop_type, prop_value);
223
else if (strcmp (element_name, "value") == 0)
225
if (parser->array != NULL)
230
if (G_LIKELY (attribute_names != NULL))
232
for (i = 0; attribute_names[i] != NULL; i++)
234
if (strcmp (attribute_names[i], "type") == 0)
235
value_type = attribute_values[i];
236
else if (strcmp (attribute_names[i], "value") == 0)
237
value_value = attribute_values[i];
241
if (value_type != NULL && value_value != NULL)
243
type = migrate_default_gtype_from_string (value_type);
245
if (type != G_TYPE_INVALID && type != G_TYPE_NONE && type != G_TYPE_BOXED)
247
value2 = g_new0 (GValue, 1);
248
g_value_init (value2, type);
250
migrate_default_set_value (value2, value_value);
252
g_ptr_array_add (parser->array, value2);
256
g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
257
"Found value has unknown type \"%s\"", value_type);
262
g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
263
"Found value element with missing type (%s) or value (%s)",
264
value_type, value_value);
269
g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
270
"Found value element without an array property");
275
g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
276
"Unknown start element \"%s\"", element_name);
283
migrate_default_end_element_handler (GMarkupParseContext *context,
284
const gchar *element_name,
288
ConfigParser *parser = user_data;
292
if (strcmp (element_name, "channel") == 0)
294
if (G_LIKELY (parser->channel != NULL))
296
g_object_unref (G_OBJECT (parser->channel));
297
parser->channel = NULL;
300
if (parser->path != NULL)
302
g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
303
"Property path still contains items");
306
else if (strcmp (element_name, "property") == 0)
308
if (parser->array != NULL)
310
prop_path = migrate_default_property_path (parser);
311
xfconf_channel_set_arrayv (parser->channel, prop_path, parser->array);
314
xfconf_array_free (parser->array);
315
parser->array = NULL;
318
li = g_slist_last (parser->path);
322
parser->path = g_slist_delete_link (parser->path, li);
326
g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
327
"Element could no be popped from the path");
330
else if (strcmp (element_name, "value") == 0)
336
g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
337
"Unknown end element \"%s\"", element_name);
343
static GMarkupParser markup_parser =
345
migrate_default_start_element_handler,
346
migrate_default_end_element_handler,
355
migrate_default (const gchar *filename,
360
GMarkupParseContext *context;
361
ConfigParser *parser;
362
gboolean succeed = FALSE;
364
g_return_val_if_fail (filename != NULL, FALSE);
365
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
367
if (!g_file_get_contents (filename, &contents, &length, error))
370
parser = g_slice_new0 (ConfigParser);
373
context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
375
if (g_markup_parse_context_parse (context, contents, length, error))
377
/* check if the entire file is parsed */
378
if (g_markup_parse_context_end_parse (context, error))
383
g_markup_parse_context_free (context);
384
g_slice_free (ConfigParser, parser);