Commit e8d3b459 authored by Pavel Cisler's avatar Pavel Cisler Committed by Pavel Cisler
Browse files

Work in progress on saving drop locations during a copy/move operation.

2000-09-11  Pavel Cisler  <pavel@eazel.com>

	* libnautilus-extensions/nautilus-directory-notify.h:
	* libnautilus-extensions/nautilus-directory.c:
	* libnautilus-extensions/nautilus-file-changes-queue.c:
	* libnautilus-extensions/nautilus-file-changes-queue.h:
	* libnautilus-extensions/nautilus-file-operations.c:
	(icon_position_iterator_new), (icon_position_iterator_free),
	(create_xfer_dialog), (handle_xfer_vfs_error),
	(apply_one_position), (sync_xfer_callback),
	(nautilus_file_operations_copy_move),
	(nautilus_file_changes_queue_schedule_position_setting),
	(position_setting_list_free),
	(nautilus_directory_set_icon_position),
	(nautilus_directory_schedule_metadata_copy),
	(nautilus_directory_schedule_metadata_move),
	(nautilus_file_changes_consume_changes),
	(nautilus_directory_schedule_position_setting):

	Work in progress on saving drop locations during a copy/move operation.
	Add a new NautilusFileChangesQueue element type to handle scheduling
	of the position saving operation. Hook it up to a call that saves the
	icon position into the metadata.
	Add icon position handling to the synchronous copy engine callback.

	* libnautilus-extensions/nautilus-icon-container.h:
	* libnautilus-extensions/nautilus-icon-dnd.c:
	(handle_nonlocal_move):
	Pass relative icon positions (FIXME 626).

	* src/file-manager/fm-directory-view.c:
	(fm_directory_view_move_copy_items):
	* src/file-manager/fm-directory-view.h:
	* src/file-manager/fm-icon-view.c: (icon_view_move_copy_items):
	Add drop location to relative icon positions to get correct icon drop
	placement.

	* libnautilus-extensions/nautilus-file-operations.c:
	(get_link_name), (get_duplicate_name), (handle_xfer_duplicate):
	Rework a bit, fix a leak (FIXME 2556).

	* libnautilus-extensions/nautilus-file-operations.c:
	(nautilus_file_operations_copy_move),
	Fix a leak.

	* libnautilus-extensions/nautilus-file-operations.c:
	(create_xfer_dialog):
	Fix a bug in dialog result handling code.

	* libnautilus-extensions/nautilus-drag.h:
	Some minor tweaks
parent 9b9e79d1
2000-09-11 Pavel Cisler <pavel@eazel.com>
* libnautilus-extensions/nautilus-directory-notify.h:
* libnautilus-extensions/nautilus-directory.c:
* libnautilus-extensions/nautilus-file-changes-queue.c:
* libnautilus-extensions/nautilus-file-changes-queue.h:
* libnautilus-extensions/nautilus-file-operations.c:
(icon_position_iterator_new), (icon_position_iterator_free),
(create_xfer_dialog), (handle_xfer_vfs_error),
(apply_one_position), (sync_xfer_callback),
(nautilus_file_operations_copy_move),
(nautilus_file_changes_queue_schedule_position_setting),
(position_setting_list_free),
(nautilus_directory_set_icon_position),
(nautilus_directory_schedule_metadata_copy),
(nautilus_directory_schedule_metadata_move),
(nautilus_file_changes_consume_changes),
(nautilus_directory_schedule_position_setting):
Work in progress on saving drop locations during a copy/move operation.
Add a new NautilusFileChangesQueue element type to handle scheduling
of the position saving operation. Hook it up to a call that saves the
icon position into the metadata.
Add icon position handling to the synchronous copy engine callback.
* libnautilus-extensions/nautilus-icon-container.h:
* libnautilus-extensions/nautilus-icon-dnd.c:
(handle_nonlocal_move):
Pass relative icon positions (FIXME 626).
* src/file-manager/fm-directory-view.c:
(fm_directory_view_move_copy_items):
* src/file-manager/fm-directory-view.h:
* src/file-manager/fm-icon-view.c: (icon_view_move_copy_items):
Add drop location to relative icon positions to get correct icon drop
placement.
* libnautilus-extensions/nautilus-file-operations.c:
(get_link_name), (get_duplicate_name), (handle_xfer_duplicate):
Rework a bit, fix a leak (FIXME 2556).
* libnautilus-extensions/nautilus-file-operations.c:
(nautilus_file_operations_copy_move),
Fix a leak.
* libnautilus-extensions/nautilus-file-operations.c:
(create_xfer_dialog):
Fix a bug in dialog result handling code.
* libnautilus-extensions/nautilus-drag.h:
Some minor tweaks
2000-09-12 Andy Hertzfeld <andy@eazel.com>
* src/nautilus-zoom-control.c: (draw_number):
......@@ -132,9 +184,6 @@
figure out which sidebar failed. Done in order to fix null
string being passed to dialogue function which segfaulted
Nautilus on Solaris.
Yes children, your Nautilus will now run and frollick in the green,
green pasture of the multi-cpu UltraSparc.
2000-09-11 Robey Pointer <robey@eazel.com>
......
......@@ -23,6 +23,7 @@
*/
#include <glib.h>
#include <gdk/gdk.h>
#include <libnautilus-extensions/nautilus-file.h>
typedef struct {
......@@ -30,13 +31,19 @@ typedef struct {
char *to_uri;
} URIPair;
typedef struct {
char *uri;
GdkPoint point;
} NautilusFileChangesQueuePositionSetting;
/* Almost-public change notification calls */
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
void nautilus_directory_notify_files_removed (GList *uris);
void nautilus_directory_schedule_metadata_copy (GList *uri_pairs);
void nautilus_directory_schedule_metadata_move (GList *uri_pairs);
void nautilus_directory_schedule_metadata_remove (GList *uris);
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
void nautilus_directory_notify_files_removed (GList *uris);
void nautilus_directory_schedule_metadata_copy (GList *uri_pairs);
void nautilus_directory_schedule_metadata_move (GList *uri_pairs);
void nautilus_directory_schedule_metadata_remove (GList *uris);
void nautilus_directory_schedule_position_setting (GList *position_setting_list);
/* Change notification hack.
......@@ -44,6 +51,6 @@ void nautilus_directory_schedule_metadata_remove (GList *uris);
* a notification. Eventually this should become private, but for now
* it needs to be used for code like the thumbnail generation.
*/
void nautilus_file_changed (NautilusFile *file);
void nautilus_file_changed (NautilusFile *file);
void nautilus_file_forget_activation_uri (NautilusFile *file);
void nautilus_file_forget_activation_uri (NautilusFile *file);
......@@ -913,6 +913,25 @@ nautilus_directory_copy_metadata (const char *source_uri, const char *dest_uri)
nautilus_directory_unref (destination_directory);
}
static void
nautilus_directory_set_icon_position (const char *uri, GdkPoint point)
{
NautilusDirectory *destination_directory;
char *destination_file_name;
char *position_string;
destination_directory = get_parent_directory (uri);
destination_file_name = uri_get_basename (uri);
position_string = g_strdup_printf ("%d,%d", point.x, point.y);
nautilus_directory_set_file_metadata (destination_directory,
destination_file_name, NAUTILUS_METADATA_KEY_ICON_POSITION, NULL, position_string);
g_free (position_string);
g_free (destination_file_name);
nautilus_directory_unref (destination_directory);
}
#undef METADATA_COPY_DEBUG
void
nautilus_directory_schedule_metadata_copy (GList *uri_pairs)
......@@ -922,9 +941,6 @@ nautilus_directory_schedule_metadata_copy (GList *uri_pairs)
for (p = uri_pairs; p != NULL; p = p->next) {
pair = (URIPair *)p->data;
#ifdef METADATA_COPY_DEBUG
g_print ("copy metadata from %s to %s\n", pair->from_uri, pair->to_uri);
#endif
nautilus_directory_copy_metadata (pair->from_uri, pair->to_uri);
}
}
......@@ -937,9 +953,6 @@ nautilus_directory_schedule_metadata_move (GList *uri_pairs)
for (p = uri_pairs; p != NULL; p = p->next) {
pair = (URIPair *)p->data;
#ifdef METADATA_COPY_DEBUG
g_print ("move metadata from %s to %s\n", pair->from_uri, pair->to_uri);
#endif
nautilus_directory_move_metadata (pair->from_uri, pair->to_uri);
}
}
......@@ -961,6 +974,19 @@ nautilus_directory_schedule_metadata_remove (GList *uris)
}
}
void
nautilus_directory_schedule_position_setting (GList *position_setting_list)
{
GList *p;
const NautilusFileChangesQueuePositionSetting *item;
for (p = position_setting_list; p != NULL; p = p->next) {
item = (const NautilusFileChangesQueuePositionSetting *)p->data;
nautilus_directory_set_icon_position (item->uri, item->point);
}
}
gboolean
nautilus_directory_contains_file (NautilusDirectory *directory,
NautilusFile *file)
......
......@@ -54,7 +54,7 @@ typedef enum {
NAUTILUS_ICON_DND_KEYWORD
} NautilusIconDndTargetType;
/* DnD-related information. */
/* drag&drop-related information. */
typedef struct {
GtkTargetList *target_list;
......
......@@ -23,10 +23,10 @@
*/
#include <config.h>
#include "nautilus-file-changes-queue.h"
#include "nautilus-glib-extensions.h"
#include "nautilus-directory-notify.h"
#include "nautilus-file-changes-queue.h"
#include "nautilus-glib-extensions.h"
#ifdef G_THREADS_ENABLED
#define MUTEX_LOCK(a) if ((a) != NULL) g_mutex_lock (a)
......@@ -43,13 +43,15 @@ typedef enum {
CHANGE_FILE_MOVED,
CHANGE_METADATA_COPY,
CHANGE_METADATA_MOVE,
CHANGE_METADATA_REMOVE
CHANGE_METADATA_REMOVE,
CHANGE_POSITION_SETTING
} NautilusFileChangeKind;
typedef struct {
NautilusFileChangeKind kind;
char *from_uri;
char *to_uri;
GdkPoint point;
} NautilusFileChange;
typedef struct {
......@@ -224,6 +226,22 @@ nautilus_file_changes_queue_schedule_metadata_remove (const char *uri)
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_schedule_position_setting (const char *uri,
GdkPoint point)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
queue = nautilus_file_changes_queue_get ();
new_item = g_new (NautilusFileChange, 1);
new_item->kind = CHANGE_POSITION_SETTING;
new_item->from_uri = g_strdup (uri);
new_item->point = point;
nautilus_file_changes_queue_add_common (queue, new_item);
}
static NautilusFileChange *
nautilus_file_changes_queue_get_change (NautilusFileChangesQueue *queue)
{
......@@ -273,6 +291,20 @@ pairs_list_free (GList *pairs)
nautilus_g_list_free_deep (pairs);
}
static void
position_setting_list_free (GList *list)
{
GList *p;
NautilusFileChangesQueuePositionSetting *item;
for (p = list; p != NULL; p = p->next) {
item = p->data;
g_free (item->uri);
}
/* delete the list and the now empty structs */
nautilus_g_list_free_deep (list);
}
/* go through changes in the change queue, send ones with the same kind
* in a list to the different nautilus_directory_notify calls
*/
......@@ -282,11 +314,13 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
NautilusFileChange *change;
GList *additions, *deletions, *moves;
GList *metadata_copy_requests, *metadata_move_requests, *metadata_remove_requests;
GList *position_setting_requests;
URIPair *pair;
NautilusFileChangesQueuePositionSetting *position_setting;
int kind;
int chunk_count;
NautilusFileChangesQueue *queue;
additions = NULL;
deletions = NULL;
......@@ -294,6 +328,7 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
metadata_copy_requests = NULL;
metadata_move_requests = NULL;
metadata_remove_requests = NULL;
position_setting_requests = NULL;
kind = CHANGE_FILE_INITIAL;
queue = nautilus_file_changes_queue_get();
......@@ -321,7 +356,8 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
g_assert ((deletions != NULL) + (moves != NULL)
+ (additions != NULL) + (metadata_copy_requests != NULL)
+ (metadata_move_requests != NULL)
+ (metadata_remove_requests != NULL) <= 1);
+ (metadata_remove_requests != NULL)
+ (position_setting_requests != NULL) <= 1);
if (deletions != NULL) {
nautilus_directory_notify_files_removed (deletions);
......@@ -350,9 +386,14 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
}
if (metadata_remove_requests != NULL) {
nautilus_directory_schedule_metadata_remove (metadata_remove_requests);
pairs_list_free (metadata_remove_requests);
nautilus_g_list_free_deep (metadata_remove_requests);
metadata_remove_requests = NULL;
}
if (position_setting_requests != NULL) {
nautilus_directory_schedule_position_setting (position_setting_requests);
position_setting_list_free (position_setting_requests);
position_setting_requests = NULL;
}
}
if (change == NULL) {
......@@ -398,6 +439,14 @@ nautilus_file_changes_consume_changes (gboolean consume_all)
change->from_uri);
break;
case CHANGE_POSITION_SETTING:
position_setting = g_new (NautilusFileChangesQueuePositionSetting, 1);
position_setting->uri = change->from_uri;
position_setting->point = change->point;
position_setting_requests = g_list_append (position_setting_requests,
position_setting);
break;
default:
g_assert_not_reached ();
break;
......
......@@ -27,16 +27,18 @@
#include <glib.h>
void nautilus_file_changes_queue_file_added (const char *uri);
void nautilus_file_changes_queue_file_removed (const char *uri);
void nautilus_file_changes_queue_file_moved (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_remove (const char *uri);
void nautilus_file_changes_queue_file_added (const char *uri);
void nautilus_file_changes_queue_file_removed (const char *uri);
void nautilus_file_changes_queue_file_moved (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_queue_schedule_metadata_remove (const char *uri);
void nautilus_file_changes_queue_schedule_position_setting (const char *uri,
GdkPoint point);
void nautilus_file_changes_consume_changes (gboolean consume_all);
void nautilus_file_changes_consume_changes (gboolean consume_all);
#endif /* NAUTILUS_FILE_CHANGES_QUEUE_H */
......@@ -46,7 +46,8 @@ typedef enum {
XFER_LINK
} XferKind;
typedef struct XferInfo {
/* Copy engine callback state */
typedef struct {
GnomeVFSAsyncHandle *handle;
GtkWidget *progress_dialog;
const char *operation_title; /* "Copying files" */
......@@ -61,6 +62,60 @@ typedef struct XferInfo {
gboolean show_progress_dialog;
} XferInfo;
/* Struct used to control applying icon positions to
* top level items during a copy, drag, new folder creation and
* link creation
*/
typedef struct {
GdkPoint *icon_positions;
int last_icon_position_index;
GList *uris;
const GList *last_uri;
} IconPositionIterator;
static IconPositionIterator *
icon_position_iterator_new (const GdkPoint *icon_positions, const GList *uris)
{
IconPositionIterator *result;
int uri_count;
const GList *p;
uri_count = g_list_length ((GList *)uris);
result = g_new (IconPositionIterator, 1);
result->icon_positions = g_new (GdkPoint, uri_count);
memcpy (result->icon_positions, icon_positions, uri_count * sizeof (GdkPoint));
result->last_icon_position_index = 0;
result->uris = NULL;
/* FIXME:
* should use escaped string here
*/
for (p = uris; p != NULL; p = p->next) {
result->uris = g_list_prepend (result->uris,
gnome_vfs_unescape_string_for_display (p->data));
}
result->uris = g_list_reverse (result->uris);
result->last_uri = result->uris;
return result;
}
static void
icon_position_iterator_free (IconPositionIterator *position_iterator)
{
if (position_iterator == NULL) {
return;
}
g_free (position_iterator->icon_positions);
nautilus_g_list_free_deep (position_iterator->uris);
g_free (position_iterator);
}
char *
nautilus_convert_to_unescaped_string_for_display (char *escaped)
{
......@@ -73,7 +128,6 @@ nautilus_convert_to_unescaped_string_for_display (char *escaped)
return result;
}
static void
xfer_dialog_clicked_callback (NautilusFileOperationsProgress *dialog,
int button_number,
......@@ -91,8 +145,9 @@ static void
create_xfer_dialog (const GnomeVFSXferProgressInfo *progress_info,
XferInfo *xfer_info)
{
if (!xfer_info->show_progress_dialog)
if (!xfer_info->show_progress_dialog) {
return;
}
g_return_if_fail (xfer_info->progress_dialog == NULL);
......@@ -339,7 +394,7 @@ handle_xfer_vfs_error (const GnomeVFSXferProgressInfo *progress_info,
switch (result) {
case 0:
return GNOME_VFS_XFER_ERROR_ACTION_SKIP;
case 2:
case 1:
return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
}
} else {
......@@ -426,13 +481,15 @@ handle_xfer_overwrite (const GnomeVFSXferProgressInfo *progress_info,
}
/* Note that we have these two separate functions with separate format
* strings for ease of localization. Resist the urge to "optimize" them
* for English.
* strings for ease of localization.
*/
static char *
get_link_name (const char *name, int count)
get_link_name (char *name, int count)
{
const char *format;
char *result;
g_assert (name != NULL);
if (count < 1) {
......@@ -440,51 +497,56 @@ get_link_name (const char *name, int count)
count = 1;
}
/* Handle special cases for low numbers.
* Perhaps for some locales we will need to add more.
*/
switch (count) {
case 1:
return g_strdup_printf (_("link to %s"), name);
case 2:
return g_strdup_printf (_("another link to %s"), name);
}
/* Handle special cases for the first few numbers of each ten.
* For locales where getting this exactly right is difficult,
* these can just be made all the same as the general case below.
*/
switch (count % 10) {
case 1:
/* Localizers: Feel free to leave out the "st" suffix
* if there's no way to do that nicely for a
* particular language.
*/
return g_strdup_printf (_("%dst link to %s"), count, name);
case 2:
/* Localizers: Feel free to leave out the "nd" suffix
* if there's no way to do that nicely for a
* particular language.
*/
return g_strdup_printf (_("%dnd link to %s"), count, name);
case 3:
/* Localizers: Feel free to leave out the "rd" suffix
* if there's no way to do that nicely for a
* particular language.
if (count <= 2) {
/* Handle special cases for low numbers.
* Perhaps for some locales we will need to add more.
*/
return g_strdup_printf (_("%drd link to %s"), count, name);
default:
/* Localizers: Feel free to leave out the "th" suffix
* if there's no way to do that nicely for a
* particular language.
switch (count) {
case 1:
format = _("link to %s");
break;
case 2:
format = _("another link to %s");
break;
}
result = g_strdup_printf (format, name);
} else {
/* Handle special cases for the first few numbers of each ten.
* For locales where getting this exactly right is difficult,
* these can just be made all the same as the general case below.
*/
return g_strdup_printf (_("%dth link to %s"), count, name);
switch (count % 10) {
case 1:
/* Localizers: Feel free to leave out the "st" suffix
* if there's no way to do that nicely for a
* particular language.
*/
format = _("%dst link to %s");
break;
case 2:
format = _("%dnd link to %s");
break;
case 3:
format = _("%drd link to %s");
break;
default:
format = _("%dth link to %s");
break;
}
result = g_strdup_printf (format, count, name);
}
g_free (name);
return result;
}
static char *
get_duplicate_name (const char *name, int count)
get_duplicate_name (char *name, int count)
{
const char *format;
char *result;
g_assert (name != NULL);
if (count < 1) {
......@@ -492,31 +554,47 @@ get_duplicate_name (const char *name, int count)
count = 1;
}
/* Handle special cases for low numbers.
* Perhaps for some locales we will need to add more.
*/
switch (count) {
case 1:
return g_strdup_printf (_("%s (copy)"), name);
case 2:
return g_strdup_printf (_("%s (another copy)"), name);
}
if (count <= 2) {
/* Handle special cases for low numbers.
* Perhaps for some locales we will need to add more.
*/
switch (count) {
case 1:
format = _("%s (copy)");
break;
case 2:
format = _("%s (another copy)");
break;
/* Handle special cases for the first few numbers of each ten.
* For locales where getting this exactly right is difficult,
* these can just be made all the same as the general case below.
*/
switch (count % 10) {
case 1:
return g_strdup_printf (_("%s (%dst copy)"), name, count);
case 2:
return g_strdup_printf (_("%s (%dnd copy)"), name, count);
case 3:
return g_strdup_printf (_("%s (%drd copy)"), name, count);
}
result = g_strdup_printf (format, name);
} else {
/* Handle special cases for the first few numbers of each ten.
* For locales where getting this exactly right is difficult,
* these can just be made all the same as the general case below.
*/
switch (count % 10) {
case 1:
format = _("%s (%dst copy)");