[gnome-control-center] background: Major rework of the CcBackgroundItem code



commit ca14846ef95ab65b6a01b87e2975913e8b93074e
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Feb 10 20:30:57 2011 +0000

    background: Major rework of the CcBackgroundItem code
    
    It now is a full GObject, will be able to track the original
    XML file for a wallpaper, as well as which values are set in it.
    
    This will allow us to restore wallpapers properly, and only offer
    editing options when those aren't already hard-coded inside the
    item.

 configure.ac                             |    2 +
 panels/background/Makefile.am            |   28 +-
 panels/background/bg-colors-source.c     |   28 +-
 panels/background/bg-flickr-source.c     |   26 +-
 panels/background/bg-pictures-source.c   |   28 +-
 panels/background/bg-source.c            |    4 +-
 panels/background/bg-wallpapers-source.c |   25 +-
 panels/background/cc-background-item.c   |  909 ++++++++++++++++++++++++------
 panels/background/cc-background-item.h   |  144 +++---
 panels/background/cc-background-panel.c  |  139 +++--
 panels/background/gnome-wp-xml.c         |  240 ++++-----
 panels/background/gnome-wp-xml.h         |    1 +
 12 files changed, 1080 insertions(+), 494 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index ef5c174..df8c113 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,6 +55,8 @@ PKG_CHECK_MODULES(LIBCANBERRA_GTK, libcanberra-gtk3, [
   ], [:])
 AM_CONDITIONAL(HAVE_LIBCANBERRA_GTK, test "x$CANBERRA_GTK" = "x1")
 
+AC_PATH_PROG([GLIB_MKENUMS],[glib-mkenums])
+
 dnl Region panel
 savecppflags=$CPPFLAGS
 CPPFLAGS="$CPPFLAGS $X_CFLAGS"
diff --git a/panels/background/Makefile.am b/panels/background/Makefile.am
index cba8746..601e5fa 100644
--- a/panels/background/Makefile.am
+++ b/panels/background/Makefile.am
@@ -34,6 +34,8 @@ libbackground_la_SOURCES =		\
 	cc-background-panel.h	\
 	cc-background-item.c	\
 	cc-background-item.h	\
+	gdesktop-enums-types.c	\
+	gdesktop-enums-types.h	\
 	bg-source.c		\
 	bg-source.h		\
 	bg-pictures-source.c			\
@@ -60,12 +62,36 @@ INCLUDES += $(SOCIALWEB_CFLAGS)
 libbackground_la_LIBADD += $(SOCIALWEB_LIBS)
 endif
 
+gdesktop-enums-types.h: stamp-gdesktop-enums-types.h
+	@true
+
+stamp-gdesktop-enums-types.h: $(includedir)/gsettings-desktop-schemas/gdesktop-enums.h cc-background-item.h Makefile
+	$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) \
+			--fhead "#ifndef __GDESKTOP_ENUMS_TYPES_H__\n#define __GDESKTOP_ENUMS_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+			--fprod "/* enumerations from \"@filename \" */\n" \
+			--vhead "GType @enum_name _get_type (void) G_GNUC_CONST;\n#define G_DESKTOP_TYPE_ ENUMSHORT@ (@enum_name _get_type())\n" \
+			--ftail "G_END_DECLS\n\n#endif /* __GDESKTOP_ENUMS_TYPES_H__ */" $(includedir)/gsettings-desktop-schemas/gdesktop-enums.h cc-background-item.h) >> xgen-gtbh \
+	&& (cmp -s xgen-gtbh gdesktop-enums-types.h || cp xgen-gtbh gdesktop-enums-types.h ) \
+	&& rm -f xgen-gtbh \
+	&& echo timestamp > $(@F)
+
+gdesktop-enums-types.c: $(includedir)/gsettings-desktop-schemas/gdesktop-enums.h cc-background-item.h Makefile gdesktop-enums-types.h
+	$(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) \
+			--fhead "#include <gdesktop-enums.h>\n#include \"gdesktop-enums-types.h\"\n#include \"cc-background-item.h\"" \
+			--fprod "\n/* enumerations from \"@filename \" */" \
+			--vhead "GType\n enum_name@_get_type (void)\n{\n  static GType etype = 0;\n  if (etype == 0) {\n    static const G Type@Value values[] = {" \
+			--vprod "      { @VALUENAME@, \"@VALUENAME \", \"@valuenick \" }," \
+			--vtail "      { 0, NULL, NULL }\n    };\n    etype = g_ type@_register_static (\"@EnumName \", values);\n  }\n  return etype;\n}\n" \
+		$(includedir)/gsettings-desktop-schemas/gdesktop-enums.h cc-background-item.h) > xgen-gtbc \
+	&& cp xgen-gtbc gdesktop-enums-types.c  \
+	&& rm -f xgen-gtbc
+
 @INTLTOOL_DESKTOP_RULE@
 
 desktopdir = $(datadir)/applications
 desktop_in_files = gnome-background-panel.desktop.in
 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
 
-CLEANFILES = $(desktop_in_files) $(desktop_DATA)
+CLEANFILES = $(desktop_in_files) $(desktop_DATA) stamp-gdesktop-enums-types.h gdesktop-enums-types.h gdesktop-enums-types.c
 
 -include $(top_srcdir)/git.mk
diff --git a/panels/background/bg-colors-source.c b/panels/background/bg-colors-source.c
index 0d4622a..a182467 100644
--- a/panels/background/bg-colors-source.c
+++ b/panels/background/bg-colors-source.c
@@ -26,6 +26,7 @@
 #include "cc-background-item.h"
 
 #include <glib/gi18n-lib.h>
+#include <gsettings-desktop-schemas/gdesktop-enums.h>
 
 G_DEFINE_TYPE (BgColorsSource, bg_colors_source, BG_TYPE_SOURCE)
 
@@ -55,36 +56,29 @@ bg_colors_source_init (BgColorsSource *self)
   GnomeDesktopThumbnailFactory *thumb_factory;
   guint i;
   GtkListStore *store;
-  GdkColor pcolor, scolor;
 
   store = bg_source_get_liststore (BG_SOURCE (self));
 
   thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
 
-  gdk_color_parse (PCOLOR, &pcolor);
-  gdk_color_parse (SCOLOR, &scolor);
-
   for (i = 0; i < G_N_ELEMENTS (items); i++)
     {
-      GnomeWPItem *item;
+      CcBackgroundItem *item;
       GIcon *pixbuf;
 
-      item = g_new0 (GnomeWPItem, 1);
-
-      item->filename = g_strdup ("(none)");
-      item->name = g_strdup (_(items[i].name));
-
-      item->pcolor = gdk_color_copy (&pcolor);
-      item->scolor = gdk_color_copy (&scolor);
-
-      item->shade_type = items[i].type;
+      item = cc_background_item_new (NULL);
 
-      cc_background_item_ensure_gnome_bg (item);
+      g_object_set (G_OBJECT (item),
+		    "name", _(items[i].name),
+		    "primary-color", PCOLOR,
+		    "secondary-color", SCOLOR,
+		    "shading", items[i].type,
+		    NULL);
 
       /* insert the item into the liststore */
       pixbuf = cc_background_item_get_thumbnail (item,
-                                            thumb_factory,
-                                            THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
+						 thumb_factory,
+						 THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
       gtk_list_store_insert_with_values (store, NULL, 0,
                                          0, pixbuf,
                                          1, item,
diff --git a/panels/background/bg-flickr-source.c b/panels/background/bg-flickr-source.c
index 8f9f401..3fe18a7 100644
--- a/panels/background/bg-flickr-source.c
+++ b/panels/background/bg-flickr-source.c
@@ -27,6 +27,7 @@
 #include <libsocialweb-client/sw-client-service.h>
 
 #include "cc-background-item.h"
+#include <gsettings-desktop-schemas/gdesktop-enums.h>
 
 G_DEFINE_TYPE (BgFlickrSource, bg_flickr_source, BG_TYPE_SOURCE)
 
@@ -88,25 +89,24 @@ _view_items_added_cb (SwClientItemView *item_view,
 
   for (l = items; l; l = l->next)
     {
-      GnomeWPItem *item;
+      CcBackgroundItem *item;
       GdkPixbuf *pixbuf;
-      GdkColor color = { 0, 0, 0, 0 };
       SwItem *sw_item = (SwItem *) l->data;
       const gchar *thumb_url;
 
-      item = g_new0 (GnomeWPItem, 1);
+      item = cc_background_item_new (NULL);
 
-      item->options = G_DESKTOP_BACKGROUND_STYLE_ZOOM;
-      item->name = g_strdup (sw_item_get_value (sw_item, "title"));
-      item->source_url = g_strdup (sw_item_get_value (sw_item,
-                                                      "x-flickr-photo-url"));
+      g_object_set (G_OBJECT (item),
+		    "placement", G_DESKTOP_BACKGROUND_STYLE_ZOOM,
+		    "name", sw_item_get_value (sw_item, "title"),
+		    "primary-color", "#000000000000",
+		    "seconday-color", "#000000000000",
+		    "shading", G_DESKTOP_BACKGROUND_SHADING_SOLID,
+		    "source-url", sw_item_get_value (sw_item, "x-flickr-photo-url"),
+		    NULL);
 
-      item->pcolor = gdk_color_copy (&color);
-      item->scolor = gdk_color_copy (&color);
-
-      item->shade_type = G_DESKTOP_BACKGROUND_SHADING_SOLID;
-
-      cc_background_item_ensure_gnome_bg (item);
+      //FIXME
+//      cc_background_item_ensure_gnome_bg (item);
 
       /* insert the item into the liststore */
       thumb_url = sw_item_get_value (sw_item, "thumbnail");
diff --git a/panels/background/bg-pictures-source.c b/panels/background/bg-pictures-source.c
index 234e785..c7e362d 100644
--- a/panels/background/bg-pictures-source.c
+++ b/panels/background/bg-pictures-source.c
@@ -27,7 +27,7 @@
 #include <string.h>
 #include <gio/gio.h>
 #include <libgnome-desktop/gnome-desktop-thumbnail.h>
-
+#include <gsettings-desktop-schemas/gdesktop-enums.h>
 
 G_DEFINE_TYPE (BgPicturesSource, bg_pictures_source, BG_TYPE_SOURCE)
 
@@ -122,7 +122,7 @@ picture_scaled (GObject *source_object,
                 gpointer user_data)
 {
   BgPicturesSource *bg_source = BG_PICTURES_SOURCE (user_data);
-  GnomeWPItem *item;
+  CcBackgroundItem *item;
   GError *error = NULL;
   GdkPixbuf *pixbuf;
 
@@ -138,7 +138,7 @@ picture_scaled (GObject *source_object,
     {
       g_warning ("Failed to load image: %s", error->message);
       g_error_free (error);
-      cc_background_item_free (item);
+      g_object_unref (item);
       return;
     }
 
@@ -149,8 +149,11 @@ picture_scaled (GObject *source_object,
                                      -1);
   tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
                                        &iter);
+  //FIXME rowref
+#if 0
   item->rowref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
                                              tree_path);
+#endif
   gtk_tree_path_free (tree_path);
 
   g_object_unref (pixbuf);
@@ -162,7 +165,7 @@ picture_opened_for_read (GObject *source_object,
                          gpointer user_data)
 {
   BgPicturesSource *bg_source = BG_PICTURES_SOURCE (user_data);
-  GnomeWPItem *item;
+  CcBackgroundItem *item;
   GFileInputStream *stream;
   GError *error = NULL;
 
@@ -176,7 +179,7 @@ picture_opened_for_read (GObject *source_object,
       g_warning ("Failed to load picture '%s': %s", filename, error->message);
       g_free (filename);
       g_error_free (error);
-      cc_background_item_free (item);
+      g_object_unref (item);
       return;
     }
 
@@ -196,7 +199,6 @@ file_info_async_ready (GObject      *source,
                        gpointer      user_data)
 {
   BgPicturesSource *bg_source = BG_PICTURES_SOURCE (user_data);
-  BgPicturesSourcePrivate *priv = bg_source->priv;
   GList *files, *l;
   GError *err = NULL;
   GFile *parent;
@@ -234,17 +236,15 @@ file_info_async_ready (GObject      *source,
       if (!strcmp ("image/png", content_type)
           || !strcmp ("image/jpeg", content_type))
         {
-          GnomeWPItem *item;
+          CcBackgroundItem *item;
           gchar *filename;
           GFile *file;
 
           filename = g_build_filename (path, g_file_info_get_name (info), NULL);
 
-          /* create a new GnomeWpItem */
-          item = cc_background_item_new (filename, NULL,
-                                    info,
-                                    priv->thumb_factory);
-
+          /* create a new CcBackgroundItem */
+          item = cc_background_item_new (filename);
+          cc_background_item_load (item, info);
           if (!item)
             {
               g_warning ("Could not load picture \"%s\"", filename);
@@ -254,8 +254,8 @@ file_info_async_ready (GObject      *source,
 
           file = g_file_new_for_path (filename);
           g_free (filename);
-          if (item->options == G_DESKTOP_BACKGROUND_STYLE_NONE)
-            item->options = G_DESKTOP_BACKGROUND_STYLE_ZOOM;
+          if (cc_background_item_get_placement (item) == G_DESKTOP_BACKGROUND_STYLE_NONE)
+            g_object_set (G_OBJECT (item), "placement", G_DESKTOP_BACKGROUND_STYLE_ZOOM, NULL);
           g_object_set_data (G_OBJECT (file), "item", item);
           g_file_read_async (file, 0, NULL, picture_opened_for_read, bg_source);
           g_object_unref (file);
diff --git a/panels/background/bg-source.c b/panels/background/bg-source.c
index 23f6262..6b81eee 100644
--- a/panels/background/bg-source.c
+++ b/panels/background/bg-source.c
@@ -76,12 +76,12 @@ free_tree_model_items (GtkTreeModel *model,
                        GtkTreeIter  *iter,
                        gpointer      data)
 {
-  GnomeWPItem *item = NULL;
+  CcBackgroundItem *item = NULL;
 
   gtk_tree_model_get (model, iter, 1, &item, -1);
 
   if (item)
-    cc_background_item_free (item);
+    g_object_unref (item);
 
   return FALSE;
 }
diff --git a/panels/background/bg-wallpapers-source.c b/panels/background/bg-wallpapers-source.c
index 7a5a703..2d5e9d8 100644
--- a/panels/background/bg-wallpapers-source.c
+++ b/panels/background/bg-wallpapers-source.c
@@ -107,13 +107,15 @@ bg_wallpapers_source_class_init (BgWallpapersSourceClass *klass)
   object_class->finalize = bg_wallpapers_source_finalize;
 }
 
+//FIXME
+#if 0
 static gboolean
 find_wallpaper (gpointer key,
                 gpointer value,
                 gpointer data)
 {
   GnomeBG *bg = data;
-  GnomeWPItem *item = value;
+  CcBackgroundItem *item = value;
 
   return item->bg == bg;
 }
@@ -126,7 +128,7 @@ item_changed_cb (GnomeBG    *bg,
   GtkTreeModel *model;
   GtkTreeIter iter;
   GtkTreePath *path;
-  GnomeWPItem *item;
+  CcBackgroundItem *item;
 
   item = g_hash_table_find (data->wp_hash, find_wallpaper, bg);
 
@@ -157,29 +159,32 @@ item_changed_cb (GnomeBG    *bg,
                                          data);
     }
 }
-
+#endif
 
 
 
 static void
 load_wallpapers (gchar              *key,
-                 GnomeWPItem        *item,
+                 CcBackgroundItem        *item,
                  BgWallpapersSource *source)
 {
   BgWallpapersSourcePrivate *priv = source->priv;
   GtkTreeIter iter;
-  GtkTreePath *path;
+//  GtkTreePath *path;
   GIcon *pixbuf;
   GtkListStore *store = bg_source_get_liststore (BG_SOURCE (source));
+  gboolean deleted;
+
+  g_object_get (G_OBJECT (item), "is-deleted", &deleted, NULL);
 
-  if (item->deleted == TRUE)
+  if (deleted)
     return;
 
   gtk_list_store_append (store, &iter);
 
   pixbuf = cc_background_item_get_thumbnail (item, priv->thumb_factory,
                                         THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
-  cc_background_item_update_size (item, NULL);
+//  cc_background_item_update_size (item, NULL);
 
   gtk_list_store_set (store, &iter,
                       0, pixbuf,
@@ -189,9 +194,11 @@ load_wallpapers (gchar              *key,
   if (pixbuf)
     g_object_unref (pixbuf);
 
+#if 0
   path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
   item->rowref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path);
   gtk_tree_path_free (path);
+#endif
 }
 
 static void
@@ -208,7 +215,7 @@ list_load_cb (GObject *source_object,
 			self);
 
   g_hash_table_destroy (wp_xml->wp_hash);
-  g_object_unref (wp_xml->settings);
+//  g_object_unref (wp_xml->settings);
   g_free (wp_xml);
 }
 
@@ -220,7 +227,7 @@ reload_wallpapers (BgWallpapersSource *self)
   /* set up wallpaper source */
   wp_xml = g_new0 (GnomeWpXml, 1);
   wp_xml->wp_hash = g_hash_table_new (g_str_hash, g_str_equal);
-  wp_xml->settings = g_settings_new (WP_PATH_ID);
+//  wp_xml->settings = g_settings_new (WP_PATH_ID);
   wp_xml->wp_model = bg_source_get_liststore (BG_SOURCE (self));
   wp_xml->thumb_width = THUMBNAIL_WIDTH;
   wp_xml->thumb_height = THUMBNAIL_HEIGHT;
diff --git a/panels/background/cc-background-item.c b/panels/background/cc-background-item.c
index 6fe2969..cfd40fd 100644
--- a/panels/background/cc-background-item.c
+++ b/panels/background/cc-background-item.c
@@ -1,223 +1,792 @@
-/*
- *  Authors: Rodney Dawes <dobey ximian com>
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  *
- *  Copyright 2003-2006 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2010-2011 Red Hat, Inc.
  *
- *  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 free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *  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.
+ * 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.
+ * 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 Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
 
-#include <config.h>
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <glib/gi18n-lib.h>
+
+#include <gconf/gconf-client.h>
+
+#include <libgnome-desktop/gnome-bg.h>
+#include <gsettings-desktop-schemas/gdesktop-enums.h>
 
-#include <glib/gi18n.h>
-#include <string.h>
 #include "cc-background-item.h"
+#include "gdesktop-enums-types.h"
+
+#define CC_BACKGROUND_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_BACKGROUND_ITEM, CcBackgroundItemPrivate))
 
-static void set_bg_properties (GnomeWPItem *item)
+struct CcBackgroundItemPrivate
 {
-  if (!item->bg)
-    return;
+        /* properties */
+        char            *name;
+        char            *filename;
+        char            *size;
+        GDesktopBackgroundStyle placement;
+        GDesktopBackgroundShading shading;
+        char            *primary_color;
+        char            *secondary_color;
+        char            *source_url; /* Used by the Flickr source */
+        char            *source_xml; /* Used by the Wallpapers source */
+        gboolean         is_deleted;
+        CcBackgroundItemFlags flags;
+
+        /* internal */
+        GnomeBG         *bg;
+        char            *mime_type;
+        int              width;
+        int              height;
+};
+
+enum {
+        PROP_0,
+        PROP_NAME,
+        PROP_FILENAME,
+        PROP_PLACEMENT,
+        PROP_SHADING,
+        PROP_PRIMARY_COLOR,
+        PROP_SECONDARY_COLOR,
+        PROP_IS_DELETED,
+        PROP_SOURCE_URL,
+        PROP_SOURCE_XML,
+        PROP_FLAGS,
+        PROP_SIZE
+};
+
+enum {
+        CHANGED,
+        LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+static void     cc_background_item_class_init     (CcBackgroundItemClass *klass);
+static void     cc_background_item_init           (CcBackgroundItem      *background_item);
+static void     cc_background_item_finalize       (GObject               *object);
+
+G_DEFINE_TYPE (CcBackgroundItem, cc_background_item, G_TYPE_OBJECT)
+
+#if 0
+static GConfEnumStringPair placement_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" },
+        { 0, NULL }
+};
+
+static GConfEnumStringPair shading_lookup[] = {
+        { GNOME_BG_COLOR_SOLID, "solid" },
+        { GNOME_BG_COLOR_H_GRADIENT, "horizontal-gradient" },
+        { GNOME_BG_COLOR_V_GRADIENT, "vertical-gradient" },
+        { 0, NULL }
+};
+
+static const char *
+placement_to_string (GnomeBGPlacement type)
+{
+        return gconf_enum_to_string (placement_lookup, type);
+}
 
-  if (item->filename)
-    gnome_bg_set_filename (item->bg, item->filename);
+static const char *
+shading_to_string (GnomeBGColorType type)
+{
+        return gconf_enum_to_string (shading_lookup, type);
+}
 
-  gnome_bg_set_color (item->bg, item->shade_type, item->pcolor, item->scolor);
-  gnome_bg_set_placement (item->bg, item->options);
+static GnomeBGPlacement
+string_to_placement (const char *option)
+{
+        int i = GNOME_BG_PLACEMENT_SCALED;
+        if (option != NULL) {
+                gconf_string_to_enum (placement_lookup, option, &i);
+        }
+        return i;
 }
 
-void cc_background_item_ensure_gnome_bg (GnomeWPItem *item)
+static GnomeBGColorType
+string_to_shading (const char *shading)
+{
+        int i = GNOME_BG_COLOR_SOLID;
+        if (shading != NULL) {
+                gconf_string_to_enum (shading_lookup, shading, &i);
+        }
+        return i;
+}
+#endif
+static GEmblem *
+get_slideshow_icon (void)
 {
-  if (!item->bg)
-    item->bg = gnome_bg_new ();
+	GIcon *themed;
+	GEmblem *emblem;
+	themed = g_themed_icon_new ("slideshow-emblem");
+	emblem = g_emblem_new_with_origin (themed, G_EMBLEM_ORIGIN_DEVICE);
+	g_object_unref (themed);
+	return emblem;
+}
 
-  g_object_set_data (G_OBJECT (item->bg), "cc-background-item", item);
+static void
+set_bg_properties (CcBackgroundItem *item)
+{
+        GdkColor pcolor = { 0, 0, 0, 0 };
+        GdkColor scolor = { 0, 0, 0, 0 };
+
+        if (item->priv->filename)
+                gnome_bg_set_filename (item->priv->bg, item->priv->filename);
 
-  set_bg_properties (item);
+        if (item->priv->primary_color != NULL) {
+                gdk_color_parse (item->priv->primary_color, &pcolor);
+        }
+        if (item->priv->secondary_color != NULL) {
+                gdk_color_parse (item->priv->secondary_color, &scolor);
+        }
+
+        gnome_bg_set_color (item->priv->bg, item->priv->shading, &pcolor, &scolor);
+        gnome_bg_set_placement (item->priv->bg, item->priv->placement);
 }
 
-void cc_background_item_update (GnomeWPItem *item) {
-  GSettings *settings;
-  GdkColor color1 = { 0, 0, 0, 0 }, color2 = { 0, 0, 0, 0 };
-  gchar *s;
 
-  settings = g_settings_new (WP_PATH_ID);
+gboolean
+cc_background_item_changes_with_time (CcBackgroundItem *item)
+{
+        gboolean changes;
 
-  item->options = g_settings_get_enum (settings, WP_OPTIONS_KEY);
-  item->shade_type = g_settings_get_enum (settings, WP_SHADING_KEY);
+        changes = FALSE;
+        if (item->priv->bg != NULL) {
+                changes = gnome_bg_changes_with_time (item->priv->bg);
+        }
+        return changes;
+}
 
-  s = g_settings_get_string (settings, WP_PCOLOR_KEY);
-  if (s != NULL) {
-    gdk_color_parse (s, &color1);
-    g_free (s);
-  }
+static void
+update_size (CcBackgroundItem *item)
+{
+	g_free (item->priv->size);
+	item->priv->size = NULL;
+
+	if (item->priv->filename == NULL || g_str_equal (item->priv->filename, "(none)")) {
+		item->priv->size = g_strdup ("");
+	} else {
+		if (gnome_bg_has_multiple_sizes (item->priv->bg) || gnome_bg_changes_with_time (item->priv->bg)) {
+			item->priv->size = g_strdup (_("multiple sizes"));
+		} else {
+			/* translators: 100 Ã? 100px
+			 * Note that this is not an "x", but U+00D7 MULTIPLICATION SIGN */
+			item->priv->size = g_strdup_printf (_("%d \303\227 %d"),
+							    item->priv->width,
+							    item->priv->height);
+		}
+	}
+}
 
-  s = g_settings_get_string (settings, WP_SCOLOR_KEY);
-  if (s != NULL) {
-    gdk_color_parse (s, &color2);
-    g_free (s);
-  }
+GIcon *
+cc_background_item_get_frame_thumbnail (CcBackgroundItem             *item,
+                                        GnomeDesktopThumbnailFactory *thumbs,
+                                        int                           width,
+                                        int                           height,
+                                        int                           frame)
+{
+        GdkPixbuf *pixbuf = NULL;
+        GIcon *icon = NULL;
+
+        set_bg_properties (item);
+
+        if (frame >= 0)
+                pixbuf = gnome_bg_create_frame_thumbnail (item->priv->bg,
+                                                          thumbs,
+                                                          gdk_screen_get_default (),
+                                                          width,
+                                                          height,
+                                                          frame);
+        else
+                pixbuf = gnome_bg_create_thumbnail (item->priv->bg,
+                                                    thumbs,
+                                                    gdk_screen_get_default(),
+                                                    width,
+                                                    height);
+
+        if (pixbuf != NULL
+            && frame != -2
+            && gnome_bg_changes_with_time (item->priv->bg)) {
+                GEmblem *emblem;
+
+                emblem = get_slideshow_icon ();
+                icon = g_emblemed_icon_new (G_ICON (pixbuf), emblem);
+                g_object_unref (emblem);
+                g_object_unref (pixbuf);
+        } else {
+                icon = G_ICON (pixbuf);
+	}
+
+        gnome_bg_get_image_size (item->priv->bg,
+                                 thumbs,
+                                 width,
+                                 height,
+                                 &item->priv->width,
+                                 &item->priv->height);
+
+        update_size (item);
+
+        return icon;
+}
 
-  g_object_unref (settings);
 
-  if (item->pcolor != NULL)
-    gdk_color_free (item->pcolor);
+GIcon *
+cc_background_item_get_thumbnail (CcBackgroundItem             *item,
+                                  GnomeDesktopThumbnailFactory *thumbs,
+                                  int                           width,
+                                  int                           height)
+{
+        return cc_background_item_get_frame_thumbnail (item, thumbs, width, height, -1);
+}
 
-  if (item->scolor != NULL)
-    gdk_color_free (item->scolor);
+static void
+update_info (CcBackgroundItem *item,
+	     GFileInfo        *_info)
+{
+        GFile     *file;
+        GFileInfo *info;
+
+	if (_info == NULL) {
+		file = g_file_new_for_commandline_arg (item->priv->filename);
+
+		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);
+	} else {
+		info = g_object_ref (_info);
+	}
+
+        g_free (item->priv->mime_type);
+        item->priv->mime_type = NULL;
+
+        if (info == NULL
+            || g_file_info_get_content_type (info) == NULL) {
+                if (item->priv->filename == NULL) {
+                        item->priv->mime_type = g_strdup ("image/x-no-data");
+                        g_free (item->priv->name);
+                        item->priv->name = g_strdup (_("No Desktop Background"));
+                        //item->priv->size = 0;
+                }
+        } else {
+                if (item->priv->name == NULL) {
+                        const char *name;
+
+                        g_free (item->priv->name);
+
+                        name = g_file_info_get_name (info);
+                        if (g_utf8_validate (name, -1, NULL))
+                                item->priv->name = g_strdup (name);
+                        else
+                                item->priv->name = g_filename_to_utf8 (name,
+                                                                       -1,
+                                                                       NULL,
+                                                                       NULL,
+                                                                       NULL);
+                }
+
+                item->priv->mime_type = g_strdup (g_file_info_get_content_type (info));
+
+#if 0
+                item->priv->size = g_file_info_get_size (info);
+                item->priv->mtime = g_file_info_get_attribute_uint64 (info,
+                                                                      G_FILE_ATTRIBUTE_TIME_MODIFIED);
+#endif
+        }
+
+        if (info != NULL)
+                g_object_unref (info);
 
-  item->pcolor = gdk_color_copy (&color1);
-  item->scolor = gdk_color_copy (&color2);
+}
 
-  set_bg_properties (item);
+static void
+on_bg_changed (GnomeBG          *bg,
+               CcBackgroundItem *item)
+{
+        g_signal_emit (item, signals[CHANGED], 0);
 }
 
-GnomeWPItem * cc_background_item_new (const gchar * filename,
-				 GHashTable * wallpapers,
-				 GFileInfo * file_info,
-				 GnomeDesktopThumbnailFactory * thumbnails) {
-  GnomeWPItem *item = g_new0 (GnomeWPItem, 1);
+gboolean
+cc_background_item_load (CcBackgroundItem *item,
+			 GFileInfo        *info)
+{
+        g_return_val_if_fail (item != NULL, FALSE);
+        g_return_val_if_fail (item->priv->filename != NULL, FALSE);
 
-  item->filename = g_strdup (filename);
-  item->fileinfo = gnome_wp_info_new (filename, file_info, thumbnails);
+        update_info (item, info);
 
-  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 (item->priv->mime_type != NULL
+            && (g_str_has_prefix (item->priv->mime_type, "image/")
+                || strcmp (item->priv->mime_type, "application/xml") == 0)) {
+                set_bg_properties (item);
+        } else {
+		return FALSE;
+        }
 
-    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);
+        update_size (item);
 
-    cc_background_item_update (item);
-    cc_background_item_ensure_gnome_bg (item);
-    cc_background_item_update_size (item, NULL);
+        return TRUE;
+}
 
-    if (wallpapers)
-      g_hash_table_insert (wallpapers, item->filename, item);
-  } else {
-    cc_background_item_free (item);
-    item = NULL;
-  }
+static void
+_set_name (CcBackgroundItem *item,
+           const char       *value)
+{
+        g_free (item->priv->name);
+        item->priv->name = g_strdup (value);
+}
+
+const char *
+cc_background_item_get_name (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
 
-  return item;
+	return item->priv->name;
 }
 
-void cc_background_item_free (GnomeWPItem * item) {
-  if (item == NULL) {
-    return;
-  }
+static void
+_set_filename (CcBackgroundItem *item,
+               const char       *value)
+{
+        g_free (item->priv->filename);
+        item->priv->filename = g_strdup (value);
+}
 
-  g_free (item->name);
-  g_free (item->filename);
-  g_free (item->size);
+const char *
+cc_background_item_get_filename (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
 
-  if (item->pcolor != NULL)
-    gdk_color_free (item->pcolor);
+	return item->priv->filename;
+}
 
-  if (item->scolor != NULL)
-    gdk_color_free (item->scolor);
+static void
+_set_placement (CcBackgroundItem        *item,
+                GDesktopBackgroundStyle  value)
+{
+        item->priv->placement = value;
+}
 
-  gnome_wp_info_free (item->fileinfo);
-  if (item->bg)
-    g_object_unref (item->bg);
+static void
+_set_shading (CcBackgroundItem          *item,
+              GDesktopBackgroundShading  value)
+{
+        item->priv->shading = value;
+}
 
-  gtk_tree_row_reference_free (item->rowref);
+static void
+_set_primary_color (CcBackgroundItem *item,
+                    const char       *value)
+{
+        g_free (item->priv->primary_color);
+        item->priv->primary_color = g_strdup (value);
+}
 
-  g_free (item->source_url);
+const char *
+cc_background_item_get_pcolor (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
 
-  g_free (item);
+	return item->priv->primary_color;
 }
 
-static GEmblem *
-get_slideshow_icon (void)
+static void
+_set_secondary_color (CcBackgroundItem *item,
+                      const char       *value)
 {
-	GIcon *themed;
-	GEmblem *emblem;
+        g_free (item->priv->secondary_color);
+        item->priv->secondary_color = g_strdup (value);
+}
 
-	themed = g_themed_icon_new ("slideshow-emblem");
-	emblem = g_emblem_new_with_origin (themed, G_EMBLEM_ORIGIN_DEVICE);
-	g_object_unref (themed);
-	return emblem;
+const char *
+cc_background_item_get_scolor (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
+
+	return item->priv->secondary_color;
 }
 
-GIcon * cc_background_item_get_frame_thumbnail (GnomeWPItem * item,
-					       GnomeDesktopThumbnailFactory * thumbs,
-                                               int width,
-                                               int height,
-                                               gint frame) {
-  GdkPixbuf *pixbuf = NULL;
-  GIcon *icon = NULL;
-
-  set_bg_properties (item);
-
-  if (frame >= 0)
-    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 && frame != -2 && gnome_bg_changes_with_time (item->bg))
-    {
-      GEmblem *emblem;
-
-      emblem = get_slideshow_icon ();
-      icon = g_emblemed_icon_new (G_ICON (pixbuf), emblem);
-      g_object_unref (emblem);
-      g_object_unref (pixbuf);
-    }
-  else
-    {
-      icon = G_ICON (pixbuf);
-    }
-
-  gnome_bg_get_image_size (item->bg, thumbs, width, height, &item->width, &item->height);
-
-  return icon;
-}
-
-
-GIcon * cc_background_item_get_thumbnail (GnomeWPItem * item,
-					 GnomeDesktopThumbnailFactory * thumbs,
-                                         gint width,
-                                         gint height) {
-  return cc_background_item_get_frame_thumbnail (item, thumbs, width, height, -1);
-}
-
-void cc_background_item_update_size (GnomeWPItem * item,
-				GnomeDesktopThumbnailFactory * thumbs) {
-  g_free (item->size);
-  item->size = NULL;
-
-  if (!strcmp (item->filename, "(none)")) {
-    item->size = g_strdup ("");
-  } else {
-    if (gnome_bg_has_multiple_sizes (item->bg) || gnome_bg_changes_with_time (item->bg))
-      item->size = g_strdup (_("multiple sizes"));
-    else {
-      if (thumbs != NULL && (item->width <= 0 || item->height <= 0)) {
-        gnome_bg_get_image_size (item->bg, thumbs, 1, 1, &item->width, &item->height);
-      }
-      if (item->width > 0 && item->height > 0) {
-        /* translators: 100 Ã? 100px
-         * Note that this is not an "x", but U+00D7 MULTIPLICATION SIGN */
-        item->size = g_strdup_printf (_("%d \303\227 %d"),
-				      item->width,
-				      item->height);
-      } else {
-        item->size = g_strdup ("");
-      }
-    }
-  }
+GDesktopBackgroundStyle
+cc_background_item_get_placement (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), G_DESKTOP_BACKGROUND_STYLE_SCALED);
+
+	return item->priv->placement;
+}
+
+GDesktopBackgroundShading
+cc_background_item_get_shading (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), G_DESKTOP_BACKGROUND_SHADING_SOLID);
+
+	return item->priv->shading;
+}
+
+static void
+_set_is_deleted (CcBackgroundItem *item,
+                 gboolean          value)
+{
+        item->priv->is_deleted = value;
+}
+
+static void
+_set_source_url (CcBackgroundItem *item,
+                 const char       *value)
+{
+        g_free (item->priv->source_url);
+        item->priv->source_url = g_strdup (value);
+}
+
+const char *
+cc_background_item_get_source_url (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
+
+	return item->priv->source_url;
+}
+
+static void
+_set_source_xml (CcBackgroundItem *item,
+                 const char       *value)
+{
+        g_free (item->priv->source_xml);
+        item->priv->source_xml = g_strdup (value);
+}
+
+const char *
+cc_background_item_get_source_xml (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
+
+	return item->priv->source_xml;
+}
+
+static void
+_set_flags (CcBackgroundItem      *item,
+            CcBackgroundItemFlags  value)
+{
+	item->priv->flags = value;
+}
+
+CcBackgroundItemFlags
+cc_background_item_get_flags (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), 0);
+
+	return item->priv->flags;
+}
+
+const char *
+cc_background_item_get_size (CcBackgroundItem *item)
+{
+	g_return_val_if_fail (CC_IS_BACKGROUND_ITEM (item), NULL);
+
+	return item->priv->size;
+}
+
+static void
+cc_background_item_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+        CcBackgroundItem *self;
+
+        self = CC_BACKGROUND_ITEM (object);
+
+        switch (prop_id) {
+        case PROP_NAME:
+                _set_name (self, g_value_get_string (value));
+                break;
+        case PROP_FILENAME:
+                _set_filename (self, g_value_get_string (value));
+                break;
+        case PROP_PLACEMENT:
+                _set_placement (self, g_value_get_enum (value));
+                break;
+        case PROP_SHADING:
+                _set_shading (self, g_value_get_enum (value));
+                break;
+        case PROP_PRIMARY_COLOR:
+                _set_primary_color (self, g_value_get_string (value));
+                break;
+        case PROP_SECONDARY_COLOR:
+                _set_secondary_color (self, g_value_get_string (value));
+                break;
+        case PROP_IS_DELETED:
+                _set_is_deleted (self, g_value_get_boolean (value));
+                break;
+	case PROP_SOURCE_URL:
+		_set_source_url (self, g_value_get_string (value));
+		break;
+	case PROP_SOURCE_XML:
+		_set_source_xml (self, g_value_get_string (value));
+		break;
+	case PROP_FLAGS:
+		_set_flags (self, g_value_get_flags (value));
+		break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+cc_background_item_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+        CcBackgroundItem *self;
+
+        self = CC_BACKGROUND_ITEM (object);
+
+        switch (prop_id) {
+        case PROP_NAME:
+                g_value_set_string (value, self->priv->name);
+                break;
+        case PROP_FILENAME:
+                g_value_set_string (value, self->priv->filename);
+                break;
+        case PROP_PLACEMENT:
+                g_value_set_enum (value, self->priv->placement);
+                break;
+        case PROP_SHADING:
+                g_value_set_enum (value, self->priv->shading);
+                break;
+        case PROP_PRIMARY_COLOR:
+                g_value_set_string (value, self->priv->primary_color);
+                break;
+        case PROP_SECONDARY_COLOR:
+                g_value_set_string (value, self->priv->secondary_color);
+                break;
+        case PROP_IS_DELETED:
+                g_value_set_boolean (value, self->priv->is_deleted);
+                break;
+	case PROP_SOURCE_URL:
+		g_value_set_string (value, self->priv->source_url);
+		break;
+	case PROP_SOURCE_XML:
+		g_value_set_string (value, self->priv->source_xml);
+		break;
+	case PROP_FLAGS:
+		g_value_set_flags (value, self->priv->flags);
+		break;
+	case PROP_SIZE:
+		g_value_set_string (value, self->priv->size);
+		break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static GObject *
+cc_background_item_constructor (GType                  type,
+                                guint                  n_construct_properties,
+                                GObjectConstructParam *construct_properties)
+{
+        CcBackgroundItem      *background_item;
+
+        background_item = CC_BACKGROUND_ITEM (G_OBJECT_CLASS (cc_background_item_parent_class)->constructor (type,
+                                                                                                                         n_construct_properties,
+                                                                                                                         construct_properties));
+
+        return G_OBJECT (background_item);
+}
+
+static void
+cc_background_item_class_init (CcBackgroundItemClass *klass)
+{
+        GObjectClass  *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->get_property = cc_background_item_get_property;
+        object_class->set_property = cc_background_item_set_property;
+        object_class->constructor = cc_background_item_constructor;
+        object_class->finalize = cc_background_item_finalize;
+
+        signals [CHANGED]
+                = g_signal_new ("changed",
+                                G_TYPE_FROM_CLASS (object_class),
+                                G_SIGNAL_RUN_LAST,
+                                0,
+                                NULL,
+                                NULL,
+                                g_cclosure_marshal_VOID__VOID,
+                                G_TYPE_NONE,
+                                0);
+
+        g_object_class_install_property (object_class,
+                                         PROP_NAME,
+                                         g_param_spec_string ("name",
+                                                              "name",
+                                                              "name",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+        g_object_class_install_property (object_class,
+                                         PROP_FILENAME,
+                                         g_param_spec_string ("filename",
+                                                              "filename",
+                                                              "filename",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+        g_object_class_install_property (object_class,
+                                         PROP_PLACEMENT,
+					 g_param_spec_enum ("placement",
+							    "placement",
+							    "placement",
+							    G_DESKTOP_TYPE_DESKTOP_BACKGROUND_STYLE,
+							    G_DESKTOP_BACKGROUND_STYLE_SCALED,
+							    G_PARAM_READWRITE));
+
+        g_object_class_install_property (object_class,
+                                         PROP_SHADING,
+                                         g_param_spec_enum ("shading",
+							    "shading",
+							    "shading",
+							    G_DESKTOP_TYPE_DESKTOP_BACKGROUND_SHADING,
+							    G_DESKTOP_BACKGROUND_SHADING_SOLID,
+							    G_PARAM_READWRITE));
+        g_object_class_install_property (object_class,
+                                         PROP_PRIMARY_COLOR,
+                                         g_param_spec_string ("primary-color",
+                                                              "primary-color",
+                                                              "primary-color",
+                                                              "#000000000000",
+                                                              G_PARAM_READWRITE));
+        g_object_class_install_property (object_class,
+                                         PROP_SECONDARY_COLOR,
+                                         g_param_spec_string ("secondary-color",
+                                                              "secondary-color",
+                                                              "secondary-color",
+                                                              "#000000000000",
+                                                              G_PARAM_READWRITE));
+
+        g_object_class_install_property (object_class,
+                                         PROP_IS_DELETED,
+                                         g_param_spec_boolean ("is-deleted",
+                                                               NULL,
+                                                               NULL,
+                                                               FALSE,
+                                                               G_PARAM_READWRITE));
+
+        g_object_class_install_property (object_class,
+                                         PROP_SOURCE_URL,
+                                         g_param_spec_string ("source-url",
+                                                              "source-url",
+                                                              "source-url",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+
+        g_object_class_install_property (object_class,
+                                         PROP_SOURCE_XML,
+                                         g_param_spec_string ("source-xml",
+                                                              "source-xml",
+                                                              "source-xml",
+                                                              NULL,
+                                                              G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_FLAGS,
+					 g_param_spec_flags ("flags",
+							     "flags",
+							     "flags",
+							     G_DESKTOP_TYPE_BACKGROUND_ITEM_FLAGS,
+							     0,
+							     G_PARAM_READWRITE));
+
+        g_object_class_install_property (object_class,
+                                         PROP_SIZE,
+                                         g_param_spec_string ("size",
+                                                              "size",
+                                                              "size",
+                                                              NULL,
+                                                              G_PARAM_READABLE));
+
+
+        g_type_class_add_private (klass, sizeof (CcBackgroundItemPrivate));
+}
+
+static void
+cc_background_item_init (CcBackgroundItem *item)
+{
+        item->priv = CC_BACKGROUND_ITEM_GET_PRIVATE (item);
+
+        item->priv->bg = gnome_bg_new ();
+
+        g_signal_connect (item->priv->bg,
+                          "changed",
+                          G_CALLBACK (on_bg_changed),
+                          item);
+
+        item->priv->shading = G_DESKTOP_BACKGROUND_SHADING_SOLID;
+        item->priv->placement = G_DESKTOP_BACKGROUND_STYLE_SCALED;
+        item->priv->primary_color = g_strdup ("#000000000000");
+        item->priv->secondary_color = g_strdup ("#000000000000");
+        item->priv->flags = 0;
+}
+
+static void
+cc_background_item_finalize (GObject *object)
+{
+        CcBackgroundItem *item;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (CC_IS_BACKGROUND_ITEM (object));
+
+        item = CC_BACKGROUND_ITEM (object);
+
+        g_return_if_fail (item->priv != NULL);
+
+        g_free (item->priv->name);
+        g_free (item->priv->filename);
+        g_free (item->priv->primary_color);
+        g_free (item->priv->secondary_color);
+        g_free (item->priv->mime_type);
+        g_free (item->priv->size);
+
+        if (item->priv->bg != NULL)
+                g_object_unref (item->priv->bg);
+
+        G_OBJECT_CLASS (cc_background_item_parent_class)->finalize (object);
+}
+
+CcBackgroundItem *
+cc_background_item_new (const char *filename)
+{
+        GObject *object;
+
+        object = g_object_new (CC_TYPE_BACKGROUND_ITEM,
+                               "filename", filename,
+                               NULL);
+
+        return CC_BACKGROUND_ITEM (object);
 }
diff --git a/panels/background/cc-background-item.h b/panels/background/cc-background-item.h
index 99b55ea..25ffed3 100644
--- a/panels/background/cc-background-item.h
+++ b/panels/background/cc-background-item.h
@@ -1,89 +1,97 @@
-/*
- *  Authors: Rodney Dawes <dobey ximian com>
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  *
- *  Copyright 2003-2006 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2010-2011 Red Hat, Inc.
  *
- *  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 free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *  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.
+ * 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.
+ * 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 Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
-#include <glib.h>
-#include <gio/gio.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gtk/gtk.h>
-#include <libgnome-desktop/gnome-desktop-thumbnail.h>
-#include <libgnome-desktop/gnome-bg.h>
-#include <gsettings-desktop-schemas/gdesktop-enums.h>
 
-#include "gnome-wp-info.h"
+#ifndef __CC_BACKGROUND_ITEM_H
+#define __CC_BACKGROUND_ITEM_H
+
+#include <glib-object.h>
 
-#ifndef _GNOME_WP_ITEM_H_
-#define _GNOME_WP_ITEM_H_
+#include <libgnome-desktop/gnome-desktop-thumbnail.h>
+#include <gsettings-desktop-schemas/gdesktop-enums.h>
+#include <libgnome-desktop/gnome-bg.h>
 
-#define WP_PATH_ID "org.gnome.desktop.background"
-#define WP_FILE_KEY "picture-filename"
-#define WP_OPTIONS_KEY "picture-options"
-#define WP_SHADING_KEY "color-shading-type"
-#define WP_PCOLOR_KEY "primary-color"
-#define WP_SCOLOR_KEY "secondary-color"
+G_BEGIN_DECLS
 
-typedef struct _GnomeWPItem GnomeWPItem;
+#define CC_TYPE_BACKGROUND_ITEM         (cc_background_item_get_type ())
+#define CC_BACKGROUND_ITEM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), CC_TYPE_BACKGROUND_ITEM, CcBackgroundItem))
+#define CC_BACKGROUND_ITEM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), CC_TYPE_BACKGROUND_ITEM, CcBackgroundItemClass))
+#define CC_IS_BACKGROUND_ITEM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), CC_TYPE_BACKGROUND_ITEM))
+#define CC_IS_BACKGROUND_ITEM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), CC_TYPE_BACKGROUND_ITEM))
+#define CC_BACKGROUND_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CC_TYPE_BACKGROUND_ITEM, CcBackgroundItemClass))
 
-struct _GnomeWPItem {
-  GnomeBG *bg;
+typedef enum {
+	CC_BACKGROUND_ITEM_HAS_SHADING = 1 << 0,
+	CC_BACKGROUND_ITEM_HAS_PLACEMENT = 1 << 1,
+	CC_BACKGROUND_ITEM_HAS_PCOLOR = 1 << 2,
+	CC_BACKGROUND_ITEM_HAS_SCOLOR = 1 << 3,
+	CC_BACKGROUND_ITEM_HAS_FNAME = 1 << 4
+} CcBackgroundItemFlags;
 
-  gchar * name;
-  gchar * filename;
-  gchar * size;
-  GDesktopBackgroundStyle options;
-  GDesktopBackgroundShading shade_type;
+#define CC_BACKGROUND_ITEM_HAS_ALL (CC_BACKGROUND_ITEM_HAS_SHADING &	\
+				    CC_BACKGROUND_ITEM_HAS_PLACEMENT &	\
+				    CC_BACKGROUND_ITEM_HAS_PCOLOR &	\
+				    CC_BACKGROUND_ITEM_HAS_SCOLOR &	\
+				    CC_BACKGROUND_ITEM_HAS_FNAME)
 
-  gchar * source_url;
+typedef struct CcBackgroundItemPrivate CcBackgroundItemPrivate;
 
-  /* Where the Item is in the List */
-  GtkTreeRowReference * rowref;
+typedef struct
+{
+        GObject                  parent;
+        CcBackgroundItemPrivate *priv;
+} CcBackgroundItem;
 
-  /* Real colors */
-  GdkColor * pcolor;
-  GdkColor * scolor;
+typedef struct
+{
+        GObjectClass   parent_class;
+        void (* changed)           (CcBackgroundItem *item);
+} CcBackgroundItemClass;
 
-  GnomeWPInfo * fileinfo;
+GType              cc_background_item_get_type (void);
 
-  /* Did the user remove us? */
-  gboolean deleted;
+CcBackgroundItem * cc_background_item_new                 (const char                   *filename);
+gboolean           cc_background_item_load                (CcBackgroundItem             *item,
+							   GFileInfo                    *info);
+gboolean           cc_background_item_changes_with_time   (CcBackgroundItem             *item);
 
-  /* Width and Height of the original image */
-  gint width;
-  gint height;
-};
+GIcon     *        cc_background_item_get_thumbnail       (CcBackgroundItem             *item,
+                                                           GnomeDesktopThumbnailFactory *thumbs,
+                                                           int                           width,
+                                                           int                           height);
+GIcon     *        cc_background_item_get_frame_thumbnail (CcBackgroundItem             *item,
+                                                           GnomeDesktopThumbnailFactory *thumbs,
+                                                           int                           width,
+                                                           int                           height,
+                                                           int                           frame);
 
-GnomeWPItem * cc_background_item_new (const gchar *filename,
-				 GHashTable *wallpapers,
-				 GFileInfo *file_info,
-				 GnomeDesktopThumbnailFactory *thumbnails);
+GDesktopBackgroundStyle   cc_background_item_get_placement  (CcBackgroundItem *item);
+GDesktopBackgroundShading cc_background_item_get_shading    (CcBackgroundItem *item);
+const char *              cc_background_item_get_filename   (CcBackgroundItem *item);
+const char *              cc_background_item_get_source_url (CcBackgroundItem *item);
+const char *              cc_background_item_get_source_xml (CcBackgroundItem *item);
+CcBackgroundItemFlags     cc_background_item_get_flags      (CcBackgroundItem *item);
+const char *              cc_background_item_get_pcolor     (CcBackgroundItem *item);
+const char *              cc_background_item_get_scolor     (CcBackgroundItem *item);
+const char *              cc_background_item_get_name       (CcBackgroundItem *item);
+const char *              cc_background_item_get_size       (CcBackgroundItem *item);
 
-void cc_background_item_free (GnomeWPItem *item);
-GIcon * cc_background_item_get_thumbnail (GnomeWPItem *item,
-				     GnomeDesktopThumbnailFactory *thumbs,
-				     gint width,
-				     gint height);
-GIcon * cc_background_item_get_frame_thumbnail (GnomeWPItem *item,
-					   GnomeDesktopThumbnailFactory *thumbs,
-					   gint width,
-					   gint height,
-					   gint frame);
-void cc_background_item_update (GnomeWPItem *item);
-void cc_background_item_update_size (GnomeWPItem *item, GnomeDesktopThumbnailFactory *thumbs);
-void cc_background_item_ensure_gnome_bg (GnomeWPItem *item);
+G_END_DECLS
 
-#endif
+#endif /* __CC_BACKGROUND_ITEM_H */
diff --git a/panels/background/cc-background-panel.c b/panels/background/cc-background-panel.c
index b1f351f..e77613e 100644
--- a/panels/background/cc-background-panel.c
+++ b/panels/background/cc-background-panel.c
@@ -21,6 +21,10 @@
 
 #include <config.h>
 
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <gsettings-desktop-schemas/gdesktop-enums.h>
+
 #include "cc-background-panel.h"
 #include "bg-wallpapers-source.h"
 #include "bg-pictures-source.h"
@@ -33,8 +37,12 @@
 #include "gnome-wp-xml.h"
 #include "cc-background-item.h"
 
-#include <string.h>
-#include <glib/gi18n-lib.h>
+#define WP_PATH_ID "org.gnome.desktop.background"
+#define WP_FILE_KEY "picture-filename"
+#define WP_OPTIONS_KEY "picture-options"
+#define WP_SHADING_KEY "color-shading-type"
+#define WP_PCOLOR_KEY "primary-color"
+#define WP_SCOLOR_KEY "secondary-color"
 
 enum {
   COL_SOURCE_NAME,
@@ -65,7 +73,7 @@ struct _CcBackgroundPanelPrivate
 
   GnomeDesktopThumbnailFactory *thumb_factory;
 
-  GnomeWPItem *current_background;
+  CcBackgroundItem *current_background;
   gboolean current_source_readonly;
   gint current_source;
 
@@ -198,7 +206,7 @@ cc_background_panel_finalize (GObject *object)
 
   if (priv->current_background)
     {
-      cc_background_item_free (priv->current_background);
+      g_object_unref (priv->current_background);
       priv->current_background = NULL;
     }
 
@@ -232,7 +240,7 @@ source_update_edit_box (CcBackgroundPanelPrivate *priv)
       gtk_widget_show (WID ("style-pcolor"));
 
       if (priv->current_background &&
-	  priv->current_background->shade_type == G_DESKTOP_BACKGROUND_SHADING_SOLID)
+	  cc_background_item_get_shading (priv->current_background) == G_DESKTOP_BACKGROUND_SHADING_SOLID)
         gtk_widget_hide (WID ("style-scolor"));
       else
         gtk_widget_show (WID ("style-scolor"));
@@ -259,12 +267,12 @@ setup_edit_box (CcBackgroundPanelPrivate *priv)
 {
   g_assert (priv->current_background);
 
-  if (g_str_equal (priv->current_background->filename, "(none)"))
+  if (cc_background_item_get_filename (priv->current_background) == NULL)
     {
       gtk_widget_hide (WID ("style-combobox"));
       gtk_widget_show (WID ("style-pcolor"));
 
-      if (priv->current_background->shade_type == G_DESKTOP_BACKGROUND_SHADING_SOLID)
+      if (cc_background_item_get_shading (priv->current_background) == G_DESKTOP_BACKGROUND_SHADING_SOLID)
         gtk_widget_hide (WID ("style-scolor"));
       else
         gtk_widget_show (WID ("style-scolor"));
@@ -363,7 +371,7 @@ select_style (GtkComboBox *box,
 
 static void
 update_preview (CcBackgroundPanelPrivate *priv,
-                GnomeWPItem              *item,
+                CcBackgroundItem         *item,
                 gboolean                  redraw_preview)
 {
   gchar *markup;
@@ -371,6 +379,17 @@ update_preview (CcBackgroundPanelPrivate *priv,
 
   if (item && priv->current_background)
     {
+      //FIXME is that correct?
+      g_object_unref (priv->current_background);
+      priv->current_background = g_object_ref (item);
+#if 0
+      g_object_set (G_OBJECT (priv->current_background),
+      		    "primary-color", cc_background_item_get_pcolor (item),
+      		    "secondary-color", cc_background_item_get_scolor (item),
+      		    "filename", cc_background_item_get_filename (item),
+      		    "placement", cc_background_item_get_placement (item),
+      		    "shading", cc_background_item_get_shading (item),
+
       if (priv->current_background->pcolor)
         gdk_color_free (priv->current_background->pcolor);
       priv->current_background->pcolor = gdk_color_copy (item->pcolor);
@@ -393,6 +412,7 @@ update_preview (CcBackgroundPanelPrivate *priv,
 
       cc_background_item_ensure_gnome_bg (priv->current_background);
       cc_background_item_update_size (priv->current_background, priv->thumb_factory);
+#endif
     }
 
   source_update_edit_box (priv);
@@ -401,22 +421,24 @@ update_preview (CcBackgroundPanelPrivate *priv,
 
   if (priv->current_background)
     {
-      markup = g_strdup_printf ("<b>%s</b>", priv->current_background->name);
+      GdkColor pcolor, scolor;
+
+      markup = g_strdup_printf ("<b>%s</b>", cc_background_item_get_name (priv->current_background));
       gtk_label_set_markup (GTK_LABEL (WID ("background-label")), markup);
       g_free (markup);
 
-      gtk_label_set_text (GTK_LABEL (WID ("size_label")), priv->current_background->size);
+      gtk_label_set_text (GTK_LABEL (WID ("size_label")), cc_background_item_get_size (priv->current_background));
+
+      gdk_color_parse (cc_background_item_get_pcolor (priv->current_background), &pcolor);
+      gdk_color_parse (cc_background_item_get_scolor (priv->current_background), &scolor);
 
-      gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-pcolor")),
-                                  priv->current_background->pcolor);
-      gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-scolor")),
-                                  priv->current_background->scolor);
+      gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-pcolor")), &pcolor);
+      gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-scolor")), &scolor);
 
       select_style (GTK_COMBO_BOX (WID ("style-combobox")),
-                    priv->current_background->options);
+                    cc_background_item_get_placement (priv->current_background));
 
-      if (priv->current_background->bg)
-        changes_with_time = gnome_bg_changes_with_time (priv->current_background->bg);
+      changes_with_time = cc_background_item_changes_with_time (priv->current_background);
     }
 
   gtk_widget_set_visible (WID ("slide_image"), changes_with_time);
@@ -433,10 +455,11 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
   GtkTreeIter iter;
   GList *list;
   GtkTreeModel *model;
-  GnomeWPItem *item;
-  gchar *pcolor, *scolor;
+  CcBackgroundItem *item;
   CcBackgroundPanelPrivate *priv = panel->priv;
+  char *pcolor, *scolor;
   gboolean draw_preview = TRUE;
+  const char *filename;
 
   list = gtk_icon_view_get_selected_items (icon_view);
 
@@ -449,8 +472,8 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
   gtk_combo_box_get_active_iter (GTK_COMBO_BOX (WID ("sources-combobox")),
                                  &iter);
   gtk_tree_model_get (model, &iter,
-  		      COL_SOURCE_READONLY, &priv->current_source_readonly,
-  		      COL_SOURCE_TYPE, &priv->current_source, -1);
+		      COL_SOURCE_READONLY, &priv->current_source_readonly,
+		      COL_SOURCE_TYPE, &priv->current_source, -1);
 
   model = gtk_icon_view_get_model (icon_view);
 
@@ -461,12 +484,14 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
 
   gtk_tree_model_get (model, &iter, 1, &item, -1);
 
-  if (!g_strcmp0 (item->filename, "(none)"))
+  filename = cc_background_item_get_filename (item);
+
+  if (filename == NULL)
     {
       g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, G_DESKTOP_BACKGROUND_STYLE_NONE);
       g_settings_set_string (priv->settings, WP_FILE_KEY, "");
     }
-  else if (item->source_url)
+  else if (cc_background_item_get_source_url (item) != NULL)
     {
       GFile *source, *dest;
       gchar *cache_path;
@@ -476,7 +501,7 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
                                      "gnome-background",
                                      NULL);
 
-      source = g_file_new_for_uri (item->source_url);
+      source = g_file_new_for_uri (cc_background_item_get_source_url (item));
       dest = g_file_new_for_path (cache_path);
 
       /* create a blank image to use until the source image is ready */
@@ -514,9 +539,8 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
                          copy_finished_cb, panel);
 
       g_settings_set_string (priv->settings, WP_FILE_KEY, cache_path);
-      g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, item->options);
-      g_free (item->filename);
-      item->filename = cache_path;
+      g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, cc_background_item_get_placement (item));
+      g_object_set (G_OBJECT (item), "filename", cache_path, NULL);
 
       /* delay the updated drawing of the preview until the copy finishes */
       draw_preview = FALSE;
@@ -525,15 +549,15 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
     {
        gchar *uri;
 
-       if (g_utf8_validate (item->filename, -1, NULL))
-         uri = g_strdup (item->filename);
+       //FIXME this is garbage, either use uri, or not
+       if (g_utf8_validate (filename, -1, NULL))
+         uri = g_strdup (filename);
        else
-         uri = g_filename_to_utf8 (item->filename, -1, NULL, NULL, NULL);
+         uri = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
 
        if (uri == NULL)
          {
-           g_warning ("Failed to convert filename to UTF-8: %s",
-                      item->filename);
+           g_warning ("Failed to convert filename to UTF-8: %s", filename);
          }
        else
          {
@@ -541,10 +565,10 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
            g_free (uri);
          }
 
-       g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, item->options);
+       g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, cc_background_item_get_placement (item));
     }
 
-  g_settings_set_enum (priv->settings, WP_SHADING_KEY, item->shade_type);
+  g_settings_set_enum (priv->settings, WP_SHADING_KEY, cc_background_item_get_shading (item));
 
   /* When changing for another colour, don't overwrite what's
    * in GSettings, but read from it instead */
@@ -552,20 +576,17 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
     {
       pcolor = g_settings_get_string (priv->settings, WP_PCOLOR_KEY);
       scolor = g_settings_get_string (priv->settings, WP_SCOLOR_KEY);
-      gdk_color_parse (pcolor, item->pcolor);
-      gdk_color_parse (scolor, item->scolor);
+      g_object_set (G_OBJECT (item),
+		    "primary-color", pcolor,
+		    "secondary-color", scolor,
+		    NULL);
     }
   else
     {
-      pcolor = gdk_color_to_string (item->pcolor);
-      scolor = gdk_color_to_string (item->scolor);
-      g_settings_set_string (priv->settings, WP_PCOLOR_KEY, pcolor);
-      g_settings_set_string (priv->settings, WP_SCOLOR_KEY, scolor);
+      g_settings_set_string (priv->settings, WP_PCOLOR_KEY, cc_background_item_get_pcolor (item));
+      g_settings_set_string (priv->settings, WP_SCOLOR_KEY, cc_background_item_get_scolor (item));
     }
 
-  g_free (pcolor);
-  g_free (scolor);
-
   /* Apply all changes */
   g_settings_apply (priv->settings);
 
@@ -668,7 +689,7 @@ style_changed_cb (GtkComboBox       *box,
   g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, value);
 
   if (priv->current_background)
-    priv->current_background->options = value;
+    g_object_set (G_OBJECT (priv->current_background), "placement", value, NULL);
 
   g_settings_apply (priv->settings);
 
@@ -688,20 +709,16 @@ color_changed_cb (GtkColorButton    *button,
   if (WID ("style-pcolor") == GTK_WIDGET (button))
     is_pcolor = TRUE;
 
+  value = gdk_color_to_string (&color);
+
   if (priv->current_background)
     {
-      if (is_pcolor)
-        *priv->current_background->pcolor = color;
-      else
-        *priv->current_background->scolor = color;
+      g_object_set (G_OBJECT (priv->current_background),
+		    is_pcolor ? "primary-color" : "secondary-color", value, NULL);
     }
 
-  value = gdk_color_to_string (&color);
-
-  if (is_pcolor)
-    g_settings_set_string (priv->settings, WP_PCOLOR_KEY, value);
-  else
-    g_settings_set_string (priv->settings, WP_SCOLOR_KEY, value);
+  g_settings_set_string (priv->settings,
+			 is_pcolor ? WP_PCOLOR_KEY : WP_SCOLOR_KEY, value);
 
   g_settings_apply (priv->settings);
 
@@ -822,19 +839,15 @@ cc_background_panel_init (CcBackgroundPanel *self)
 
   /* initalise the current background information from settings */
   filename = g_settings_get_string (priv->settings, WP_FILE_KEY);
-  if (!filename || !g_strcmp0 (filename, ""))
-    {
-      g_free (filename);
-      filename = g_strdup ("(none)");
-    }
-
-  priv->current_background = g_new0 (GnomeWPItem, 1);
-  priv->current_background->filename = filename;
-  priv->current_background->name = g_strdup (_("Current background"));
+  priv->current_background = cc_background_item_new (filename);
+  g_object_set (G_OBJECT (priv->current_background), "name", _("Current background"), NULL);
 
+  //FIXME call load?
+#if 0
   cc_background_item_update (priv->current_background);
   cc_background_item_ensure_gnome_bg (priv->current_background);
   cc_background_item_update_size (priv->current_background, priv->thumb_factory);
+#endif
 
   update_preview (priv, NULL, TRUE);
 
diff --git a/panels/background/gnome-wp-xml.c b/panels/background/gnome-wp-xml.c
index fd77fdc..46b2fe2 100644
--- a/panels/background/gnome-wp-xml.c
+++ b/panels/background/gnome-wp-xml.c
@@ -18,18 +18,15 @@
  *
  */
 
-#include "cc-background-item.h"
-#include "gnome-wp-xml.h"
 #include <gio/gio.h>
 #include <string.h>
 #include <libxml/parser.h>
 #include <libgnome-desktop/gnome-bg.h>
 #include <gsettings-desktop-schemas/gdesktop-enums.h>
 
-static const gchar *wp_item_option_to_string (GDesktopBackgroundStyle type);
-static const gchar *wp_item_shading_to_string (GDesktopBackgroundShading type);
-static GDesktopBackgroundStyle wp_item_string_to_option (const gchar *option);
-static GDesktopBackgroundShading wp_item_string_to_shading (const gchar *shade_type);
+#include "gdesktop-enums-types.h"
+#include "cc-background-item.h"
+#include "gnome-wp-xml.h"
 
 static gboolean gnome_wp_xml_get_bool (const xmlNode * parent,
 				       const gchar * prop_name) {
@@ -52,6 +49,7 @@ static gboolean gnome_wp_xml_get_bool (const xmlNode * parent,
   return ret_val;
 }
 
+#if 0
 static void gnome_wp_xml_set_bool (const xmlNode * parent,
 				   const xmlChar * prop_name, gboolean value) {
   g_return_if_fail (parent != NULL);
@@ -63,6 +61,44 @@ static void gnome_wp_xml_set_bool (const xmlNode * parent,
     xmlSetProp ((xmlNode *) parent, prop_name, (xmlChar *)"false");
   }
 }
+#endif
+
+static struct {
+	int value;
+	const char *string;
+} lookups[] = {
+	{ G_DESKTOP_BACKGROUND_SHADING_HORIZONTAL, "horizontal-gradient" },
+	{ G_DESKTOP_BACKGROUND_SHADING_VERTICAL, "vertical-gradient" },
+};
+
+static int
+enum_string_to_value (GType type,
+		      const char *string)
+{
+	GEnumClass *eclass;
+	GEnumValue *value;
+
+	eclass = G_ENUM_CLASS (g_type_class_peek (type));
+	value = g_enum_get_value_by_nick (eclass, string);
+
+	/* Here's a bit of hand-made parsing, bad bad */
+	if (value == NULL) {
+		guint i;
+		for (i = 0; i < G_N_ELEMENTS (lookups); i++) {
+			if (g_str_equal (lookups[i].string, string))
+				return lookups[i].value;
+		}
+		g_warning ("Unhandled value '%s' for enum '%s'",
+			   string, G_FLAGS_CLASS_TYPE_NAME (eclass));
+		g_assert_not_reached ();
+	}
+
+	return value->value;
+}
+
+#define NONE "(none)"
+#define UNSET_FLAG(flag) G_STMT_START{ (flags&=~(flag)); }G_STMT_END
+#define SET_FLAG(flag) G_STMT_START{ (flags|=flag); }G_STMT_END
 
 static void gnome_wp_xml_load_xml (GnomeWpXml *data,
 				   const gchar * filename) {
@@ -70,8 +106,8 @@ static void gnome_wp_xml_load_xml (GnomeWpXml *data,
   xmlNode * root, * list, * wpa;
   xmlChar * nodelang;
   const gchar * const * syslangs;
-  GdkColor color1, color2;
   gint i;
+  char *fname;
 
   wplist = xmlParseFile (filename);
 
@@ -79,74 +115,91 @@ static void gnome_wp_xml_load_xml (GnomeWpXml *data,
     return;
 
   syslangs = g_get_language_names ();
+  fname = NULL;
 
   root = xmlDocGetRootElement (wplist);
 
   for (list = root->children; list != NULL; list = list->next) {
     if (!strcmp ((gchar *)list->name, "wallpaper")) {
-      GnomeWPItem * wp;
+      CcBackgroundItem * item;
+      CcBackgroundItemFlags flags = 0;
       gchar *pcolor = NULL, *scolor = NULL;
-      gboolean have_scale = FALSE, have_shade = FALSE;
 
-      wp = g_new0 (GnomeWPItem, 1);
+      item = cc_background_item_new (NULL);
 
-      wp->deleted = gnome_wp_xml_get_bool (list, "deleted");
+      g_object_set (G_OBJECT (item),
+		    "is-deleted", gnome_wp_xml_get_bool (list, "deleted"),
+		    "source-xml", filename,
+		    NULL);
 
       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);
+	    if (strcmp (content, NONE) == 0) {
+	      fname = NULL;
+	    } else if (g_utf8_validate (content, -1, NULL) &&
+		     g_file_test (content, G_FILE_TEST_EXISTS)) {
+	      fname = g_strdup (content);
+	    } else {
+	      fname = g_filename_from_utf8 (content, -1, NULL, NULL, NULL);
+	    }
+	    SET_FLAG(CC_BACKGROUND_ITEM_HAS_FNAME);
+	    g_object_set (G_OBJECT (item), "filename", fname, NULL);
 	  } else {
 	    break;
 	  }
 	} else if (!strcmp ((gchar *)wpa->name, "name")) {
 	  if (wpa->last != NULL && wpa->last->content != NULL) {
+	    char *name;
 	    nodelang = xmlNodeGetLang (wpa->last);
 
-	    if (wp->name == NULL && nodelang == NULL) {
-	       wp->name = g_strdup (g_strstrip ((gchar *)wpa->last->content));
+	    g_object_get (G_OBJECT (item), "name", &name, NULL);
+
+	    if (name == NULL && nodelang == NULL) {
+	       g_object_set (G_OBJECT (item), "name",
+			     g_strstrip ((gchar *)wpa->last->content), NULL);
             } 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));
+		   g_object_set (G_OBJECT (item), "name",
+				 g_strstrip ((gchar *)wpa->last->content), NULL);
 	           break;
 	         }
 	       }
 	    }
 
+	    g_free (name);
 	    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;
+	    g_object_set (G_OBJECT (item), "placement",
+			  enum_string_to_value (G_DESKTOP_TYPE_DESKTOP_BACKGROUND_STYLE,
+						g_strstrip ((gchar *)wpa->last->content)), NULL);
+	    SET_FLAG(CC_BACKGROUND_ITEM_HAS_PLACEMENT);
 	  }
 	} 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;
+	    g_object_set (G_OBJECT (item), "shading",
+			  enum_string_to_value (G_DESKTOP_TYPE_DESKTOP_BACKGROUND_SHADING,
+						g_strstrip ((gchar *)wpa->last->content)), NULL);
+	    SET_FLAG(CC_BACKGROUND_ITEM_HAS_SHADING);
 	  }
 	} else if (!strcmp ((gchar *)wpa->name, "pcolor")) {
 	  if (wpa->last != NULL) {
 	    pcolor = g_strdup (g_strstrip ((gchar *)wpa->last->content));
+	    SET_FLAG(CC_BACKGROUND_ITEM_HAS_PCOLOR);
 	  }
 	} else if (!strcmp ((gchar *)wpa->name, "scolor")) {
 	  if (wpa->last != NULL) {
 	    scolor = g_strdup (g_strstrip ((gchar *)wpa->last->content));
+	    SET_FLAG(CC_BACKGROUND_ITEM_HAS_SCOLOR);
 	  }
 	} else if (!strcmp ((gchar *)wpa->name, "text")) {
 	  /* Do nothing here, libxml2 is being weird */
@@ -156,57 +209,39 @@ static void gnome_wp_xml_load_xml (GnomeWpXml *data,
       }
 
       /* 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) {
+      if (fname == NULL ||
+	  g_hash_table_lookup (data->wp_hash, fname) != NULL) {
 
-	cc_background_item_free (wp);
+	g_object_unref (item);
 	g_free (pcolor);
 	g_free (scolor);
 	continue;
       }
 
       /* Verify the colors and alloc some GdkColors here */
-      if (!have_scale) {
-        wp->options = g_settings_get_enum (data->settings, WP_OPTIONS_KEY);
-      }
+      if (pcolor)
+        g_object_set (G_OBJECT (item), "primary-color", pcolor, NULL);
+      if (scolor)
+        g_object_set (G_OBJECT (item), "secondary-color", scolor, NULL);
 
-      if (!have_shade) {
-        wp->shade_type = g_settings_get_enum (data->settings, WP_SHADING_KEY);
-      }
+      g_object_set (G_OBJECT (item), "flags", flags, NULL);
 
-      if (pcolor == NULL) {
-	pcolor = g_settings_get_string (data->settings, WP_PCOLOR_KEY);
-      }
-      if (scolor == NULL) {
-	scolor = g_settings_get_string (data->settings, WP_SCOLOR_KEY);
-      }
-      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, NULL, data->thumb_factory);
-
-	if (wp->name == NULL || !strcmp (wp->filename, "(none)")) {
-	  g_free (wp->name);
-	  wp->name = g_strdup (wp->fileinfo->name);
-	}
-
+      if (fname != NULL) {
+#if 0
         cc_background_item_ensure_gnome_bg (wp);
 	cc_background_item_update_size (wp, NULL);
-	g_hash_table_insert (data->wp_hash, wp->filename, wp);
+#endif
+	g_hash_table_insert (data->wp_hash, g_strdup (filename), item);
       } else {
-	cc_background_item_free (wp);
-        wp = NULL;
+	g_object_unref (item);
+        item = NULL;
       }
     }
   }
+  g_free (fname);
   xmlFreeDoc (wplist);
 }
 
@@ -355,15 +390,18 @@ void gnome_wp_xml_load_list_async (GnomeWpXml *data,
 	g_object_unref (result);
 }
 
-static void gnome_wp_list_flatten (const gchar * key, GnomeWPItem * item,
+#if 0
+static void gnome_wp_list_flatten (const gchar * key, CcBackgroundItem * item,
 				   GSList ** list) {
   g_return_if_fail (key != NULL);
   g_return_if_fail (item != NULL);
 
   *list = g_slist_prepend (*list, item);
 }
-
+#endif
 void gnome_wp_xml_save_list (GnomeWpXml *data) {
+	//FIXME implement save or remove?
+#if 0
   xmlDoc * wplist;
   xmlNode * root, * wallpaper, * item;
   GSList * list = NULL;
@@ -387,7 +425,7 @@ void gnome_wp_xml_save_list (GnomeWpXml *data) {
   xmlDocSetRootElement (wplist, root);
 
   while (list != NULL) {
-    GnomeWPItem * wpitem = list->data;
+    CcBackgroundItem * wpitem = list->data;
     const char * none = "(none)";
     gchar * filename;
     const gchar * scale, * shade;
@@ -418,83 +456,11 @@ void gnome_wp_xml_save_list (GnomeWpXml *data) {
     g_free (filename);
 
     list = g_slist_delete_link (list, list);
-    cc_background_item_free (wpitem);
+    g_object_unref (wpitem);
   }
   xmlSaveFormatFile (wpfile, wplist, 1);
   xmlFreeDoc (wplist);
   g_free (wpfile);
+#endif
 }
 
-static struct {
-  GDesktopBackgroundStyle value;
-  gchar *string;
-} options_lookup[] = {
-  { G_DESKTOP_BACKGROUND_STYLE_CENTERED, "centered" },
-  { G_DESKTOP_BACKGROUND_STYLE_STRETCHED, "stretched" },
-  { G_DESKTOP_BACKGROUND_STYLE_SCALED, "scaled" },
-  { G_DESKTOP_BACKGROUND_STYLE_ZOOM, "zoom" },
-  { G_DESKTOP_BACKGROUND_STYLE_WALLPAPER, "wallpaper" },
-  { G_DESKTOP_BACKGROUND_STYLE_SPANNED, "spanned" },
-  { 0, NULL }
-};
-
-static struct {
-  GDesktopBackgroundShading value;
-  gchar *string;
-} shade_lookup[] = {
-  { G_DESKTOP_BACKGROUND_SHADING_SOLID, "solid" },
-  { G_DESKTOP_BACKGROUND_SHADING_HORIZONTAL, "horizontal-gradient" },
-  { G_DESKTOP_BACKGROUND_SHADING_VERTICAL, "vertical-gradient" },
-  { 0, NULL }
-};
-
-static const
-gchar *wp_item_option_to_string (GDesktopBackgroundStyle type)
-{
-  int i;
-
-  for (i = 0; options_lookup[i].value != 0; i++) {
-    if (options_lookup[i].value == type)
-      return (const gchar *) options_lookup[i].string;
-  }
-
-  return "scaled";
-}
-
-static const
-gchar *wp_item_shading_to_string (GDesktopBackgroundShading type)
-{
-  int i;
-
-  for (i = 0; shade_lookup[i].value != 0; i++) {
-    if (shade_lookup[i].value == type)
-      return (const gchar *) shade_lookup[i].string;
-  }
-
-  return "solid";
-}
-
-static GDesktopBackgroundStyle
-wp_item_string_to_option (const gchar *option)
-{
-  gint i;
-
-  for (i = 0; options_lookup[i].value != 0; i++) {
-    if (g_str_equal (options_lookup[i].string, option))
-      return options_lookup[i].value;
-  }
-
-  return G_DESKTOP_BACKGROUND_STYLE_SCALED;
-}
-
-static GDesktopBackgroundShading
-wp_item_string_to_shading (const gchar *shade_type)
-{
-  int i;
-
-  for (i = 0; shade_lookup[i].value != 0; i++) {
-    if (g_str_equal (shade_lookup[i].string, shade_type))
-      return options_lookup[i].value;
-  }
-  return G_DESKTOP_BACKGROUND_SHADING_SOLID;
-}
diff --git a/panels/background/gnome-wp-xml.h b/panels/background/gnome-wp-xml.h
index 178e2cb..a4b9a6a 100644
--- a/panels/background/gnome-wp-xml.h
+++ b/panels/background/gnome-wp-xml.h
@@ -22,6 +22,7 @@
 #define _GNOME_WP_XML_H_
 
 #include <libgnome-desktop/gnome-desktop-thumbnail.h>
+#include <gtk/gtk.h>
 #include <gio/gio.h>
 
 typedef struct _GnomeWpXml GnomeWpXml;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]