2
* Authors: Rodney Dawes <dobey@ximian.com>
4
* Copyright 2003-2006 Novell, Inc. (www.novell.com)
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of version 2 of the GNU General Public License
8
* as published by the Free Software Foundation
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
21
#include "appearance.h"
22
#include "gnome-wp-item.h"
25
#include <libxml/parser.h>
27
static gboolean gnome_wp_xml_get_bool (const xmlNode * parent,
28
const gchar * prop_name) {
30
gboolean ret_val = FALSE;
32
g_return_val_if_fail (parent != NULL, FALSE);
33
g_return_val_if_fail (prop_name != NULL, FALSE);
35
prop = xmlGetProp ((xmlNode *) parent, (xmlChar*)prop_name);
37
if (!g_ascii_strcasecmp ((gchar *)prop, "true") || !g_ascii_strcasecmp ((gchar *)prop, "1")) {
48
static void gnome_wp_xml_set_bool (const xmlNode * parent,
49
const xmlChar * prop_name, gboolean value) {
50
g_return_if_fail (parent != NULL);
51
g_return_if_fail (prop_name != NULL);
54
xmlSetProp ((xmlNode *) parent, prop_name, (xmlChar *)"true");
56
xmlSetProp ((xmlNode *) parent, prop_name, (xmlChar *)"false");
60
static void gnome_wp_load_legacy (AppearanceData *data) {
62
gchar * foo, * filename;
64
filename = g_build_filename (g_get_home_dir (), ".gnome2",
65
"wallpapers.list", NULL);
67
if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
68
if ((fp = fopen (filename, "r")) != NULL) {
69
foo = (gchar *) g_malloc (sizeof (gchar) * 4096);
70
while (fgets (foo, 4096, fp)) {
73
if (foo[strlen (foo) - 1] == '\n') {
74
foo[strlen (foo) - 1] = '\0';
77
item = g_hash_table_lookup (data->wp_hash, foo);
82
if (!g_file_test (foo, G_FILE_TEST_EXISTS)) {
86
item = gnome_wp_item_new (foo, data->wp_hash, data->thumb_factory);
87
if (item != NULL && item->fileinfo == NULL) {
88
gnome_wp_item_free (item);
99
static void gnome_wp_xml_load_xml (AppearanceData *data,
100
const gchar * filename) {
102
xmlNode * root, * list, * wpa;
104
const gchar * const * syslangs;
105
GdkColor color1, color2;
108
wplist = xmlParseFile (filename);
113
syslangs = g_get_language_names ();
115
root = xmlDocGetRootElement (wplist);
117
for (list = root->children; list != NULL; list = list->next) {
118
if (!strcmp ((gchar *)list->name, "wallpaper")) {
120
gchar *pcolor = NULL, *scolor = NULL;
122
gboolean have_scale = FALSE, have_shade = FALSE;
124
wp = g_new0 (GnomeWPItem, 1);
126
wp->deleted = gnome_wp_xml_get_bool (list, "deleted");
128
for (wpa = list->children; wpa != NULL; wpa = wpa->next) {
129
if (wpa->type == XML_COMMENT_NODE) {
131
} else if (!strcmp ((gchar *)wpa->name, "filename")) {
132
if (wpa->last != NULL && wpa->last->content != NULL) {
133
const char * none = "(none)";
134
gchar *content = g_strstrip ((gchar *)wpa->last->content);
136
if (!strcmp (content, none))
137
wp->filename = g_strdup (content);
138
else if (g_utf8_validate (content, -1, NULL) &&
139
g_file_test (content, G_FILE_TEST_EXISTS))
140
wp->filename = g_strdup (content);
142
wp->filename = g_filename_from_utf8 (content, -1, NULL, NULL, NULL);
146
} else if (!strcmp ((gchar *)wpa->name, "name")) {
147
if (wpa->last != NULL && wpa->last->content != NULL) {
148
nodelang = xmlNodeGetLang (wpa->last);
150
if (wp->name == NULL && nodelang == NULL) {
151
wp->name = g_strdup (g_strstrip ((gchar *)wpa->last->content));
153
for (i = 0; syslangs[i] != NULL; i++) {
154
if (!strcmp (syslangs[i], (gchar *)nodelang)) {
156
wp->name = g_strdup (g_strstrip ((gchar *)wpa->last->content));
166
} else if (!strcmp ((gchar *)wpa->name, "options")) {
167
if (wpa->last != NULL) {
168
wp->options = wp_item_string_to_option (g_strstrip ((gchar *)wpa->last->content));
171
} else if (!strcmp ((gchar *)wpa->name, "shade_type")) {
172
if (wpa->last != NULL) {
173
wp->shade_type = wp_item_string_to_shading (g_strstrip ((gchar *)wpa->last->content));
176
} else if (!strcmp ((gchar *)wpa->name, "pcolor")) {
177
if (wpa->last != NULL) {
178
pcolor = g_strdup (g_strstrip ((gchar *)wpa->last->content));
180
} else if (!strcmp ((gchar *)wpa->name, "scolor")) {
181
if (wpa->last != NULL) {
182
scolor = g_strdup (g_strstrip ((gchar *)wpa->last->content));
184
} else if (!strcmp ((gchar *)wpa->name, "text")) {
185
/* Do nothing here, libxml2 is being weird */
187
g_warning ("Unknown Tag: %s", wpa->name);
191
/* Make sure we don't already have this one and that filename exists */
192
if (wp->filename == NULL ||
193
g_hash_table_lookup (data->wp_hash, wp->filename) != NULL) {
195
gnome_wp_item_free (wp);
201
/* Verify the colors and alloc some GdkColors here */
203
s = gconf_client_get_string (data->client, WP_OPTIONS_KEY, NULL);
204
wp->options = wp_item_string_to_option (s);
209
s = gconf_client_get_string (data->client, WP_SHADING_KEY, NULL);
210
wp->shade_type = wp_item_string_to_shading (s);
214
if (pcolor == NULL) {
215
pcolor = gconf_client_get_string (data->client,
216
WP_PCOLOR_KEY, NULL);
218
if (scolor == NULL) {
219
scolor = gconf_client_get_string (data->client,
220
WP_SCOLOR_KEY, NULL);
222
gdk_color_parse (pcolor, &color1);
223
gdk_color_parse (scolor, &color2);
227
wp->pcolor = gdk_color_copy (&color1);
228
wp->scolor = gdk_color_copy (&color2);
230
if ((wp->filename != NULL &&
231
g_file_test (wp->filename, G_FILE_TEST_EXISTS)) ||
232
!strcmp (wp->filename, "(none)")) {
233
wp->fileinfo = gnome_wp_info_new (wp->filename, data->thumb_factory);
235
if (wp->name == NULL || !strcmp (wp->filename, "(none)")) {
237
wp->name = g_strdup (wp->fileinfo->name);
240
gnome_wp_item_ensure_gnome_bg (wp);
241
gnome_wp_item_update_description (wp);
242
g_hash_table_insert (data->wp_hash, wp->filename, wp);
244
gnome_wp_item_free (wp);
252
static void gnome_wp_file_changed (GFileMonitor *monitor,
255
GFileMonitorEvent event_type,
256
AppearanceData *data) {
259
switch (event_type) {
260
case G_FILE_MONITOR_EVENT_CHANGED:
261
case G_FILE_MONITOR_EVENT_CREATED:
262
filename = g_file_get_path (file);
263
gnome_wp_xml_load_xml (data, filename);
271
static void gnome_wp_xml_add_monitor (GFile *directory,
272
AppearanceData *data) {
273
GFileMonitor *monitor;
274
GError *error = NULL;
276
monitor = g_file_monitor_directory (directory,
283
path = g_file_get_parse_name (directory);
284
g_warning ("Unable to monitor directory %s: %s",
285
path, error->message);
286
g_error_free (error);
291
g_signal_connect (monitor, "changed",
292
G_CALLBACK (gnome_wp_file_changed),
296
static void gnome_wp_xml_load_from_dir (const gchar *path,
297
AppearanceData *data) {
299
GFileEnumerator *enumerator;
300
GError *error = NULL;
303
if (!g_file_test (path, G_FILE_TEST_IS_DIR)) {
307
directory = g_file_new_for_path (path);
308
enumerator = g_file_enumerate_children (directory,
309
G_FILE_ATTRIBUTE_STANDARD_NAME,
310
G_FILE_QUERY_INFO_NONE,
314
g_warning ("Unable to check directory %s: %s", path, error->message);
315
g_error_free (error);
316
g_object_unref (directory);
320
while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL))) {
321
const gchar *filename;
324
filename = g_file_info_get_name (info);
325
fullpath = g_build_filename (path, filename, NULL);
326
g_object_unref (info);
328
gnome_wp_xml_load_xml (data, fullpath);
331
g_file_enumerator_close (enumerator, NULL, NULL);
333
gnome_wp_xml_add_monitor (directory, data);
335
g_object_unref (directory);
338
void gnome_wp_xml_load_list (AppearanceData *data) {
339
const char * const *system_data_dirs;
344
wpdbfile = g_build_filename (g_get_home_dir (),
349
if (g_file_test (wpdbfile, G_FILE_TEST_EXISTS)) {
350
gnome_wp_xml_load_xml (data, wpdbfile);
353
wpdbfile = g_build_filename (g_get_home_dir (),
357
if (g_file_test (wpdbfile, G_FILE_TEST_EXISTS)) {
358
gnome_wp_xml_load_xml (data, wpdbfile);
363
datadir = g_build_filename (g_get_user_data_dir (),
364
"gnome-background-properties",
366
gnome_wp_xml_load_from_dir (datadir, data);
369
system_data_dirs = g_get_system_data_dirs ();
370
for (i = 0; system_data_dirs[i]; i++) {
371
datadir = g_build_filename (system_data_dirs[i],
372
"gnome-background-properties",
374
gnome_wp_xml_load_from_dir (datadir, data);
378
gnome_wp_xml_load_from_dir (WALLPAPER_DATADIR, data);
380
gnome_wp_load_legacy (data);
383
static void gnome_wp_list_flatten (const gchar * key, GnomeWPItem * item,
385
g_return_if_fail (key != NULL);
386
g_return_if_fail (item != NULL);
388
*list = g_slist_prepend (*list, item);
391
void gnome_wp_xml_save_list (AppearanceData *data) {
393
xmlNode * root, * wallpaper, * item;
394
GSList * list = NULL;
397
g_hash_table_foreach (data->wp_hash,
398
(GHFunc) gnome_wp_list_flatten, &list);
399
g_hash_table_destroy (data->wp_hash);
400
list = g_slist_reverse (list);
402
wpfile = g_build_filename (g_get_home_dir (),
407
xmlKeepBlanksDefault (0);
409
wplist = xmlNewDoc ((xmlChar *)"1.0");
410
xmlCreateIntSubset (wplist, (xmlChar *)"wallpapers", NULL, (xmlChar *)"gnome-wp-list.dtd");
411
root = xmlNewNode (NULL, (xmlChar *)"wallpapers");
412
xmlDocSetRootElement (wplist, root);
414
while (list != NULL) {
415
GnomeWPItem * wpitem = list->data;
416
const char * none = "(none)";
418
const gchar * scale, * shade;
419
gchar * pcolor, * scolor;
421
if (!strcmp (wpitem->filename, none) ||
422
(g_utf8_validate (wpitem->filename, -1, NULL) &&
423
g_file_test (wpitem->filename, G_FILE_TEST_EXISTS)))
424
filename = g_strdup (wpitem->filename);
426
filename = g_filename_to_utf8 (wpitem->filename, -1, NULL, NULL, NULL);
428
pcolor = gdk_color_to_string (wpitem->pcolor);
429
scolor = gdk_color_to_string (wpitem->scolor);
430
scale = wp_item_option_to_string (wpitem->options);
431
shade = wp_item_shading_to_string (wpitem->shade_type);
433
wallpaper = xmlNewChild (root, NULL, (xmlChar *)"wallpaper", NULL);
434
gnome_wp_xml_set_bool (wallpaper, (xmlChar *)"deleted", wpitem->deleted);
435
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"name", (xmlChar *)wpitem->name);
436
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"filename", (xmlChar *)filename);
437
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"options", (xmlChar *)scale);
438
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"shade_type", (xmlChar *)shade);
439
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"pcolor", (xmlChar *)pcolor);
440
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"scolor", (xmlChar *)scolor);
445
list = g_slist_delete_link (list, list);
446
gnome_wp_item_free (wpitem);
448
xmlSaveFormatFile (wpfile, wplist, 1);