Commit db2c5a92 authored by Alexander Larsson's avatar Alexander Larsson Committed by Alexander Larsson
Browse files

Implement duplicate.

2007-12-05  Alexander Larsson  <alexl@redhat.com>

        * libnautilus-private/nautilus-file-operations.[ch]:
	Implement duplicate.


svn path=/trunk/; revision=13496
parent 1885aa39
2007-12-05 Alexander Larsson <alexl@redhat.com>
* libnautilus-private/nautilus-file-operations.[ch]:
Implement duplicate.
2007-12-05 Alexander Larsson <alexl@redhat.com> 2007-12-05 Alexander Larsson <alexl@redhat.com>
* src/file-manager/fm-directory-view.c: * src/file-manager/fm-directory-view.c:
......
...@@ -78,7 +78,7 @@ static gboolean confirm_trash_auto_value; ...@@ -78,7 +78,7 @@ static gboolean confirm_trash_auto_value;
/* TODO: /* TODO:
* Implement missing functions: * Implement missing functions:
* duplicate, link, new file, new folder, set_permissions recursive * link, new file, new folder, set_permissions recursive
* TESTING!!! * TESTING!!!
*/ */
...@@ -306,6 +306,9 @@ get_link_name (char *name, int count) ...@@ -306,6 +306,9 @@ get_link_name (char *name, int count)
return result; return result;
} }
#endif /* GIO_CONVERSION_DONE */
/* Localizers: /* Localizers:
* Feel free to leave out the st, nd, rd and th suffix or * Feel free to leave out the st, nd, rd and th suffix or
* make some or all of them match. * make some or all of them match.
...@@ -584,45 +587,6 @@ get_duplicate_name (const char *name, int count_increment) ...@@ -584,45 +587,6 @@ get_duplicate_name (const char *name, int count_increment)
return result; return result;
} }
static char *
get_next_duplicate_name (char *name, int count_increment)
{
char *unescaped_name;
char *unescaped_tmp_name;
char *unescaped_result;
char *result;
char *new_file;
unescaped_tmp_name = gnome_vfs_unescape_string (name, "/");
g_free (name);
unescaped_name = g_filename_to_utf8 (unescaped_tmp_name, -1,
NULL, NULL, NULL);
if (!unescaped_name) {
/* Couldn't convert to utf8 - probably
* G_BROKEN_FILENAMES not set when it should be.
* Try converting from the locale */
unescaped_name = g_locale_to_utf8 (unescaped_tmp_name, -1, NULL, NULL, NULL);
if (!unescaped_name) {
unescaped_name = eel_make_valid_utf8 (unescaped_tmp_name);
}
}
g_free (unescaped_tmp_name);
unescaped_result = get_duplicate_name (unescaped_name, count_increment);
g_free (unescaped_name);
new_file = g_filename_from_utf8 (unescaped_result, -1, NULL, NULL, NULL);
result = gnome_vfs_escape_path_string (new_file);
g_free (unescaped_result);
g_free (new_file);
return result;
}
#endif /* GIO_CONVERSION_DONE */
static char * static char *
custom_full_name_to_string (char *format, va_list va) custom_full_name_to_string (char *format, va_list va)
{ {
...@@ -2241,14 +2205,21 @@ report_copy_progress (CopyMoveJob *copy_job, ...@@ -2241,14 +2205,21 @@ report_copy_progress (CopyMoveJob *copy_job,
} }
if (source_info->num_files == 1) { if (source_info->num_files == 1) {
if (copy_job->destination != NULL) {
nautilus_progress_info_take_status (job->progress, nautilus_progress_info_take_status (job->progress,
f (is_move ? f (is_move ?
_("Moving \"%B\" to \"%B\""): _("Moving \"%B\" to \"%B\""):
_("Copying \"%B\" to \"%B\""), _("Copying \"%B\" to \"%B\""),
(GFile *)copy_job->files->data, (GFile *)copy_job->files->data,
copy_job->destination)); copy_job->destination));
} else {
nautilus_progress_info_take_status (job->progress,
f (_("Duplicating \"%B\""),
(GFile *)copy_job->files->data));
}
} else if (copy_job->files != NULL && } else if (copy_job->files != NULL &&
copy_job->files->next == NULL) { copy_job->files->next == NULL) {
if (copy_job->destination != NULL) {
nautilus_progress_info_take_status (job->progress, nautilus_progress_info_take_status (job->progress,
f (is_move? f (is_move?
ngettext ("Moving %d file (in \"%B\") to \"%B\"", ngettext ("Moving %d file (in \"%B\") to \"%B\"",
...@@ -2262,6 +2233,15 @@ report_copy_progress (CopyMoveJob *copy_job, ...@@ -2262,6 +2233,15 @@ report_copy_progress (CopyMoveJob *copy_job,
(GFile *)copy_job->files->data, (GFile *)copy_job->files->data,
copy_job->destination)); copy_job->destination));
} else { } else {
nautilus_progress_info_take_status (job->progress,
f (ngettext ("Duplicating %d file (in \"%B\")",
"Duplicating %d files (in \"%B\")",
files_left),
files_left,
(GFile *)copy_job->files->data));
}
} else {
if (copy_job->destination != NULL) {
nautilus_progress_info_take_status (job->progress, nautilus_progress_info_take_status (job->progress,
f (is_move? f (is_move?
ngettext ("Moving %d file to \"%B\"", ngettext ("Moving %d file to \"%B\"",
...@@ -2272,6 +2252,13 @@ report_copy_progress (CopyMoveJob *copy_job, ...@@ -2272,6 +2252,13 @@ report_copy_progress (CopyMoveJob *copy_job,
"Copying %d files to \"%B\"", "Copying %d files to \"%B\"",
files_left), files_left),
files_left, copy_job->destination)); files_left, copy_job->destination));
} else {
nautilus_progress_info_take_status (job->progress,
f (ngettext ("Duplicating %d file",
"Duplicating %d files",
files_left),
files_left));
}
} }
total_size = MAX (source_info->num_bytes, transfer_info->num_bytes); total_size = MAX (source_info->num_bytes, transfer_info->num_bytes);
...@@ -2305,6 +2292,58 @@ report_copy_progress (CopyMoveJob *copy_job, ...@@ -2305,6 +2292,58 @@ report_copy_progress (CopyMoveJob *copy_job,
nautilus_progress_info_set_progress (job->progress, (double)transfer_info->num_bytes / total_size); nautilus_progress_info_set_progress (job->progress, (double)transfer_info->num_bytes / total_size);
} }
static GFile *
get_unique_target_file (GFile *src,
GFile *dest_dir,
gboolean same_fs,
int count)
{
const char *editname, *end;
char *basename, *new_name;
GFileInfo *info;
GFile *dest;
dest = NULL;
info = g_file_query_info (src,
G_FILE_ATTRIBUTE_STD_EDIT_NAME,
0, NULL, NULL);
if (info != NULL) {
editname = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STD_EDIT_NAME);
if (editname != NULL) {
new_name = get_duplicate_name (editname, count);
dest = g_file_get_child_for_display_name (dest_dir, new_name, NULL);
g_free (new_name);
}
g_object_unref (info);
}
if (dest == NULL) {
basename = g_file_get_basename (src);
if (g_utf8_validate (basename, -1, NULL)) {
new_name = get_duplicate_name (basename, count);
dest = g_file_get_child_for_display_name (dest_dir, new_name, NULL);
g_free (new_name);
}
if (dest == NULL) {
end = strrchr (basename, '.');
if (end != NULL) {
count += atoi (end + 1);
}
new_name = g_strdup_printf ("%s.%d", basename, count);
dest = g_file_get_child (dest_dir, new_name);
g_free (new_name);
}
g_free (basename);
}
return dest;
}
static GFile * static GFile *
get_target_file (GFile *src, get_target_file (GFile *src,
GFile *dest_dir, GFile *dest_dir,
...@@ -2390,6 +2429,7 @@ static void copy_move_file (CopyMoveJob *job, ...@@ -2390,6 +2429,7 @@ static void copy_move_file (CopyMoveJob *job,
GFile *src, GFile *src,
GFile *dest_dir, GFile *dest_dir,
gboolean same_fs, gboolean same_fs,
gboolean unique_names,
SourceInfo *source_info, SourceInfo *source_info,
TransferInfo *transfer_info, TransferInfo *transfer_info,
GHashTable *debuting_files, GHashTable *debuting_files,
...@@ -2502,7 +2542,7 @@ copy_move_directory (CopyMoveJob *copy_job, ...@@ -2502,7 +2542,7 @@ copy_move_directory (CopyMoveJob *copy_job,
(info = g_file_enumerator_next_file (enumerator, job->cancellable, skip_error?NULL:&error)) != NULL) { (info = g_file_enumerator_next_file (enumerator, job->cancellable, skip_error?NULL:&error)) != NULL) {
src_file = g_file_get_child (src, src_file = g_file_get_child (src,
g_file_info_get_name (info)); g_file_info_get_name (info));
copy_move_file (copy_job, src_file, dest, same_fs, source_info, transfer_info, NULL, NULL, FALSE, &local_skipped_file); copy_move_file (copy_job, src_file, dest, same_fs, FALSE, source_info, transfer_info, NULL, NULL, FALSE, &local_skipped_file);
g_object_unref (src_file); g_object_unref (src_file);
g_object_unref (info); g_object_unref (info);
} }
...@@ -2790,6 +2830,7 @@ copy_move_file (CopyMoveJob *copy_job, ...@@ -2790,6 +2830,7 @@ copy_move_file (CopyMoveJob *copy_job,
GFile *src, GFile *src,
GFile *dest_dir, GFile *dest_dir,
gboolean same_fs, gboolean same_fs,
gboolean unique_names,
SourceInfo *source_info, SourceInfo *source_info,
TransferInfo *transfer_info, TransferInfo *transfer_info,
GHashTable *debuting_files, GHashTable *debuting_files,
...@@ -2806,6 +2847,7 @@ copy_move_file (CopyMoveJob *copy_job, ...@@ -2806,6 +2847,7 @@ copy_move_file (CopyMoveJob *copy_job,
gboolean would_recurse; gboolean would_recurse;
CommonJob *job; CommonJob *job;
gboolean res; gboolean res;
int unique_name_nr;
job = (CommonJob *)copy_job; job = (CommonJob *)copy_job;
...@@ -2814,7 +2856,13 @@ copy_move_file (CopyMoveJob *copy_job, ...@@ -2814,7 +2856,13 @@ copy_move_file (CopyMoveJob *copy_job,
return; return;
} }
unique_name_nr = 1;
if (unique_names) {
dest = get_unique_target_file (src, dest_dir, same_fs, unique_name_nr++);
} else {
dest = get_target_file (src, dest_dir, same_fs); dest = get_target_file (src, dest_dir, same_fs);
}
retry: retry:
...@@ -2868,6 +2916,13 @@ copy_move_file (CopyMoveJob *copy_job, ...@@ -2868,6 +2916,13 @@ copy_move_file (CopyMoveJob *copy_job,
IS_IO_ERROR (error, EXISTS)) { IS_IO_ERROR (error, EXISTS)) {
gboolean is_merge; gboolean is_merge;
if (unique_names) {
g_object_unref (dest);
dest = get_unique_target_file (src, dest_dir, same_fs, unique_name_nr++);
g_error_free (error);
goto retry;
}
is_merge = FALSE; is_merge = FALSE;
if (is_dir (dest)) { if (is_dir (dest)) {
if (is_dir (src)) { if (is_dir (src)) {
...@@ -3070,11 +3125,14 @@ copy_files (CopyMoveJob *job, ...@@ -3070,11 +3125,14 @@ copy_files (CopyMoveJob *job,
int i; int i;
GdkPoint *point; GdkPoint *point;
gboolean skipped_file; gboolean skipped_file;
gboolean unique_names;
GFile *dest;
common = &job->common; common = &job->common;
report_copy_progress (job, source_info, transfer_info); report_copy_progress (job, source_info, transfer_info);
unique_names = (job->destination == NULL);
i = 0; i = 0;
for (l = job->files; for (l = job->files;
l != NULL && !job_aborted (common); l != NULL && !job_aborted (common);
...@@ -3093,12 +3151,21 @@ copy_files (CopyMoveJob *job, ...@@ -3093,12 +3151,21 @@ copy_files (CopyMoveJob *job,
same_fs = has_fs_id (src, dest_fs_id); same_fs = has_fs_id (src, dest_fs_id);
} }
if (job->destination) {
dest = g_object_ref (job->destination);
} else {
dest = g_file_get_parent (src);
}
if (dest) {
skipped_file = FALSE; skipped_file = FALSE;
copy_move_file (job, src, job->destination, copy_move_file (job, src, dest,
same_fs, same_fs, unique_names,
source_info, transfer_info, source_info, transfer_info,
job->debuting_files, job->debuting_files,
point, FALSE, &skipped_file); point, FALSE, &skipped_file);
g_object_unref (dest);
}
i++; i++;
} }
} }
...@@ -3114,7 +3181,9 @@ copy_job_done (gpointer user_data) ...@@ -3114,7 +3181,9 @@ copy_job_done (gpointer user_data)
} }
eel_g_object_list_free (job->files); eel_g_object_list_free (job->files);
if (job->destination) {
g_object_unref (job->destination); g_object_unref (job->destination);
}
g_hash_table_unref (job->debuting_files); g_hash_table_unref (job->debuting_files);
g_free (job->icon_positions); g_free (job->icon_positions);
...@@ -3133,6 +3202,7 @@ copy_job (GIOJob *io_job, ...@@ -3133,6 +3202,7 @@ copy_job (GIOJob *io_job,
SourceInfo source_info; SourceInfo source_info;
TransferInfo transfer_info; TransferInfo transfer_info;
char *dest_fs_id; char *dest_fs_id;
GFile *dest;
job = user_data; job = user_data;
common = &job->common; common = &job->common;
...@@ -3150,10 +3220,20 @@ copy_job (GIOJob *io_job, ...@@ -3150,10 +3220,20 @@ copy_job (GIOJob *io_job,
goto aborted; goto aborted;
} }
if (job->destination) {
dest = g_object_ref (job->destination);
} else {
/* Duplication, no dest,
* use source for free size, etc
*/
dest = g_file_get_parent (job->files->data);
}
verify_destination (&job->common, verify_destination (&job->common,
job->destination, dest,
&dest_fs_id, &dest_fs_id,
source_info.num_bytes); source_info.num_bytes);
g_object_unref (dest);
if (job_aborted (common)) { if (job_aborted (common)) {
goto aborted; goto aborted;
} }
...@@ -3507,7 +3587,7 @@ move_files (CopyMoveJob *job, ...@@ -3507,7 +3587,7 @@ move_files (CopyMoveJob *job,
selected overwrite on all toplevel items */ selected overwrite on all toplevel items */
skipped_file = FALSE; skipped_file = FALSE;
copy_move_file (job, src, job->destination, copy_move_file (job, src, job->destination,
same_fs, same_fs, FALSE,
source_info, transfer_info, source_info, transfer_info,
job->debuting_files, job->debuting_files,
point, TRUE, &skipped_file); point, TRUE, &skipped_file);
...@@ -3652,7 +3732,35 @@ nautilus_file_operations_move (GList *files, ...@@ -3652,7 +3732,35 @@ nautilus_file_operations_move (GList *files,
job->common.cancellable); job->common.cancellable);
} }
void
nautilus_file_operations_duplicate (GList *files,
GArray *relative_item_points,
GtkWindow *parent_window,
NautilusCopyCallback done_callback,
gpointer done_callback_data)
{
CopyMoveJob *job;
job = op_job_new (CopyMoveJob, parent_window);
job->done_callback = done_callback;
job->done_callback_data = done_callback_data;
job->files = eel_g_object_list_copy (files);
job->destination = NULL;
if (relative_item_points != NULL &&
relative_item_points->len > 0) {
job->icon_positions =
g_memdup (relative_item_points->data,
sizeof (GdkPoint) * relative_item_points->len);
job->n_icon_positions = relative_item_points->len;
}
job->debuting_files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, NULL);
g_schedule_io_job (copy_job,
job,
NULL, /* destroy notify */
0,
job->common.cancellable);
}
static void static void
not_supported_yet (void) not_supported_yet (void)
...@@ -3704,7 +3812,10 @@ nautilus_file_operations_copy_move (const GList *item_uris, ...@@ -3704,7 +3812,10 @@ nautilus_file_operations_copy_move (const GList *item_uris,
GFile *dest; GFile *dest;
GtkWindow *parent_window; GtkWindow *parent_window;
dest = NULL;
if (target_dir) {
dest = g_file_new_for_uri (target_dir); dest = g_file_new_for_uri (target_dir);
}
locations = location_list_from_uri_list (item_uris); locations = location_list_from_uri_list (item_uris);
parent_window = NULL; parent_window = NULL;
...@@ -3713,14 +3824,20 @@ nautilus_file_operations_copy_move (const GList *item_uris, ...@@ -3713,14 +3824,20 @@ nautilus_file_operations_copy_move (const GList *item_uris,
} }
if (copy_action == GDK_ACTION_COPY) { if (copy_action == GDK_ACTION_COPY) {
if (target_dir == NULL) {
nautilus_file_operations_duplicate (locations,
relative_item_points,
parent_window,
done_callback, done_callback_data);
} else {
nautilus_file_operations_copy (locations, nautilus_file_operations_copy (locations,
relative_item_points, relative_item_points,
dest, dest,
parent_window, parent_window,
done_callback, done_callback_data); done_callback, done_callback_data);
}
} else if (copy_action == GDK_ACTION_MOVE) { } else if (copy_action == GDK_ACTION_MOVE) {
if (g_file_has_uri_scheme (dest, "trash")) { if (g_file_has_uri_scheme (dest, "trash")) {
nautilus_file_operations_trash_or_delete (locations, nautilus_file_operations_trash_or_delete (locations,
parent_window, parent_window,
...@@ -3738,7 +3855,9 @@ nautilus_file_operations_copy_move (const GList *item_uris, ...@@ -3738,7 +3855,9 @@ nautilus_file_operations_copy_move (const GList *item_uris,
} }
eel_g_object_list_free (locations); eel_g_object_list_free (locations);
if (dest) {
g_object_unref (dest); g_object_unref (dest);
}
} }
void void
...@@ -3863,7 +3982,6 @@ nautilus_self_check_file_operations (void) ...@@ -3863,7 +3982,6 @@ nautilus_self_check_file_operations (void)
{ {
setlocale (LC_MESSAGES, "C"); setlocale (LC_MESSAGES, "C");
#ifdef GIO_CONVERSION_DONE
/* test the next duplicate name generator */ /* test the next duplicate name generator */
EEL_CHECK_STRING_RESULT (get_duplicate_name (" (copy)", 1), " (another copy)"); EEL_CHECK_STRING_RESULT (get_duplicate_name (" (copy)", 1), " (another copy)");
...@@ -3908,8 +4026,6 @@ nautilus_self_check_file_operations (void) ...@@ -3908,8 +4026,6 @@ nautilus_self_check_file_operations (void)
EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy)", 1), "foo (124th copy)"); EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy)", 1), "foo (124th copy)");
EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy).txt", 1), "foo (124th copy).txt"); EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy).txt", 1), "foo (124th copy).txt");
#endif /* GIO_CONVERSION_DONE */
setlocale (LC_MESSAGES, ""); setlocale (LC_MESSAGES, "");
} }
......
...@@ -109,4 +109,11 @@ void nautilus_file_operations_move (GList *files, ...@@ -109,4 +109,11 @@ void nautilus_file_operations_move (GList *files,
NautilusCopyCallback done_callback, NautilusCopyCallback done_callback,
gpointer done_callback_data); gpointer done_callback_data);
void nautilus_file_operations_duplicate (GList *files,
GArray *relative_item_points,
GtkWindow *parent_window,
NautilusCopyCallback done_callback,
gpointer done_callback_data);
#endif /* NAUTILUS_FILE_OPERATIONS_H */ #endif /* NAUTILUS_FILE_OPERATIONS_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment