Re: [Nautilus-list] Using drag and drop to copy files in Nautilus?
- From: Benjamin Kahn <xkahn zoned net>
- To: Jonathan Blandford <jrb redhat com>
- Cc: nautilus-list lists eazel com
- Subject: Re: [Nautilus-list] Using drag and drop to copy files in Nautilus?
- Date: 30 Jul 2001 02:01:10 -0400
Attached is a patch to Nautilus which adds the Drag and Drop
functionality I wanted. I based it on the stuff you did. I gave it
minimal testing. (It compiles, it installs, it copied a file when I did
the drag.) Let me know if you find anything wrong with it.
On 25 Jul 2001 11:15:43 -0400, Jonathan Blandford wrote:
> Benjamin Kahn <xkahn ximian com> writes:
>
> > I'm writing a small panel applet which allows you to browse your home
> > directory as a panel menu.
> >
> > <plug> it's in gnome cvs in module file_menu_applet if you want to check
> > it out.</plug>
> >
> > Anyway, I've been hooking up drag and drop and it's working okay. Except
> > in Nautilus. I'm trying to make Nautilus copy or move the file, but it
> > isn't working. I'm using text/uri-list as my mime type and Nautilus treats
> > that as a URL link. Reading through the nautilus drag and drop source
> > code, it looks like that's all it will ever do with that mime type. (I
> > tested it with the panel and with gmc just to be sure.)
> >
> > So does this mean that I have to use Nautilus's internal mime
> > type: x-special/gnome-icon-list to perform a move and copy? Is there any
> > other way to do it? What risks should I look out for if I use a type is
> > seems obviously internal?
>
> Surprisingly enough, I just ran into this bug yesterday, and tried to
> fix it a bit (in the redhat-outstanding-patches branch). It seems like
> the handling of text/uri-list is sort of poor. I'd like this to be
> improved at some point -- maybe I'll have time today. If you want to
> look at it, I can tell you where the code is handled.
>
> Thanks,
> -Jonathan
Index: libnautilus-private/nautilus-icon-container.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.c,v
retrieving revision 1.216
diff -u -r1.216 nautilus-icon-container.c
--- libnautilus-private/nautilus-icon-container.c 2001/07/19 21:35:13 1.216
+++ libnautilus-private/nautilus-icon-container.c 2001/07/30 05:52:43
@@ -3224,9 +3224,10 @@
object_class->type,
GTK_SIGNAL_OFFSET (NautilusIconContainerClass,
handle_uri_list),
- gtk_marshal_NONE__POINTER_INT_INT,
- GTK_TYPE_NONE, 3,
+ eel_gtk_marshal_NONE__POINTER_INT_INT_INT,
+ GTK_TYPE_NONE, 4,
GTK_TYPE_POINTER,
+ GTK_TYPE_INT,
GTK_TYPE_INT,
GTK_TYPE_INT);
Index: libnautilus-private/nautilus-icon-dnd.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-dnd.c,v
retrieving revision 1.91
diff -u -r1.91 nautilus-icon-dnd.c
--- libnautilus-private/nautilus-icon-dnd.c 2001/07/20 17:36:33 1.91
+++ libnautilus-private/nautilus-icon-dnd.c 2001/07/30 05:52:43
@@ -84,6 +84,7 @@
int y);
static void receive_dropped_uri_list (NautilusIconContainer *container,
char* keyword,
+ GdkDragAction action,
int x,
int y);
static void nautilus_icon_container_free_drag_data (NautilusIconContainer *container);
@@ -461,7 +462,7 @@
case EEL_ICON_DND_URL:
receive_dropped_uri_list
(NAUTILUS_ICON_CONTAINER (widget),
- (char*) data->data, x, y);
+ (char*) data->data, context->action, x, y);
gtk_drag_finish (context, TRUE, FALSE, time);
break;
@@ -660,7 +661,7 @@
/* handle dropped uri list */
static void
-receive_dropped_uri_list (NautilusIconContainer *container, char *uri_list, int x, int y)
+receive_dropped_uri_list (NautilusIconContainer *container, char *uri_list, GdkDragAction action, int x, int y)
{
if (uri_list == NULL) {
return;
@@ -668,6 +669,7 @@
gtk_signal_emit_by_name (GTK_OBJECT (container), "handle_uri_list",
uri_list,
+ action,
x, y);
}
Index: src/file-manager/fm-desktop-icon-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-desktop-icon-view.c,v
retrieving revision 1.139
diff -u -r1.139 fm-desktop-icon-view.c
--- src/file-manager/fm-desktop-icon-view.c 2001/07/23 10:42:36 1.139
+++ src/file-manager/fm-desktop-icon-view.c 2001/07/30 05:52:43
@@ -114,6 +114,7 @@
FMDesktopIconView *icon_view);
static void icon_view_handle_uri_list (NautilusIconContainer *container,
const char *item_uris,
+ GdkDragAction action,
int x,
int y,
FMDirectoryView *view);
@@ -865,7 +866,7 @@
static void
icon_view_handle_uri_list (NautilusIconContainer *container, const char *item_uris,
- int x, int y, FMDirectoryView *view)
+ GdkDragAction action, int x, int y, FMDirectoryView *view)
{
GList *uri_list, *node;
GnomeDesktopEntry *entry;
Index: src/file-manager/fm-icon-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-icon-view.c,v
retrieving revision 1.208
diff -u -r1.208 fm-icon-view.c
--- src/file-manager/fm-icon-view.c 2001/07/15 09:00:44 1.208
+++ src/file-manager/fm-icon-view.c 2001/07/30 05:52:43
@@ -34,6 +34,7 @@
#include <eel/eel-gtk-extensions.h>
#include <eel/eel-gtk-macros.h>
#include <eel/eel-string.h>
+#include <eel/eel-vfs-extensions.h>
#include <errno.h>
#include <fcntl.h>
#include <gtk/gtkmain.h>
@@ -45,10 +46,12 @@
#include <libgnome/gnome-i18n.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-metadata.h>
+#include <libgnome/gnome-mime.h>
#include <libgnomevfs/gnome-vfs-async-ops.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-xfer.h>
+#include <libgnomevfs/gnome-vfs-mime.h>
#include <libnautilus-private/nautilus-audio-player.h>
#include <libnautilus-private/nautilus-bonobo-extensions.h>
#include <libnautilus-private/nautilus-directory-background.h>
@@ -115,49 +118,56 @@
} MenuItemType;
/* forward declarations */
-static void create_icon_container (FMIconView *icon_view);
-static void fm_icon_view_initialize (FMIconView *icon_view);
-static void fm_icon_view_initialize_class (FMIconViewClass *klass);
-static gboolean fm_icon_view_is_empty (FMDirectoryView *view);
-static void fm_icon_view_set_directory_sort_by (FMIconView *icon_view,
- NautilusFile *file,
- const char *sort_by);
-static void fm_icon_view_set_zoom_level (FMIconView *view,
- NautilusZoomLevel new_level,
- gboolean always_set_level);
-gboolean fm_icon_view_supports_auto_layout (FMIconView *view);
-static void fm_icon_view_update_icon_container_fonts (FMIconView *icon_view);
-static void fm_icon_view_update_icon_container_smooth_font (FMIconView *icon_view);
-static void fm_icon_view_update_icon_container_font_size_table (FMIconView *icon_view);
-static void fm_icon_view_update_click_mode (FMIconView *icon_view);
-static void fm_icon_view_update_smooth_graphics_mode (FMIconView *icon_view);
-static gboolean fm_icon_view_using_tighter_layout (FMIconView *icon_view);
-static gboolean fm_icon_view_get_directory_tighter_layout (FMIconView *icon_view,
- NautilusFile *file);
-static void fm_icon_view_set_directory_tighter_layout (FMIconView *icon_view,
- NautilusFile *file,
- gboolean tighter_layout);
-static gboolean real_supports_auto_layout (FMIconView *view);
-static const SortCriterion *get_sort_criterion_by_id (const char *id);
-static const SortCriterion *get_sort_criterion_by_sort_type (NautilusFileSortType sort_type);
-static void set_sort_criterion_by_id (FMIconView *icon_view,
- const char *id);
-static gboolean set_sort_reversed (FMIconView *icon_view,
- gboolean new_value);
-static void switch_to_manual_layout (FMIconView *view);
-static void preview_audio (FMIconView *icon_view,
- NautilusFile *file,
- gboolean start_flag);
-static void update_layout_menus (FMIconView *view);
-static void default_sort_in_reverse_order_changed_callback (gpointer callback_data);
-static void default_sort_order_changed_callback (gpointer callback_data);
-static void default_use_tighter_layout_changed_callback (gpointer callback_data);
-static void default_use_manual_layout_changed_callback (gpointer callback_data);
-static void default_zoom_level_changed_callback (gpointer callback_data);
-static void default_zoom_level_font_size_changed_callback (gpointer callback_data);
-static void font_changed_callback (gpointer callback_data);
-static void smooth_font_changed_callback (gpointer callback_data);
+static void create_icon_container (FMIconView *icon_view);
+static void fm_icon_view_initialize (FMIconView *icon_view);
+static void fm_icon_view_initialize_class (FMIconViewClass *klass);
+static gboolean fm_icon_view_is_empty (FMDirectoryView *view);
+static void fm_icon_view_set_directory_sort_by (FMIconView *icon_view,
+ NautilusFile *file,
+ const char *sort_by);
+static void fm_icon_view_set_zoom_level (FMIconView *view,
+ NautilusZoomLevel new_level,
+ gboolean always_set_level);
+gboolean fm_icon_view_supports_auto_layout (FMIconView *view);
+static void fm_icon_view_update_icon_container_fonts (FMIconView *icon_view);
+static void fm_icon_view_update_icon_container_smooth_font (FMIconView *icon_view);
+static void fm_icon_view_update_icon_container_font_size_table (FMIconView *icon_view);
+static void fm_icon_view_update_click_mode (FMIconView *icon_view);
+static void fm_icon_view_update_smooth_graphics_mode (FMIconView *icon_view);
+static gboolean fm_icon_view_using_tighter_layout (FMIconView *icon_view);
+static gboolean fm_icon_view_get_directory_tighter_layout (FMIconView *icon_view,
+ NautilusFile *file);
+static void fm_icon_view_set_directory_tighter_layout (FMIconView *icon_view,
+ NautilusFile *file,
+ gboolean tighter_layout);
+static gboolean real_supports_auto_layout (FMIconView *view);
+static const SortCriterion *get_sort_criterion_by_id (const char *id);
+static const SortCriterion *get_sort_criterion_by_sort_type (NautilusFileSortType sort_type);
+static void set_sort_criterion_by_id (FMIconView *icon_view,
+ const char *id);
+static gboolean set_sort_reversed (FMIconView *icon_view,
+ gboolean new_value);
+static void switch_to_manual_layout (FMIconView *view);
+static void preview_audio (FMIconView *icon_view,
+ NautilusFile *file,
+ gboolean start_flag);
+static void update_layout_menus (FMIconView *view);
+static void default_sort_in_reverse_order_changed_callback (gpointer callback_data);
+static void default_sort_order_changed_callback (gpointer callback_data);
+static void default_use_tighter_layout_changed_callback (gpointer callback_data);
+static void default_use_manual_layout_changed_callback (gpointer callback_data);
+static void default_zoom_level_changed_callback (gpointer callback_data);
+static void default_zoom_level_font_size_changed_callback (gpointer callback_data);
+static void font_changed_callback (gpointer callback_data);
+static void smooth_font_changed_callback (gpointer callback_data);
+static void icon_view_handle_uri_list (NautilusIconContainer *container,
+ const char *item_uris,
+ GdkDragAction action,
+ int x,
+ int y,
+ FMIconView *view);
+
static int preview_sound_auto_value;
EEL_DEFINE_CLASS_BOILERPLATE (FMIconView,
@@ -2001,7 +2011,7 @@
char **additional_text,
FMIconView *icon_view)
{
- char *actual_uri, *path;
+ char *actual_uri;
char *attribute_names;
char **text_array;
int i , slot_index;
@@ -2025,15 +2035,13 @@
if (nautilus_file_is_nautilus_link (file)) {
/* FIXME bugzilla.eazel.com 2531: Does sync. I/O and works only locally. */
actual_uri = nautilus_file_get_uri (file);
- path = gnome_vfs_get_local_path_from_uri (actual_uri);
- g_free (actual_uri);
- if (path != NULL) {
- *additional_text = nautilus_link_local_get_additional_text (path);
- g_free (path);
- return;
- }
+ *additional_text = NULL;
+ /* This looks pretty bad. It would be nice to get the additional text to only appear if
+ * you zoom in a lot */
+ /* *additional_text = nautilus_link_local_get_additional_text (actual_uri); */
+ return;
}
-
+
/* Find out what attributes go below each icon. */
attribute_names = fm_icon_view_get_icon_text_attribute_names (icon_view);
text_array = g_strsplit (attribute_names, "|", 0);
@@ -2318,6 +2326,8 @@
static void
fm_icon_view_initialize (FMIconView *icon_view)
{
+ NautilusIconContainer *icon_container;
+
g_return_if_fail (GTK_BIN (icon_view)->child == NULL);
icon_view->details = g_new0 (FMIconViewDetails, 1);
@@ -2326,6 +2336,7 @@
icon_view->details->timeout = -1;
icon_view->details->audio_preview_file = NULL;
create_icon_container (icon_view);
+ icon_container = get_icon_container (icon_view);
eel_preferences_add_callback_while_alive (NAUTILUS_PREFERENCES_ICON_VIEW_FONT,
font_changed_callback,
@@ -2359,6 +2370,12 @@
default_zoom_level_changed_callback,
icon_view,
GTK_OBJECT (icon_view));
+
+ gtk_signal_connect (GTK_OBJECT (icon_container),
+ "handle_uri_list",
+ GTK_SIGNAL_FUNC (icon_view_handle_uri_list),
+ icon_view);
+
}
static gboolean
@@ -2647,4 +2664,135 @@
fm_icon_view_update_smooth_graphics_mode (icon_view);
gtk_widget_show (GTK_WIDGET (icon_container));
+}
+
+static void
+icon_view_handle_uri_list (NautilusIconContainer *container, const char *item_uris,
+ GdkDragAction action, int x, int y, FMIconView *view)
+{
+
+ GList *uri_list, *node, *real_uri_list = NULL;
+ GnomeDesktopEntry *entry;
+ GdkPoint point;
+ char *uri, *local_path;
+ char *stripped_uri;
+ const char *last_slash, *link_name;
+ char *container_uri;
+ char *container_path;
+
+ if (item_uris == NULL) {
+ return;
+ }
+
+ container_uri = fm_directory_view_get_uri (FM_DIRECTORY_VIEW (view));
+ container_path = gnome_vfs_get_local_path_from_uri (container_uri);
+
+ /* If the container_path is bad at this point,
+ * we need to pop up an annoying warning.
+ * FIXME: What we should do
+ * is not accept drags on this icon view. To fix this, look in:
+ * nautilus-icon-dnd.c:1218 the call to be blocked
+ * nautilus-icon-container.c:3363 the call to that function
+ */
+
+ if (container_path == NULL) {
+
+ eel_show_warning_dialog (_("This view does not accept this type of Drag."),
+ _("Drag and Drop error"),
+ fm_directory_view_get_containing_window (view));
+
+ g_free (container_path);
+ g_free (container_uri);
+
+ return;
+ }
+
+ if (action == GDK_ACTION_ASK) {
+ action = eel_drag_drop_action_ask
+ (GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
+ }
+
+ /* We don't support GDK_ACTION_ASK or GDK_ACTION_PRIVATE
+ * and we don't support combinations either. */
+ if ((action != GDK_ACTION_DEFAULT) &&
+ (action != GDK_ACTION_COPY) &&
+ (action != GDK_ACTION_MOVE) &&
+ (action != GDK_ACTION_LINK)) {
+ eel_show_warning_dialog (_("Unknown Drag Action."),
+ _("Drag and Drop error"),
+ fm_directory_view_get_containing_window (view));
+ g_free (container_path);
+ g_free (container_uri);
+
+ return;
+ }
+
+ point.x = x;
+ point.y = y;
+
+ uri_list = gnome_uri_list_extract_uris (item_uris);
+
+ /* Most of what comes in here is not really URIs, but
+ * rather paths that have a file: prefix in them.
+ */
+ for (node = uri_list; node != NULL; node = node->next) {
+ real_uri_list = g_list_append (real_uri_list,
+ eel_make_uri_from_half_baked_uri (node->data));
+ }
+
+ switch (action) {
+ case GDK_ACTION_DEFAULT: /* We'll say that the default is copy. */
+ case GDK_ACTION_COPY:
+ case GDK_ACTION_MOVE:
+ fm_directory_view_move_copy_items (real_uri_list, NULL, fm_directory_view_get_uri (view),
+ action, 0, 0, view);
+ break;
+ case GDK_ACTION_LINK:
+ for (node = real_uri_list; node != NULL; node = node->next) {
+
+ /* Make a link using the desktop file contents? */
+ local_path = gnome_vfs_get_local_path_from_uri (uri);
+ if (local_path != NULL) {
+ entry = gnome_desktop_entry_load (local_path);
+ if (entry != NULL) {
+
+ /* FIXME: Handle name conflicts? */
+ nautilus_link_local_create_from_gnome_entry (entry, container_path, &point);
+ gnome_desktop_entry_free (entry);
+ }
+ g_free (local_path);
+ if (entry != NULL) {
+ continue;
+ }
+ }
+
+ /* Make a link from the URI alone. Generate the file
+ * name by extracting the basename of the URI.
+ */
+ /* FIXME: This should be using eel_uri_get_basename
+ * instead of a "roll our own" solution.
+ */
+ stripped_uri = eel_str_strip_trailing_chr (uri, '/');
+ last_slash = strrchr (stripped_uri, '/');
+ link_name = last_slash == NULL ? NULL : last_slash + 1;
+
+ if (!eel_str_is_empty (link_name)) {
+ /* FIXME: Handle name conflicts? */
+ nautilus_link_local_create (container_path, link_name,
+ "gnome-http-url", uri,
+ &point, NAUTILUS_LINK_GENERIC);
+ }
+
+ g_free (stripped_uri);
+
+ break;
+ }
+
+ }
+
+ gnome_uri_list_free_strings (real_uri_list);
+
+ g_free (container_path);
+ g_free (container_uri);
+ gnome_uri_list_free_strings (uri_list);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]