diff --git a/configure.ac b/configure.ac index 4bec8d03c..4839fdb3e 100644 --- a/configure.ac +++ b/configure.ac @@ -274,6 +274,23 @@ AC_MSG_RESULT([$enable_examples]) AM_CONDITIONAL(BUILD_EXAMPLES, test "x$enable_examples" = "xyes") +dnl ============================================== +dnl libsocialweb +dnl ============================================== + +AC_MSG_CHECKING([Enable libsocialweb support]) +AC_ARG_WITH([libsocialweb], + AC_HELP_STRING([--with-libsocialweb], + [enable libsocialweb support]),, + [with_libsocialweb=no]) +AC_MSG_RESULT([$with_libsocialweb]) + +if test "x$with_libsocialweb" == "xyes"; then + PKG_CHECK_MODULES(SOCIALWEB, libsocialweb-client) + AC_DEFINE(HAVE_LIBSOCIALWEB, 1, [Defined if libsocialweb is available]) +fi +AM_CONDITIONAL(WITH_LIBSOCIALWEB, test "x$with_libsocialweb" = "xyes") + dnl ======================================= dnl Update Mime Database @@ -356,6 +373,8 @@ help/Makefile libgnome-control-center/Makefile libgnome-control-center/libgnome-control-center.pc panels/Makefile +panels/background/Makefile +panels/background/gnome-background-panel.desktop.in panels/datetime/Makefile panels/datetime/gnome-datetime-panel.desktop.in panels/default-applications/Makefile diff --git a/panels/Makefile.am b/panels/Makefile.am index 66a22e3b9..8e989f9e6 100644 --- a/panels/Makefile.am +++ b/panels/Makefile.am @@ -1,4 +1,6 @@ -SUBDIRS=display \ +SUBDIRS= \ + background \ + display \ mouse \ keyboard \ network \ diff --git a/panels/background/Makefile.am b/panels/background/Makefile.am new file mode 100644 index 000000000..aa9f1a1d8 --- /dev/null +++ b/panels/background/Makefile.am @@ -0,0 +1,53 @@ +# This is used in GNOMECC_CAPPLETS_CFLAGS +cappletname = background + +uidir = $(pkgdatadir)/ui/background +dist_ui_DATA = \ + background.ui + + +INCLUDES = \ + $(PANEL_CFLAGS) \ + $(GNOMECC_CAPPLETS_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \ + -DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \ + -DDATADIR="\"$(uidir)\"" \ + -DGNOME_DESKTOP_USE_UNSTABLE_API \ + $(NULL) + +ccpanelsdir = $(PANELS_DIR) +ccpanels_LTLIBRARIES = libbackground.la + +libbackground_la_SOURCES = \ + background-module.c \ + cc-background-panel.c \ + cc-background-panel.h \ + bg-pictures-source.c \ + bg-pictures-source.h \ + bg-wallpapers-source.c \ + bg-wallpapers-source.h \ + bg-colors-source.c \ + bg-colors-source.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_la_LIBADD = $(PANEL_LIBS) $(DBUS_LIBS) +libbackground_la_LDFLAGS = $(PANEL_LDFLAGS) + +if WITH_LIBSOCIALWEB +libbackground_la_SOURCES += bg-flickr-source.c bg-flickr-source.h +INCLUDES += $(SOCIALWEB_CFLAGS) +libbackground_la_LIBADD += $(SOCIALWEB_LIBS) +endif + +@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) + +-include $(top_srcdir)/git.mk diff --git a/panels/background/background-module.c b/panels/background/background-module.c new file mode 100644 index 000000000..0571f5ec6 --- /dev/null +++ b/panels/background/background-module.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + +#include + +#include "cc-background-panel.h" + +#include + +void +g_io_module_load (GIOModule *module) +{ + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + + /* register the panel */ + cc_background_panel_register (module); +} + +void +g_io_module_unload (GIOModule *module) +{ +} diff --git a/panels/background/background.ui b/panels/background/background.ui new file mode 100644 index 000000000..0cd11546a --- /dev/null +++ b/panels/background/background.ui @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + Tile + wallpaper + + + Zoom + zoom + + + Center + centered + + + Scale + scaled + + + Fill + stretched + + + Span + spanned + + + + + + + + + + + + + + + + + + + + + + + + + True + vertical + 12 + + + True + 12 + + + 150 + True + True + automatic + automatic + in + + + True + True + sources-liststore + False + False + 0 + + + Sources + + + + 0 + + + + + + + + + False + 0 + + + + + 400 + 300 + True + True + automatic + automatic + in + + + True + True + 4 + 4 + 4 + + + + 0 + + + + + + + 1 + + + + + 0 + + + + + 175 + True + 12 + + + 200 + True + + + False + 0 + + + + + True + vertical + 12 + + + True + 0 + + + 0 + + + + + True + 12 + + + True + style-liststore + 0 + + + + 0 + + + + + False + 0 + + + + + True + True + True + #000000000000 + + + False + 1 + + + + + False + 1 + + + + + 1 + + + + + False + 1 + + + + diff --git a/panels/background/bg-colors-source.c b/panels/background/bg-colors-source.c new file mode 100644 index 000000000..26e697d89 --- /dev/null +++ b/panels/background/bg-colors-source.c @@ -0,0 +1,158 @@ +/* bg-colors-source.c */ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + +#include +#include "bg-colors-source.h" + +#include "gnome-wp-item.h" + +#include + +G_DEFINE_TYPE (BgColorsSource, bg_colors_source, G_TYPE_OBJECT) + +#define COLORS_SOURCE_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), BG_TYPE_COLORS_SOURCE, BgColorsSourcePrivate)) + +struct _BgColorsSourcePrivate +{ + GtkListStore *store; +}; + + +static void +bg_colors_source_dispose (GObject *object) +{ + BgColorsSourcePrivate *priv = BG_COLORS_SOURCE (object)->priv; + + if (priv->store) + { + g_object_unref (priv->store); + priv->store = NULL; + } + + G_OBJECT_CLASS (bg_colors_source_parent_class)->dispose (object); +} + +static void +bg_colors_source_finalize (GObject *object) +{ + G_OBJECT_CLASS (bg_colors_source_parent_class)->finalize (object); +} + +static void +bg_colors_source_class_init (BgColorsSourceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (BgColorsSourcePrivate)); + + object_class->dispose = bg_colors_source_dispose; + object_class->finalize = bg_colors_source_finalize; +} + +static gchar *colors[] = +{ + "#c4a000", + "#ce5c00", + "#8f5902", + "#4e9a06", + "#204a87", + "#5c3566", + "#a40000", + "#babdb6", + "#2e3436", + "#000000", + NULL +}; + +static gchar *color_names[] = +{ + N_("Butter"), + N_("Orange"), + N_("Chocolate"), + N_("Chameleon"), + N_("Blue"), + N_("Plum"), + N_("Red"), + N_("Aluminium"), + N_("Gray"), + N_("Black"), + NULL +}; + +static void +bg_colors_source_init (BgColorsSource *self) +{ + GnomeDesktopThumbnailFactory *thumb_factory; + BgColorsSourcePrivate *priv; + gchar **c, **n; + + + priv = self->priv = COLORS_SOURCE_PRIVATE (self); + + priv->store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_POINTER); + + thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL); + + for (c = colors, n = color_names; *c; c++, n++) + { + GnomeWPItem *item; + GdkPixbuf *pixbuf; + GdkColor color; + + item = g_new0 (GnomeWPItem, 1); + + item->filename = g_strdup ("(none)"); + item->name = g_strdup (_(*n)); + + gdk_color_parse (*c, &color); + item->pcolor = gdk_color_copy (&color); + item->scolor = gdk_color_copy (&color); + + item->shade_type = GNOME_BG_COLOR_SOLID; + + gnome_wp_item_ensure_gnome_bg (item); + + /* insert the item into the liststore */ + pixbuf = gnome_wp_item_get_thumbnail (item, + thumb_factory, + 100, 75); + gtk_list_store_insert_with_values (priv->store, NULL, 0, + 0, pixbuf, + 1, item, + -1); + } + + g_object_unref (thumb_factory); +} + +BgColorsSource * +bg_colors_source_new (void) +{ + return g_object_new (BG_TYPE_COLORS_SOURCE, NULL); +} + +GtkListStore * +bg_colors_source_get_liststore (BgColorsSource *source) +{ + return source->priv->store; +} diff --git a/panels/background/bg-colors-source.h b/panels/background/bg-colors-source.h new file mode 100644 index 000000000..395b628f1 --- /dev/null +++ b/panels/background/bg-colors-source.h @@ -0,0 +1,75 @@ +/* bg-colors-source.h */ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + +#ifndef _BG_COLORS_SOURCE_H +#define _BG_COLORS_SOURCE_H + +#include + +G_BEGIN_DECLS + +#define BG_TYPE_COLORS_SOURCE bg_colors_source_get_type() + +#define BG_COLORS_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + BG_TYPE_COLORS_SOURCE, BgColorsSource)) + +#define BG_COLORS_SOURCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + BG_TYPE_COLORS_SOURCE, BgColorsSourceClass)) + +#define BG_IS_COLORS_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + BG_TYPE_COLORS_SOURCE)) + +#define BG_IS_COLORS_SOURCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + BG_TYPE_COLORS_SOURCE)) + +#define BG_COLORS_SOURCE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + BG_TYPE_COLORS_SOURCE, BgColorsSourceClass)) + +typedef struct _BgColorsSource BgColorsSource; +typedef struct _BgColorsSourceClass BgColorsSourceClass; +typedef struct _BgColorsSourcePrivate BgColorsSourcePrivate; + +struct _BgColorsSource +{ + GObject parent; + + BgColorsSourcePrivate *priv; +}; + +struct _BgColorsSourceClass +{ + GObjectClass parent_class; +}; + +GType bg_colors_source_get_type (void) G_GNUC_CONST; + +BgColorsSource *bg_colors_source_new (void); +GtkListStore * bg_colors_source_get_liststore (BgColorsSource *source); + +G_END_DECLS + +#endif /* _BG_COLORS_SOURCE_H */ diff --git a/panels/background/bg-flickr-source.c b/panels/background/bg-flickr-source.c new file mode 100644 index 000000000..50637d8c0 --- /dev/null +++ b/panels/background/bg-flickr-source.c @@ -0,0 +1,183 @@ +/* bg-flickr-source.c */ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + +#include "bg-flickr-source.h" + +#include +#include +#include + +#include "gnome-wp-item.h" + +G_DEFINE_TYPE (BgFlickrSource, bg_flickr_source, G_TYPE_OBJECT) + +#define FLICKR_SOURCE_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), BG_TYPE_FLICKR_SOURCE, BgFlickrSourcePrivate)) + +struct _BgFlickrSourcePrivate +{ + GtkListStore *store; + + SwClient *client; + SwClientService *service; +}; + + +static void +bg_flickr_source_dispose (GObject *object) +{ + BgFlickrSourcePrivate *priv = BG_FLICKR_SOURCE (object)->priv; + + if (priv->store) + { + g_object_unref (priv->store); + priv->store = NULL; + } + + if (priv->client) + { + g_object_unref (priv->client); + priv->client = NULL; + } + + if (priv->service) + { + g_object_unref (priv->service); + priv->service = NULL; + } + + G_OBJECT_CLASS (bg_flickr_source_parent_class)->dispose (object); +} + +static void +bg_flickr_source_finalize (GObject *object) +{ + G_OBJECT_CLASS (bg_flickr_source_parent_class)->finalize (object); +} + +static void +bg_flickr_source_class_init (BgFlickrSourceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (BgFlickrSourcePrivate)); + + object_class->dispose = bg_flickr_source_dispose; + object_class->finalize = bg_flickr_source_finalize; +} + +static void +_view_items_added_cb (SwClientItemView *item_view, + GList *items, + gpointer userdata) +{ + GList *l; + BgFlickrSourcePrivate *priv = (BgFlickrSourcePrivate *) userdata; + + for (l = items; l; l = l->next) + { + GnomeWPItem *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->options = GNOME_BG_PLACEMENT_ZOOMED; + 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")); + + item->pcolor = gdk_color_copy (&color); + item->scolor = gdk_color_copy (&color); + + item->shade_type = GNOME_BG_COLOR_SOLID; + + gnome_wp_item_ensure_gnome_bg (item); + + /* insert the item into the liststore */ + thumb_url = sw_item_get_value (sw_item, "thumbnail"); + pixbuf = gdk_pixbuf_new_from_file_at_scale (thumb_url, 100, 75, TRUE, + NULL); + gtk_list_store_insert_with_values (priv->store, NULL, 0, + 0, pixbuf, + 1, item, + -1); + } +} + +static void +_query_open_view_cb (SwClientService *service, + SwClientItemView *item_view, + gpointer userdata) +{ + + if (!item_view) + { + g_warning ("Could not connect to Flickr service"); + return; + } + + g_signal_connect (item_view, + "items-added", + (GCallback)_view_items_added_cb, + userdata); + sw_client_item_view_start (item_view); +} + +static void +bg_flickr_source_init (BgFlickrSource *self) +{ + GnomeDesktopThumbnailFactory *thumb_factory; + BgFlickrSourcePrivate *priv; + + priv = self->priv = FLICKR_SOURCE_PRIVATE (self); + + priv->client = sw_client_new (); + priv->service = sw_client_get_service (priv->client, "flickr"); + sw_client_service_query_open_view (priv->service, + "feed", + NULL, + _query_open_view_cb, + priv); + + priv->store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_POINTER); + + thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL); + + + + g_object_unref (thumb_factory); +} + +BgFlickrSource * +bg_flickr_source_new (void) +{ + return g_object_new (BG_TYPE_FLICKR_SOURCE, NULL); +} + +GtkListStore * +bg_flickr_source_get_liststore (BgFlickrSource *source) +{ + return source->priv->store; +} diff --git a/panels/background/bg-flickr-source.h b/panels/background/bg-flickr-source.h new file mode 100644 index 000000000..880341f83 --- /dev/null +++ b/panels/background/bg-flickr-source.h @@ -0,0 +1,75 @@ +/* bg-flickr-source.h */ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + +#ifndef _BG_FLICKR_SOURCE_H +#define _BG_FLICKR_SOURCE_H + +#include + +G_BEGIN_DECLS + +#define BG_TYPE_FLICKR_SOURCE bg_flickr_source_get_type() + +#define BG_FLICKR_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + BG_TYPE_FLICKR_SOURCE, BgFlickrSource)) + +#define BG_FLICKR_SOURCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + BG_TYPE_FLICKR_SOURCE, BgFlickrSourceClass)) + +#define BG_IS_FLICKR_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + BG_TYPE_FLICKR_SOURCE)) + +#define BG_IS_FLICKR_SOURCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + BG_TYPE_FLICKR_SOURCE)) + +#define BG_FLICKR_SOURCE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + BG_TYPE_FLICKR_SOURCE, BgFlickrSourceClass)) + +typedef struct _BgFlickrSource BgFlickrSource; +typedef struct _BgFlickrSourceClass BgFlickrSourceClass; +typedef struct _BgFlickrSourcePrivate BgFlickrSourcePrivate; + +struct _BgFlickrSource +{ + GObject parent; + + BgFlickrSourcePrivate *priv; +}; + +struct _BgFlickrSourceClass +{ + GObjectClass parent_class; +}; + +GType bg_flickr_source_get_type (void) G_GNUC_CONST; + +BgFlickrSource *bg_flickr_source_new (void); +GtkListStore * bg_flickr_source_get_liststore (BgFlickrSource *source); + +G_END_DECLS + +#endif /* _BG_FLICKR_SOURCE_H */ diff --git a/panels/background/bg-pictures-source.c b/panels/background/bg-pictures-source.c new file mode 100644 index 000000000..e5845448a --- /dev/null +++ b/panels/background/bg-pictures-source.c @@ -0,0 +1,280 @@ +/* bg-pictures-source.c */ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + +#include "bg-pictures-source.h" + +#include "gnome-wp-item.h" + +#include +#include +#include + + +G_DEFINE_TYPE (BgPicturesSource, bg_pictures_source, G_TYPE_OBJECT) + +#define PICTURES_SOURCE_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), BG_TYPE_PICTURES_SOURCE, BgPicturesSourcePrivate)) + +struct _BgPicturesSourcePrivate +{ + GtkListStore *liststore; + + GFile *dir; + + GCancellable *cancellable; + + GnomeDesktopThumbnailFactory *thumb_factory; +}; + + +static void +bg_pictures_source_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +bg_pictures_source_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +bg_pictures_source_dispose (GObject *object) +{ + BgPicturesSourcePrivate *priv = BG_PICTURES_SOURCE (object)->priv; + + if (priv->cancellable) + { + g_cancellable_cancel (priv->cancellable); + g_object_unref (priv->cancellable); + priv->cancellable = NULL; + } + + if (priv->liststore) + { + g_object_unref (priv->liststore); + priv->liststore = NULL; + } + + if (priv->thumb_factory) + { + g_object_unref (priv->thumb_factory); + priv->thumb_factory = NULL; + } + + if (priv->dir) + { + g_object_unref (priv->dir); + priv->dir = NULL; + } + + G_OBJECT_CLASS (bg_pictures_source_parent_class)->dispose (object); +} + +static void +bg_pictures_source_finalize (GObject *object) +{ + G_OBJECT_CLASS (bg_pictures_source_parent_class)->finalize (object); +} + +static void +bg_pictures_source_class_init (BgPicturesSourceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (BgPicturesSourcePrivate)); + + object_class->get_property = bg_pictures_source_get_property; + object_class->set_property = bg_pictures_source_set_property; + object_class->dispose = bg_pictures_source_dispose; + object_class->finalize = bg_pictures_source_finalize; +} + +static void +file_info_async_ready (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + BgPicturesSourcePrivate *priv = BG_PICTURES_SOURCE (user_data)->priv; + GList *files, *l; + GError *err = NULL; + GFile *parent; + gchar *path; + + files = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source), + res, + &err); + + if (err) + { + g_warning ("Could not get pictures file information: %s", err->message); + g_error_free (err); + + g_list_foreach (files, (GFunc) g_object_unref, NULL); + g_list_free (files); + return; + } + + parent = g_file_enumerator_get_container (G_FILE_ENUMERATOR (source)); + path = g_file_get_path (parent); + + + /* iterate over the available files */ + for (l = files; l; l = g_list_next (l)) + { + GFileInfo *info = l->data; + const gchar *content_type; + + /* find png and jpeg files */ + content_type = g_file_info_get_content_type (info); + + if (!content_type) + continue; + + if (!strcmp ("image/png", content_type) + || !strcmp ("image/jpeg", content_type)) + { + GdkPixbuf *pixbuf; + GnomeWPItem *item; + gchar *filename; + GtkTreeIter iter; + GtkTreePath *tree_path; + + filename = g_build_filename (path, g_file_info_get_name (info), NULL); + + /* create a new GnomeWpItem */ + item = gnome_wp_item_new (filename, NULL, + priv->thumb_factory); + + if (!item) + { + g_warning ("Could not load picture \"%s\"", filename); + g_free (filename); + continue; + } + + + + /* insert the item into the liststore */ + pixbuf = gdk_pixbuf_new_from_file_at_scale (filename, 100, 75, TRUE, + NULL); + gtk_list_store_insert_with_values (priv->liststore, &iter, 0, + 0, pixbuf, + 1, item, + -1); + tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->liststore), + &iter); + item->rowref = + gtk_tree_row_reference_new (GTK_TREE_MODEL (priv->liststore), + tree_path); + gtk_tree_path_free (tree_path); + + g_free (filename); + } + } + + g_list_foreach (files, (GFunc) g_object_unref, NULL); + g_list_free (files); + + g_free (path); +} + +static void +dir_enum_async_ready (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + BgPicturesSourcePrivate *priv = BG_PICTURES_SOURCE (user_data)->priv; + GFileEnumerator *enumerator; + GError *err = NULL; + + enumerator = g_file_enumerate_children_finish (G_FILE (source), res, &err); + + if (err) + { + g_warning ("Could not fill pictures source: %s", err->message); + g_error_free (err); + return; + } + + /* get the files */ + g_file_enumerator_next_files_async (enumerator, + G_MAXINT, + G_PRIORITY_LOW, + priv->cancellable, + file_info_async_ready, + user_data); +} + +static void +bg_pictures_source_init (BgPicturesSource *self) +{ + const gchar *pictures_path; + BgPicturesSourcePrivate *priv; + priv = self->priv = PICTURES_SOURCE_PRIVATE (self); + + + priv->liststore = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_POINTER); + + priv->cancellable = g_cancellable_new (); + + pictures_path = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES); + priv->dir = g_file_new_for_path (pictures_path); + + g_file_enumerate_children_async (priv->dir, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_LOW, priv->cancellable, + dir_enum_async_ready, self); + + priv->thumb_factory = + gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL); + +} + +BgPicturesSource * +bg_pictures_source_new (void) +{ + return g_object_new (BG_TYPE_PICTURES_SOURCE, NULL); +} + +GtkListStore* +bg_pictures_source_get_liststore (BgPicturesSource *source) +{ + return source->priv->liststore; +} diff --git a/panels/background/bg-pictures-source.h b/panels/background/bg-pictures-source.h new file mode 100644 index 000000000..36281bfb0 --- /dev/null +++ b/panels/background/bg-pictures-source.h @@ -0,0 +1,76 @@ +/* bg-pictures-source.h */ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + + +#ifndef _BG_PICTURES_SOURCE_H +#define _BG_PICTURES_SOURCE_H + +#include + +G_BEGIN_DECLS + +#define BG_TYPE_PICTURES_SOURCE bg_pictures_source_get_type() + +#define BG_PICTURES_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + BG_TYPE_PICTURES_SOURCE, BgPicturesSource)) + +#define BG_PICTURES_SOURCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + BG_TYPE_PICTURES_SOURCE, BgPicturesSourceClass)) + +#define BG_IS_PICTURES_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + BG_TYPE_PICTURES_SOURCE)) + +#define BG_IS_PICTURES_SOURCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + BG_TYPE_PICTURES_SOURCE)) + +#define BG_PICTURES_SOURCE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + BG_TYPE_PICTURES_SOURCE, BgPicturesSourceClass)) + +typedef struct _BgPicturesSource BgPicturesSource; +typedef struct _BgPicturesSourceClass BgPicturesSourceClass; +typedef struct _BgPicturesSourcePrivate BgPicturesSourcePrivate; + +struct _BgPicturesSource +{ + GObject parent; + + BgPicturesSourcePrivate *priv; +}; + +struct _BgPicturesSourceClass +{ + GObjectClass parent_class; +}; + +GType bg_pictures_source_get_type (void) G_GNUC_CONST; + +BgPicturesSource *bg_pictures_source_new (void); +GtkListStore *bg_pictures_source_get_liststore (BgPicturesSource *source); + +G_END_DECLS + +#endif /* _BG_PICTURES_SOURCE_H */ diff --git a/panels/background/bg-wallpapers-source.c b/panels/background/bg-wallpapers-source.c new file mode 100644 index 000000000..527e6646c --- /dev/null +++ b/panels/background/bg-wallpapers-source.c @@ -0,0 +1,237 @@ +/* bg-wallpapers-source.c */ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + + +#include "bg-wallpapers-source.h" + +#include "gnome-wp-item.h" +#include "gnome-wp-xml.h" + +#include +#include + +G_DEFINE_TYPE (BgWallpapersSource, bg_wallpapers_source, G_TYPE_OBJECT) + +#define WALLPAPERS_SOURCE_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), BG_TYPE_WALLPAPERS_SOURCE, BgWallpapersSourcePrivate)) + +struct _BgWallpapersSourcePrivate +{ + GtkListStore *store; + GnomeDesktopThumbnailFactory *thumb_factory; +}; + + +static void +bg_wallpapers_source_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +bg_wallpapers_source_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +bg_wallpapers_source_dispose (GObject *object) +{ + BgWallpapersSourcePrivate *priv = BG_WALLPAPERS_SOURCE (object)->priv; + + if (priv->store) + { + g_object_unref (priv->store); + priv->store = NULL; + } + + if (priv->thumb_factory) + { + g_object_unref (priv->thumb_factory); + priv->thumb_factory = NULL; + } + + G_OBJECT_CLASS (bg_wallpapers_source_parent_class)->dispose (object); +} + +static void +bg_wallpapers_source_finalize (GObject *object) +{ + G_OBJECT_CLASS (bg_wallpapers_source_parent_class)->finalize (object); +} + +static void +bg_wallpapers_source_class_init (BgWallpapersSourceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (BgWallpapersSourcePrivate)); + + object_class->get_property = bg_wallpapers_source_get_property; + object_class->set_property = bg_wallpapers_source_set_property; + object_class->dispose = bg_wallpapers_source_dispose; + object_class->finalize = bg_wallpapers_source_finalize; +} + +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, + BgWallpapersSourcePrivate *priv) +{ + GtkTreeIter iter; + GtkTreePath *path; + GdkPixbuf *pixbuf; + + if (item->deleted == TRUE) + return; + + gtk_list_store_append (GTK_LIST_STORE (priv->store), &iter); + + pixbuf = gnome_wp_item_get_thumbnail (item, priv->thumb_factory, + 100, 75); + gnome_wp_item_update_description (item); + + gtk_list_store_set (GTK_LIST_STORE (priv->store), &iter, + 0, pixbuf, + 1, item, + -1); + + if (pixbuf) + g_object_unref (pixbuf); + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->store), &iter); + item->rowref = gtk_tree_row_reference_new (GTK_TREE_MODEL (priv->store), path); + ///g_signal_connect (item->bg, "changed", G_CALLBACK (item_changed_cb), priv->wp_xml); + gtk_tree_path_free (path); +} + +static void +bg_wallpapers_source_init (BgWallpapersSource *self) +{ + GnomeWpXml *wp_xml; + BgWallpapersSourcePrivate *priv; + + priv = self->priv = WALLPAPERS_SOURCE_PRIVATE (self); + + priv->store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_POINTER); + + priv->thumb_factory = + gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL); + + /* 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->client = gconf_client_get_default (); + wp_xml->wp_model = priv->store; + wp_xml->thumb_width = 100; + wp_xml->thumb_height = 75; + wp_xml->thumb_factory = priv->thumb_factory; + + gnome_wp_xml_load_list (wp_xml); + g_hash_table_foreach (wp_xml->wp_hash, + (GHFunc) load_wallpapers, + priv); + + g_hash_table_destroy (wp_xml->wp_hash); + g_object_unref (wp_xml->client); + g_free (wp_xml); +} + +BgWallpapersSource * +bg_wallpapers_source_new (void) +{ + return g_object_new (BG_TYPE_WALLPAPERS_SOURCE, NULL); +} + + +GtkListStore * +bg_wallpapers_source_get_liststore (BgWallpapersSource *source) +{ + return source->priv->store; +} diff --git a/panels/background/bg-wallpapers-source.h b/panels/background/bg-wallpapers-source.h new file mode 100644 index 000000000..f9ad58fea --- /dev/null +++ b/panels/background/bg-wallpapers-source.h @@ -0,0 +1,76 @@ +/* bg-wallpapers-source.h */ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + + +#ifndef _BG_WALLPAPERS_SOURCE_H +#define _BG_WALLPAPERS_SOURCE_H + +#include + +G_BEGIN_DECLS + +#define BG_TYPE_WALLPAPERS_SOURCE bg_wallpapers_source_get_type() + +#define BG_WALLPAPERS_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + BG_TYPE_WALLPAPERS_SOURCE, BgWallpapersSource)) + +#define BG_WALLPAPERS_SOURCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + BG_TYPE_WALLPAPERS_SOURCE, BgWallpapersSourceClass)) + +#define BG_IS_WALLPAPERS_SOURCE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + BG_TYPE_WALLPAPERS_SOURCE)) + +#define BG_IS_WALLPAPERS_SOURCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + BG_TYPE_WALLPAPERS_SOURCE)) + +#define BG_WALLPAPERS_SOURCE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + BG_TYPE_WALLPAPERS_SOURCE, BgWallpapersSourceClass)) + +typedef struct _BgWallpapersSource BgWallpapersSource; +typedef struct _BgWallpapersSourceClass BgWallpapersSourceClass; +typedef struct _BgWallpapersSourcePrivate BgWallpapersSourcePrivate; + +struct _BgWallpapersSource +{ + GObject parent; + + BgWallpapersSourcePrivate *priv; +}; + +struct _BgWallpapersSourceClass +{ + GObjectClass parent_class; +}; + +GType bg_wallpapers_source_get_type (void) G_GNUC_CONST; + +BgWallpapersSource *bg_wallpapers_source_new (void); +GtkListStore *bg_wallpapers_source_get_liststore (BgWallpapersSource *source); + +G_END_DECLS + +#endif /* _BG_WALLPAPERS_SOURCE_H */ diff --git a/panels/background/cc-background-panel.c b/panels/background/cc-background-panel.c new file mode 100644 index 000000000..02be5d25f --- /dev/null +++ b/panels/background/cc-background-panel.c @@ -0,0 +1,647 @@ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + +#include + +#include "cc-background-panel.h" +#include "bg-wallpapers-source.h" +#include "bg-pictures-source.h" +#include "bg-colors-source.h" + +#ifdef HAVE_LIBSOCIALWEB +#include "bg-flickr-source.h" +#endif + +#include "gnome-wp-xml.h" +#include "gnome-wp-item.h" + +#include +#include + +G_DEFINE_DYNAMIC_TYPE (CcBackgroundPanel, cc_background_panel, CC_TYPE_PANEL) + +#define BACKGROUND_PANEL_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_BACKGROUND_PANEL, CcBackgroundPanelPrivate)) + +struct _CcBackgroundPanelPrivate +{ + GtkBuilder *builder; + + BgWallpapersSource *wallpapers_source; + BgPicturesSource *pictures_source; + BgColorsSource *colors_source; + +#ifdef HAVE_LIBSOCIALWEB + BgFlickrSource *flickr_source; +#endif + + GtkListStore *selected_store; + + GConfClient *client; + + GnomeDesktopThumbnailFactory *thumb_factory; + + GnomeWPItem *current_background; + gboolean current_source_readonly; + + GCancellable *copy_cancellable; + + GtkWidget *spinner; +}; + +enum +{ + SOURCE_WALLPAPERS, + SOURCE_PICTURES, + SOURCE_COLORS, +#ifdef HAVE_LIBSOCIALWEB + SOURCE_FLICKR +#endif +}; + + +#define WID(y) (GtkWidget *) gtk_builder_get_object (priv->builder, y) + +static void +cc_background_panel_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +cc_background_panel_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +cc_background_panel_dispose (GObject *object) +{ + CcBackgroundPanelPrivate *priv = CC_BACKGROUND_PANEL (object)->priv; + + if (priv->builder) + { + g_object_unref (priv->builder); + priv->builder = NULL; + } + + if (priv->wallpapers_source) + { + g_object_unref (priv->wallpapers_source); + priv->wallpapers_source = NULL; + } + + if (priv->pictures_source) + { + g_object_unref (priv->pictures_source); + priv->pictures_source = NULL; + } + + if (priv->colors_source) + { + g_object_unref (priv->colors_source); + priv->colors_source = NULL; + } +#ifdef HAVE_LIBSOCIALWEB + if (priv->flickr_source) + { + g_object_unref (priv->flickr_source); + priv->flickr_source = NULL; + } +#endif + + if (priv->client) + { + g_object_unref (priv->client); + priv->client = NULL; + } + + if (priv->copy_cancellable) + { + g_object_unref (priv->copy_cancellable); + priv->copy_cancellable = NULL; + } + + if (priv->thumb_factory) + { + g_object_unref (priv->thumb_factory); + priv->thumb_factory = NULL; + } + + G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object); +} + +static void +cc_background_panel_finalize (GObject *object) +{ + CcBackgroundPanelPrivate *priv = CC_BACKGROUND_PANEL (object)->priv; + + if (priv->current_background) + { + gnome_wp_item_free (priv->current_background); + priv->current_background = NULL; + } + + G_OBJECT_CLASS (cc_background_panel_parent_class)->finalize (object); +} + +static void +cc_background_panel_class_init (CcBackgroundPanelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (CcBackgroundPanelPrivate)); + + object_class->get_property = cc_background_panel_get_property; + object_class->set_property = cc_background_panel_set_property; + object_class->dispose = cc_background_panel_dispose; + object_class->finalize = cc_background_panel_finalize; +} + +static void +cc_background_panel_class_finalize (CcBackgroundPanelClass *klass) +{ + +} + +static void +source_changed_cb (GtkTreeSelection *selection, + CcBackgroundPanelPrivate *priv) +{ + GtkTreeIter iter; + GtkTreeModel *model; + GtkListStore *store; + GtkIconView *view; + guint type; + + gtk_tree_selection_get_selected (selection, &model, &iter); + gtk_tree_model_get (model, &iter, + 1, &type, + 2, &priv->current_source_readonly, -1); + + view = (GtkIconView *) gtk_builder_get_object (priv->builder, + "backgrounds-iconview"); + + if (type == SOURCE_WALLPAPERS) + store = bg_wallpapers_source_get_liststore (priv->wallpapers_source); + else if (type == SOURCE_PICTURES) + store = bg_pictures_source_get_liststore (priv->pictures_source); + else if (type == SOURCE_COLORS) + store = bg_colors_source_get_liststore (priv->colors_source); +#ifdef HAVE_LIBSOCIALWEB + else if (type == SOURCE_FLICKR) + store = bg_flickr_source_get_liststore (priv->flickr_source); +#endif + else + store = NULL; + + priv->selected_store = store; + + gtk_icon_view_set_model (view, GTK_TREE_MODEL (store)); +} + +static void +copy_finished_cb (GObject *source_object, + GAsyncResult *result, + gpointer pointer) +{ + CcBackgroundPanelPrivate *priv = (CcBackgroundPanelPrivate*) pointer; + + if (priv->spinner) + { + gtk_widget_destroy (GTK_WIDGET (priv->spinner)); + priv->spinner = NULL; + } + + gtk_widget_show (WID ("preview-area")); + +} + +static void +update_preview (CcBackgroundPanelPrivate *priv, + GnomeWPItem *item) +{ + gchar *markup; + + if (item && priv->current_background) + { + if (priv->current_background->pcolor) + gdk_color_free (priv->current_background->pcolor); + priv->current_background->pcolor = gdk_color_copy (item->pcolor); + + if (priv->current_background->scolor) + gdk_color_free (priv->current_background->scolor); + priv->current_background->scolor = gdk_color_copy (item->scolor); + + + + g_free (priv->current_background->filename); + priv->current_background->filename = g_strdup (item->filename); + + g_free (priv->current_background->name); + priv->current_background->name = g_strdup (item->name); + + priv->current_background->options = item->options; + } + + + if (!priv->current_source_readonly) + gtk_widget_show (WID ("edit-hbox")); + else + gtk_widget_hide (WID ("edit-hbox")); + + if (priv->current_background) + { + markup = g_strdup_printf ("%s", priv->current_background->name); + gtk_label_set_markup (GTK_LABEL (WID ("background-label")), markup); + g_free (markup); + + gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-color")), + priv->current_background->pcolor); + + gtk_combo_box_set_active (GTK_COMBO_BOX (WID ("style-combobox")), + priv->current_background->options); + } + + gtk_widget_queue_draw (WID ("preview-area")); +} + +static void +backgrounds_changed_cb (GtkIconView *icon_view, + CcBackgroundPanelPrivate *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 if (item->source_url) + { + GFile *source, *dest; + gchar *cache_path; + GdkPixbuf *pixbuf; + + cache_path = g_build_filename (g_get_user_cache_dir (), + "background", + NULL); + + source = g_file_new_for_uri (item->source_url); + dest = g_file_new_for_path (cache_path); + + /* create a blank image to use until the source image is ready */ + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1); + gdk_pixbuf_fill (pixbuf, 0x00000000); + gdk_pixbuf_save (pixbuf, cache_path, "png", NULL, NULL); + g_object_unref (pixbuf); + + if (priv->copy_cancellable) + { + g_cancellable_cancel (priv->copy_cancellable); + g_cancellable_reset (priv->copy_cancellable); + + } + + if (priv->spinner) + { + gtk_widget_destroy (GTK_WIDGET (priv->spinner)); + priv->spinner = NULL; + } + + /* create a spinner while the file downloads */ + priv->spinner = gtk_spinner_new (); + gtk_spinner_start (GTK_SPINNER (priv->spinner)); + gtk_box_pack_start (GTK_BOX (WID ("details-box")), priv->spinner, FALSE, + FALSE, 0); + gtk_box_reorder_child (GTK_BOX (WID ("details-box")), priv->spinner, 0); + gtk_widget_set_size_request (priv->spinner, 150, 75); + gtk_widget_show (priv->spinner); + gtk_widget_hide (WID ("preview-area")); + + + g_file_copy_async (source, dest, G_FILE_COPY_OVERWRITE, + G_PRIORITY_DEFAULT, priv->copy_cancellable, + NULL, NULL, + copy_finished_cb, priv); + + gconf_change_set_set_string (cs, WP_FILE_KEY, + cache_path); + gconf_change_set_set_string (cs, WP_OPTIONS_KEY, + wp_item_option_to_string (item->options)); + g_free (item->filename); + item->filename = cache_path; + } + 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->client, cs, TRUE, NULL); + + gconf_change_set_unref (cs); + + /* update the preview information */ + update_preview (priv, item); +} + +static gboolean +preview_expose_cb (GtkWidget *widget, + GdkEventExpose *expose, + CcBackgroundPanel *panel) +{ + cairo_t *cr; + GtkAllocation allocation; + CcBackgroundPanelPrivate *priv = panel->priv; + GdkPixbuf *pixbuf = NULL; + + cr = gdk_cairo_create (gtk_widget_get_window (widget)); + + gtk_widget_get_allocation (widget, &allocation); + + if (priv->current_background) + { + pixbuf = gnome_wp_item_get_thumbnail (priv->current_background, + priv->thumb_factory, + allocation.width, + allocation.height); + g_object_ref (pixbuf); + } + + if (pixbuf) + { + gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); + + cairo_paint (cr); + + g_object_unref (pixbuf); + } + + cairo_destroy (cr); + + return TRUE; +} + +static void +style_changed_cb (GtkComboBox *box, + CcBackgroundPanel *panel) +{ + CcBackgroundPanelPrivate *priv = panel->priv; + GtkTreeModel *model; + GtkTreeIter iter; + gchar *value; + + gtk_combo_box_get_active_iter (box, &iter); + + model = gtk_combo_box_get_model (box); + + gtk_tree_model_get (model, &iter, 1, &value, -1); + + gconf_client_set_string (priv->client, + "/desktop/gnome/background/picture_options", + value, NULL); + + g_free (value); + + if (priv->current_background) + priv->current_background->options = gtk_combo_box_get_active (box); + + update_preview (priv, NULL); +} + +static void +color_changed_cb (GtkColorButton *button, + CcBackgroundPanel *panel) +{ + CcBackgroundPanelPrivate *priv = panel->priv; + GdkColor color; + gchar *value; + + gtk_color_button_get_color (button, &color); + + if (priv->current_background) + *priv->current_background->pcolor = color; + + value = gdk_color_to_string (&color); + + gconf_client_set_string (priv->client, + "/desktop/gnome/background/primary_color", + value, NULL); + + gconf_client_set_string (priv->client, + "/desktop/gnome/background/secondary_color", + value, NULL); + + g_free (value); + + update_preview (priv, NULL); +} + +static void +cc_background_panel_init (CcBackgroundPanel *self) +{ + CcBackgroundPanelPrivate *priv; + gchar *objects[] = { "backgrounds-liststore", "style-liststore", + "sources-liststore", "background-panel", NULL }; + GError *err = NULL; + GtkWidget *widget; + GtkTreeSelection *selection; + gint width, height; + GtkListStore *store; + gchar *filename; + + priv = self->priv = BACKGROUND_PANEL_PRIVATE (self); + + priv->builder = gtk_builder_new (); + + gtk_builder_add_objects_from_file (priv->builder, + DATADIR"/background.ui", + objects, &err); + + if (err) + { + g_warning ("Could not load ui: %s", err->message); + g_error_free (err); + return; + } + + priv->client = gconf_client_get_default (); + + store = (GtkListStore*) gtk_builder_get_object (priv->builder, + "sources-liststore"); + + priv->pictures_source = bg_pictures_source_new (); + gtk_list_store_insert_with_values (store, NULL, G_MAXINT, + 0, _("Wallpapers"), + 1, SOURCE_WALLPAPERS, + 2, TRUE, -1); + + priv->wallpapers_source = bg_wallpapers_source_new (); + gtk_list_store_insert_with_values (store, NULL, G_MAXINT, + 0, _("Pictures Folder"), + 1, SOURCE_PICTURES, + 2, FALSE, -1); + + priv->colors_source = bg_colors_source_new (); + gtk_list_store_insert_with_values (store, NULL, G_MAXINT, + 0, _("Colors"), + 1, SOURCE_COLORS, + 2, TRUE, -1); + +#ifdef HAVE_LIBSOCIALWEB + priv->flickr_source = bg_flickr_source_new (); + gtk_list_store_insert_with_values (store, NULL, G_MAXINT, + 0, _("Flickr"), + 1, SOURCE_FLICKR, + 2, FALSE, -1); +#endif + + + /* add the top level widget */ + widget = (GtkWidget*) + gtk_builder_get_object (priv->builder, "background-panel"); + + gtk_container_add (GTK_CONTAINER (self), widget); + gtk_widget_show_all (GTK_WIDGET (self)); + + /* connect to source change signal */ + widget = WID ("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 = WID ("backgrounds-iconview"); + g_signal_connect (widget, "selection-changed", + G_CALLBACK (backgrounds_changed_cb), + priv); + + /* setup preview area */ + widget = WID ("preview-area"); + g_signal_connect (widget, "expose-event", G_CALLBACK (preview_expose_cb), + self); + + + width = 150; + height = width * ((double) gdk_screen_get_height (gdk_screen_get_default ()) / + (double) gdk_screen_get_width (gdk_screen_get_default ())); + + gtk_widget_set_size_request (widget, width, height); + + g_signal_connect (WID ("style-combobox"), "changed", + G_CALLBACK (style_changed_cb), self); + + g_signal_connect (WID ("style-color"), "color-set", + G_CALLBACK (color_changed_cb), self); + + priv->copy_cancellable = g_cancellable_new (); + + priv->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL); + + /* initalise the current background information from gconf */ + filename = gconf_client_get_string (priv->client, WP_FILE_KEY, NULL); + 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 (""); + + gnome_wp_item_update (priv->current_background); + gnome_wp_item_ensure_gnome_bg (priv->current_background); + + update_preview (priv, NULL); +} + +void +cc_background_panel_register (GIOModule *module) +{ + cc_background_panel_register_type (G_TYPE_MODULE (module)); + g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT, + CC_TYPE_BACKGROUND_PANEL, + "background", 0); +} + diff --git a/panels/background/cc-background-panel.h b/panels/background/cc-background-panel.h new file mode 100644 index 000000000..d9836b1af --- /dev/null +++ b/panels/background/cc-background-panel.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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. + * + * 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. + * + * Author: Thomas Wood + * + */ + + +#ifndef _CC_BACKGROUND_PANEL_H +#define _CC_BACKGROUND_PANEL_H + +#include + +G_BEGIN_DECLS + +#define CC_TYPE_BACKGROUND_PANEL cc_background_panel_get_type() + +#define CC_BACKGROUND_PANEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + CC_TYPE_BACKGROUND_PANEL, CcBackgroundPanel)) + +#define CC_BACKGROUND_PANEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + CC_TYPE_BACKGROUND_PANEL, CcBackgroundPanelClass)) + +#define CC_IS_BACKGROUND_PANEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + CC_TYPE_BACKGROUND_PANEL)) + +#define CC_IS_BACKGROUND_PANEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + CC_TYPE_BACKGROUND_PANEL)) + +#define CC_BACKGROUND_PANEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + CC_TYPE_BACKGROUND_PANEL, CcBackgroundPanelClass)) + +typedef struct _CcBackgroundPanel CcBackgroundPanel; +typedef struct _CcBackgroundPanelClass CcBackgroundPanelClass; +typedef struct _CcBackgroundPanelPrivate CcBackgroundPanelPrivate; + +struct _CcBackgroundPanel +{ + CcPanel parent; + + CcBackgroundPanelPrivate *priv; +}; + +struct _CcBackgroundPanelClass +{ + CcPanelClass parent_class; +}; + +GType cc_background_panel_get_type (void) G_GNUC_CONST; + +void cc_background_panel_register (GIOModule *module); + +G_END_DECLS + +#endif /* _CC_BACKGROUND_PANEL_H */ diff --git a/panels/background/gnome-background-panel.desktop.in.in b/panels/background/gnome-background-panel.desktop.in.in new file mode 100644 index 000000000..67b540d5d --- /dev/null +++ b/panels/background/gnome-background-panel.desktop.in.in @@ -0,0 +1,11 @@ +[Desktop Entry] +_Name=Background +_Comment=Change the background +Exec=gnome-control-center background +Icon=preferences-desktop-wallpaper +Terminal=false +Type=Application +StartupNotify=true +Categories=GNOME;GTK;Settings;DesktopSettings; +OnlyShowIn=GNOME; +X-GNOME-Settings-Panel=background diff --git a/panels/background/gnome-wp-info.c b/panels/background/gnome-wp-info.c new file mode 100644 index 000000000..7df6030ae --- /dev/null +++ b/panels/background/gnome-wp-info.c @@ -0,0 +1,87 @@ +/* + * Authors: Rodney Dawes + * + * 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 +#include +#include +#include +#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/gnome-wp-info.h b/panels/background/gnome-wp-info.h new file mode 100644 index 000000000..ea1051e28 --- /dev/null +++ b/panels/background/gnome-wp-info.h @@ -0,0 +1,45 @@ +/* + * Authors: Rodney Dawes + * + * 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 +#include + +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/gnome-wp-item.c b/panels/background/gnome-wp-item.c new file mode 100644 index 000000000..09685e1c9 --- /dev/null +++ b/panels/background/gnome-wp-item.c @@ -0,0 +1,315 @@ +/* + * Authors: Rodney Dawes + * + * 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 + +#include +#include +#include +#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->bg) + return; + + 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 (); + + g_object_set_data (G_OBJECT (item->bg), "gnome-wp-item", item); + + 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); + + set_bg_properties (item); +} + +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); + + if (wallpapers) + 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: wallpaper name + * mime type, size + * Folder: /path/to/file + */ + item->description = g_markup_printf_escaped (_("%s\n" + "%s, %s\n" + "Folder: %s"), + item->name, + description, + size, + dirname); + } else { + /* translators: wallpaper name + * Image missing + * Folder: /path/to/file + */ + item->description = g_markup_printf_escaped (_("%s\n" + "%s\n" + "Folder: %s"), + item->name, + _("Image missing"), + dirname); + } + + g_free (size); + g_free (dirname); + } +} diff --git a/panels/background/gnome-wp-item.h b/panels/background/gnome-wp-item.h new file mode 100644 index 000000000..d7b24692e --- /dev/null +++ b/panels/background/gnome-wp-item.h @@ -0,0 +1,92 @@ +/* + * Authors: Rodney Dawes + * + * 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 +#include +#include +#include +#include +#include + +#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; + + gchar * source_url; + + /* 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/gnome-wp-xml.c b/panels/background/gnome-wp-xml.c new file mode 100644 index 000000000..51aba445f --- /dev/null +++ b/panels/background/gnome-wp-xml.c @@ -0,0 +1,449 @@ +/* + * Authors: Rodney Dawes + * + * 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 +#include +#include + +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/gnome-wp-xml.h b/panels/background/gnome-wp-xml.h new file mode 100644 index 000000000..2ea8c2abc --- /dev/null +++ b/panels/background/gnome-wp-xml.h @@ -0,0 +1,43 @@ +/* + * Authors: Rodney Dawes + * + * 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 +#include + +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 +