2008-04-17 Jens Granseuer <jensgr@gmx.net> Patch by: Lincoln de Sousa <lincoln@minaslivre.org> * gnome-wp-xml.c (gnome_wp_file_changed), (gnome_wp_xml_add_monitor), (gnome_wp_xml_load_from_dir), (gnome_wp_xml_load_list): replace gnome-vfs by gio (part of bug #524401) svn path=/trunk/; revision=8656
449 lines
13 KiB
C
449 lines
13 KiB
C
/*
|
|
* Authors: Rodney Dawes <dobey@ximian.com>
|
|
*
|
|
* Copyright 2003-2006 Novell, Inc. (www.novell.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of version 2 of the GNU General Public License
|
|
* as published by the Free Software Foundation
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
#include "appearance.h"
|
|
#include "gnome-wp-item.h"
|
|
#include <gio/gio.h>
|
|
#include <string.h>
|
|
#include <libxml/parser.h>
|
|
|
|
static gboolean gnome_wp_xml_get_bool (const xmlNode * parent,
|
|
const gchar * prop_name) {
|
|
xmlChar * prop;
|
|
gboolean ret_val = FALSE;
|
|
|
|
g_return_val_if_fail (parent != NULL, FALSE);
|
|
g_return_val_if_fail (prop_name != NULL, FALSE);
|
|
|
|
prop = xmlGetProp ((xmlNode *) parent, (xmlChar*)prop_name);
|
|
if (prop != NULL) {
|
|
if (!g_strcasecmp ((gchar *)prop, "true") || !g_strcasecmp ((gchar *)prop, "1")) {
|
|
ret_val = TRUE;
|
|
} else {
|
|
ret_val = FALSE;
|
|
}
|
|
g_free (prop);
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
static void gnome_wp_xml_set_bool (const xmlNode * parent,
|
|
const xmlChar * prop_name, gboolean value) {
|
|
g_return_if_fail (parent != NULL);
|
|
g_return_if_fail (prop_name != NULL);
|
|
|
|
if (value) {
|
|
xmlSetProp ((xmlNode *) parent, prop_name, (xmlChar *)"true");
|
|
} else {
|
|
xmlSetProp ((xmlNode *) parent, prop_name, (xmlChar *)"false");
|
|
}
|
|
}
|
|
|
|
static void gnome_wp_load_legacy (AppearanceData *data) {
|
|
FILE * fp;
|
|
gchar * foo, * filename;
|
|
|
|
filename = g_build_filename (g_get_home_dir (), ".gnome2",
|
|
"wallpapers.list", NULL);
|
|
|
|
if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
|
|
if ((fp = fopen (filename, "r")) != NULL) {
|
|
foo = (gchar *) g_malloc (sizeof (gchar) * 4096);
|
|
while (fgets (foo, 4096, fp)) {
|
|
GnomeWPItem * item;
|
|
|
|
if (foo[strlen (foo) - 1] == '\n') {
|
|
foo[strlen (foo) - 1] = '\0';
|
|
}
|
|
|
|
item = g_hash_table_lookup (data->wp_hash, foo);
|
|
if (item != NULL) {
|
|
continue;
|
|
}
|
|
|
|
if (!g_file_test (foo, G_FILE_TEST_EXISTS)) {
|
|
continue;
|
|
}
|
|
|
|
item = gnome_wp_item_new (foo, data->wp_hash, data->thumb_factory);
|
|
if (item != NULL && item->fileinfo == NULL) {
|
|
gnome_wp_item_free (item);
|
|
}
|
|
}
|
|
fclose (fp);
|
|
g_free (foo);
|
|
}
|
|
}
|
|
|
|
g_free (filename);
|
|
}
|
|
|
|
static void gnome_wp_xml_load_xml (AppearanceData *data,
|
|
const gchar * filename) {
|
|
xmlDoc * wplist;
|
|
xmlNode * root, * list, * wpa;
|
|
xmlChar * nodelang;
|
|
const gchar * const * syslangs;
|
|
GdkColor color1, color2;
|
|
gint i;
|
|
|
|
wplist = xmlParseFile (filename);
|
|
|
|
if (!wplist)
|
|
return;
|
|
|
|
syslangs = g_get_language_names ();
|
|
|
|
root = xmlDocGetRootElement (wplist);
|
|
|
|
for (list = root->children; list != NULL; list = list->next) {
|
|
if (!strcmp ((gchar *)list->name, "wallpaper")) {
|
|
GnomeWPItem * wp;
|
|
gchar *pcolor = NULL, *scolor = NULL;
|
|
gchar *s;
|
|
gboolean have_scale = FALSE, have_shade = FALSE;
|
|
|
|
wp = g_new0 (GnomeWPItem, 1);
|
|
|
|
wp->deleted = gnome_wp_xml_get_bool (list, "deleted");
|
|
|
|
for (wpa = list->children; wpa != NULL; wpa = wpa->next) {
|
|
if (!strcmp ((gchar *)wpa->name, "filename")) {
|
|
if (wpa->last != NULL && wpa->last->content != NULL) {
|
|
const char * none = "(none)";
|
|
gchar *content = g_strstrip ((gchar *)wpa->last->content);
|
|
|
|
if (!strcmp (content, none))
|
|
wp->filename = g_strdup (content);
|
|
else if (g_utf8_validate (content, -1, NULL) &&
|
|
g_file_test (content, G_FILE_TEST_EXISTS))
|
|
wp->filename = g_strdup (content);
|
|
else
|
|
wp->filename = g_filename_from_utf8 (content, -1, NULL, NULL, NULL);
|
|
} else {
|
|
break;
|
|
}
|
|
} else if (!strcmp ((gchar *)wpa->name, "name")) {
|
|
if (wpa->last != NULL && wpa->last->content != NULL) {
|
|
nodelang = xmlNodeGetLang (wpa->last);
|
|
|
|
if (wp->name == NULL && nodelang == NULL) {
|
|
wp->name = g_strdup (g_strstrip ((gchar *)wpa->last->content));
|
|
} else {
|
|
for (i = 0; syslangs[i] != NULL; i++) {
|
|
if (!strcmp (syslangs[i], (gchar *)nodelang)) {
|
|
g_free (wp->name);
|
|
wp->name = g_strdup (g_strstrip ((gchar *)wpa->last->content));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
xmlFree (nodelang);
|
|
} else {
|
|
break;
|
|
}
|
|
} else if (!strcmp ((gchar *)wpa->name, "options")) {
|
|
if (wpa->last != NULL) {
|
|
wp->options = wp_item_string_to_option (g_strstrip ((gchar *)wpa->last->content));
|
|
have_scale = TRUE;
|
|
}
|
|
} else if (!strcmp ((gchar *)wpa->name, "shade_type")) {
|
|
if (wpa->last != NULL) {
|
|
wp->shade_type = wp_item_string_to_shading (g_strstrip ((gchar *)wpa->last->content));
|
|
have_shade = TRUE;
|
|
}
|
|
} else if (!strcmp ((gchar *)wpa->name, "pcolor")) {
|
|
if (wpa->last != NULL) {
|
|
pcolor = g_strdup (g_strstrip ((gchar *)wpa->last->content));
|
|
}
|
|
} else if (!strcmp ((gchar *)wpa->name, "scolor")) {
|
|
if (wpa->last != NULL) {
|
|
scolor = g_strdup (g_strstrip ((gchar *)wpa->last->content));
|
|
}
|
|
} else if (!strcmp ((gchar *)wpa->name, "text")) {
|
|
/* Do nothing here, libxml2 is being weird */
|
|
} else {
|
|
g_warning ("Unknown Tag: %s\n", wpa->name);
|
|
}
|
|
}
|
|
|
|
/* Make sure we don't already have this one and that filename exists */
|
|
if (wp->filename == NULL ||
|
|
g_hash_table_lookup (data->wp_hash, wp->filename) != NULL) {
|
|
|
|
gnome_wp_item_free (wp);
|
|
g_free (pcolor);
|
|
g_free (scolor);
|
|
continue;
|
|
}
|
|
|
|
/* Verify the colors and alloc some GdkColors here */
|
|
if (!have_scale) {
|
|
s = gconf_client_get_string (data->client, WP_OPTIONS_KEY, NULL);
|
|
wp->options = wp_item_string_to_option (s);
|
|
g_free (s);
|
|
}
|
|
|
|
if (!have_shade) {
|
|
s = gconf_client_get_string (data->client, WP_SHADING_KEY, NULL);
|
|
wp->shade_type = wp_item_string_to_shading (s);
|
|
g_free (s);
|
|
}
|
|
|
|
if (pcolor == NULL) {
|
|
pcolor = gconf_client_get_string (data->client,
|
|
WP_PCOLOR_KEY, NULL);
|
|
}
|
|
if (scolor == NULL) {
|
|
scolor = gconf_client_get_string (data->client,
|
|
WP_SCOLOR_KEY, NULL);
|
|
}
|
|
gdk_color_parse (pcolor, &color1);
|
|
gdk_color_parse (scolor, &color2);
|
|
g_free (pcolor);
|
|
g_free (scolor);
|
|
|
|
wp->pcolor = gdk_color_copy (&color1);
|
|
wp->scolor = gdk_color_copy (&color2);
|
|
|
|
if ((wp->filename != NULL &&
|
|
g_file_test (wp->filename, G_FILE_TEST_EXISTS)) ||
|
|
!strcmp (wp->filename, "(none)")) {
|
|
wp->fileinfo = gnome_wp_info_new (wp->filename, data->thumb_factory);
|
|
|
|
if (wp->name == NULL || !strcmp (wp->filename, "(none)")) {
|
|
g_free (wp->name);
|
|
wp->name = g_strdup (wp->fileinfo->name);
|
|
}
|
|
|
|
gnome_wp_item_update_description (wp);
|
|
g_hash_table_insert (data->wp_hash, wp->filename, wp);
|
|
gnome_wp_item_ensure_gnome_bg (wp);
|
|
} else {
|
|
gnome_wp_item_free (wp);
|
|
wp = NULL;
|
|
}
|
|
}
|
|
}
|
|
xmlFreeDoc (wplist);
|
|
}
|
|
|
|
static void gnome_wp_file_changed (GFileMonitor *monitor,
|
|
GFile *file,
|
|
GFile *other_file,
|
|
GFileMonitorEvent event_type,
|
|
AppearanceData *data) {
|
|
gchar * filename;
|
|
|
|
switch (event_type) {
|
|
case G_FILE_MONITOR_EVENT_CHANGED:
|
|
case G_FILE_MONITOR_EVENT_CREATED:
|
|
filename = g_file_get_path (file);
|
|
gnome_wp_xml_load_xml (data, filename);
|
|
g_free (filename);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void gnome_wp_xml_add_monitor (GFile *directory,
|
|
AppearanceData *data) {
|
|
GFileMonitor *monitor;
|
|
GError *error = NULL;
|
|
|
|
monitor = g_file_monitor_directory (directory,
|
|
G_FILE_MONITOR_NONE,
|
|
NULL,
|
|
&error);
|
|
if (error != NULL) {
|
|
gchar *path;
|
|
|
|
path = g_file_get_parse_name (directory);
|
|
g_warning ("Unable to monitor directory %s: %s",
|
|
path, error->message);
|
|
g_error_free (error);
|
|
g_free (path);
|
|
return;
|
|
}
|
|
|
|
g_signal_connect (monitor, "changed",
|
|
G_CALLBACK (gnome_wp_file_changed),
|
|
data);
|
|
}
|
|
|
|
static void gnome_wp_xml_load_from_dir (const gchar *path,
|
|
AppearanceData *data) {
|
|
GFile *directory;
|
|
GFileEnumerator *enumerator;
|
|
GError *error = NULL;
|
|
GFileInfo *info;
|
|
|
|
if (!g_file_test (path, G_FILE_TEST_IS_DIR)) {
|
|
return;
|
|
}
|
|
|
|
directory = g_file_new_for_path (path);
|
|
enumerator = g_file_enumerate_children (directory,
|
|
G_FILE_ATTRIBUTE_STANDARD_NAME,
|
|
G_FILE_QUERY_INFO_NONE,
|
|
NULL,
|
|
&error);
|
|
if (error != NULL) {
|
|
g_warning ("Unable to check directory %s: %s", path, error->message);
|
|
g_error_free (error);
|
|
g_object_unref (directory);
|
|
return;
|
|
}
|
|
|
|
while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL))) {
|
|
const gchar *filename;
|
|
gchar *fullpath;
|
|
|
|
filename = g_file_info_get_name (info);
|
|
fullpath = g_build_filename (path, filename, NULL);
|
|
g_object_unref (info);
|
|
|
|
gnome_wp_xml_load_xml (data, fullpath);
|
|
g_free (fullpath);
|
|
}
|
|
g_file_enumerator_close (enumerator, NULL, NULL);
|
|
|
|
gnome_wp_xml_add_monitor (directory, data);
|
|
|
|
g_object_unref (directory);
|
|
}
|
|
|
|
void gnome_wp_xml_load_list (AppearanceData *data) {
|
|
const gchar * xdgdirslist;
|
|
gchar * wpdbfile;
|
|
gchar ** xdgdirs;
|
|
gint i;
|
|
|
|
wpdbfile = g_build_filename (g_get_home_dir (),
|
|
".gnome2",
|
|
"backgrounds.xml",
|
|
NULL);
|
|
|
|
if (g_file_test (wpdbfile, G_FILE_TEST_EXISTS)) {
|
|
gnome_wp_xml_load_xml (data, wpdbfile);
|
|
} else {
|
|
g_free (wpdbfile);
|
|
wpdbfile = g_build_filename (g_get_home_dir (),
|
|
".gnome2",
|
|
"wp-list.xml",
|
|
NULL);
|
|
if (g_file_test (wpdbfile, G_FILE_TEST_EXISTS)) {
|
|
gnome_wp_xml_load_xml (data, wpdbfile);
|
|
}
|
|
}
|
|
g_free (wpdbfile);
|
|
|
|
xdgdirslist = g_getenv ("XDG_DATA_DIRS");
|
|
if (xdgdirslist == NULL || strcmp (xdgdirslist, "") == 0)
|
|
xdgdirslist = "/usr/local/share:/usr/share";
|
|
|
|
xdgdirs = g_strsplit (xdgdirslist, ":", -1);
|
|
for (i = 0; xdgdirs && xdgdirs[i]; i++) {
|
|
gchar * datadir;
|
|
|
|
datadir = g_build_filename (xdgdirs[i], "gnome-background-properties",
|
|
NULL);
|
|
gnome_wp_xml_load_from_dir (datadir, data);
|
|
g_free (datadir);
|
|
}
|
|
g_strfreev (xdgdirs);
|
|
|
|
gnome_wp_xml_load_from_dir (WALLPAPER_DATADIR, data);
|
|
|
|
gnome_wp_load_legacy (data);
|
|
}
|
|
|
|
static void gnome_wp_list_flatten (const gchar * key, GnomeWPItem * item,
|
|
GSList ** list) {
|
|
g_return_if_fail (key != NULL);
|
|
g_return_if_fail (item != NULL);
|
|
|
|
*list = g_slist_prepend (*list, item);
|
|
}
|
|
|
|
void gnome_wp_xml_save_list (AppearanceData *data) {
|
|
xmlDoc * wplist;
|
|
xmlNode * root, * wallpaper, * item;
|
|
GSList * list = NULL;
|
|
gchar * wpfile;
|
|
|
|
g_hash_table_foreach (data->wp_hash,
|
|
(GHFunc) gnome_wp_list_flatten, &list);
|
|
g_hash_table_destroy (data->wp_hash);
|
|
list = g_slist_reverse (list);
|
|
|
|
wpfile = g_build_filename (g_get_home_dir (),
|
|
"/.gnome2",
|
|
"backgrounds.xml",
|
|
NULL);
|
|
|
|
xmlKeepBlanksDefault (0);
|
|
|
|
wplist = xmlNewDoc ((xmlChar *)"1.0");
|
|
xmlCreateIntSubset (wplist, (xmlChar *)"wallpapers", NULL, (xmlChar *)"gnome-wp-list.dtd");
|
|
root = xmlNewNode (NULL, (xmlChar *)"wallpapers");
|
|
xmlDocSetRootElement (wplist, root);
|
|
|
|
while (list != NULL) {
|
|
GnomeWPItem * wpitem = list->data;
|
|
const char * none = "(none)";
|
|
gchar * filename;
|
|
const gchar * scale, * shade;
|
|
gchar * pcolor, * scolor;
|
|
|
|
if (!strcmp (wpitem->filename, none) ||
|
|
(g_utf8_validate (wpitem->filename, -1, NULL) &&
|
|
g_file_test (wpitem->filename, G_FILE_TEST_EXISTS)))
|
|
filename = g_strdup (wpitem->filename);
|
|
else
|
|
filename = g_filename_to_utf8 (wpitem->filename, -1, NULL, NULL, NULL);
|
|
|
|
pcolor = gdk_color_to_string (wpitem->pcolor);
|
|
scolor = gdk_color_to_string (wpitem->scolor);
|
|
scale = wp_item_option_to_string (wpitem->options);
|
|
shade = wp_item_shading_to_string (wpitem->shade_type);
|
|
|
|
wallpaper = xmlNewChild (root, NULL, (xmlChar *)"wallpaper", NULL);
|
|
gnome_wp_xml_set_bool (wallpaper, (xmlChar *)"deleted", wpitem->deleted);
|
|
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"name", (xmlChar *)wpitem->name);
|
|
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"filename", (xmlChar *)filename);
|
|
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"options", (xmlChar *)scale);
|
|
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"shade_type", (xmlChar *)shade);
|
|
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"pcolor", (xmlChar *)pcolor);
|
|
item = xmlNewTextChild (wallpaper, NULL, (xmlChar *)"scolor", (xmlChar *)scolor);
|
|
g_free (pcolor);
|
|
g_free (scolor);
|
|
g_free (filename);
|
|
|
|
list = g_slist_delete_link (list, list);
|
|
gnome_wp_item_free (wpitem);
|
|
}
|
|
xmlSaveFormatFile (wpfile, wplist, 1);
|
|
xmlFreeDoc (wplist);
|
|
g_free (wpfile);
|
|
}
|