[gnome-control-center] background: New background panel design



commit 79ec684fa4912a1e5bff17ce11b036cef4a298aa
Author: William Jon McCann <jmccann redhat com>
Date:   Tue May 22 11:34:20 2012 -0400

    background: New background panel design
    
    Implement a new design for the wallpaper selection.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=676539

 panels/background/Makefile.am                    |    6 +-
 panels/background/background.ui                  |  352 ++-----
 panels/background/bg-colors-source.c             |   61 +-
 panels/background/bg-flickr-source.c             |    2 +-
 panels/background/bg-pictures-source.c           |    2 +-
 panels/background/bg-source.h                    |    4 +-
 panels/background/bg-wallpapers-source.c         |    2 +-
 panels/background/cc-background-chooser-dialog.c |  335 ++++++
 panels/background/cc-background-chooser-dialog.h |   60 ++
 panels/background/cc-background-panel.c          | 1194 ++++++----------------
 panels/background/display-base.png               |  Bin 22374 -> 0 bytes
 panels/background/display-overlay.png            |  Bin 9549 -> 6700 bytes
 12 files changed, 824 insertions(+), 1194 deletions(-)
---
diff --git a/panels/background/Makefile.am b/panels/background/Makefile.am
index b359ea2..bc40aff 100644
--- a/panels/background/Makefile.am
+++ b/panels/background/Makefile.am
@@ -4,7 +4,6 @@ cappletname = background
 uidir = $(pkgdatadir)/ui/background
 dist_ui_DATA = \
 	background.ui \
-	display-base.png \
 	display-overlay.png
 
 slideshowicondir = $(datadir)/icons/hicolor/scalable/categories/
@@ -18,7 +17,8 @@ INCLUDES =						\
 	$(BACKGROUND_PANEL_CFLAGS)			\
 	-DGNOMELOCALEDIR="\"$(datadir)/locale\""	\
 	-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\""		\
-	-DDATADIR="\"$(uidir)\""			\
+	-DUIDIR="\"$(uidir)\""				\
+	-DDATADIR="\"$(datadir)\""			\
 	-DGNOME_DESKTOP_USE_UNSTABLE_API		\
 	$(NULL)
 
@@ -32,6 +32,8 @@ BUILT_SOURCES =            \
 libbackground_la_SOURCES =		\
 	$(BUILT_SOURCES)		\
 	background-module.c		\
+	cc-background-chooser-dialog.c	\
+	cc-background-chooser-dialog.h	\
 	cc-background-panel.c		\
 	cc-background-panel.h		\
 	cc-background-item.c		\
diff --git a/panels/background/background.ui b/panels/background/background.ui
index 0e35d7c..e6e2e5a 100644
--- a/panels/background/background.ui
+++ b/panels/background/background.ui
@@ -1,76 +1,74 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy project-wide -->
-  <object class="GtkListStore" id="sources-liststore">
-    <columns>
-      <!-- column-name source-name -->
-      <column type="gchararray"/>
-      <!-- column-name source-id -->
-      <column type="guint"/>
-      <!-- column-name source-pointer -->
-      <column type="gpointer"/>
-    </columns>
-  </object>
+  <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkHBox" id="background-panel">
     <property name="visible">True</property>
+    <property name="can_focus">False</property>
     <property name="border_width">10</property>
     <property name="spacing">12</property>
     <child>
-      <object class="GtkVBox" id="vbox2">
+      <object class="GtkVBox" id="vbox3">
         <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">0</property>
-        <child>
-          <object class="GtkComboBox" id="sources-combobox">
-            <property name="visible">True</property>
-            <property name="model">sources-liststore</property>
-            <child>
-              <object class="GtkCellRendererText" id="cellrenderertext2"/>
-              <attributes>
-                <attribute name="text">0</attribute>
-              </attributes>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">0</property>
-            <property name="padding">6</property>
-          </packing>
-        </child>
+        <property name="can_focus">False</property>
+        <property name="spacing">6</property>
         <child>
-          <object class="GtkScrolledWindow" id="scrolledwindow1">
-            <property name="width_request">220</property>
-            <property name="height_request">380</property>
+          <object class="GtkAspectFrame" id="aspectframe1">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="hscrollbar_policy">automatic</property>
-            <property name="vscrollbar_policy">automatic</property>
-            <property name="shadow_type">in</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">12</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">none</property>
             <child>
-              <object class="GtkIconView" id="backgrounds-iconview">
+              <object class="GtkButton" id="background-set-button">
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="row_spacing">0</property>
-                <property name="column_spacing">0</property>
-                <property name="margin">0</property>
-                <child>
-                  <object class="GtkCellRendererPixbuf" id="pixbuf-renderer">
-                    <property name="stock_size">6</property>
-                  </object>
-                  <attributes>
-                    <attribute name="gicon">0</attribute>
-                  </attributes>
-                </child>
+                <property name="receives_default">True</property>
+                <property name="valign">center</property>
                 <child>
-                  <!-- this cell renderer is here just to have
-                       the text spoken in orca -->
-                  <object class="GtkCellRendererText" id="text-renderer">
-                    <property name="visible">False</property>
+                  <object class="GtkBox" id="box1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="hexpand">True</property>
+                    <property name="spacing">18</property>
+                    <child>
+                      <object class="GtkDrawingArea" id="background-desktop-drawingarea">
+                        <property name="width_request">417</property>
+                        <property name="height_request">250</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="valign">center</property>
+                        <property name="margin_left">6</property>
+                        <property name="margin_right">6</property>
+                        <property name="margin_top">6</property>
+                        <property name="margin_bottom">6</property>
+                        <property name="hexpand">True</property>
+                        <property name="vexpand">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkDrawingArea" id="background-lock-drawingarea">
+                        <property name="can_focus">False</property>
+                        <property name="no_show_all">True</property>
+                        <property name="valign">center</property>
+                        <property name="margin_left">6</property>
+                        <property name="margin_right">6</property>
+                        <property name="margin_top">6</property>
+                        <property name="hexpand">True</property>
+                        <property name="vexpand">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
-                  <attributes>
-                    <attribute name="text">2</attribute>
-                  </attributes>
                 </child>
               </object>
             </child>
@@ -78,265 +76,88 @@
           <packing>
             <property name="expand">True</property>
             <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkToolbar" id="toolbar1">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="icon_size">1</property>
-            <property name="toolbar-style">icons</property>
-            <style>
-              <class name="inline-toolbar"/>
-            </style>
-            <child>
-              <object class="GtkToolButton" id="add_button">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Add wallpaper</property>
-                <property name="use_action_appearance">False</property>
-                <property name="use_underline">True</property>
-                <property name="icon_name">list-add-symbolic</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkToolButton" id="remove_button">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Remove wallpaper</property>
-                <property name="use_action_appearance">False</property>
-                <property name="use_underline">True</property>
-                <property name="icon_name">list-remove-symbolic</property>
-                <property name="sensitive">False</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="homogeneous">True</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-      </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">0</property>
-      </packing>
-    </child>
-    <child>
-      <object class="GtkVBox" id="vbox3">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="spacing">6</property>
-        <child>
-          <object class="GtkHBox" id="heading-hbox">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="spacing">24</property>
-            <child>
-              <object class="GtkLabel" id="background-label">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">0</property>
-                <property name="label">Current background</property>
-                <attributes>
-                  <attribute name="weight" value="bold"/>
-                </attributes>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="size_label">
-                <property name="visible">True</property>
-                <property name="xalign">1</property>
-                <property name="label">1280x700px</property>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
             <property name="position">0</property>
           </packing>
         </child>
         <child>
-          <object class="GtkDrawingArea" id="preview-area">
-            <property name="visible">True</property>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
           <object class="GtkHBox" id="bottom-hbox">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="spacing">12</property>
             <child>
               <object class="GtkHBox" id="hbox2">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">center</property>
                 <property name="spacing">2</property>
                 <child>
                   <object class="GtkImage" id="slide_image">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="icon_name">slideshow-symbolic</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkLabel" id="slide-label">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="xalign">0</property>
                     <property name="label" translatable="yes" comments="This refers to a slideshow background">Changes throughout the day</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkLabel" id="strut">
                     <property name="visible">True</property>
-                    <property name="label" translatable="no"> </property>
+                    <property name="can_focus">False</property>
+                    <property name="label"> </property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
               </object>
               <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">0</property>
               </packing>
             </child>
-            <child>
-              <object class="GtkHBox" id="edit-hbox">
-                <property name="visible">True</property>
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkColorButton" id="style-pcolor">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="color">#000000000000</property>
-                    <child internal-child="accessible">
-                      <object class="AtkObject" id="style-pcolor-a11y">
-                        <property name="accessible-name" translatable="yes">Primary Color</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkButton" id="swap-color-button">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
-                    <child internal-child="accessible">
-                      <object class="AtkObject" id="swap-color-a11y">
-                        <property name="accessible-name" translatable="yes">Swap colors</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkImage" id="image1">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="icon_name">object-flip-horizontal-symbolic</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkComboBox" id="style-combobox">
-                    <property name="visible">True</property>
-                    <property name="model">style-liststore</property>
-                    <property name="active">0</property>
-                    <child>
-                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
-                      <attributes>
-                        <attribute name="text">0</attribute>
-                      </attributes>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="pack_type">end</property>
-                    <property name="position">3</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkColorButton" id="style-scolor">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="color">#000000000000</property>
-                    <child internal-child="accessible">
-                      <object class="AtkObject" id="style-scolor-a11y">
-                        <property name="accessible-name" translatable="yes">Secondary color</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="pack_type">end</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
           </object>
           <packing>
             <property name="expand">False</property>
+            <property name="fill">True</property>
             <property name="position">2</property>
           </packing>
         </child>
       </object>
       <packing>
-        <property name="position">1</property>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
       </packing>
     </child>
   </object>
-  <object class="GtkSizeGroup" id="sizegroup">
-    <property name="mode">vertical</property>
-    <widgets>
-      <widget name="sources-combobox"/>
-      <widget name="heading-hbox"/>
-      <widget name="slide-label"/>
-      <widget name="strut"/>
-    </widgets>
+  <object class="GtkListStore" id="sources-liststore">
+    <columns>
+      <!-- column-name source-name -->
+      <column type="gchararray"/>
+      <!-- column-name source-id -->
+      <column type="guint"/>
+      <!-- column-name source-pointer -->
+      <column type="gpointer"/>
+    </columns>
   </object>
   <object class="GtkListStore" id="style-liststore">
     <columns>
@@ -372,4 +193,13 @@
       </row>
     </data>
   </object>
+  <object class="GtkSizeGroup" id="sizegroup">
+    <property name="mode">vertical</property>
+    <widgets>
+      <widget name="sources-combobox"/>
+      <widget name="heading-hbox"/>
+      <widget name="slide-label"/>
+      <widget name="strut"/>
+    </widgets>
+  </object>
 </interface>
diff --git a/panels/background/bg-colors-source.c b/panels/background/bg-colors-source.c
index dac87ca..9fa41d3 100644
--- a/panels/background/bg-colors-source.c
+++ b/panels/background/bg-colors-source.c
@@ -39,32 +39,24 @@ bg_colors_source_class_init (BgColorsSourceClass *klass)
 }
 
 struct {
-	const char *name;
-	GDesktopBackgroundShading type;
-	int orientation;
+  GDesktopBackgroundShading type;
+  int orientation;
+  const char *pcolor;
 } items[] = {
-	{ N_("Horizontal Gradient"), G_DESKTOP_BACKGROUND_SHADING_HORIZONTAL, GTK_ORIENTATION_HORIZONTAL },
-	{ N_("Vertical Gradient"), G_DESKTOP_BACKGROUND_SHADING_VERTICAL, GTK_ORIENTATION_VERTICAL },
-	{ N_("Solid Color"), G_DESKTOP_BACKGROUND_SHADING_SOLID, -1 },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#8f5902" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#770000" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#ad7fa8" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#edd400" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#67915c" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#f57900" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#6aa978" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#57667c" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#727e6f" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#d59659" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#86af8f" },
+  { G_DESKTOP_BACKGROUND_SHADING_SOLID, -1, "#828b98" },
 };
 
-#define PCOLOR "#023c88"
-#define SCOLOR "#5789ca"
-
-static GEmblem *
-get_arrow_icon (GtkOrientation orientation)
-{
-  GIcon *themed;
-  GEmblem *emblem;
-  if (orientation == GTK_ORIENTATION_HORIZONTAL)
-    themed = g_themed_icon_new ("go-next-symbolic");
-  else
-    themed = g_themed_icon_new ("go-down-symbolic");
-  emblem = g_emblem_new_with_origin (themed, G_EMBLEM_ORIGIN_DEVICE);
-  g_object_unref (themed);
-  return emblem;
-}
-
 static void
 bg_colors_source_init (BgColorsSource *self)
 {
@@ -74,7 +66,7 @@ bg_colors_source_init (BgColorsSource *self)
 
   store = bg_source_get_liststore (BG_SOURCE (self));
 
-  thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
+  thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
 
   for (i = 0; i < G_N_ELEMENTS (items); i++)
     {
@@ -91,33 +83,22 @@ bg_colors_source_init (BgColorsSource *self)
       /* It does have a URI, it's "none" */
 
       g_object_set (G_OBJECT (item),
-		    "name", _(items[i].name),
-		    "primary-color", PCOLOR,
-		    "secondary-color", SCOLOR,
+                    "uri", "file:///" DATADIR "/gnome-shell/theme/noise-texture.png",
+		    "primary-color", items[i].pcolor,
+		    "secondary-color", items[i].pcolor,
 		    "shading", items[i].type,
-		    "placement", G_DESKTOP_BACKGROUND_STYLE_NONE,
+		    "placement", G_DESKTOP_BACKGROUND_STYLE_WALLPAPER,
 		    "flags", flags,
 		    NULL);
+      cc_background_item_load (item, NULL);
 
       /* insert the item into the liststore */
       pixbuf = cc_background_item_get_thumbnail (item,
 						 thumb_factory,
 						 THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
-      if (items[i].orientation != -1)
-        {
-          GEmblem *emblem;
-          GIcon *icon;
-
-	  emblem = get_arrow_icon (items[i].orientation);
-	  icon = g_emblemed_icon_new (G_ICON (pixbuf), emblem);
-	  g_object_unref (emblem);
-	  g_object_unref (pixbuf);
-	  pixbuf = icon;
-	}
       gtk_list_store_insert_with_values (store, NULL, 0,
                                          0, pixbuf,
                                          1, item,
-                                         2, _(items[i].name),
                                          -1);
 
       g_object_unref (pixbuf);
diff --git a/panels/background/bg-flickr-source.c b/panels/background/bg-flickr-source.c
index 9219d75..7915b7f 100644
--- a/panels/background/bg-flickr-source.c
+++ b/panels/background/bg-flickr-source.c
@@ -156,7 +156,7 @@ bg_flickr_source_init (BgFlickrSource *self)
                                      _query_open_view_cb,
                                      self);
 
-  thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
+  thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
 
   g_object_unref (thumb_factory);
 }
diff --git a/panels/background/bg-pictures-source.c b/panels/background/bg-pictures-source.c
index 34ac849..67dd07b 100644
--- a/panels/background/bg-pictures-source.c
+++ b/panels/background/bg-pictures-source.c
@@ -569,7 +569,7 @@ bg_pictures_source_init (BgPicturesSource *self)
   g_object_unref (dir);
 
   priv->thumb_factory =
-    gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
+    gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
 }
 
 BgPicturesSource *
diff --git a/panels/background/bg-source.h b/panels/background/bg-source.h
index b73265f..24e9ad5 100644
--- a/panels/background/bg-source.h
+++ b/panels/background/bg-source.h
@@ -26,8 +26,8 @@
 
 G_BEGIN_DECLS
 
-#define THUMBNAIL_WIDTH 48
-#define THUMBNAIL_HEIGHT 48
+#define THUMBNAIL_WIDTH 256
+#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
 
 #define BG_TYPE_SOURCE bg_source_get_type()
 
diff --git a/panels/background/bg-wallpapers-source.c b/panels/background/bg-wallpapers-source.c
index 7b1e2ab..03978f2 100644
--- a/panels/background/bg-wallpapers-source.c
+++ b/panels/background/bg-wallpapers-source.c
@@ -183,7 +183,7 @@ bg_wallpapers_source_init (BgWallpapersSource *self)
   priv = self->priv = WALLPAPERS_SOURCE_PRIVATE (self);
 
   priv->thumb_factory =
-    gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
+    gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
   priv->xml = cc_background_xml_new ();
   g_signal_connect (G_OBJECT (priv->xml), "added",
 		    G_CALLBACK (item_added), self);
diff --git a/panels/background/cc-background-chooser-dialog.c b/panels/background/cc-background-chooser-dialog.c
new file mode 100644
index 0000000..8ebaa61
--- /dev/null
+++ b/panels/background/cc-background-chooser-dialog.c
@@ -0,0 +1,335 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include "cc-background-chooser-dialog.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 "cc-background-item.h"
+#include "cc-background-xml.h"
+
+#define WP_PATH_ID "org.gnome.desktop.background"
+#define WP_URI_KEY "picture-uri"
+#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
+{
+  SOURCE_WALLPAPERS,
+  SOURCE_PICTURES,
+  SOURCE_COLORS,
+#ifdef HAVE_LIBSOCIALWEB
+  SOURCE_FLICKR
+#endif
+};
+
+struct _CcBackgroundChooserDialogPrivate
+{
+  GtkListStore *sources;
+  GtkWidget *icon_view;
+
+  BgWallpapersSource *wallpapers_source;
+  BgPicturesSource *pictures_source;
+  BgColorsSource *colors_source;
+#ifdef HAVE_LIBSOCIALWEB
+  BgFlickrSource *flickr_source;
+#endif
+
+  GnomeDesktopThumbnailFactory *thumb_factory;
+  gint current_source;
+
+  GCancellable *copy_cancellable;
+
+  GtkWidget *spinner;
+};
+
+#define CC_CHOOSER_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CC_TYPE_BACKGROUND_CHOOSER_DIALOG, CcBackgroundChooserDialogPrivate))
+
+enum
+{
+  PROP_0,
+};
+
+G_DEFINE_TYPE (CcBackgroundChooserDialog, cc_background_chooser_dialog, GTK_TYPE_DIALOG)
+
+static void
+cc_background_chooser_dialog_realize (GtkWidget *widget)
+{
+  CcBackgroundChooserDialog *chooser = CC_BACKGROUND_CHOOSER_DIALOG (widget);
+  GtkWindow *parent;
+
+  parent = gtk_window_get_transient_for (GTK_WINDOW (chooser));
+  if (parent != NULL)
+    {
+      gint width;
+      gint height;
+
+      gtk_window_get_size (parent, &width, &height);
+      gtk_widget_set_size_request (GTK_WIDGET (chooser), (gint) (0.5 * width), (gint) (0.9 * height));
+    }
+
+  gtk_icon_view_set_model (GTK_ICON_VIEW (chooser->priv->icon_view),
+                           GTK_TREE_MODEL (bg_source_get_liststore (BG_SOURCE (chooser->priv->wallpapers_source))));
+
+  GTK_WIDGET_CLASS (cc_background_chooser_dialog_parent_class)->realize (widget);
+}
+
+static void
+cc_background_chooser_dialog_dispose (GObject *object)
+{
+  CcBackgroundChooserDialog *chooser = CC_BACKGROUND_CHOOSER_DIALOG (object);
+  CcBackgroundChooserDialogPrivate *priv = chooser->priv;
+
+  if (priv->copy_cancellable)
+    {
+      /* cancel any copy operation */
+      g_cancellable_cancel (priv->copy_cancellable);
+
+      g_clear_object (&priv->copy_cancellable);
+    }
+
+  g_clear_object (&priv->pictures_source);
+  g_clear_object (&priv->colors_source);
+  g_clear_object (&priv->wallpapers_source);
+  g_clear_object (&priv->thumb_factory);
+
+  G_OBJECT_CLASS (cc_background_chooser_dialog_parent_class)->dispose (object);
+}
+
+static void
+cc_background_chooser_dialog_finalize (GObject *object)
+{
+
+  G_OBJECT_CLASS (cc_background_chooser_dialog_parent_class)->finalize (object);
+}
+
+static void
+on_view_toggled (GtkToggleButton           *button,
+                 CcBackgroundChooserDialog *chooser)
+{
+  BgSource *source;
+
+  if (!gtk_toggle_button_get_active (button))
+    return;
+
+  source = g_object_get_data (G_OBJECT (button), "source");
+  gtk_icon_view_set_model (GTK_ICON_VIEW (chooser->priv->icon_view),
+                           GTK_TREE_MODEL (bg_source_get_liststore (source)));
+
+}
+
+static void
+on_selection_changed (GtkIconView               *icon_view,
+                      CcBackgroundChooserDialog *chooser)
+{
+  GList *list;
+
+  list = gtk_icon_view_get_selected_items (icon_view);
+  gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
+                                     GTK_RESPONSE_OK,
+                                     (list != NULL));
+
+  g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
+}
+
+static void
+on_item_activated (GtkIconView               *icon_view,
+                   GtkTreePath               *path,
+                   CcBackgroundChooserDialog *chooser)
+{
+  gtk_dialog_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK);
+}
+
+static void
+cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
+{
+  CcBackgroundChooserDialogPrivate *priv;
+  GtkCellRenderer *renderer;
+  GtkWidget *sw_content;
+  GtkWidget *vbox;
+  GtkWidget *button1;
+  GtkWidget *button;
+  GtkWidget *hbox;
+  GtkWidget *grid;
+  GtkStyleContext *context;
+
+  chooser->priv = CC_CHOOSER_DIALOG_GET_PRIVATE (chooser);
+  priv = chooser->priv;
+
+  priv->wallpapers_source = bg_wallpapers_source_new ();
+  priv->pictures_source = bg_pictures_source_new ();
+  priv->colors_source = bg_colors_source_new ();
+#ifdef HAVE_LIBSOCIALWEB
+  priv->flickr_source = bg_flickr_source_new ();
+#endif
+
+  gtk_container_set_border_width (GTK_CONTAINER (chooser), 6);
+  gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
+  gtk_window_set_resizable (GTK_WINDOW (chooser), FALSE);
+  /* translators: This is the title of the wallpaper chooser dialog. */
+  gtk_window_set_title (GTK_WINDOW (chooser), _("Select Background"));
+
+  vbox = gtk_dialog_get_content_area (GTK_DIALOG (chooser));
+  grid = gtk_grid_new ();
+  gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
+  gtk_widget_set_margin_bottom (grid, 6);
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_VERTICAL);
+  gtk_grid_set_row_spacing (GTK_GRID (grid), 12);
+  gtk_grid_set_column_spacing (GTK_GRID (grid), 0);
+  gtk_container_add (GTK_CONTAINER (vbox), grid);
+
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
+  gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
+  gtk_widget_set_hexpand (hbox, TRUE);
+  gtk_container_add (GTK_CONTAINER (grid), hbox);
+  context = gtk_widget_get_style_context (hbox);
+  gtk_style_context_add_class (context, "linked");
+
+  button1 = gtk_radio_button_new_with_label (NULL, _("Wallpapers"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button1), TRUE);
+  context = gtk_widget_get_style_context (button1);
+  gtk_style_context_add_class (context, "raised");
+  gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button1), FALSE);
+  gtk_container_add (GTK_CONTAINER (hbox), button1);
+  g_signal_connect (button1, "toggled", G_CALLBACK (on_view_toggled), chooser);
+  g_object_set_data (G_OBJECT (button1), "source", priv->wallpapers_source);
+
+  button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button1), _("Pictures"));
+  context = gtk_widget_get_style_context (button);
+  gtk_style_context_add_class (context, "raised");
+  gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+  gtk_container_add (GTK_CONTAINER (hbox), button);
+  g_signal_connect (button, "toggled", G_CALLBACK (on_view_toggled), chooser);
+  g_object_set_data (G_OBJECT (button), "source", priv->pictures_source);
+
+  button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button1), _("Colors"));
+  context = gtk_widget_get_style_context (button);
+  gtk_style_context_add_class (context, "raised");
+  gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+  gtk_container_add (GTK_CONTAINER (hbox), button);
+  g_signal_connect (button, "toggled", G_CALLBACK (on_view_toggled), chooser);
+  g_object_set_data (G_OBJECT (button), "source", priv->colors_source);
+
+#ifdef HAVE_LIBSOCIALWEB
+  button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button1), _("Flickr"));
+  context = gtk_widget_get_style_context (button);
+  gtk_style_context_add_class (context, "raised");
+  gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
+  gtk_container_add (GTK_CONTAINER (hbox), button);
+  g_signal_connect (button, "toggled", G_CALLBACK (on_view_toggled), chooser);
+  g_object_set_data (G_OBJECT (button), "source", priv->flickr_source);
+#endif
+
+  sw_content = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw_content), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw_content), GTK_SHADOW_IN);
+  gtk_widget_set_hexpand (sw_content, TRUE);
+  gtk_widget_set_vexpand (sw_content, TRUE);
+  gtk_container_add (GTK_CONTAINER (grid), sw_content);
+  g_object_set (sw_content,
+                "width-request", 850,
+                "height-request", 550,
+                NULL);
+
+  priv->icon_view = gtk_icon_view_new ();
+  gtk_widget_set_hexpand (priv->icon_view, TRUE);
+  gtk_container_add (GTK_CONTAINER (sw_content), priv->icon_view);
+  g_signal_connect (priv->icon_view, "selection-changed", G_CALLBACK (on_selection_changed), chooser);
+  g_signal_connect (priv->icon_view, "item-activated", G_CALLBACK (on_item_activated), chooser);
+
+  renderer = gtk_cell_renderer_pixbuf_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->icon_view),
+                              renderer,
+                              FALSE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->icon_view),
+                                  renderer,
+                                  "gicon", 0,
+                                  NULL);
+
+  gtk_dialog_add_button (GTK_DIALOG (chooser), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+  gtk_dialog_add_button (GTK_DIALOG (chooser), _("Select"), GTK_RESPONSE_OK);
+  gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK);
+  gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_OK, FALSE);
+
+  gtk_widget_show_all (vbox);
+}
+
+static void
+cc_background_chooser_dialog_class_init (CcBackgroundChooserDialogClass *klass)
+{
+  GObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = G_OBJECT_CLASS (klass);
+  object_class->dispose = cc_background_chooser_dialog_dispose;
+  object_class->finalize = cc_background_chooser_dialog_finalize;
+
+  widget_class = GTK_WIDGET_CLASS (klass);
+  widget_class->realize = cc_background_chooser_dialog_realize;
+
+  g_type_class_add_private (object_class, sizeof (CcBackgroundChooserDialogPrivate));
+}
+
+GtkWidget *
+cc_background_chooser_dialog_new (void)
+{
+  return g_object_new (CC_TYPE_BACKGROUND_CHOOSER_DIALOG, NULL);
+}
+
+CcBackgroundItem *
+cc_background_chooser_dialog_get_item (CcBackgroundChooserDialog *chooser)
+{
+  CcBackgroundChooserDialogPrivate *priv = chooser->priv;
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+  GList *list;
+  CcBackgroundItem *item;
+
+  item = NULL;
+  list = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (priv->icon_view));
+
+  if (!list)
+    return NULL;
+
+  model = gtk_icon_view_get_model (GTK_ICON_VIEW (priv->icon_view));
+
+  if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) list->data) == FALSE)
+    goto bail;
+
+  gtk_tree_model_get (model, &iter, 1, &item, -1);
+
+bail:
+  g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
+
+  return item;
+}
diff --git a/panels/background/cc-background-chooser-dialog.h b/panels/background/cc-background-chooser-dialog.h
new file mode 100644
index 0000000..6be191f
--- /dev/null
+++ b/panels/background/cc-background-chooser-dialog.h
@@ -0,0 +1,60 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __CC_PANEL_CHOOSER_DIALOG_H__
+#define __CC_PANEL_CHOOSER_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#include "cc-background-item.h"
+
+G_BEGIN_DECLS
+
+#define CC_TYPE_BACKGROUND_CHOOSER_DIALOG            (cc_background_chooser_dialog_get_type ())
+#define CC_BACKGROUND_CHOOSER_DIALOG(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), CC_TYPE_BACKGROUND_CHOOSER_DIALOG, CcBackgroundChooserDialog))
+#define CC_BACKGROUND_CHOOSER_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CC_TYPE_BACKGROUND_CHOOSER_DIALOG, CcBackgroundChooserDialogClass))
+#define CC_IS_BACKGROUND_CHOOSER_DIALOG(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), CC_TYPE_BACKGROUND_CHOOSER_DIALOG))
+#define CC_IS_BACKGROUND_CHOOSER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CC_TYPE_BACKGROUND_CHOOSER_DIALOG))
+#define CC_BACKGROUND_CHOOSER_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), CC_TYPE_BACKGROUND_CHOOSER_DIALOG, CcBackgroundChooserDialogClass))
+
+typedef struct _CcBackgroundChooserDialog        CcBackgroundChooserDialog;
+typedef struct _CcBackgroundChooserDialogClass   CcBackgroundChooserDialogClass;
+typedef struct _CcBackgroundChooserDialogPrivate CcBackgroundChooserDialogPrivate;
+
+struct _CcBackgroundChooserDialog
+{
+  GtkDialog parent_instance;
+  CcBackgroundChooserDialogPrivate *priv;
+};
+
+struct _CcBackgroundChooserDialogClass
+{
+  GtkDialogClass parent_class;
+};
+
+GType                  cc_background_chooser_dialog_get_type               (void) G_GNUC_CONST;
+GtkWidget *            cc_background_chooser_dialog_new                    (void);
+
+CcBackgroundItem *     cc_background_chooser_dialog_get_item               (CcBackgroundChooserDialog *chooser);
+
+G_END_DECLS
+
+#endif /* __CC_BACKGROUND_CHOOSER_DIALOG_H__ */
diff --git a/panels/background/cc-background-panel.c b/panels/background/cc-background-panel.c
index 7eeca08..137a515 100644
--- a/panels/background/cc-background-panel.c
+++ b/panels/background/cc-background-panel.c
@@ -22,21 +22,19 @@
 #include <config.h>
 
 #include <string.h>
+#include <glib.h>
 #include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
+
 #include <gdesktop-enums.h>
 
 #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 "cc-background-item.h"
 #include "cc-background-xml.h"
 
+#include "cc-background-chooser-dialog.h"
+
 #define WP_PATH_ID "org.gnome.desktop.background"
 #define WP_URI_KEY "picture-uri"
 #define WP_OPTIONS_KEY "picture-options"
@@ -44,13 +42,6 @@
 #define WP_PCOLOR_KEY "primary-color"
 #define WP_SCOLOR_KEY "secondary-color"
 
-enum {
-  COL_SOURCE_NAME,
-  COL_SOURCE_TYPE,
-  COL_SOURCE,
-  NUM_COLS
-};
-
 G_DEFINE_DYNAMIC_TYPE (CcBackgroundPanel, cc_background_panel, CC_TYPE_PANEL)
 
 #define BACKGROUND_PANEL_PRIVATE(o) \
@@ -59,41 +50,23 @@ G_DEFINE_DYNAMIC_TYPE (CcBackgroundPanel, cc_background_panel, CC_TYPE_PANEL)
 struct _CcBackgroundPanelPrivate
 {
   GtkBuilder *builder;
-
-  BgWallpapersSource *wallpapers_source;
-  BgPicturesSource *pictures_source;
-  BgColorsSource *colors_source;
-
-#ifdef HAVE_LIBSOCIALWEB
-  BgFlickrSource *flickr_source;
-#endif
+  GDBusConnection *connection;
 
   GSettings *settings;
 
   GnomeDesktopThumbnailFactory *thumb_factory;
 
   CcBackgroundItem *current_background;
-  gint current_source;
 
   GCancellable *copy_cancellable;
 
   GtkWidget *spinner;
 
-  GdkPixbuf *display_base;
   GdkPixbuf *display_overlay;
+  GdkPixbuf *display_screenshot;
+  char *screenshot_path;
 };
 
-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 const char *
@@ -103,32 +76,6 @@ cc_background_panel_get_help_uri (CcPanel *panel)
 }
 
 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;
@@ -142,31 +89,6 @@ cc_background_panel_dispose (GObject *object)
       priv->spinner = 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->settings)
     {
       g_object_unref (priv->settings);
@@ -188,18 +110,23 @@ cc_background_panel_dispose (GObject *object)
       priv->thumb_factory = NULL;
     }
 
-  if (priv->display_base)
-    {
-      g_object_unref (priv->display_base);
-      priv->display_base = NULL;
-    }
-
   if (priv->display_overlay)
     {
       g_object_unref (priv->display_overlay);
       priv->display_overlay = NULL;
     }
 
+  if (priv->display_screenshot)
+    {
+      g_object_unref (priv->display_screenshot);
+      priv->display_screenshot = NULL;
+    }
+
+  g_free (priv->screenshot_path);
+  priv->screenshot_path = NULL;
+
+  g_clear_object (&priv->connection);
+
   G_OBJECT_CLASS (cc_background_panel_parent_class)->dispose (object);
 }
 
@@ -227,8 +154,6 @@ cc_background_panel_class_init (CcBackgroundPanelClass *klass)
 
   panel_class->get_help_uri = cc_background_panel_get_help_uri;
 
-  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;
 }
@@ -239,153 +164,293 @@ cc_background_panel_class_finalize (CcBackgroundPanelClass *klass)
 }
 
 static void
-source_update_edit_box (CcBackgroundPanelPrivate *priv,
-			gboolean                  initial)
+update_preview (CcBackgroundPanelPrivate *priv,
+                CcBackgroundItem         *item)
 {
-  CcBackgroundItemFlags flags;
-
-  flags = cc_background_item_get_flags (priv->current_background);
+  gboolean changes_with_time;
 
-  if ((flags & CC_BACKGROUND_ITEM_HAS_SCOLOR &&
-       priv->current_source != SOURCE_COLORS) ||
-      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"));
+  if (item && priv->current_background)
+    {
+      g_object_unref (priv->current_background);
+      priv->current_background = cc_background_item_copy (item);
+      cc_background_item_load (priv->current_background, NULL);
+    }
 
-  if (flags & CC_BACKGROUND_ITEM_HAS_PCOLOR &&
-      priv->current_source != SOURCE_COLORS)
-    gtk_widget_hide (WID ("style-pcolor"));
-  else
-    gtk_widget_show (WID ("style-pcolor"));
+  changes_with_time = FALSE;
 
-  if (gtk_widget_get_visible (WID ("style-pcolor")) &&
-      gtk_widget_get_visible (WID ("style-scolor")))
-    gtk_widget_show (WID ("swap-color-button"));
-  else
-    gtk_widget_hide (WID ("swap-color-button"));
+  if (priv->current_background)
+    {
+      changes_with_time = cc_background_item_changes_with_time (priv->current_background);
+    }
 
-  if (flags & CC_BACKGROUND_ITEM_HAS_PLACEMENT ||
-      cc_background_item_get_uri (priv->current_background) == NULL)
-    gtk_widget_hide (WID ("style-combobox"));
-  else
-    gtk_widget_show (WID ("style-combobox"));
+  gtk_widget_set_visible (WID ("slide_image"), changes_with_time);
+  gtk_widget_set_visible (WID ("slide-label"), changes_with_time);
 
-  /* FIXME What to do if the background has a gradient shading
-   * and provides the colours? */
+  gtk_widget_queue_draw (WID ("background-desktop-drawingarea"));
 }
 
-static void
-source_changed_cb (GtkComboBox              *combo,
-                   CcBackgroundPanelPrivate *priv)
+static char *
+get_save_path (void)
 {
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GtkIconView *view;
-  guint type;
-  BgSource *source;
-
-  gtk_combo_box_get_active_iter (combo, &iter);
-  model = gtk_combo_box_get_model (combo);
-  gtk_tree_model_get (model, &iter,
-                      COL_SOURCE_TYPE, &type,
-                      COL_SOURCE, &source, -1);
-
-  view = (GtkIconView *) gtk_builder_get_object (priv->builder,
-                                                 "backgrounds-iconview");
-
-  gtk_icon_view_set_model (view,
-                           GTK_TREE_MODEL (bg_source_get_liststore (source)));
+  return g_build_filename (g_get_user_config_dir (),
+                           "gnome-control-center",
+                           "backgrounds",
+                           "last-edited.xml",
+                           NULL);
 }
 
 static void
-select_style (GtkComboBox *box,
-	      GDesktopBackgroundStyle new_style)
+update_display_preview (CcBackgroundPanel *panel)
 {
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  gboolean cont;
+  CcBackgroundPanelPrivate *priv = panel->priv;
+  GtkWidget *widget;
+  GtkAllocation allocation;
+  const gint preview_width = 416;
+  const gint preview_height = 248;
+  GdkPixbuf *pixbuf;
+  GIcon *icon;
+  cairo_t *cr;
 
-  model = gtk_combo_box_get_model (box);
-  cont = gtk_tree_model_get_iter_first (model, &iter);
-  while (cont != FALSE)
-    {
-      GDesktopBackgroundStyle style;
+  widget = WID ("background-desktop-drawingarea");
+  gtk_widget_get_allocation (widget, &allocation);
+
+  if (!priv->current_background)
+    return;
 
-      gtk_tree_model_get (model, &iter,
-			  1, &style,
-			  -1);
+  icon = cc_background_item_get_frame_thumbnail (priv->current_background,
+                                                 priv->thumb_factory,
+                                                 preview_width,
+                                                 preview_height,
+                                                 -2, TRUE);
+  pixbuf = GDK_PIXBUF (icon);
 
-      if (style == new_style)
-        {
-          gtk_combo_box_set_active_iter (box, &iter);
-          break;
-	}
-      cont = gtk_tree_model_iter_next (model, &iter);
+  cr = gdk_cairo_create (gtk_widget_get_window (widget));
+  gdk_cairo_set_source_pixbuf (cr,
+                               pixbuf,
+                               0, 0);
+  cairo_paint (cr);
+  g_object_unref (pixbuf);
+
+  pixbuf = NULL;
+  if (panel->priv->display_screenshot != NULL)
+    pixbuf = gdk_pixbuf_scale_simple (panel->priv->display_screenshot,
+                                      preview_width,
+                                      preview_height,
+                                      GDK_INTERP_BILINEAR);
+
+  if (pixbuf)
+    {
+      gdk_cairo_set_source_pixbuf (cr,
+                                   pixbuf,
+                                   0, 0);
+      cairo_paint (cr);
     }
 
-  if (cont == FALSE)
-    gtk_combo_box_set_active (box, -1);
+  if (priv->display_overlay)
+    {
+      gdk_cairo_set_source_pixbuf (cr,
+                                   priv->display_overlay,
+                                   0, 0);
+      cairo_paint (cr);
+    }
+
+  cairo_destroy (cr);
 }
 
 static void
-update_preview (CcBackgroundPanelPrivate *priv,
-                CcBackgroundItem         *item)
+on_screenshot_finished (GObject *source,
+                        GAsyncResult *res,
+                        gpointer user_data)
 {
-  gchar *markup;
-  gboolean changes_with_time;
+  CcBackgroundPanel *panel = user_data;
+  CcBackgroundPanelPrivate *priv = panel->priv;
+  GError *error;
+  GdkRectangle rect;
+  GtkWidget *widget;
+  GdkPixbuf *pixbuf;
+  cairo_surface_t *surface;
+  cairo_t *cr;
+  int width;
+  int height;
+
+  error = NULL;
+  g_dbus_connection_call_finish (panel->priv->connection,
+                                 res,
+                                 &error);
+
+  if (error != NULL) {
+    g_debug ("Unable to get screenshot: %s",
+             error->message);
+    g_error_free (error);
+    /* fallback? */
+    goto out;
+  }
 
-  if (item && priv->current_background)
+  pixbuf = gdk_pixbuf_new_from_file (panel->priv->screenshot_path, &error);
+  if (error != NULL)
     {
-      g_object_unref (priv->current_background);
-      priv->current_background = cc_background_item_copy (item);
-      cc_background_item_load (priv->current_background, NULL);
+      g_debug ("Unable to use GNOME Shell's builtin screenshot interface: %s",
+               error->message);
+      g_error_free (error);
+      goto out;
     }
 
-  source_update_edit_box (priv, FALSE);
+  width = gdk_pixbuf_get_width (pixbuf);
+  height = gdk_pixbuf_get_height (pixbuf);
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                        width, height);
+  cr = cairo_create (surface);
+  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+  cairo_paint (cr);
+  g_object_unref (pixbuf);
 
-  changes_with_time = FALSE;
+  /* clear the workarea */
+   widget = WID ("background-desktop-drawingarea");
+  gdk_screen_get_monitor_workarea (gtk_widget_get_screen (widget), 0, &rect);
 
-  if (priv->current_background)
-    {
-      GdkColor pcolor, scolor;
-      char *escaped;
+  cairo_save (cr);
+  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+  cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
+  cairo_fill (cr);
+  cairo_restore (cr);
 
-      escaped = g_markup_escape_text (cc_background_item_get_name (priv->current_background), -1);
-      markup = g_strdup_printf ("<b>%s</b>", escaped);
-      g_free (escaped);
+  g_clear_object (&panel->priv->display_screenshot);
+  panel->priv->display_screenshot = gdk_pixbuf_get_from_surface (surface,
+                                                                 0, 0,
+                                                                 width,
+                                                                 height);
+  /* remove the temporary file created by the shell */
+  g_unlink (panel->priv->screenshot_path);
+  g_free (priv->screenshot_path);
+  priv->screenshot_path = NULL;
 
-      gtk_label_set_markup (GTK_LABEL (WID ("background-label")), markup);
-      g_free (markup);
+  cairo_destroy (cr);
+  cairo_surface_destroy (surface);
 
-      gtk_label_set_text (GTK_LABEL (WID ("size_label")), cc_background_item_get_size (priv->current_background));
+ out:
+  update_display_preview (panel);
+}
 
-      gdk_color_parse (cc_background_item_get_pcolor (priv->current_background), &pcolor);
-      gdk_color_parse (cc_background_item_get_scolor (priv->current_background), &scolor);
+static void
+get_screenshot_async (CcBackgroundPanel *panel,
+                      GdkRectangle      *rectangle)
+{
+  gchar *path, *tmpname;
+  const gchar *method_name;
+  GVariant *method_params;
 
-      gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-pcolor")), &pcolor);
-      gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-scolor")), &scolor);
+  path = g_build_filename (g_get_user_cache_dir (), "gnome-control-center", NULL);
+  g_mkdir_with_parents (path, 0700);
 
-      select_style (GTK_COMBO_BOX (WID ("style-combobox")),
-                    cc_background_item_get_placement (priv->current_background));
+  tmpname = g_strdup_printf ("scr-%d.png", g_random_int ());
+  g_free (panel->priv->screenshot_path);
+  panel->priv->screenshot_path = g_build_filename (path, tmpname, NULL);
+  g_free (path);
+  g_free (tmpname);
+
+  method_name = "ScreenshotArea";
+  method_params = g_variant_new ("(iiiibs)",
+                                 rectangle->x, rectangle->y,
+                                 rectangle->width, rectangle->height,
+                                 FALSE, /* flash */
+                                 panel->priv->screenshot_path);
+
+  g_dbus_connection_call (panel->priv->connection,
+                          "org.gnome.Shell",
+                          "/org/gnome/Shell",
+                          "org.gnome.Shell",
+                          method_name,
+                          method_params,
+                          NULL,
+                          G_DBUS_CALL_FLAGS_NONE,
+                          -1,
+                          NULL,
+                          on_screenshot_finished,
+                          panel);
+}
 
-      changes_with_time = cc_background_item_changes_with_time (priv->current_background);
-    }
+static gboolean
+on_preview_draw (GtkWidget         *widget,
+                 cairo_t           *cr,
+                 CcBackgroundPanel *panel)
+{
+  /* we have another shot in flight or an existing cache */
+  if (panel->priv->display_screenshot == NULL
+      && panel->priv->screenshot_path == NULL)
+    {
+      GdkRectangle rect;
 
-  gtk_widget_set_visible (WID ("slide_image"), changes_with_time);
-  gtk_widget_set_visible (WID ("slide-label"), changes_with_time);
+      gdk_screen_get_monitor_geometry (gtk_widget_get_screen (widget), 0, &rect);
+      get_screenshot_async (panel, &rect);
+    }
+  else
+    update_display_preview (panel);
 
-  gtk_widget_queue_draw (WID ("preview-area"));
+  return TRUE;
 }
 
-static char *
-get_save_path (void)
+static void
+load_current_bg (CcBackgroundPanel *self)
 {
-  return g_build_filename (g_get_user_config_dir (),
-			   "gnome-control-center",
-			   "backgrounds",
-			   "last-edited.xml",
-			   NULL);
+  CcBackgroundPanelPrivate *priv;
+  CcBackgroundItem *saved, *configured;
+  gchar *uri, *pcolor, *scolor;
+
+  priv = self->priv;
+
+  /* Load the saved configuration */
+  uri = get_save_path ();
+  saved = cc_background_xml_get_item (uri);
+  g_free (uri);
+
+  /* initalise the current background information from settings */
+  uri = g_settings_get_string (priv->settings, WP_URI_KEY);
+  if (uri && *uri == '\0')
+    {
+      g_free (uri);
+      uri = NULL;
+    }
+  else
+    {
+      GFile *file;
+
+      file = g_file_new_for_commandline_arg (uri);
+      g_object_unref (file);
+    }
+  configured = cc_background_item_new (uri);
+  g_free (uri);
+
+  pcolor = g_settings_get_string (priv->settings, WP_PCOLOR_KEY);
+  scolor = g_settings_get_string (priv->settings, WP_SCOLOR_KEY);
+  g_object_set (G_OBJECT (configured),
+                "name", _("Current background"),
+                "placement", g_settings_get_enum (priv->settings, WP_OPTIONS_KEY),
+                "shading", g_settings_get_enum (priv->settings, WP_SHADING_KEY),
+                "primary-color", pcolor,
+                "secondary-color", scolor,
+                NULL);
+  g_free (pcolor);
+  g_free (scolor);
+
+  if (saved != NULL && cc_background_item_compare (saved, configured))
+    {
+      CcBackgroundItemFlags flags;
+      flags = cc_background_item_get_flags (saved);
+      /* Special case for colours */
+      if (cc_background_item_get_placement (saved) == G_DESKTOP_BACKGROUND_STYLE_NONE)
+        flags &=~ (CC_BACKGROUND_ITEM_HAS_PCOLOR | CC_BACKGROUND_ITEM_HAS_SCOLOR);
+      g_object_set (G_OBJECT (configured),
+		    "name", cc_background_item_get_name (saved),
+		    "flags", flags,
+		    "source-url", cc_background_item_get_source_url (saved),
+		    "source-xml", cc_background_item_get_source_xml (saved),
+		    NULL);
+    }
+  if (saved != NULL)
+    g_object_unref (saved);
+
+  priv->current_background = configured;
+  cc_background_item_load (priv->current_background, NULL);
 }
 
 static gboolean
@@ -455,103 +520,19 @@ copy_finished_cb (GObject      *source_object,
 }
 
 static void
-update_remove_button (CcBackgroundPanel *panel,
-		      CcBackgroundItem  *item)
-{
-  CcBackgroundPanelPrivate *priv;
-  const char *uri;
-  char *cache_path;
-  GFile *bg, *cache, *parent;
-  gboolean sensitive = FALSE;
-
-  priv = panel->priv;
-
-  if (priv->current_source != SOURCE_PICTURES)
-    goto bail;
-
-  uri = cc_background_item_get_uri (item);
-  if (uri == NULL)
-    goto bail;
-
-  bg = g_file_new_for_uri (uri);
-  parent = g_file_get_parent (bg);
-  if (parent == NULL)
-    {
-      g_object_unref (bg);
-      goto bail;
-    }
-  cache_path = bg_pictures_source_get_cache_path ();
-  cache = g_file_new_for_path (cache_path);
-  g_free (cache_path);
-
-  if (g_file_equal (parent, cache))
-    sensitive = TRUE;
-
-  g_object_unref (parent);
-  g_object_unref (cache);
-
-bail:
-  gtk_widget_set_sensitive (WID ("remove_button"), sensitive);
-
-}
-
-static CcBackgroundItem *
-get_selected_item (CcBackgroundPanel *panel)
+set_background (CcBackgroundPanel *panel,
+                CcBackgroundItem  *item)
 {
   CcBackgroundPanelPrivate *priv = panel->priv;
-  GtkIconView *icon_view;
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GList *list;
-  CcBackgroundItem *item;
-
-  icon_view = GTK_ICON_VIEW (WID ("backgrounds-iconview"));
-  item = NULL;
-  list = gtk_icon_view_get_selected_items (icon_view);
-
-  if (!list)
-    return NULL;
-
-  model = gtk_icon_view_get_model (icon_view);
-
-  if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) list->data) == FALSE)
-    goto bail;
-
-  gtk_tree_model_get (model, &iter, 1, &item, -1);
-
-bail:
-  g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
-  g_list_free (list);
-
-  return item;
-}
-
-static void
-backgrounds_changed_cb (GtkIconView       *icon_view,
-                        CcBackgroundPanel *panel)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  CcBackgroundItem *item;
-  CcBackgroundPanelPrivate *priv = panel->priv;
-  char *pcolor, *scolor;
+  GDesktopBackgroundStyle style;
   gboolean draw_preview = TRUE;
   const char *uri;
   CcBackgroundItemFlags flags;
   char *filename;
 
-  item = get_selected_item (panel);
-
   if (item == NULL)
     return;
 
-  /* Update current source */
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (WID ("sources-combobox")));
-  gtk_combo_box_get_active_iter (GTK_COMBO_BOX (WID ("sources-combobox")),
-                                 &iter);
-  gtk_tree_model_get (model, &iter,
-		      COL_SOURCE_TYPE, &priv->current_source, -1);
-
   uri = cc_background_item_get_uri (item);
   flags = cc_background_item_get_flags (item);
 
@@ -561,10 +542,10 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
       g_settings_set_string (priv->settings, WP_URI_KEY, "");
     }
   else if (cc_background_item_get_source_url (item) != NULL &&
-	   cc_background_item_get_needs_download (item))
+           cc_background_item_get_needs_download (item))
     {
       GFile *source, *dest;
-      gchar *cache_path, *basename, *dest_path, *display_name, *dest_uri;
+      char *cache_path, *basename, *dest_path, *display_name, *dest_uri;
       GdkPixbuf *pixbuf;
 
       cache_path = bg_pictures_source_get_cache_path ();
@@ -573,7 +554,7 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
           g_warning ("Failed to create directory '%s'", cache_path);
           g_free (cache_path);
           return;
-	}
+        }
       g_free (cache_path);
 
       dest_path = bg_pictures_source_get_unique_path (cc_background_item_get_source_url (item));
@@ -625,10 +606,10 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
 
       g_settings_set_string (priv->settings, WP_URI_KEY, dest_uri);
       g_object_set (G_OBJECT (item),
-		    "uri", dest_uri,
-		    "needs-download", FALSE,
-		    "name", display_name,
-		    NULL);
+                    "uri", dest_uri,
+                    "needs-download", FALSE,
+                    "name", display_name,
+                    NULL);
       g_free (display_name);
       g_free (dest_uri);
 
@@ -647,7 +628,6 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
     }
   else if (uri != NULL)
     {
-      GDesktopBackgroundStyle style;
       style = g_settings_get_enum (priv->settings, WP_OPTIONS_KEY);
       if (style == G_DESKTOP_BACKGROUND_STYLE_NONE)
         g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, cc_background_item_get_placement (item));
@@ -656,37 +636,12 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
   if (flags & CC_BACKGROUND_ITEM_HAS_SHADING)
     g_settings_set_enum (priv->settings, WP_SHADING_KEY, cc_background_item_get_shading (item));
 
-  /* When changing to a background with colours set,
-   * don't overwrite what's in GSettings, but read
-   * from it instead.
-   * We have a hack for the colors source though */
-  if (flags & CC_BACKGROUND_ITEM_HAS_PCOLOR &&
-      priv->current_source != SOURCE_COLORS)
-    {
-      g_settings_set_string (priv->settings, WP_PCOLOR_KEY, cc_background_item_get_pcolor (item));
-    }
-  else
-    {
-      pcolor = g_settings_get_string (priv->settings, WP_PCOLOR_KEY);
-      g_object_set (G_OBJECT (item), "primary-color", pcolor, NULL);
-    }
-
-  if (flags & CC_BACKGROUND_ITEM_HAS_SCOLOR &&
-      priv->current_source != SOURCE_COLORS)
-    {
-      g_settings_set_string (priv->settings, WP_SCOLOR_KEY, cc_background_item_get_scolor (item));
-    }
-  else
-    {
-      scolor = g_settings_get_string (priv->settings, WP_SCOLOR_KEY);
-      g_object_set (G_OBJECT (item), "secondary-color", scolor, NULL);
-    }
+  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));
 
   /* Apply all changes */
   g_settings_apply (priv->settings);
 
-  update_remove_button (panel, item);
-
   /* update the preview information */
   if (draw_preview != FALSE)
     {
@@ -699,503 +654,55 @@ backgrounds_changed_cb (GtkIconView       *icon_view,
     }
 }
 
-static gboolean
-preview_draw_cb (GtkWidget         *widget,
-                 cairo_t           *cr,
-                 CcBackgroundPanel *panel)
-{
-  GtkAllocation allocation;
-  CcBackgroundPanelPrivate *priv = panel->priv;
-  GdkPixbuf *pixbuf = NULL;
-  const gint preview_width = 416;
-  const gint preview_height = 248;
-  const gint preview_x = 45;
-  const gint preview_y = 84;
-  GdkPixbuf *preview, *temp;
-  gint size;
-
-  gtk_widget_get_allocation (widget, &allocation);
-
-  if (priv->current_background)
-    {
-      GIcon *icon;
-      icon = cc_background_item_get_frame_thumbnail (priv->current_background,
-                                                     priv->thumb_factory,
-                                                     preview_width,
-                                                     preview_height,
-                                                     -2, TRUE);
-      pixbuf = GDK_PIXBUF (icon);
-    }
-
-  if (!priv->display_base)
-    return FALSE;
-
-
-  preview = gdk_pixbuf_copy (priv->display_base);
-
-  if (pixbuf)
-    {
-      gdk_pixbuf_composite (pixbuf, preview,
-                            preview_x, preview_y,
-                            preview_width, preview_height,
-                            preview_x, preview_y, 1, 1,
-                            GDK_INTERP_BILINEAR, 255);
-
-      g_object_unref (pixbuf);
-    }
-
-
-  if (priv->display_overlay)
-    {
-      gdk_pixbuf_composite (priv->display_overlay, preview,
-                            0, 0, 512, 512,
-                            0, 0, 1, 1,
-                            GDK_INTERP_BILINEAR, 255);
-    }
-
-
-  if (allocation.width < allocation.height)
-    size = allocation.width;
-  else
-    size = allocation.height;
-
-  temp = gdk_pixbuf_scale_simple (preview, size, size, GDK_INTERP_BILINEAR);
-
-  gdk_cairo_set_source_pixbuf (cr,
-                               temp,
-                               allocation.width / 2 - (size / 2),
-                               allocation.height / 2 - (size / 2));
-  cairo_paint (cr);
-
-  g_object_unref (temp);
-  g_object_unref (preview);
-
-  return TRUE;
-}
-
-static void
-style_changed_cb (GtkComboBox       *box,
-                  CcBackgroundPanel *panel)
-{
-  CcBackgroundPanelPrivate *priv = panel->priv;
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  GDesktopBackgroundStyle value;
-
-  if (!gtk_combo_box_get_active_iter (box, &iter))
-    {
-      return;
-    }
-
-  model = gtk_combo_box_get_model (box);
-
-  gtk_tree_model_get (model, &iter, 1, &value, -1);
-
-  g_settings_set_enum (priv->settings, WP_OPTIONS_KEY, value);
-
-  if (priv->current_background)
-    g_object_set (G_OBJECT (priv->current_background), "placement", value, NULL);
-
-  g_settings_apply (priv->settings);
-
-  update_preview (priv, NULL);
-}
-
-static void
-color_changed_cb (GtkColorButton    *button,
-                  CcBackgroundPanel *panel)
-{
-  CcBackgroundPanelPrivate *priv = panel->priv;
-  GdkColor color;
-  gchar *value;
-  gboolean is_pcolor = FALSE;
-
-  gtk_color_button_get_color (button, &color);
-  if (WID ("style-pcolor") == GTK_WIDGET (button))
-    is_pcolor = TRUE;
-
-  value = gdk_color_to_string (&color);
-
-  if (priv->current_background)
-    {
-      g_object_set (G_OBJECT (priv->current_background),
-		    is_pcolor ? "primary-color" : "secondary-color", value, NULL);
-    }
-
-  g_settings_set_string (priv->settings,
-			 is_pcolor ? WP_PCOLOR_KEY : WP_SCOLOR_KEY, value);
-
-  g_settings_apply (priv->settings);
-
-  g_free (value);
-
-  update_preview (priv, NULL);
-}
-
-static void
-swap_colors_clicked (GtkButton         *button,
-                     CcBackgroundPanel *panel)
-{
-  CcBackgroundPanelPrivate *priv = panel->priv;
-  GdkColor pcolor, scolor;
-  char *new_pcolor, *new_scolor;
-
-  gtk_color_button_get_color (GTK_COLOR_BUTTON (WID ("style-pcolor")), &pcolor);
-  gtk_color_button_get_color (GTK_COLOR_BUTTON (WID ("style-scolor")), &scolor);
-
-  gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-scolor")), &pcolor);
-  gtk_color_button_set_color (GTK_COLOR_BUTTON (WID ("style-pcolor")), &scolor);
-
-  new_pcolor = gdk_color_to_string (&scolor);
-  new_scolor = gdk_color_to_string (&pcolor);
-
-  g_object_set (priv->current_background,
-                "primary-color", new_pcolor,
-                "secondary-color", new_scolor,
-                NULL);
-
-  g_settings_set_string (priv->settings, WP_PCOLOR_KEY, new_pcolor);
-  g_settings_set_string (priv->settings, WP_SCOLOR_KEY, new_scolor);
-
-  g_free (new_pcolor);
-  g_free (new_scolor);
-
-  g_settings_apply (priv->settings);
-
-  update_preview (priv, NULL);
-}
-
 static void
-row_inserted (GtkTreeModel      *tree_model,
-	      GtkTreePath       *path,
-	      GtkTreeIter       *iter,
-	      CcBackgroundPanel *panel)
+on_chooser_dialog_response (GtkDialog         *dialog,
+                            int                response_id,
+                            CcBackgroundPanel *self)
 {
-  GtkListStore *store;
-  CcBackgroundPanelPrivate *priv;
-
-  priv = panel->priv;
-
-  store = bg_source_get_liststore (BG_SOURCE (panel->priv->pictures_source));
-  g_signal_handlers_disconnect_by_func (G_OBJECT (store), G_CALLBACK (row_inserted), panel);
-
-  /* Change source */
-  gtk_combo_box_set_active (GTK_COMBO_BOX (WID ("sources-combobox")), SOURCE_PICTURES);
-
-  /* And select the newly added item */
-  gtk_icon_view_select_path (GTK_ICON_VIEW (WID ("backgrounds-iconview")), path);
-}
-
-static void
-add_custom_wallpaper (CcBackgroundPanel *panel,
-		      const char        *uri)
-{
-  GtkListStore *store;
-
-  store = bg_source_get_liststore (BG_SOURCE (panel->priv->pictures_source));
-  g_signal_connect (G_OBJECT (store), "row-inserted",
-		    G_CALLBACK (row_inserted), panel);
-
-  if (bg_pictures_source_add (panel->priv->pictures_source, uri) == FALSE) {
-    g_signal_handlers_disconnect_by_func (G_OBJECT (store), G_CALLBACK (row_inserted), panel);
-    return;
-  }
-
-  /* Wait for the item to get added */
-}
-
-static void
-file_chooser_response (GtkDialog         *chooser,
-                       gint               response,
-                       CcBackgroundPanel *panel)
-{
-  GSList *selected, *l;
-
-  if (response != GTK_RESPONSE_ACCEPT)
+  if (response_id == GTK_RESPONSE_OK)
     {
-      gtk_widget_destroy (GTK_WIDGET (chooser));
-      return;
-    }
+      CcBackgroundItem *item;
 
-  selected = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (chooser));
-  gtk_widget_destroy (GTK_WIDGET (chooser));
-
-  for (l = selected; l != NULL; l = l->next)
-    {
-      char *uri = l->data;
-      add_custom_wallpaper (panel, uri);
-      g_free (uri);
-    }
-  g_slist_free (selected);
-}
-
-static void
-update_chooser_preview (GtkFileChooser    *chooser,
-			CcBackgroundPanel *panel)
-{
-  GnomeDesktopThumbnailFactory *thumb_factory;
-  char *uri;
-
-  thumb_factory = panel->priv->thumb_factory;
-
-  uri = gtk_file_chooser_get_preview_uri (chooser);
-
-  if (uri)
-    {
-      GdkPixbuf *pixbuf = NULL;
-      const gchar *mime_type = NULL;
-      GFile *file;
-      GFileInfo *file_info;
-      GtkWidget *preview;
-
-      preview = gtk_file_chooser_get_preview_widget (chooser);
-
-      file = g_file_new_for_uri (uri);
-      file_info = g_file_query_info (file,
-				     G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
-				     G_FILE_QUERY_INFO_NONE,
-				     NULL, NULL);
-      g_object_unref (file);
-
-      if (file_info != NULL) {
-	      mime_type = g_file_info_get_content_type (file_info);
-	      g_object_unref (file_info);
-      }
-
-      if (mime_type)
-        {
-        pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumb_factory,
-								     uri,
-								     mime_type);
-	}
-
-      gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
-					 GTK_RESPONSE_ACCEPT,
-					 (pixbuf != NULL));
-
-      if (pixbuf != NULL)
+      item = cc_background_chooser_dialog_get_item (CC_BACKGROUND_CHOOSER_DIALOG (dialog));
+      if (item != NULL)
         {
-          gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
-	  g_object_unref (pixbuf);
-	}
-      else
-        {
-          gtk_image_set_from_stock (GTK_IMAGE (preview),
-				    GTK_STOCK_DIALOG_QUESTION,
-				    GTK_ICON_SIZE_DIALOG);
-	}
-
-      if (bg_pictures_source_is_known (panel->priv->pictures_source, uri))
-        gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT, FALSE);
-      else
-        gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT, TRUE);
-
-      g_free (uri);
-    }
-
-  gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
-}
-
-static void
-add_button_clicked (GtkButton         *button,
-		    CcBackgroundPanel *panel)
-{
-  GtkWidget *chooser;
-  const gchar *folder;
-  GtkWidget *preview;
-  GtkFileFilter *filter;
-  CcBackgroundPanelPrivate *priv;
-  const char * const * content_types;
-  guint i;
-
-  priv = panel->priv;
-
-  filter = gtk_file_filter_new ();
-  content_types = bg_pictures_get_support_content_types ();
-  for (i = 0; content_types[i] != NULL; i++)
-    gtk_file_filter_add_mime_type (filter, content_types[i]);
-
-  chooser = gtk_file_chooser_dialog_new (_("Browse for more pictures"),
-					 GTK_WINDOW (gtk_widget_get_toplevel (WID ("background-panel"))),
-					 GTK_FILE_CHOOSER_ACTION_OPEN,
-					 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-					 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-					 NULL);
-  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
-  gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser), TRUE);
-
-  gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
-
-  preview = gtk_image_new ();
-  gtk_widget_set_size_request (preview, 128, -1);
-  gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (chooser), preview);
-  gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (chooser), FALSE);
-  gtk_widget_show (preview);
-  g_signal_connect (chooser, "update-preview",
-		    G_CALLBACK (update_chooser_preview), panel);
-
-  folder = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
-  if (folder)
-    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
-					 folder);
-
-  g_signal_connect (chooser, "response",
-		    G_CALLBACK (file_chooser_response), panel);
-
-  gtk_window_present (GTK_WINDOW (chooser));
-}
-
-static void
-remove_button_clicked (GtkButton         *button,
-		       CcBackgroundPanel *panel)
-{
-  CcBackgroundItem *item;
-  GtkListStore *store;
-  GtkTreePath *path;
-  CcBackgroundPanelPrivate *priv;
-
-  priv = panel->priv;
-
-  item = get_selected_item (panel);
-  if (item == NULL)
-    g_assert_not_reached ();
-
-  bg_pictures_source_remove (panel->priv->pictures_source, item);
-  g_object_unref (item);
-
-  /* Are there any items left in the pictures tree store? */
-  store = bg_source_get_liststore (BG_SOURCE (panel->priv->pictures_source));
-  if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 0)
-    gtk_combo_box_set_active (GTK_COMBO_BOX (WID ("sources-combobox")), SOURCE_WALLPAPERS);
-
-  path = gtk_tree_path_new_from_string ("0");
-  gtk_icon_view_select_path (GTK_ICON_VIEW (WID ("backgrounds-iconview")), path);
-  gtk_tree_path_free (path);
-}
-
-static void
-load_current_bg (CcBackgroundPanel *self)
-{
-  CcBackgroundPanelPrivate *priv;
-  CcBackgroundItem *saved, *configured;
-  gchar *uri, *pcolor, *scolor;
-
-  priv = self->priv;
-
-  /* Load the saved configuration */
-  uri = get_save_path ();
-  saved = cc_background_xml_get_item (uri);
-  g_free (uri);
-
-  /* initalise the current background information from settings */
-  uri = g_settings_get_string (priv->settings, WP_URI_KEY);
-  if (uri && *uri == '\0')
-    {
-      g_free (uri);
-      uri = NULL;
-    }
-  else
-    {
-      GFile *file;
-
-      file = g_file_new_for_commandline_arg (uri);
-      g_object_unref (file);
-    }
-  configured = cc_background_item_new (uri);
-  g_free (uri);
-
-  pcolor = g_settings_get_string (priv->settings, WP_PCOLOR_KEY);
-  scolor = g_settings_get_string (priv->settings, WP_SCOLOR_KEY);
-  g_object_set (G_OBJECT (configured),
-		"name", _("Current background"),
-		"placement", g_settings_get_enum (priv->settings, WP_OPTIONS_KEY),
-		"shading", g_settings_get_enum (priv->settings, WP_SHADING_KEY),
-		"primary-color", pcolor,
-		"secondary-color", scolor,
-		NULL);
-  g_free (pcolor);
-  g_free (scolor);
-
-  if (saved != NULL && cc_background_item_compare (saved, configured))
-    {
-      CcBackgroundItemFlags flags;
-      flags = cc_background_item_get_flags (saved);
-      /* Special case for colours */
-      if (cc_background_item_get_placement (saved) == G_DESKTOP_BACKGROUND_STYLE_NONE)
-        flags &=~ (CC_BACKGROUND_ITEM_HAS_PCOLOR | CC_BACKGROUND_ITEM_HAS_SCOLOR);
-      g_object_set (G_OBJECT (configured),
-		    "name", cc_background_item_get_name (saved),
-		    "flags", flags,
-		    "source-url", cc_background_item_get_source_url (saved),
-		    "source-xml", cc_background_item_get_source_xml (saved),
-		    NULL);
+          set_background (self, item);
+          g_object_unref (item);
+        }
     }
-  if (saved != NULL)
-    g_object_unref (saved);
-
-  priv->current_background = configured;
-  cc_background_item_load (priv->current_background, NULL);
-}
-
-static void
-scrolled_realize_cb (GtkWidget         *scrolled,
-                     CcBackgroundPanel *self)
-{
-  /* FIXME, hack for https://bugzilla.gnome.org/show_bug.cgi?id=645649 */
-  GdkScreen *screen;
-  GdkRectangle rect;
-  int monitor;
 
-  screen = gtk_widget_get_screen (scrolled);
-  monitor = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (scrolled));
-  gdk_screen_get_monitor_geometry (screen, monitor, &rect);
-  if (rect.height <= 768)
-    g_object_set (G_OBJECT (scrolled), "height-request", 280, NULL);
+  gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
 static void
-cc_background_panel_drag_uris (GtkWidget *widget,
-			       GdkDragContext *context, gint x, gint y,
-			       GtkSelectionData *data, guint info, guint time,
-			       CcBackgroundPanel *panel)
+on_background_button_clicked (GtkButton         *button,
+                              CcBackgroundPanel *self)
 {
-  gint i;
-  char *uri;
-  gchar **uris;
-
-  uris = gtk_selection_data_get_uris (data);
-  if (!uris)
-    return;
+  CcBackgroundPanelPrivate *priv = self->priv;
+  GtkWidget *dialog;
 
-  gtk_drag_finish (context, TRUE, FALSE, time);
-
-  for (i = 0; uris[i] != NULL; i++) {
-    uri = uris[i];
-    if (!bg_pictures_source_is_known (panel->priv->pictures_source, uri)) {
-      add_custom_wallpaper (panel, uri);
-    }
-  }
-
-  g_strfreev(uris);
+  dialog = cc_background_chooser_dialog_new ();
+  gtk_window_set_transient_for (GTK_WINDOW (dialog),
+                                GTK_WINDOW (gtk_widget_get_toplevel (WID ("background-panel"))));
+  gtk_widget_show (dialog);
+  g_signal_connect (dialog, "response", G_CALLBACK (on_chooser_dialog_response), self);
 }
 
 static void
 cc_background_panel_init (CcBackgroundPanel *self)
 {
   CcBackgroundPanelPrivate *priv;
-  gchar *objects[] = { "style-liststore",
-      "sources-liststore", "background-panel", "sizegroup", NULL };
+  gchar *objects[] = {"background-panel", NULL };
   GError *err = NULL;
   GtkWidget *widget;
-  GtkListStore *store;
-  GtkStyleContext *context;
 
   priv = self->priv = BACKGROUND_PANEL_PRIVATE (self);
 
   priv->builder = gtk_builder_new ();
+  priv->connection = g_application_get_dbus_connection (g_application_get_default ());
 
   gtk_builder_add_objects_from_file (priv->builder,
-                                     DATADIR"/background.ui",
+                                     UIDIR"/background.ui",
                                      objects, &err);
 
   if (err)
@@ -1205,119 +712,34 @@ cc_background_panel_init (CcBackgroundPanel *self)
       return;
     }
 
-  /* See shell_notify_cb for details */
-  g_signal_connect (WID ("scrolledwindow1"), "realize",
-                    G_CALLBACK (scrolled_realize_cb), self);
-
   priv->settings = g_settings_new (WP_PATH_ID);
   g_settings_delay (priv->settings);
 
-  store = (GtkListStore*) gtk_builder_get_object (priv->builder,
-                                                  "sources-liststore");
-
-  priv->wallpapers_source = bg_wallpapers_source_new ();
-  gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
-                                     COL_SOURCE_NAME, _("Wallpapers"),
-                                     COL_SOURCE_TYPE, SOURCE_WALLPAPERS,
-                                     COL_SOURCE, priv->wallpapers_source,
-                                     -1);
-
-  priv->pictures_source = bg_pictures_source_new ();
-  gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
-                                     COL_SOURCE_NAME, _("Pictures Folder"),
-                                     COL_SOURCE_TYPE, SOURCE_PICTURES,
-                                     COL_SOURCE, priv->pictures_source,
-                                     -1);
-
-  priv->colors_source = bg_colors_source_new ();
-  gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
-                                     COL_SOURCE_NAME, _("Colors & Gradients"),
-                                     COL_SOURCE_TYPE, SOURCE_COLORS,
-                                     COL_SOURCE, priv->colors_source,
-                                     -1);
-
-#ifdef HAVE_LIBSOCIALWEB
-  priv->flickr_source = bg_flickr_source_new ();
-  gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
-                                     COL_SOURCE_NAME, _("Flickr"),
-                                     COL_SOURCE_TYPE, SOURCE_FLICKR,
-                                     COL_SOURCE, priv->flickr_source,
-                                     -1);
-#endif
-
-
   /* add the top level widget */
   widget = WID ("background-panel");
 
   gtk_container_add (GTK_CONTAINER (self), widget);
   gtk_widget_show_all (GTK_WIDGET (self));
 
-  /* connect to source change signal */
-  widget = WID ("sources-combobox");
-  g_signal_connect (widget, "changed", G_CALLBACK (source_changed_cb), priv);
-
-  /* select first item */
-  gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
-
-  /* connect to the background iconview change signal */
-  widget = WID ("backgrounds-iconview");
-  g_signal_connect (widget, "selection-changed",
-                    G_CALLBACK (backgrounds_changed_cb),
-                    self);
-
-  /* Join treeview and buttons */
-  widget = WID ("scrolledwindow1");
-  context = gtk_widget_get_style_context (widget);
-  gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
-  widget = WID ("toolbar1");
-  context = gtk_widget_get_style_context (widget);
-  gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
-
-  g_signal_connect (WID ("add_button"), "clicked",
-		    G_CALLBACK (add_button_clicked), self);
-  g_signal_connect (WID ("remove_button"), "clicked",
-		    G_CALLBACK (remove_button_clicked), self);
-
-  /* Add drag and drop support for bg images */
-  widget = WID ("scrolledwindow1");
-  gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
-  gtk_drag_dest_add_uri_targets (widget);
-  g_signal_connect (widget, "drag-data-received",
-		    G_CALLBACK (cc_background_panel_drag_uris), self);
-
-
   /* setup preview area */
-  gtk_label_set_ellipsize (GTK_LABEL (WID ("background-label")), PANGO_ELLIPSIZE_END);
-  widget = WID ("preview-area");
-  g_signal_connect (widget, "draw", G_CALLBACK (preview_draw_cb),
+  widget = WID ("background-desktop-drawingarea");
+  g_signal_connect (widget, "draw", G_CALLBACK (on_preview_draw),
                     self);
 
-  priv->display_base = gdk_pixbuf_new_from_file (DATADIR "/display-base.png",
-                                                 NULL);
+  priv->copy_cancellable = g_cancellable_new ();
+
   priv->display_overlay = gdk_pixbuf_new_from_file (DATADIR
                                                     "/display-overlay.png",
                                                     NULL);
 
-  g_signal_connect (WID ("style-combobox"), "changed",
-                    G_CALLBACK (style_changed_cb), self);
-
-  g_signal_connect (WID ("style-pcolor"), "color-set",
-                    G_CALLBACK (color_changed_cb), self);
-  g_signal_connect (WID ("style-scolor"), "color-set",
-                    G_CALLBACK (color_changed_cb), self);
-  g_signal_connect (WID ("swap-color-button"), "clicked",
-                    G_CALLBACK (swap_colors_clicked), self);
-
-  priv->copy_cancellable = g_cancellable_new ();
-
-  priv->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
+  priv->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE);
 
   load_current_bg (self);
 
   update_preview (priv, NULL);
 
-  /* Setup the edit box with our current settings */
-  source_update_edit_box (priv, TRUE);
+  widget = WID ("background-set-button");
+  g_signal_connect (widget, "clicked", G_CALLBACK (on_background_button_clicked), self);
 }
 
 void
diff --git a/panels/background/display-overlay.png b/panels/background/display-overlay.png
index 74113ac..f5cf785 100644
Binary files a/panels/background/display-overlay.png and b/panels/background/display-overlay.png differ



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