Index: src/file-manager/fm-directory-view.c =================================================================== --- src/file-manager/fm-directory-view.c (revision 14207) +++ src/file-manager/fm-directory-view.c (revision 14208) @@ -8569,6 +8569,40 @@ target_uri, item_uris, fm_directory_view_get_containing_window (view)); return; + } else if (copy_action == GDK_ACTION_COPY && + nautilus_is_file_roller_installed () && + target_file != NULL && + nautilus_file_is_archive (target_file)) { + char *command, *quoted_uri, *tmp; + const GList *l; + GdkScreen *screen; + + /* Handle dropping onto a file-roller archiver file, instead of starting a move/copy */ + + nautilus_file_unref (target_file); + + quoted_uri = g_shell_quote (target_uri); + command = g_strconcat ("file-roller -a ", quoted_uri, NULL); + g_free (quoted_uri); + + for (l = item_uris; l != NULL; l = l->next) { + quoted_uri = g_shell_quote ((char *) l->data); + + tmp = g_strconcat (command, " ", quoted_uri, NULL); + g_free (command); + command = tmp; + + g_free (quoted_uri); + } + + screen = gtk_widget_get_screen (GTK_WIDGET (view)); + if (screen == NULL) { + screen = gdk_screen_get_default (); + } + gdk_spawn_command_line_on_screen (screen, command, NULL); + g_free (command); + + return; } nautilus_file_unref (target_file); =================================================================== --- libnautilus-private/nautilus-dnd.c (revision 14207) +++ libnautilus-private/nautilus-dnd.c (revision 14208) @@ -368,7 +368,7 @@ const char *dropped_uri; GFile *target, *dropped; GdkDragAction actions; - NautilusFile *target_file; + NautilusFile *dropped_file, *target_file; if (target_uri_string == NULL) { *action = 0; @@ -389,7 +389,8 @@ } dropped_uri = ((NautilusDragSelectionItem *)items->data)->uri; - target_file = nautilus_file_get_existing_by_uri (dropped_uri); + dropped_file = nautilus_file_get_existing_by_uri (dropped_uri); + target_file = nautilus_file_get_existing_by_uri (target_uri_string); /* * Check for trash URI. We do a find_directory for any Trash directory. @@ -402,13 +403,15 @@ *action = GDK_ACTION_MOVE; } + nautilus_file_unref (dropped_file); nautilus_file_unref (target_file); return; - } else if (target_file != NULL && nautilus_file_is_launcher (target_file)) { + } else if (dropped_file != NULL && nautilus_file_is_launcher (dropped_file)) { if (actions & GDK_ACTION_MOVE) { *action = GDK_ACTION_MOVE; } + nautilus_file_unref (dropped_file); nautilus_file_unref (target_file); return; } else if (eel_uri_is_desktop (target_uri_string)) { @@ -419,13 +422,22 @@ *action = GDK_ACTION_MOVE; } + g_free (target); + nautilus_file_unref (dropped_file); nautilus_file_unref (target_file); return; } + } else if (target_file != NULL && nautilus_file_is_archive (target_file)) { + *action = GDK_ACTION_COPY; + + nautilus_file_unref (dropped_file); + nautilus_file_unref (target_file); + return; } else { target = g_file_new_for_uri (target_uri_string); } + nautilus_file_unref (dropped_file); nautilus_file_unref (target_file); /* Compare the first dropped uri with the target uri for same fs match. */ Index: libnautilus-private/nautilus-file-dnd.c =================================================================== --- libnautilus-private/nautilus-file-dnd.c (revision 14207) +++ libnautilus-private/nautilus-file-dnd.c (revision 14208) @@ -29,6 +29,7 @@ #include "nautilus-dnd.h" #include "nautilus-directory.h" +#include "nautilus-file-utilities.h" #include #include @@ -60,6 +61,11 @@ if (nautilus_file_is_nautilus_link (drop_target_item)) { return TRUE; } + + if (nautilus_is_file_roller_installed () && + nautilus_file_is_archive (drop_target_item)) { + return TRUE; + } return FALSE; } Index: libnautilus-private/nautilus-file.c =================================================================== --- libnautilus-private/nautilus-file.c (revision 14207) +++ libnautilus-private/nautilus-file.c (revision 14208) @@ -5936,6 +5936,45 @@ return nautilus_file_get_file_type (file) == G_FILE_TYPE_DIRECTORY; } +gboolean +nautilus_file_is_archive (NautilusFile *file) +{ + char *mime_type; + int i; + static const char * archive_mime_types[] = { "application/x-gtar", + "application/x-zip", + "application/x-zip-compressed", + "application/zip", + "application/x-zip", + "application/x-tar", + "application/x-7z-compressed", + "application/x-rar", + "application/x-rar-compressed", + "application/x-jar", + "application/x-java-archive", + "application/x-war", + "application/x-ear", + "application/x-arj" }; + /* TODO the following MIME types are ignored until file-roller supports to add + * files to them via command line: + * application/x-gzip, application/x-bzip-compressed-tar, application/x-compressed-tar + */ + + g_return_val_if_fail (file != NULL, FALSE); + + mime_type = nautilus_file_get_mime_type (file); + for (i = 0; i < G_N_ELEMENTS (archive_mime_types); i++) { + if (!strcmp (mime_type, archive_mime_types[i])) { + g_free (mime_type); + return TRUE; + } + } + g_free (mime_type); + + return FALSE; +} + + /** * nautilus_file_is_in_trash * Index: libnautilus-private/nautilus-file.h =================================================================== --- libnautilus-private/nautilus-file.h (revision 14207) +++ libnautilus-private/nautilus-file.h (revision 14208) @@ -181,6 +181,7 @@ gboolean nautilus_file_is_nautilus_link (NautilusFile *file); gboolean nautilus_file_is_executable (NautilusFile *file); gboolean nautilus_file_is_directory (NautilusFile *file); +gboolean nautilus_file_is_archive (NautilusFile *file); gboolean nautilus_file_is_in_trash (NautilusFile *file); gboolean nautilus_file_is_in_desktop (NautilusFile *file); gboolean nautilus_file_is_home (NautilusFile *file); Index: libnautilus-private/nautilus-file-utilities.c =================================================================== --- libnautilus-private/nautilus-file-utilities.c (revision 14207) +++ libnautilus-private/nautilus-file-utilities.c (revision 14208) @@ -959,6 +959,22 @@ return NULL; } +gboolean +nautilus_is_file_roller_installed (void) +{ + static int installed = - 1; + + if (installed < 0) { + if (g_find_program_in_path ("file-roller")) { + installed = 1; + } else { + installed = 0; + } + } + + return installed > 0 ? TRUE : FALSE; +} + #if !defined (NAUTILUS_OMIT_SELF_CHECK) void Index: libnautilus-private/nautilus-file-utilities.h =================================================================== --- libnautilus-private/nautilus-file-utilities.h (revision 14207) +++ libnautilus-private/nautilus-file-utilities.h (revision 14208) @@ -79,6 +79,8 @@ /* Locate a file in either the uers directory or the datadir. */ char * nautilus_get_data_file_path (const char *partial_path); +gboolean nautilus_is_file_roller_installed (void); + /* Return an allocated file name that is guranteed to be unique, but * tries to make the name readable to users. * This isn't race-free, so don't use for security-related things