[Xfce4-commits] <thunar:master> Revert "Remove XdndDirectSave0 protocol." (bug #9414).

Nick Schermer noreply at xfce.org
Mon Oct 29 22:18:01 CET 2012


Updating branch refs/heads/master
         to 134d0187afd0c2ebc2d0e47fbde4bda71b25fbb9 (commit)
       from 8b4429b68dbaf51eceae966ac9f6c339b412b5de (commit)

commit 134d0187afd0c2ebc2d0e47fbde4bda71b25fbb9
Author: Nick Schermer <nick at xfce.org>
Date:   Mon Oct 29 22:16:36 2012 +0100

    Revert "Remove XdndDirectSave0 protocol." (bug #9414).
    
    This reverts commit dfd6faa57224a9c3a697e9781aa4bd7525d9832b.
    
    THis breaks file-roller and probably some other stuff.

 thunar/thunar-standard-view.c |  155 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 149 insertions(+), 6 deletions(-)

diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c
index 559f8d5..5734691 100644
--- a/thunar/thunar-standard-view.c
+++ b/thunar/thunar-standard-view.c
@@ -400,6 +400,7 @@ static const GtkTargetEntry drag_targets[] =
 static const GtkTargetEntry drop_targets[] =
 {
   { "text/uri-list", 0, TARGET_TEXT_URI_LIST, },
+  { "XdndDirectSave0", 0, TARGET_XDND_DIRECT_SAVE0, },
   { "_NETSCAPE_URL", 0, TARGET_NETSCAPE_URL, },
 };
 
@@ -2915,7 +2916,12 @@ thunar_standard_view_drag_drop (GtkWidget          *view,
                                 guint               timestamp,
                                 ThunarStandardView *standard_view)
 {
-  GdkAtom target;
+  ThunarFile *file = NULL;
+  GdkAtom     target;
+  guchar     *prop_text;
+  GFile      *path;
+  gchar      *uri = NULL;
+  gint        prop_len;
 
   target = gtk_drag_dest_find_target (view, context, NULL);
   if (G_UNLIKELY (target == GDK_NONE))
@@ -2923,13 +2929,69 @@ thunar_standard_view_drag_drop (GtkWidget          *view,
       /* we cannot handle the drag data */
       return FALSE;
     }
+  else if (G_UNLIKELY (target == gdk_atom_intern_static_string ("XdndDirectSave0")))
+    {
+      /* determine the file for the drop position */
+      file = thunar_standard_view_get_drop_file (standard_view, x, y, NULL);
+      if (G_LIKELY (file != NULL))
+        {
+          /* determine the file name from the DnD source window */
+          if (gdk_property_get (context->source_window, gdk_atom_intern_static_string ("XdndDirectSave0"),
+                                gdk_atom_intern_static_string ("text/plain"), 0, 1024, FALSE, NULL, NULL,
+                                &prop_len, &prop_text) && prop_text != NULL)
+            {
+              /* zero-terminate the string */
+              prop_text = g_realloc (prop_text, prop_len + 1);
+              prop_text[prop_len] = '\0';
+
+              /* verify that the file name provided by the source is valid */
+              if (G_LIKELY (*prop_text != '\0' && strchr ((const gchar *) prop_text, G_DIR_SEPARATOR) == NULL))
+                {
+                  /* allocate the relative path for the target */
+                  path = g_file_resolve_relative_path (thunar_file_get_file (file),
+                                                       (const gchar *)prop_text);
+
+                  /* determine the new URI */
+                  uri = g_file_get_uri (path);
+
+                  /* setup the property */
+                  gdk_property_change (GDK_DRAWABLE (context->source_window),
+                                       gdk_atom_intern_static_string ("XdndDirectSave0"),
+                                       gdk_atom_intern_static_string ("text/plain"), 8,
+                                       GDK_PROP_MODE_REPLACE, (const guchar *) uri,
+                                       strlen (uri));
+
+                  /* cleanup */
+                  g_object_unref (path);
+                  g_free (uri);
+                }
+              else
+                {
+                  /* tell the user that the file name provided by the X Direct Save source is invalid */
+                  thunar_dialogs_show_error (GTK_WIDGET (standard_view), NULL, _("Invalid filename provided by XDS drag site"));
+                }
+
+              /* cleanup */
+              g_free (prop_text);
+            }
+
+          /* release the file reference */
+          g_object_unref (G_OBJECT (file));
+        }
+
+      /* if uri == NULL, we didn't set the property */
+      if (G_UNLIKELY (uri == NULL))
+        return FALSE;
+    }
 
   /* set state so the drag-data-received knows that
    * this is really a drop this time.
    */
   standard_view->priv->drop_occurred = TRUE;
 
-  /* request the drag data from the source */
+  /* request the drag data from the source (initiates
+   * saving in case of XdndDirectSave).
+   */
   gtk_drag_get_data (view, context, target, timestamp);
 
   /* we'll call gtk_drag_finish() later */
@@ -2974,6 +3036,7 @@ thunar_standard_view_drag_data_received (GtkWidget          *view,
 {
   GdkDragAction actions;
   GdkDragAction action;
+  ThunarFolder *folder;
   ThunarFile   *file = NULL;
   GtkWidget    *toplevel;
   gboolean      succeed = FALSE;
@@ -3003,7 +3066,42 @@ thunar_standard_view_drag_data_received (GtkWidget          *view,
       /* reset the state */
       standard_view->priv->drop_occurred = FALSE;
 
-      if (G_UNLIKELY (info == TARGET_NETSCAPE_URL))
+      /* check if we're doing XdndDirectSave */
+      if (G_UNLIKELY (info == TARGET_XDND_DIRECT_SAVE0))
+        {
+          /* we don't handle XdndDirectSave stage (3), result "F" yet */
+          if (G_UNLIKELY (selection_data->format == 8 && selection_data->length == 1 && selection_data->data[0] == 'F'))
+            {
+              /* indicate that we don't provide "F" fallback */
+              gdk_property_change (GDK_DRAWABLE (context->source_window),
+                                   gdk_atom_intern_static_string ("XdndDirectSave0"),
+                                   gdk_atom_intern_static_string ("text/plain"), 8,
+                                   GDK_PROP_MODE_REPLACE, (const guchar *) "", 0);
+            }
+          else if (G_LIKELY (selection_data->format == 8 && selection_data->length == 1 && selection_data->data[0] == 'S'))
+            {
+              /* XDS was successfull, so determine the file for the drop position */
+              file = thunar_standard_view_get_drop_file (standard_view, x, y, NULL);
+              if (G_LIKELY (file != NULL))
+                {
+                  /* verify that we have a directory here */
+                  if (thunar_file_is_directory (file))
+                    {
+                      /* reload the folder corresponding to the file */
+                      folder = thunar_folder_get_for_file (file);
+                      thunar_folder_reload (folder);
+                      g_object_unref (G_OBJECT (folder));
+                    }
+
+                  /* cleanup */
+                  g_object_unref (G_OBJECT (file));
+                }
+            }
+
+          /* in either case, we succeed! */
+          succeed = TRUE;
+        }
+      else if (G_UNLIKELY (info == TARGET_NETSCAPE_URL))
         {
           /* check if the format is valid and we have any data */
           if (G_LIKELY (selection_data->format == 8 && selection_data->length > 0))
@@ -3158,6 +3256,8 @@ thunar_standard_view_drag_motion (GtkWidget          *view,
                                   ThunarStandardView *standard_view)
 {
   GdkDragAction action = 0;
+  GtkTreePath  *path;
+  ThunarFile   *file = NULL;
   GdkAtom       target;
 
   /* request the drop data on-demand (if we don't have it already) */
@@ -3166,9 +3266,52 @@ thunar_standard_view_drag_motion (GtkWidget          *view,
       /* check if we can handle that drag data (yet?) */
       target = gtk_drag_dest_find_target (view, context, NULL);
 
-      /* request the drag data from the source */
-      if (target != GDK_NONE)
-        gtk_drag_get_data (view, context, target, timestamp);
+      if ((target == gdk_atom_intern_static_string ("XdndDirectSave0")) || (target == gdk_atom_intern_static_string ("_NETSCAPE_URL")))
+        {
+          /* determine the file for the given coordinates */
+          file = thunar_standard_view_get_drop_file (standard_view, x, y, &path);
+
+          /* check if we can save here */
+          if (G_LIKELY (file != NULL
+                        && thunar_file_is_local (file)
+                        && thunar_file_is_directory (file)
+                        && thunar_file_is_writable (file)))
+            {
+              action = context->suggested_action;
+            }
+
+          /* reset path if we cannot drop */
+          if (G_UNLIKELY (action == 0 && path != NULL))
+            {
+              gtk_tree_path_free (path);
+              path = NULL;
+            }
+
+          /* do the view highlighting */
+          if (standard_view->priv->drop_highlight != (path == NULL && action != 0))
+            {
+              standard_view->priv->drop_highlight = (path == NULL && action != 0);
+              gtk_widget_queue_draw (GTK_WIDGET (standard_view));
+            }
+
+          /* setup drop-file for the icon renderer to highlight the target */
+          g_object_set (G_OBJECT (standard_view->icon_renderer), "drop-file", (action != 0) ? file : NULL, NULL);
+
+          /* do the item highlighting */
+          (*THUNAR_STANDARD_VIEW_GET_CLASS (standard_view)->highlight_path) (standard_view, path);
+
+          /* cleanup */
+          if (G_LIKELY (file != NULL))
+            g_object_unref (G_OBJECT (file));
+          if (G_LIKELY (path != NULL))
+            gtk_tree_path_free (path);
+        }
+      else
+        {
+          /* request the drag data from the source */
+          if (target != GDK_NONE)
+            gtk_drag_get_data (view, context, target, timestamp);
+        }
 
       /* tell Gdk whether we can drop here */
       gdk_drag_status (context, action, timestamp);


More information about the Xfce4-commits mailing list