[gnome-control-center] background: Re-add drag'n'drop support



commit ccf7dc70d40538f81b087d7b674d18f7049aeba3
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Apr 14 16:06:27 2014 +0200

    background: Re-add drag'n'drop support
    
    Inside the chooser dialogue itself.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=689351

 panels/background/bg-pictures-source.c           |   40 ++++++----
 panels/background/bg-pictures-source.h           |    5 +-
 panels/background/cc-background-chooser-dialog.c |   96 ++++++++++++++++++++++
 3 files changed, 124 insertions(+), 17 deletions(-)
---
diff --git a/panels/background/bg-pictures-source.c b/panels/background/bg-pictures-source.c
index 3d0607f..6748227 100644
--- a/panels/background/bg-pictures-source.c
+++ b/panels/background/bg-pictures-source.c
@@ -327,10 +327,11 @@ in_screenshot_types (const char *content_type)
 }
 
 static gboolean
-add_single_file (BgPicturesSource *bg_source,
-                GFile            *file,
-                 const gchar      *content_type,
-                 guint64           mtime)
+add_single_file (BgPicturesSource     *bg_source,
+                 GFile                *file,
+                 const gchar          *content_type,
+                 guint64               mtime,
+                 GtkTreeRowReference **ret_row_ref)
 {
   CcBackgroundItem *item = NULL;
   CcBackgroundItemFlags flags = 0;
@@ -341,7 +342,7 @@ add_single_file (BgPicturesSource *bg_source,
   GtkListStore *store;
   GtkTreeIter iter;
   GtkTreePath *path = NULL;
-  GtkTreeRowReference *row_ref;
+  GtkTreeRowReference *row_ref = NULL;
   cairo_surface_t *surface = NULL;
   char *source_uri = NULL;
   char *uri = NULL;
@@ -479,6 +480,13 @@ add_single_file (BgPicturesSource *bg_source,
   retval = TRUE;
 
  out:
+  if (ret_row_ref)
+    {
+      if (row_ref && retval != FALSE)
+        *ret_row_ref = gtk_tree_row_reference_copy (row_ref);
+      else
+        *ret_row_ref = NULL;
+    }
   gtk_tree_path_free (path);
   g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy);
   g_clear_object (&pixbuf);
@@ -491,16 +499,17 @@ add_single_file (BgPicturesSource *bg_source,
 }
 
 static gboolean
-add_single_file_from_info (BgPicturesSource *bg_source,
-                           GFile            *file,
-                           GFileInfo        *info)
+add_single_file_from_info (BgPicturesSource     *bg_source,
+                           GFile                *file,
+                           GFileInfo            *info,
+                           GtkTreeRowReference **ret_row_ref)
 {
   const gchar *content_type;
   guint64 mtime;
 
   content_type = g_file_info_get_content_type (info);
   mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
-  return add_single_file (bg_source, file, content_type, mtime);
+  return add_single_file (bg_source, file, content_type, mtime, ret_row_ref);
 }
 
 static gboolean
@@ -520,12 +529,13 @@ add_single_file_from_media (BgPicturesSource *bg_source,
   mtime = grl_media_get_creation_date (media);
   mtime_unix = g_date_time_to_unix (mtime);
 
-  return add_single_file (bg_source, file, content_type, (guint64) mtime_unix);
+  return add_single_file (bg_source, file, content_type, (guint64) mtime_unix, NULL);
 }
 
 gboolean
-bg_pictures_source_add (BgPicturesSource *bg_source,
-                       const char       *uri)
+bg_pictures_source_add (BgPicturesSource     *bg_source,
+                        const char           *uri,
+                        GtkTreeRowReference **ret_row_ref)
 {
   GFile *file;
   GFileInfo *info;
@@ -536,7 +546,7 @@ bg_pictures_source_add (BgPicturesSource *bg_source,
   if (info == NULL)
     return FALSE;
 
-  retval = add_single_file_from_info (bg_source, file, info);
+  retval = add_single_file_from_info (bg_source, file, info, ret_row_ref);
 
   return retval;
 }
@@ -631,7 +641,7 @@ file_info_async_ready (GObject      *source,
 
       file = g_file_get_child (parent, g_file_info_get_name (info));
 
-      add_single_file_from_info (bg_source, file, info);
+      add_single_file_from_info (bg_source, file, info, NULL);
     }
 
   g_list_foreach (files, (GFunc) g_object_unref, NULL);
@@ -780,7 +790,7 @@ file_info_ready (GObject      *object,
    * reduces the ref count.
    */
   g_object_ref (file);
-  add_single_file_from_info (BG_PICTURES_SOURCE (user_data), file, info);
+  add_single_file_from_info (BG_PICTURES_SOURCE (user_data), file, info, NULL);
 }
 
 static void
diff --git a/panels/background/bg-pictures-source.h b/panels/background/bg-pictures-source.h
index eab0050..e1174d7 100644
--- a/panels/background/bg-pictures-source.h
+++ b/panels/background/bg-pictures-source.h
@@ -72,8 +72,9 @@ GType bg_pictures_source_get_type (void) G_GNUC_CONST;
 BgPicturesSource *bg_pictures_source_new            (GtkWindow *window);
 char             *bg_pictures_source_get_cache_path (void);
 char             *bg_pictures_source_get_unique_path(const char *uri);
-gboolean          bg_pictures_source_add            (BgPicturesSource *bg_source,
-                                                    const char       *uri);
+gboolean          bg_pictures_source_add            (BgPicturesSource     *bg_source,
+                                                    const char           *uri,
+                                                    GtkTreeRowReference **ret_row_ref);
 gboolean          bg_pictures_source_remove         (BgPicturesSource *bg_source,
                                                     const char       *uri);
 gboolean          bg_pictures_source_is_known       (BgPicturesSource *bg_source,
diff --git a/panels/background/cc-background-chooser-dialog.c 
b/panels/background/cc-background-chooser-dialog.c
index ea39899..3cb9cf9 100644
--- a/panels/background/cc-background-chooser-dialog.c
+++ b/panels/background/cc-background-chooser-dialog.c
@@ -50,11 +50,14 @@ struct _CcBackgroundChooserDialogPrivate
   GtkWidget *icon_view;
   GtkWidget *empty_pictures_box;
   GtkWidget *sw_content;
+  GtkWidget *pictures_button;
 
   BgWallpapersSource *wallpapers_source;
   BgPicturesSource *pictures_source;
   BgColorsSource *colors_source;
 
+  GtkTreeRowReference *item_to_focus;
+
   GnomeDesktopThumbnailFactory *thumb_factory;
 
   GCancellable *copy_cancellable;
@@ -63,6 +66,7 @@ struct _CcBackgroundChooserDialogPrivate
 
   gulong row_inserted_id;
   gulong row_deleted_id;
+  gulong row_modified_id;
 };
 
 #define CC_CHOOSER_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), 
CC_TYPE_BACKGROUND_CHOOSER_DIALOG, CcBackgroundChooserDialogPrivate))
@@ -118,6 +122,7 @@ cc_background_chooser_dialog_dispose (GObject *object)
       g_clear_object (&priv->copy_cancellable);
     }
 
+  g_clear_pointer (&chooser->priv->item_to_focus, gtk_tree_row_reference_free);
   g_clear_object (&priv->pictures_source);
   g_clear_object (&priv->colors_source);
   g_clear_object (&priv->wallpapers_source);
@@ -151,6 +156,38 @@ possibly_show_empty_pictures_box (GtkTreeModel              *model,
 }
 
 static void
+on_source_modified_cb (GtkTreeModel *tree_model,
+                       GtkTreePath  *path,
+                       GtkTreeIter  *iter,
+                       gpointer      user_data)
+{
+  GtkTreePath *to_focus_path;
+  CcBackgroundChooserDialog *chooser = user_data;
+  CcBackgroundChooserDialogPrivate *priv = chooser->priv;
+
+  if (chooser->priv->item_to_focus == NULL)
+    return;
+
+  to_focus_path = gtk_tree_row_reference_get_path (chooser->priv->item_to_focus);
+
+  if (gtk_tree_path_compare (to_focus_path, path) != 0)
+    goto out;
+
+  /* Change source */
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->pictures_button), TRUE);
+
+  /* And select the newly added item */
+  gtk_icon_view_select_path (GTK_ICON_VIEW (chooser->priv->icon_view), to_focus_path);
+  gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (chooser->priv->icon_view),
+                                to_focus_path, TRUE, 1.0, 1.0);
+  g_clear_pointer (&chooser->priv->item_to_focus, gtk_tree_row_reference_free);
+
+out:
+  gtk_tree_path_free (to_focus_path);
+
+}
+
+static void
 on_source_added_cb (GtkTreeModel *model,
                     GtkTreePath  *path,
                     GtkTreeIter  *iter,
@@ -185,6 +222,10 @@ monitor_pictures_model (CcBackgroundChooserDialog *chooser)
                                                     G_CALLBACK (on_source_removed_cb),
                                                     chooser);
 
+  chooser->priv->row_modified_id = g_signal_connect (model, "row-changed",
+                                                     G_CALLBACK (on_source_modified_cb),
+                                                     chooser);
+
   possibly_show_empty_pictures_box (model, chooser);
 }
 
@@ -207,6 +248,12 @@ cancel_monitor_pictures_model (CcBackgroundChooserDialog *chooser)
       chooser->priv->row_deleted_id = 0;
     }
 
+  if (chooser->priv->row_modified_id > 0)
+    {
+      g_signal_handler_disconnect (model, chooser->priv->row_modified_id);
+      chooser->priv->row_modified_id = 0;
+    }
+
   ensure_iconview_shown (chooser);
 }
 
@@ -256,6 +303,48 @@ on_item_activated (GtkIconView               *icon_view,
 }
 
 static void
+add_custom_wallpaper (CcBackgroundChooserDialog *chooser,
+                      const char                *uri)
+{
+  g_clear_pointer (&chooser->priv->item_to_focus, gtk_tree_row_reference_free);
+
+  monitor_pictures_model (chooser);
+  bg_pictures_source_add (chooser->priv->pictures_source, uri, &chooser->priv->item_to_focus);
+  /* and wait for the item to get added */
+}
+
+static void
+cc_background_panel_drag_uris (GtkWidget *widget,
+                               GdkDragContext *context, gint x, gint y,
+                               GtkSelectionData *data, guint info, guint time,
+                               CcBackgroundChooserDialog *chooser)
+{
+  gint i;
+  char *uri;
+  gchar **uris;
+  gboolean ret = FALSE;
+
+  uris = gtk_selection_data_get_uris (data);
+  if (!uris)
+    goto out;
+
+  for (i = 0; uris[i] != NULL; i++)
+    {
+      uri = uris[i];
+      if (!bg_pictures_source_is_known (chooser->priv->pictures_source, uri))
+        {
+          add_custom_wallpaper (chooser, uri);
+          ret = TRUE;
+        }
+    }
+
+  g_strfreev (uris);
+
+out:
+  gtk_drag_finish (context, ret, FALSE, time);
+}
+
+static void
 cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
 {
   CcBackgroundChooserDialogPrivate *priv;
@@ -323,6 +412,7 @@ cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
   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);
+  priv->pictures_button = button;
 
   button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button1), _("Colors"));
   context = gtk_widget_get_style_context (button);
@@ -341,6 +431,12 @@ cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
   gtk_widget_set_vexpand (priv->sw_content, TRUE);
   gtk_container_add (GTK_CONTAINER (grid), priv->sw_content);
 
+  /* Add drag and drop support for bg images */
+  gtk_drag_dest_set (priv->sw_content, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
+  gtk_drag_dest_add_uri_targets (priv->sw_content);
+  g_signal_connect (priv->sw_content, "drag-data-received",
+                    G_CALLBACK (cc_background_panel_drag_uris), chooser);
+
   priv->empty_pictures_box = gtk_grid_new ();
   gtk_widget_set_no_show_all (priv->empty_pictures_box, TRUE);
   gtk_grid_set_column_spacing (GTK_GRID (priv->empty_pictures_box), 12);


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