[Xfce4-commits] <xfdesktop:master> Implement the rest of the DND code without ThunarVFS.
Jannis Pohlmann
noreply at xfce.org
Tue Nov 2 01:14:48 CET 2010
Updating branch refs/heads/master
to 8fb00c02d5a5225ba1619357173f0abb6c27a21b (commit)
from abf411b4dd475483b4881ffb8888b17c3fe3e5fe (commit)
commit 8fb00c02d5a5225ba1619357173f0abb6c27a21b
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