[gnome-control-center/wip/background] backgrounds: Add "Wallpapers" source
- From: Thomas Wood <thos src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/background] backgrounds: Add "Wallpapers" source
- Date: Wed, 7 Jul 2010 17:12:39 +0000 (UTC)
commit a096ecee41de67794e60f17741a7802a19d8b44b
Author: Thomas Wood <thomas wood intel com>
Date: Wed Jul 7 18:12:15 2010 +0100
backgrounds: Add "Wallpapers" source
Add the "Wallpapers" source, that provides images from collections
installed on the system.
panels/background-screensaver/Makefile.am | 6 +-
.../background-screensaver.ui | 29 ++-
.../cc-background-screensaver-panel.c | 262 +++++++++++-
panels/background-screensaver/gnome-wp-info.c | 87 ++++
panels/background-screensaver/gnome-wp-info.h | 45 ++
panels/background-screensaver/gnome-wp-item.c | 307 +++++++++++++
panels/background-screensaver/gnome-wp-item.h | 90 ++++
panels/background-screensaver/gnome-wp-xml.c | 449 ++++++++++++++++++++
panels/background-screensaver/gnome-wp-xml.h | 43 ++
9 files changed, 1304 insertions(+), 14 deletions(-)
---
diff --git a/panels/background-screensaver/Makefile.am b/panels/background-screensaver/Makefile.am
index 65e7d37..15a9cd0 100644
--- a/panels/background-screensaver/Makefile.am
+++ b/panels/background-screensaver/Makefile.am
@@ -13,6 +13,7 @@ INCLUDES = \
-DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
-DDATADIR="\"$(uidir)\"" \
+ -DGNOME_DESKTOP_USE_UNSTABLE_API \
$(NULL)
ccpanelsdir = $(PANELS_DIR)
@@ -21,7 +22,10 @@ ccpanels_LTLIBRARIES = libbackground-screensaver.la
libbackground_screensaver_la_SOURCES = \
background-screensaver-module.c \
cc-background-screensaver-panel.c \
- cc-background-screensaver-panel.h
+ cc-background-screensaver-panel.h \
+ gnome-wp-info.c gnome-wp-item.c gnome-wp-xml.c \
+ gnome-wp-info.h gnome-wp-item.h gnome-wp-xml.h
+
libbackground_screensaver_la_LIBADD = $(PANEL_LIBS) $(DBUS_LIBS)
libbackground_screensaver_la_LDFLAGS = $(PANEL_LDFLAGS)
diff --git a/panels/background-screensaver/background-screensaver.ui b/panels/background-screensaver/background-screensaver.ui
index 4d85a42..d10b16c 100644
--- a/panels/background-screensaver/background-screensaver.ui
+++ b/panels/background-screensaver/background-screensaver.ui
@@ -2,7 +2,6 @@
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
- <object class="GtkListStore" id="backgrounds-liststore"/>
<object class="GtkListStore" id="style-liststore">
<columns>
<!-- column-name name -->
@@ -24,20 +23,36 @@
<columns>
<!-- column-name source-name -->
<column type="gchararray"/>
+ <!-- column-name source-id -->
+ <column type="guint"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Wallpapers</col>
+ <col id="1">0</col>
</row>
<row>
<col id="0" translatable="yes">Pictures Folder</col>
+ <col id="1">1</col>
</row>
<row>
<col id="0" translatable="yes">Colors</col>
+ <col id="1">2</col>
</row>
</data>
</object>
- <object class="GtkTreeModelFilter" id="wallpapers-filter">
+ <object class="GtkListStore" id="backgrounds-liststore">
+ <columns>
+ <!-- column-name pixbuf -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name data -->
+ <column type="gpointer"/>
+ <!-- column-name source-id -->
+ <column type="guint"/>
+ </columns>
+ </object>
+
+ <object class="GtkTreeModelFilter" id="backgrounds-filter">
<property name="child_model">backgrounds-liststore</property>
</object>
<object class="GtkWindow" id="window1">
@@ -47,6 +62,7 @@
<property name="spacing">12</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="width-request">120</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
@@ -74,6 +90,7 @@
</object>
<packing>
<property name="position">0</property>
+ <property name="expand">False</property>
</packing>
</child>
<child>
@@ -87,7 +104,13 @@
<object class="GtkIconView" id="backgrounds-iconview">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="model">wallpapers-filter</property>
+ <property name="model">backgrounds-filter</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="pixbuf-renderer"/>
+ <attributes>
+ <attribute name="pixbuf">0</attribute>
+ </attributes>
+ </child>
</object>
</child>
</object>
diff --git a/panels/background-screensaver/cc-background-screensaver-panel.c b/panels/background-screensaver/cc-background-screensaver-panel.c
index ec4efcb..fa137e1 100644
--- a/panels/background-screensaver/cc-background-screensaver-panel.c
+++ b/panels/background-screensaver/cc-background-screensaver-panel.c
@@ -21,6 +21,9 @@
#include "cc-background-screensaver-panel.h"
+#include "gnome-wp-xml.h"
+#include "gnome-wp-item.h"
+
G_DEFINE_DYNAMIC_TYPE (CcBackgroundScreensaverPanel, cc_background_screensaver_panel, CC_TYPE_PANEL)
#define BACKGROUND_SCREENSAVER_PANEL_PRIVATE(o) \
@@ -29,8 +32,17 @@ G_DEFINE_DYNAMIC_TYPE (CcBackgroundScreensaverPanel, cc_background_screensaver_p
struct _CcBackgroundScreensaverPanelPrivate
{
GtkBuilder *builder;
+ GnomeWpXml *wp_xml;
+
+ guint selected_source_type;
};
+enum
+{
+ SOURCE_WALLPAPERS,
+ SOURCE_PICTURES,
+ SOURCE_COLORS
+};
static void
cc_background_screensaver_panel_get_property (GObject *object,
@@ -74,7 +86,7 @@ cc_background_screensaver_panel_dispose (GObject *object)
static void
cc_background_screensaver_panel_finalize (GObject *object)
{
- CcBackgroundScreensaverPanelPrivate *priv = CC_BACKGROUND_SCREENSAVER_PANEL (object)->priv;
+ //CcBackgroundScreensaverPanelPrivate *priv = CC_BACKGROUND_SCREENSAVER_PANEL (object)->priv;
G_OBJECT_CLASS (cc_background_screensaver_panel_parent_class)->finalize (object);
}
@@ -98,22 +110,214 @@ cc_background_screensaver_panel_class_finalize (CcBackgroundScreensaverPanelClas
}
+static gboolean
+find_wallpaper (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ GnomeBG *bg = data;
+ GnomeWPItem *item = value;
+
+ return item->bg == bg;
+}
+
+static void
+item_changed_cb (GnomeBG *bg,
+ GnomeWpXml *data)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GnomeWPItem *item;
+
+ item = g_hash_table_find (data->wp_hash, find_wallpaper, bg);
+
+ if (!item)
+ return;
+
+ model = gtk_tree_row_reference_get_model (item->rowref);
+ path = gtk_tree_row_reference_get_path (item->rowref);
+
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ {
+ GdkPixbuf *pixbuf;
+
+ g_signal_handlers_block_by_func (bg, G_CALLBACK (item_changed_cb), data);
+
+ pixbuf = gnome_wp_item_get_thumbnail (item,
+ data->thumb_factory,
+ data->thumb_width,
+ data->thumb_height);
+ if (pixbuf)
+ {
+ gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter,
+ 0, pixbuf, -1);
+ g_object_unref (pixbuf);
+ }
+
+ g_signal_handlers_unblock_by_func (bg, G_CALLBACK (item_changed_cb),
+ data);
+ }
+}
+
+
+
+static void
+load_wallpapers (gchar *key,
+ GnomeWPItem *item,
+ CcBackgroundScreensaverPanelPrivate *priv)
+{
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GdkPixbuf *pixbuf;
+ GtkTreeModel *model;
+
+ if (item->deleted == TRUE)
+ return;
+
+ model = (GtkTreeModel*) gtk_builder_get_object (priv->builder,
+ "backgrounds-liststore");
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+
+ pixbuf = gnome_wp_item_get_thumbnail (item, priv->wp_xml->thumb_factory,
+ priv->wp_xml->thumb_width,
+ priv->wp_xml->thumb_height);
+ gnome_wp_item_update_description (item);
+
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ 0, pixbuf,
+ 1, item,
+ 2, SOURCE_WALLPAPERS,
+ -1);
+
+ if (pixbuf)
+ g_object_unref (pixbuf);
+
+ path = gtk_tree_model_get_path (model, &iter);
+ item->rowref = gtk_tree_row_reference_new (model, path);
+ g_signal_connect (item->bg, "changed", G_CALLBACK (item_changed_cb),
+ priv->wp_xml);
+ gtk_tree_path_free (path);
+}
+
+static gboolean
+sources_filter_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ CcBackgroundScreensaverPanelPrivate *priv)
+{
+ guint type;
+
+ gtk_tree_model_get (model, iter, 2, &type, -1);
+
+ return (type == priv->selected_source_type);
+}
+
+static void
+source_changed_cb (GtkTreeSelection *selection,
+ CcBackgroundScreensaverPanelPrivate *priv)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GtkTreeModelFilter *filter;
+
+ gtk_tree_selection_get_selected (selection, &model, &iter);
+ gtk_tree_model_get (model, &iter, 1, &priv->selected_source_type, -1);
+
+ filter = (GtkTreeModelFilter*) gtk_builder_get_object (priv->builder,
+ "backgrounds-filter");
+ gtk_tree_model_filter_refilter (filter);
+}
+
+
+static void
+backgrounds_changed_cb (GtkIconView *icon_view,
+ CcBackgroundScreensaverPanelPrivate *priv)
+{
+ GtkTreeIter iter;
+ GList *list;
+ GtkTreeModel *model;
+ GnomeWPItem *item;
+ GConfChangeSet *cs;
+ gchar *pcolor, *scolor;
+
+ list = gtk_icon_view_get_selected_items (icon_view);
+
+ if (!list)
+ return;
+
+ model = gtk_icon_view_get_model (icon_view);
+
+ gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) list->data);
+
+ g_list_free (list);
+
+ gtk_tree_model_get (model, &iter, 1, &item, -1);
+
+ cs = gconf_change_set_new ();
+
+ if (!g_strcmp0 (item->filename, "(none)"))
+ {
+ gconf_change_set_set_string (cs, WP_OPTIONS_KEY, "none");
+ gconf_change_set_set_string (cs, WP_FILE_KEY, "");
+ }
+ else
+ {
+ gchar *uri;
+
+ if (g_utf8_validate (item->filename, -1, NULL))
+ uri = g_strdup (item->filename);
+ else
+ uri = g_filename_to_utf8 (item->filename, -1, NULL, NULL, NULL);
+
+ if (uri == NULL)
+ {
+ g_warning ("Failed to convert filename to UTF-8: %s",
+ item->filename);
+ }
+ else
+ {
+ gconf_change_set_set_string (cs, WP_FILE_KEY, uri);
+ g_free (uri);
+ }
+
+ gconf_change_set_set_string (cs, WP_OPTIONS_KEY,
+ wp_item_option_to_string (item->options));
+ }
+
+ gconf_change_set_set_string (cs, WP_SHADING_KEY,
+ wp_item_shading_to_string (item->shade_type));
+
+ pcolor = gdk_color_to_string (item->pcolor);
+ scolor = gdk_color_to_string (item->scolor);
+ gconf_change_set_set_string (cs, WP_PCOLOR_KEY, pcolor);
+ gconf_change_set_set_string (cs, WP_SCOLOR_KEY, scolor);
+ g_free (pcolor);
+ g_free (scolor);
+
+ gconf_client_commit_change_set (priv->wp_xml->client, cs, TRUE, NULL);
+
+ gconf_change_set_unref (cs);
+}
static void
cc_background_screensaver_panel_init (CcBackgroundScreensaverPanel *self)
{
CcBackgroundScreensaverPanelPrivate *priv;
- gchar *objects[] = { "background-screensaver-panel",
- "backgrounds-liststore", "style-liststore", "sources-liststore",
- "wallpapers-filter", NULL };
- GtkWidget *widget;
+ gchar *objects[] = { "backgrounds-liststore", "style-liststore",
+ "sources-liststore", "backgrounds-filter",
+ "background-screensaver-panel", NULL };
GError *err = NULL;
+ GtkWidget *widget;
+ GtkTreeModelFilter *filter;
+ GtkTreeSelection *selection;
priv = self->priv = BACKGROUND_SCREENSAVER_PANEL_PRIVATE (self);
priv->builder = gtk_builder_new ();
- gtk_builder_add_objects_from_file (priv->builder, DATADIR"/background-screensaver.ui",
+ gtk_builder_add_objects_from_file (priv->builder,
+ DATADIR"/background-screensaver.ui",
objects, &err);
if (err)
@@ -124,10 +328,48 @@ cc_background_screensaver_panel_init (CcBackgroundScreensaverPanel *self)
}
- gtk_container_add (GTK_CONTAINER (self),
- GTK_WIDGET (gtk_builder_get_object (priv->builder,
- "background-screensaver-panel")));
- gtk_widget_show_all (self);
+ /* add the top level widget */
+ widget = (GtkWidget*)
+ gtk_builder_get_object (priv->builder, "background-screensaver-panel");
+
+ gtk_container_add (GTK_CONTAINER (self), widget);
+ gtk_widget_show_all (GTK_WIDGET (self));
+
+ /* set up the background sources filter */
+ filter = (GtkTreeModelFilter*) gtk_builder_get_object (priv->builder,
+ "backgrounds-filter");
+ gtk_tree_model_filter_set_visible_func (filter,
+ (GtkTreeModelFilterVisibleFunc) sources_filter_func,
+ priv,
+ NULL);
+
+ /* connect to source change signal */
+ widget = (GtkWidget*) gtk_builder_get_object (priv->builder,
+ "sources-treeview");
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+ g_signal_connect (selection, "changed", G_CALLBACK (source_changed_cb), priv);
+
+ /* connect to the background iconview change signal */
+ widget = (GtkWidget*) gtk_builder_get_object (priv->builder,
+ "backgrounds-iconview");
+ g_signal_connect (widget, "selection-changed",
+ G_CALLBACK (backgrounds_changed_cb), priv);
+
+ /* set up wallpaper source */
+ priv->wp_xml = g_new0 (GnomeWpXml, 1);
+ priv->wp_xml->wp_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->wp_xml->client = gconf_client_get_default ();
+ priv->wp_xml->wp_model = (GtkListStore*)
+ gtk_builder_get_object (priv->builder, "backgrounds-liststore");
+ priv->wp_xml->thumb_width = 100;
+ priv->wp_xml->thumb_height = 75;
+ priv->wp_xml->thumb_factory =
+ gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
+
+ gnome_wp_xml_load_list (priv->wp_xml);
+ g_hash_table_foreach (priv->wp_xml->wp_hash,
+ (GHFunc) load_wallpapers,
+ priv);
}
void
diff --git a/panels/background-screensaver/gnome-wp-info.c b/panels/background-screensaver/gnome-wp-info.c
new file mode 100644
index 0000000..7df6030
--- /dev/null
+++ b/panels/background-screensaver/gnome-wp-info.c
@@ -0,0 +1,87 @@
+/*
+ * 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 <config.h>
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include "gnome-wp-info.h"
+
+GnomeWPInfo * gnome_wp_info_new (const gchar * uri,
+ GnomeDesktopThumbnailFactory * thumbs) {
+ GnomeWPInfo *wp;
+ GFile *file;
+ GFileInfo *info;
+
+ file = g_file_new_for_commandline_arg (uri);
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_NAME ","
+ G_FILE_ATTRIBUTE_STANDARD_SIZE ","
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+ G_FILE_ATTRIBUTE_TIME_MODIFIED,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, NULL);
+ g_object_unref (file);
+
+ if (info == NULL || g_file_info_get_content_type (info) == NULL) {
+ if (!strcmp (uri, "(none)")) {
+ wp = g_new0 (GnomeWPInfo, 1);
+
+ wp->mime_type = g_strdup ("image/x-no-data");
+ wp->uri = g_strdup (uri);
+ wp->name = g_strdup (_("No Desktop Background"));
+ wp->size = 0;
+ } else {
+ wp = NULL;
+ }
+ } else {
+ wp = g_new0 (GnomeWPInfo, 1);
+
+ wp->uri = g_strdup (uri);
+
+ wp->name = g_strdup (g_file_info_get_name (info));
+ if (g_file_info_get_content_type (info) != NULL)
+ wp->mime_type = g_strdup (g_file_info_get_content_type (info));
+ wp->size = g_file_info_get_size (info);
+ wp->mtime = g_file_info_get_attribute_uint64 (info,
+ G_FILE_ATTRIBUTE_TIME_MODIFIED);
+
+ wp->thumburi = gnome_desktop_thumbnail_factory_lookup (thumbs,
+ uri,
+ wp->mtime);
+ }
+
+ if (info != NULL)
+ g_object_unref (info);
+
+ return wp;
+}
+
+void gnome_wp_info_free (GnomeWPInfo * info) {
+ if (info == NULL) {
+ return;
+ }
+
+ g_free (info->uri);
+ g_free (info->thumburi);
+ g_free (info->name);
+ g_free (info->mime_type);
+}
diff --git a/panels/background-screensaver/gnome-wp-info.h b/panels/background-screensaver/gnome-wp-info.h
new file mode 100644
index 0000000..ea1051e
--- /dev/null
+++ b/panels/background-screensaver/gnome-wp-info.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef _GNOME_WP_INFO_H_
+#define _GNOME_WP_INFO_H_
+
+#include <glib.h>
+#include <libgnomeui/gnome-desktop-thumbnail.h>
+
+typedef struct _GnomeWPInfo GnomeWPInfo;
+
+struct _GnomeWPInfo {
+ gchar * uri;
+ gchar * thumburi;
+ gchar * name;
+ gchar * mime_type;
+
+ goffset size;
+
+ time_t mtime;
+};
+
+GnomeWPInfo * gnome_wp_info_new (const gchar * uri,
+ GnomeDesktopThumbnailFactory * thumbs);
+void gnome_wp_info_free (GnomeWPInfo * info);
+
+#endif
+
diff --git a/panels/background-screensaver/gnome-wp-item.c b/panels/background-screensaver/gnome-wp-item.c
new file mode 100644
index 0000000..2cf8c3c
--- /dev/null
+++ b/panels/background-screensaver/gnome-wp-item.c
@@ -0,0 +1,307 @@
+/*
+ * 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 <config.h>
+
+#include <glib/gi18n.h>
+#include <gconf/gconf-client.h>
+#include <string.h>
+#include "gnome-wp-item.h"
+
+static GConfEnumStringPair options_lookup[] = {
+ { GNOME_BG_PLACEMENT_CENTERED, "centered" },
+ { GNOME_BG_PLACEMENT_FILL_SCREEN, "stretched" },
+ { GNOME_BG_PLACEMENT_SCALED, "scaled" },
+ { GNOME_BG_PLACEMENT_ZOOMED, "zoom" },
+ { GNOME_BG_PLACEMENT_TILED, "wallpaper" },
+ { GNOME_BG_PLACEMENT_SPANNED, "spanned" },
+ { 0, NULL }
+};
+
+static GConfEnumStringPair shade_lookup[] = {
+ { GNOME_BG_COLOR_SOLID, "solid" },
+ { GNOME_BG_COLOR_H_GRADIENT, "horizontal-gradient" },
+ { GNOME_BG_COLOR_V_GRADIENT, "vertical-gradient" },
+ { 0, NULL }
+};
+
+const gchar *wp_item_option_to_string (GnomeBGPlacement type)
+{
+ return gconf_enum_to_string (options_lookup, type);
+}
+
+const gchar *wp_item_shading_to_string (GnomeBGColorType type)
+{
+ return gconf_enum_to_string (shade_lookup, type);
+}
+
+GnomeBGPlacement wp_item_string_to_option (const gchar *option)
+{
+ int i = GNOME_BG_PLACEMENT_SCALED;
+ gconf_string_to_enum (options_lookup, option, &i);
+ return i;
+}
+
+GnomeBGColorType wp_item_string_to_shading (const gchar *shade_type)
+{
+ int i = GNOME_BG_COLOR_SOLID;
+ gconf_string_to_enum (shade_lookup, shade_type, &i);
+ return i;
+}
+
+static void set_bg_properties (GnomeWPItem *item)
+{
+ if (item->filename)
+ gnome_bg_set_filename (item->bg, item->filename);
+
+ gnome_bg_set_color (item->bg, item->shade_type, item->pcolor, item->scolor);
+ gnome_bg_set_placement (item->bg, item->options);
+}
+
+void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item)
+{
+ if (!item->bg) {
+ item->bg = gnome_bg_new ();
+
+ set_bg_properties (item);
+ }
+}
+
+void gnome_wp_item_update (GnomeWPItem *item) {
+ GConfClient *client;
+ GdkColor color1 = { 0, 0, 0, 0 }, color2 = { 0, 0, 0, 0 };
+ gchar *s;
+
+ client = gconf_client_get_default ();
+
+ s = gconf_client_get_string (client, WP_OPTIONS_KEY, NULL);
+ item->options = wp_item_string_to_option (s);
+ g_free (s);
+
+ s = gconf_client_get_string (client, WP_SHADING_KEY, NULL);
+ item->shade_type = wp_item_string_to_shading (s);
+ g_free (s);
+
+ s = gconf_client_get_string (client, WP_PCOLOR_KEY, NULL);
+ if (s != NULL) {
+ gdk_color_parse (s, &color1);
+ g_free (s);
+ }
+
+ s = gconf_client_get_string (client, WP_SCOLOR_KEY, NULL);
+ if (s != NULL) {
+ gdk_color_parse (s, &color2);
+ g_free (s);
+ }
+
+ g_object_unref (client);
+
+ if (item->pcolor != NULL)
+ gdk_color_free (item->pcolor);
+
+ if (item->scolor != NULL)
+ gdk_color_free (item->scolor);
+
+ item->pcolor = gdk_color_copy (&color1);
+ item->scolor = gdk_color_copy (&color2);
+}
+
+GnomeWPItem * gnome_wp_item_new (const gchar * filename,
+ GHashTable * wallpapers,
+ GnomeDesktopThumbnailFactory * thumbnails) {
+ GnomeWPItem *item = g_new0 (GnomeWPItem, 1);
+
+ item->filename = g_strdup (filename);
+ item->fileinfo = gnome_wp_info_new (filename, thumbnails);
+
+ if (item->fileinfo != NULL && item->fileinfo->mime_type != NULL &&
+ (g_str_has_prefix (item->fileinfo->mime_type, "image/") ||
+ strcmp (item->fileinfo->mime_type, "application/xml") == 0)) {
+
+ if (g_utf8_validate (item->fileinfo->name, -1, NULL))
+ item->name = g_strdup (item->fileinfo->name);
+ else
+ item->name = g_filename_to_utf8 (item->fileinfo->name, -1, NULL,
+ NULL, NULL);
+
+ gnome_wp_item_update (item);
+ gnome_wp_item_ensure_gnome_bg (item);
+ gnome_wp_item_update_description (item);
+
+ g_hash_table_insert (wallpapers, item->filename, item);
+ } else {
+ gnome_wp_item_free (item);
+ item = NULL;
+ }
+
+ return item;
+}
+
+void gnome_wp_item_free (GnomeWPItem * item) {
+ if (item == NULL) {
+ return;
+ }
+
+ g_free (item->name);
+ g_free (item->filename);
+ g_free (item->description);
+
+ if (item->pcolor != NULL)
+ gdk_color_free (item->pcolor);
+
+ if (item->scolor != NULL)
+ gdk_color_free (item->scolor);
+
+ gnome_wp_info_free (item->fileinfo);
+ if (item->bg)
+ g_object_unref (item->bg);
+
+ gtk_tree_row_reference_free (item->rowref);
+
+ g_free (item);
+}
+
+static GdkPixbuf *
+add_slideshow_frame (GdkPixbuf *pixbuf)
+{
+ GdkPixbuf *sheet, *sheet2;
+ GdkPixbuf *tmp;
+ gint w, h;
+
+ w = gdk_pixbuf_get_width (pixbuf);
+ h = gdk_pixbuf_get_height (pixbuf);
+
+ sheet = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, w, h);
+ gdk_pixbuf_fill (sheet, 0x00000000);
+ sheet2 = gdk_pixbuf_new_subpixbuf (sheet, 1, 1, w - 2, h - 2);
+ gdk_pixbuf_fill (sheet2, 0xffffffff);
+ g_object_unref (sheet2);
+
+ tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, w + 6, h + 6);
+
+ gdk_pixbuf_fill (tmp, 0x00000000);
+ gdk_pixbuf_composite (sheet, tmp, 6, 6, w, h, 6.0, 6.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
+ gdk_pixbuf_composite (sheet, tmp, 3, 3, w, h, 3.0, 3.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
+ gdk_pixbuf_composite (pixbuf, tmp, 0, 0, w, h, 0.0, 0.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
+
+ g_object_unref (sheet);
+
+ return tmp;
+}
+
+GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem * item,
+ GnomeDesktopThumbnailFactory * thumbs,
+ int width,
+ int height,
+ gint frame) {
+ GdkPixbuf *pixbuf = NULL;
+
+ set_bg_properties (item);
+
+ if (frame != -1)
+ pixbuf = gnome_bg_create_frame_thumbnail (item->bg, thumbs, gdk_screen_get_default (), width, height, frame);
+ else
+ pixbuf = gnome_bg_create_thumbnail (item->bg, thumbs, gdk_screen_get_default(), width, height);
+
+ if (pixbuf && gnome_bg_changes_with_time (item->bg))
+ {
+ GdkPixbuf *tmp;
+
+ tmp = add_slideshow_frame (pixbuf);
+ g_object_unref (pixbuf);
+ pixbuf = tmp;
+ }
+
+ gnome_bg_get_image_size (item->bg, thumbs, width, height, &item->width, &item->height);
+
+ return pixbuf;
+}
+
+
+GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item,
+ GnomeDesktopThumbnailFactory * thumbs,
+ gint width,
+ gint height) {
+ return gnome_wp_item_get_frame_thumbnail (item, thumbs, width, height, -1);
+}
+
+void gnome_wp_item_update_description (GnomeWPItem * item) {
+ g_free (item->description);
+
+ if (!strcmp (item->filename, "(none)")) {
+ item->description = g_strdup (item->name);
+ } else {
+ const gchar *description;
+ gchar *size;
+ gchar *dirname = g_path_get_dirname (item->filename);
+
+ description = NULL;
+ size = NULL;
+
+ if (strcmp (item->fileinfo->mime_type, "application/xml") == 0)
+ {
+ if (gnome_bg_changes_with_time (item->bg))
+ description = _("Slide Show");
+ else if (item->width > 0 && item->height > 0)
+ description = _("Image");
+ }
+ else
+ description = g_content_type_get_description (item->fileinfo->mime_type);
+
+ if (gnome_bg_has_multiple_sizes (item->bg))
+ size = g_strdup (_("multiple sizes"));
+ else if (item->width > 0 && item->height > 0) {
+ /* translators: x pixel(s) by y pixel(s) */
+ size = g_strdup_printf (_("%d %s by %d %s"),
+ item->width,
+ ngettext ("pixel", "pixels", item->width),
+ item->height,
+ ngettext ("pixel", "pixels", item->height));
+ }
+
+ if (description && size) {
+ /* translators: <b>wallpaper name</b>
+ * mime type, size
+ * Folder: /path/to/file
+ */
+ item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
+ "%s, %s\n"
+ "Folder: %s"),
+ item->name,
+ description,
+ size,
+ dirname);
+ } else {
+ /* translators: <b>wallpaper name</b>
+ * Image missing
+ * Folder: /path/to/file
+ */
+ item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
+ "%s\n"
+ "Folder: %s"),
+ item->name,
+ _("Image missing"),
+ dirname);
+ }
+
+ g_free (size);
+ g_free (dirname);
+ }
+}
diff --git a/panels/background-screensaver/gnome-wp-item.h b/panels/background-screensaver/gnome-wp-item.h
new file mode 100644
index 0000000..3a9fe61
--- /dev/null
+++ b/panels/background-screensaver/gnome-wp-item.h
@@ -0,0 +1,90 @@
+/*
+ * 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 <glib.h>
+#include <gio/gio.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gtk/gtk.h>
+#include <libgnomeui/gnome-desktop-thumbnail.h>
+#include <libgnomeui/gnome-bg.h>
+
+#include "gnome-wp-info.h"
+
+#ifndef _GNOME_WP_ITEM_H_
+#define _GNOME_WP_ITEM_H_
+
+#define WP_PATH_KEY "/desktop/gnome/background"
+#define WP_FILE_KEY WP_PATH_KEY "/picture_filename"
+#define WP_OPTIONS_KEY WP_PATH_KEY "/picture_options"
+#define WP_SHADING_KEY WP_PATH_KEY "/color_shading_type"
+#define WP_PCOLOR_KEY WP_PATH_KEY "/primary_color"
+#define WP_SCOLOR_KEY WP_PATH_KEY "/secondary_color"
+
+typedef struct _GnomeWPItem GnomeWPItem;
+
+struct _GnomeWPItem {
+ GnomeBG *bg;
+
+ gchar * name;
+ gchar * filename;
+ gchar * description;
+ GnomeBGPlacement options;
+ GnomeBGColorType shade_type;
+
+ /* Where the Item is in the List */
+ GtkTreeRowReference * rowref;
+
+ /* Real colors */
+ GdkColor * pcolor;
+ GdkColor * scolor;
+
+ GnomeWPInfo * fileinfo;
+
+ /* Did the user remove us? */
+ gboolean deleted;
+
+ /* Width and Height of the original image */
+ gint width;
+ gint height;
+};
+
+GnomeWPItem * gnome_wp_item_new (const gchar *filename,
+ GHashTable *wallpapers,
+ GnomeDesktopThumbnailFactory *thumbnails);
+
+void gnome_wp_item_free (GnomeWPItem *item);
+GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem *item,
+ GnomeDesktopThumbnailFactory *thumbs,
+ gint width,
+ gint height);
+GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem *item,
+ GnomeDesktopThumbnailFactory *thumbs,
+ gint width,
+ gint height,
+ gint frame);
+void gnome_wp_item_update (GnomeWPItem *item);
+void gnome_wp_item_update_description (GnomeWPItem *item);
+void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item);
+
+const gchar *wp_item_option_to_string (GnomeBGPlacement type);
+const gchar *wp_item_shading_to_string (GnomeBGColorType type);
+GnomeBGPlacement wp_item_string_to_option (const gchar *option);
+GnomeBGColorType wp_item_string_to_shading (const gchar *shade_type);
+
+#endif
diff --git a/panels/background-screensaver/gnome-wp-xml.c b/panels/background-screensaver/gnome-wp-xml.c
new file mode 100644
index 0000000..51aba44
--- /dev/null
+++ b/panels/background-screensaver/gnome-wp-xml.c
@@ -0,0 +1,449 @@
+/*
+ * 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 "gnome-wp-item.h"
+#include "gnome-wp-xml.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_ascii_strcasecmp ((gchar *)prop, "true") || !g_ascii_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 (GnomeWpXml *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 (GnomeWpXml *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 (wpa->type == XML_COMMENT_NODE) {
+ continue;
+ } else 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", 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_ensure_gnome_bg (wp);
+ gnome_wp_item_update_description (wp);
+ g_hash_table_insert (data->wp_hash, wp->filename, 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,
+ GnomeWpXml *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,
+ GnomeWpXml *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,
+ GnomeWpXml *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 (GnomeWpXml *data) {
+ const char * const *system_data_dirs;
+ gchar * datadir;
+ gchar * wpdbfile;
+ 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);
+
+ datadir = g_build_filename (g_get_user_data_dir (),
+ "gnome-background-properties",
+ NULL);
+ gnome_wp_xml_load_from_dir (datadir, data);
+ g_free (datadir);
+
+ system_data_dirs = g_get_system_data_dirs ();
+ for (i = 0; system_data_dirs[i]; i++) {
+ datadir = g_build_filename (system_data_dirs[i],
+ "gnome-background-properties",
+ NULL);
+ gnome_wp_xml_load_from_dir (datadir, data);
+ g_free (datadir);
+ }
+
+ 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 (GnomeWpXml *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);
+}
diff --git a/panels/background-screensaver/gnome-wp-xml.h b/panels/background-screensaver/gnome-wp-xml.h
new file mode 100644
index 0000000..2ea8c2a
--- /dev/null
+++ b/panels/background-screensaver/gnome-wp-xml.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef _GNOME_WP_XML_H_
+#define _GNOME_WP_XML_H_
+
+#include <gconf/gconf-client.h>
+#include <libgnomeui/gnome-desktop-thumbnail.h>
+
+typedef struct _GnomeWpXml GnomeWpXml;
+
+struct _GnomeWpXml
+{
+ GHashTable *wp_hash;
+ GnomeDesktopThumbnailFactory *thumb_factory;
+ GConfClient *client;
+ gint thumb_height;
+ gint thumb_width;
+ GtkListStore *wp_model;
+};
+
+void gnome_wp_xml_load_list (GnomeWpXml *data);
+void gnome_wp_xml_save_list (GnomeWpXml *data);
+
+#endif
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]