[Xfce4-commits] <xfdesktop:jannis/port-to-gio> Implement the rest of the DND code without ThunarVFS.

Jannis Pohlmann noreply at xfce.org
Sat Oct 30 00:10:02 CEST 2010


Updating branch refs/heads/jannis/port-to-gio
         to 6df396394d5a1b8cbac415413f677f95176fb2ab (commit)
       from bf7307e1fb3a6c730bd6f8c0a97b7908fa8cbc6c (commit)

commit 6df396394d5a1b8cbac415413f677f95176fb2ab
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Sat Oct 30 00:08:07 2010 +0200

    Implement the rest of the DND code without ThunarVFS.

 src/xfdesktop-file-icon-manager.c |  193 +++++++++++--------------------------
 src/xfdesktop-file-utils.c        |  132 +++++++++++++++++++++++---
 src/xfdesktop-file-utils.h        |    6 +
 3 files changed, 183 insertions(+), 148 deletions(-)

diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c
index c59bf03..52b18b0 100644
--- a/src/xfdesktop-file-icon-manager.c
+++ b/src/xfdesktop-file-icon-manager.c
@@ -1022,19 +1022,6 @@ xfdesktop_file_icon_menu_create_folder(GtkWidget *widget,
                                      GTK_WINDOW(toplevel));
 }
 
-static ThunarVfsInteractiveJobResponse
-xfdesktop_file_icon_interactive_job_ask(ThunarVfsJob *job,
-                                        const gchar *message,
-                                        ThunarVfsInteractiveJobResponse choices,
-                                        gpointer user_data)
-{
-    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
-    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
-    
-    return xfdesktop_file_utils_interactive_job_ask(GTK_WINDOW(toplevel),
-                                                    message, choices);
-}
-
 static void
 xfdesktop_file_icon_template_item_activated(GtkWidget *mi,
                                             gpointer user_data)
@@ -2796,20 +2783,6 @@ xfdesktop_file_icon_manager_drag_drop(XfdesktopIconViewManager *manager,
     return TRUE;
 }
 
-#if 0   /* FIXME: implement me */
-static void
-xfdesktop_file_icon_manager_fileop_error(ThunarVfsJob *job,
-                                         GError *error,
-                                         gpointer user_data)
-{
-    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
-    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
-    XfdesktopFileUtilsFileop fileop = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(job),
-                                                                        "--xfdesktop-fileop"));
-    
-    xfdesktop_file_utils_handle_fileop_error(GTK_WINDOW(toplevel), /* ... */);
-#endif
-
 static void
 xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager,
                                                XfdesktopIcon *drop_icon,
@@ -2821,14 +2794,11 @@ xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager
                                                guint time_)
 {
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
-#if 1
     XfdesktopFileIcon *file_icon = NULL;
-    const ThunarVfsInfo *tinfo = NULL;
-#endif
+    GFileInfo *tinfo = NULL;
+    GFile *tfile = NULL;
     gboolean copy_only = TRUE, drop_ok = FALSE;
-#if 1
-    GList *path_list;
-#endif
+    GList *file_list;
     
     if(info == TARGET_XDND_DIRECT_SAVE0) {
         /* we don't suppose XdndDirectSave stage 3, result F, i.e., the app
@@ -2895,131 +2865,84 @@ xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager
         
         g_free(exo_desktop_item_edit);
     } else if(info == TARGET_TEXT_URI_LIST) {
-#if 1
         if(drop_icon) {
             file_icon = XFDESKTOP_FILE_ICON(drop_icon);
-            tinfo = xfdesktop_file_icon_peek_info(file_icon);
+            tfile = xfdesktop_file_icon_peek_file(file_icon);
+            tinfo = xfdesktop_file_icon_peek_file_info(file_icon);
         }
         
         copy_only = (context->action != GDK_ACTION_MOVE);
         
-        path_list = thunar_vfs_path_list_from_string((gchar *)data->data, NULL);
-    
-        if(path_list) {
-            if(tinfo && tinfo->flags & THUNAR_VFS_FILE_FLAGS_EXECUTABLE) {
-                gboolean succeeded;
-                GError *error = NULL;
+        if(tfile && g_file_has_uri_scheme(tfile, "trash") && copy_only) {
+            gtk_drag_finish(context, FALSE, FALSE, time_);
+            return;
+        }
+        
+        file_list = xfdesktop_file_utils_file_list_from_string((const gchar *)data->data);
+        if(file_list) {
+            if(tinfo && xfdesktop_file_utils_file_is_executable(tinfo)) {
+                xfdesktop_file_utils_execute(fmanager->priv->folder,
+                                             tfile, file_list,
+                                             fmanager->priv->gscreen);
                 
-                succeeded = thunar_vfs_info_execute(tinfo,
-                                                    fmanager->priv->gscreen,
-                                                    path_list,
-                                                    xfce_get_homedir(),
-                                                    &error);
-                if(!succeeded) {
-                    gchar *primary = g_markup_printf_escaped(_("Failed to run \"%s\":"),
-                                                             tinfo->display_name);
-                    xfce_message_dialog(NULL, _("Run Error"),
-                                        GTK_STOCK_DIALOG_ERROR,
-                                        primary, error->message,
-                                        GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
-                                        NULL);
-                    g_free(primary);
-                    g_error_free(error);
-                } else
-                    drop_ok = TRUE;
+                /* TODO check the result of the D-Bus method and the above function
+                 * call, and only set drop_ok on success */
+                drop_ok = TRUE;
+            } else if(tfile && g_file_has_uri_scheme(tfile, "trash")) {
+                GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
+
+                /* move files to the trash */
+                xfdesktop_file_utils_trash_files(file_list,
+                                                 fmanager->priv->gscreen,
+                                                 GTK_WINDOW(toplevel));
             } else {
-                ThunarVfsJob *job = NULL;
-                GList *dest_path_list = NULL, *l;
-                const gchar *name;
-                ThunarVfsPath *base_dest_path, *dest_path;
-                /* FIXME: icky special-case hacks */
+                GFile *base_dest_file = NULL;
+                GList *l, *dest_file_list = NULL;
                 gboolean dest_is_volume = (drop_icon
                                            && XFDESKTOP_IS_VOLUME_ICON(drop_icon));
-                gboolean dest_is_special = (drop_icon
-                                            && XFDESKTOP_IS_SPECIAL_FILE_ICON(drop_icon));
-                gboolean dest_is_trash = (dest_is_special
-                                          && XFDESKTOP_SPECIAL_FILE_ICON_TRASH
-                                             == xfdesktop_special_file_icon_get_icon_type(XFDESKTOP_SPECIAL_FILE_ICON(drop_icon)));
                 
                 /* if it's a volume, but we don't have |tinfo|, this just isn't
                  * going to work */
                 if(!tinfo && dest_is_volume) {
-                    thunar_vfs_path_list_free(path_list);
+                    xfdesktop_file_utils_file_list_free(file_list);
                     gtk_drag_finish(context, FALSE, FALSE, time_);
                     return;
                 }
-                
-                if(tinfo && (dest_is_special || dest_is_volume))
-                    base_dest_path = thunar_vfs_path_ref(tinfo->path);
-                else if(tinfo && tinfo->type == THUNAR_VFS_FILE_TYPE_DIRECTORY) {
-                    gchar *pathname = g_file_get_path(fmanager->priv->folder);
-                    ThunarVfsPath *path = thunar_vfs_path_new(pathname, NULL);
-                    base_dest_path = thunar_vfs_path_relative(path,
-                                                              thunar_vfs_path_get_name(tinfo->path));
-                    thunar_vfs_path_unref(path);
-                    g_free(pathname);
+
+                if(tinfo && g_file_info_get_file_type(tinfo) == G_FILE_TYPE_DIRECTORY) {
+                    base_dest_file = g_object_ref(tfile);
                 } else {
-                    gchar *pathname = g_file_get_path(fmanager->priv->folder);
-                    ThunarVfsPath *path = thunar_vfs_path_new(pathname, NULL);
-                    base_dest_path = thunar_vfs_path_ref(path);
-                    thunar_vfs_path_unref(path);
-                    g_free(pathname);
-                }
-                
-                for(l = path_list; l; l = l->next) {
-                    ThunarVfsPath *path = (ThunarVfsPath *)l->data;
-                    
-                    /* only work with file:// URIs here */
-                    if(thunar_vfs_path_get_scheme(path) != THUNAR_VFS_PATH_SCHEME_FILE)
-                        continue;
-                    /* root nodes cause crashes */
-                    if(thunar_vfs_path_is_root(path))
-                        continue;
-                    
-                    name = thunar_vfs_path_get_name(path);
-                    dest_path = thunar_vfs_path_relative(base_dest_path,
-                                                         name);
-                    dest_path_list = g_list_prepend(dest_path_list, dest_path);
+                    base_dest_file = g_object_ref(fmanager->priv->folder);
                 }
-                thunar_vfs_path_unref(base_dest_path);
-                dest_path_list = g_list_reverse(dest_path_list);
-                
-                if(dest_path_list) {
-                    if(context->action == GDK_ACTION_LINK && !dest_is_trash)
-                        job = thunar_vfs_link_files(path_list, dest_path_list, NULL);
-                    else if(copy_only && !dest_is_trash)
-                        job = thunar_vfs_copy_files(path_list, dest_path_list, NULL);
-                    else
-                        job = thunar_vfs_move_files(path_list, dest_path_list, NULL);
-                    
-                    thunar_vfs_path_list_free(dest_path_list);
+
+                for (l = file_list; l; l = l->next) {
+                    gchar *dest_basename = g_file_get_basename(l->data);
+
+                    if(dest_basename && *dest_basename != '\0') {
+                        GFile *dest_file = g_file_get_child(base_dest_file, dest_basename);
+                        dest_file_list = g_list_prepend(dest_file_list, dest_file);
+                    }
+
+                    g_free(dest_basename);
                 }
-                
-                if(job) {
-                    drop_ok = TRUE;
-                    
-#if 0  /* FIXME: implement me: need way to pass multiple files */
-                    g_signal_connect(G_OBJECT(job), "error",
-                                     G_CALLBACK(xfdesktop_file_icon_manager_fileop_error),
-                                     fmanager);
-                    g_object_set_data(G_OBJECT(job), "--xfdesktop-fileop",
-                                      GINT_TO_POINTER(context->suggested_action == GDK_ACTION_LINK
-                                                      ? XFDESKTOP_FILE_UTILS_FILEOP_LINK
-                                                      : (copy_only
-                                                         ? XFDESKTOP_FILE_UTILS_FILEOP_COPY
-                                                         : XFDESKTOP_FILE_UTILS_FILEOP_MOVE)));
-#endif
-                    g_signal_connect(G_OBJECT(job), "ask",
-                                     G_CALLBACK(xfdesktop_file_icon_interactive_job_ask),
-                                     fmanager);
-                    g_signal_connect(G_OBJECT(job), "finished",
-                                     G_CALLBACK(g_object_unref), NULL);
+
+                g_object_unref(base_dest_file);
+
+                if(dest_file_list) {
+                    dest_file_list = g_list_reverse(dest_file_list);
+
+                    xfdesktop_file_utils_transfer_files(context->action, 
+                                                        file_list, dest_file_list,
+                                                        fmanager->priv->gscreen);
                 }
+
+                xfdesktop_file_utils_file_list_free(dest_file_list);
+
+                /* TODO check the result of the D-Bus method and the above
+                 * function call in order to set drop_ok to TRUE or FALSE */
+                drop_ok = TRUE;
             }
-            
-            thunar_vfs_path_list_free(path_list);
         }
-#endif
     }
     
     DBG("finishing drop on desktop from external source: drop_ok=%s, copy_only=%s",
diff --git a/src/xfdesktop-file-utils.c b/src/xfdesktop-file-utils.c
index 444d13b..2f640a5 100644
--- a/src/xfdesktop-file-utils.c
+++ b/src/xfdesktop-file-utils.c
@@ -316,26 +316,59 @@ xfdesktop_file_utils_file_icon_list_to_file_list(GList *icon_list)
     return g_list_reverse(file_list);
 }
 
+GList *
+xfdesktop_file_utils_file_list_from_string(const gchar *string)
+{
+    GList *list = NULL;
+    gchar **uris;
+    gsize n;
+
+    uris = g_uri_list_extract_uris(string);
+
+    for (n = 0; uris != NULL && uris[n] != NULL; ++n)
+      list = g_list_append(list, g_file_new_for_uri(uris[n]));
+
+    g_strfreev (uris);
+
+    return list;
+}
+
 gchar *
 xfdesktop_file_utils_file_list_to_string(GList *list)
 {
-  GString *string;
-  GList *lp;
-  gchar *uri;
+    GString *string;
+    GList *lp;
+    gchar *uri;
 
-  /* allocate initial string */
-  string = g_string_new(NULL);
+    /* allocate initial string */
+    string = g_string_new(NULL);
 
-  for (lp = list; lp != NULL; lp = lp->next)
-    {
-      uri = g_file_get_uri(lp->data);
-      string = g_string_append(string, uri);
-      g_free(uri);
+    for (lp = list; lp != NULL; lp = lp->next) {
+        uri = g_file_get_uri(lp->data);
+        string = g_string_append(string, uri);
+        g_free(uri);
 
-      string = g_string_append(string, "\r\n");
-    }
+        string = g_string_append(string, "\r\n");
+      }
 
-  return g_string_free(string, FALSE);
+    return g_string_free(string, FALSE);
+}
+
+gchar **
+xfdesktop_file_utils_file_list_to_uri_array(GList *file_list)
+{
+    GList *lp;
+    gchar **uris = NULL;
+    guint list_length, n;
+
+    list_length = g_list_length(file_list);
+
+    uris = g_new0(gchar *, list_length + 1);
+    for (n = 0, lp = file_list; lp != NULL; ++n, lp = lp->next)
+        uris[n] = g_file_get_uri(lp->data);
+    uris[n] = NULL;
+
+    return uris;
 }
 
 void
@@ -1211,6 +1244,79 @@ xfdesktop_file_utils_transfer_file(GdkDragAction action,
     }
 }
 
+void
+xfdesktop_file_utils_transfer_files(GdkDragAction action,
+                                    GList *source_files,
+                                    GList *target_files,
+                                    GdkScreen *screen)
+{
+    DBusGProxy *fileman_proxy;
+    
+    g_return_if_fail(source_files != NULL && G_IS_FILE(source_files->data));
+    g_return_if_fail(target_files != NULL && G_IS_FILE(target_files->data));
+    g_return_if_fail(screen == NULL || GDK_IS_SCREEN(screen));
+
+    if(!screen)
+        screen = gdk_display_get_default_screen(gdk_display_get_default());
+    
+    fileman_proxy = xfdesktop_file_utils_peek_filemanager_proxy();
+    if(fileman_proxy) {
+        GError *error = NULL;
+        gchar **source_uris = xfdesktop_file_utils_file_list_to_uri_array(source_files);
+        gchar **target_uris = xfdesktop_file_utils_file_list_to_uri_array(target_files);
+        gchar *display_name = gdk_screen_make_display_name(screen);
+        gchar *startup_id = g_strdup_printf("_TIME%d", gtk_get_current_event_time());
+
+        switch(action) {
+            case GDK_ACTION_MOVE:
+                xfdesktop_file_manager_proxy_move_into(fileman_proxy, NULL,
+                                                       (const gchar **)source_uris, 
+                                                       (const gchar *)target_uris[0],
+                                                       display_name, startup_id,
+                                                       &error);
+                break;
+            case GDK_ACTION_COPY:
+                xfdesktop_file_manager_proxy_copy_to(fileman_proxy, NULL,
+                                                     (const gchar **)source_uris, 
+                                                     (const gchar **)target_uris,
+                                                     display_name, startup_id,
+                                                     &error);
+                break;
+            case GDK_ACTION_LINK:
+                xfdesktop_file_manager_proxy_link_into(fileman_proxy, NULL,
+                                                       (const gchar **)source_uris, 
+                                                       (const gchar *)target_uris[0],
+                                                       display_name, startup_id,
+                                                       &error);
+                break;
+            default:
+                g_warning("Unsupported transfer action");
+        }
+
+        if(error) {
+            xfce_message_dialog(NULL,
+                                _("Transfer Error"), GTK_STOCK_DIALOG_ERROR,
+                                _("The file transfer could not be performed"),
+                                error->message, GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, 
+                                NULL);
+
+            g_error_free(error);
+        }
+        
+        g_free(startup_id);
+        g_free(display_name);
+        g_free(target_uris[0]);
+        g_free(source_uris[0]);
+    } else {
+        xfce_message_dialog(NULL,
+                            _("Transfer Error"), GTK_STOCK_DIALOG_ERROR,
+                            _("The file transfer could not be performed"),
+                            _("This feature requires a file manager service to "
+                              "be present (such as the one supplied by Thunar)."),
+                            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
+    }
+}
+
 static gint dbus_ref_cnt = 0;
 static DBusGConnection *dbus_gconn = NULL;
 static DBusGProxy *dbus_trash_proxy = NULL;
diff --git a/src/xfdesktop-file-utils.h b/src/xfdesktop-file-utils.h
index ba1438b..4bd9e99 100644
--- a/src/xfdesktop-file-utils.h
+++ b/src/xfdesktop-file-utils.h
@@ -63,7 +63,9 @@ gboolean xfdesktop_file_utils_volume_is_present(GVolume *volume);
 gboolean xfdesktop_file_utils_volume_is_removable(GVolume *volume);
 
 GList *xfdesktop_file_utils_file_icon_list_to_file_list(GList *icon_list);
+GList *xfdesktop_file_utils_file_list_from_string(const gchar *string);
 gchar *xfdesktop_file_utils_file_list_to_string(GList *file_list);
+gchar **xfdesktop_file_utils_file_list_to_uri_array(GList *file_list);
 void xfdesktop_file_utils_file_list_free(GList *file_list);
 
 GdkPixbuf *xfdesktop_file_utils_get_fallback_icon(gint size);
@@ -121,6 +123,10 @@ void xfdesktop_file_utils_transfer_file(GdkDragAction action,
                                         GFile *source_file,
                                         GFile *target_file,
                                         GdkScreen *screen);
+void xfdesktop_file_utils_transfer_files(GdkDragAction action,
+                                         GList *source_files,
+                                         GList *target_files,
+                                         GdkScreen *screen);
 
 
 gboolean xfdesktop_file_utils_dbus_init(void);



More information about the Xfce4-commits mailing list