Re: bug (feature request?) in nautilus



I've create attachment to bugzilla bug #48085 (original bug for this
subject). This is only patch to gnome-vfs to implement requested
functionality. You can consider it not as working patch, but as a
proposal to solve problem.

I propose to add new action MERGE, and add corresponding button in
override dialog in nautilus. It will merge directories and replace files
with the same names. But, of course, the patch to gnome-vfs should be
applied first.
	
What do nautilus developers think about it?
			Shmyrev.
cvs server: Diffing .
Index: gnome-vfs-xfer.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-xfer.c,v
retrieving revision 1.110
diff -p -u -r1.110 gnome-vfs-xfer.c
--- gnome-vfs-xfer.c	15 Dec 2003 14:57:07 -0000	1.110
+++ gnome-vfs-xfer.c	17 Mar 2004 00:14:21 -0000
@@ -317,30 +317,34 @@ handle_error (GnomeVFSResult *result,
 /* This is conceptually similiar to the previous `handle_error()' function, but
  * handles the overwrite case. 
  */
-static gboolean
+static void
 handle_overwrite (GnomeVFSResult *result,
 		  GnomeVFSProgressCallbackState *progress,
 		  GnomeVFSXferErrorMode *error_mode,
 		  GnomeVFSXferOverwriteMode *overwrite_mode,
 		  gboolean *replace,
-		  gboolean *skip)
+		  gboolean *skip,
+		  gboolean *merge)
 {
 	GnomeVFSXferOverwriteAction action;
 
+        *replace = FALSE;
+	*skip = FALSE;
+	*merge = FALSE;
+	
 	switch (*overwrite_mode) {
 	case GNOME_VFS_XFER_OVERWRITE_MODE_ABORT:
-		*replace = FALSE;
 		*result = GNOME_VFS_ERROR_FILE_EXISTS;
-		*skip = FALSE;
-		return FALSE;
+		return;
 	case GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE:
 		*replace = TRUE;
-		*skip = FALSE;
-		return TRUE;
+		return;
 	case GNOME_VFS_XFER_OVERWRITE_MODE_SKIP:
-		*replace = FALSE;
 		*skip = TRUE;
-		return FALSE;
+		return;
+	case GNOME_VFS_XFER_OVERWRITE_MODE_MERGE:
+		*merge = FALSE;
+		return;
 	case GNOME_VFS_XFER_OVERWRITE_MODE_QUERY:
 		progress->progress_info->vfs_status = *result;
 		progress->progress_info->status = GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE;
@@ -349,34 +353,33 @@ handle_overwrite (GnomeVFSResult *result
 
 		switch (action) {
 		case GNOME_VFS_XFER_OVERWRITE_ACTION_ABORT:
-			*replace = FALSE;
 			*result = GNOME_VFS_ERROR_FILE_EXISTS;
-			*skip = FALSE;
-			return FALSE;
+			return;
 		case GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE:
 			*replace = TRUE;
-			*skip = FALSE;
-			return TRUE;
+			return;
 		case GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL:
 			*replace = TRUE;
 			*overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE;
-			*skip = FALSE;
-			return TRUE;
+			return;
 		case GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP:
-			*replace = FALSE;
 			*skip = TRUE;
-			return FALSE;
+			return;
 		case GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL:
-			*replace = FALSE;
 			*skip = TRUE;
 			*overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_SKIP;
-			return FALSE;
+			return;
+		case GNOME_VFS_XFER_OVERWRITE_ACTION_MERGE:
+			*merge = TRUE;
+			return;
+		case GNOME_VFS_XFER_OVERWRITE_ACTION_MERGE_ALL:
+			*merge = TRUE;
+			*overwrite_mode = GNOME_VFS_XFER_OVERWRITE_MODE_MERGE;
+			return
+			;
 		}
 	}
-
-	*replace = FALSE;
-	*skip = FALSE;
-	return FALSE;
+	return;
 }
 
 static GnomeVFSResult
@@ -875,6 +878,7 @@ handle_name_conflicts (GList **source_ur
 	     target_item != NULL;) {
 		gboolean replace;
 		gboolean skip;
+		gboolean merge;
 		gboolean is_move_to_self;
 		GnomeVFSURI *uri, *source_uri;
 		GnomeVFSFileInfo *info;
@@ -888,19 +892,25 @@ handle_name_conflicts (GList **source_ur
 			progress_set_source_target_uris (progress, source_uri, uri);
 			 
 			/* no error getting info -- file exists, ask what to do */
-			replace = handle_overwrite (&result, progress, error_mode,
-				overwrite_mode, &replace, &skip);
+			handle_overwrite (&result, progress, error_mode,
+				overwrite_mode, &replace, &skip, &merge);
 
 			/* FIXME bugzilla.eazel.com 1207:
 			 * move items to Trash here
 			 */
+			 
+                	/* FIXME: it seems, that removing conflicting files 
+			here is duplicated functionality, since conflicting
+			file already removed in create_directory and 
+			xfer_create_target functions. Probably, the more clean 
+			code needed? i.e. any removing should be in one place */
 
 			/* get rid of the conflicting file */
-			if (replace) {
+			if (replace || merge) {
 				info = gnome_vfs_file_info_new ();
 				gnome_vfs_get_file_info_uri (uri, info, GNOME_VFS_FILE_INFO_DEFAULT);
 				progress_set_source_target_uris (progress, uri, NULL);
-				if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
+				if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY && replace) {
 					if (move_source_is_in_target (source_uri, uri)) {
 						/* Would like a better error here */
 						result = GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY;
@@ -966,32 +976,34 @@ create_directory (GnomeVFSURI *dir_uri,
 {
 	GnomeVFSResult result;
 	gboolean retry;
+	gboolean merge, skip_override, replace;
 	
 	*skip = FALSE;
 	do {
-		retry = FALSE;
-
 		result = gnome_vfs_make_directory_for_uri (dir_uri, 0777);
 
 		if (result == GNOME_VFS_ERROR_FILE_EXISTS) {
-			gboolean force_replace;
 
 			if ((xfer_options & GNOME_VFS_XFER_USE_UNIQUE_NAMES) != 0) {
 				/* just let the caller pass a unique name*/
 				return result;
 			}
 
-			retry = handle_overwrite (&result,
+			         handle_overwrite (&result,
 						  progress,
 						  error_mode,
 						  overwrite_mode,
-						  &force_replace,
-						  skip);
+						  &replace,
+						  &skip_override, &merge);
 
-			if (*skip) {
+			if (skip_override) {
+			        *skip = TRUE;
+				return GNOME_VFS_OK;
+			}
+		        if (merge) {
 				return GNOME_VFS_OK;
 			}
-			if (force_replace) {
+			if (replace) {
 				result = remove_directory (dir_uri, TRUE, progress, 
 							   xfer_options, error_mode, 
 							   skip);
@@ -1013,7 +1025,7 @@ create_directory (GnomeVFSURI *dir_uri,
 			return GNOME_VFS_OK;
 		}
 
-	} while (retry);
+	} while (retry || replace);
 
 	return result;
 }
@@ -1158,37 +1170,37 @@ xfer_create_target (GnomeVFSHandle **tar
 		    gboolean *skip)
 {
 	GnomeVFSResult result;
-	gboolean retry;
 	gboolean exclusive;
+	gboolean retry;
+	gboolean merge, replace, skip_override;
+
 
 	exclusive = (*overwrite_mode != GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE);
 
-	*skip = FALSE;
 	do {
-		retry = FALSE;
-
 		result = gnome_vfs_create_uri (target_handle, target_uri,
 					       GNOME_VFS_OPEN_WRITE,
 					       exclusive, 0666);
 
 		if (result == GNOME_VFS_ERROR_FILE_EXISTS) {
-			gboolean replace;
 
-			retry = handle_overwrite (&result,
+			         handle_overwrite (&result,
 						  progress,
 						  error_mode,
 						  overwrite_mode,
 						  &replace,
-						  skip);
+						  &skip_override, &merge);
+						  
+			*skip =  skip_override;
 
-			if (replace) {
+			if (replace || merge) {
 				exclusive = FALSE;
 			}
 
 		} else if (result != GNOME_VFS_OK) {
 			retry = handle_error (&result,  progress, error_mode, skip);
 		}
-	} while (retry);
+	} while (replace || retry || merge);
 
 	return result;
 }
Index: gnome-vfs-xfer.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-xfer.h,v
retrieving revision 1.13
diff -p -u -r1.13 gnome-vfs-xfer.h
--- gnome-vfs-xfer.h	1 Aug 2003 09:06:05 -0000	1.13
+++ gnome-vfs-xfer.h	17 Mar 2004 00:14:21 -0000
@@ -68,7 +68,9 @@ typedef enum {
 	/* Overwrite files silently.  */
 	GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE = 2,
 	/* Ignore files silently.  */
-	GNOME_VFS_XFER_OVERWRITE_MODE_SKIP = 3
+	GNOME_VFS_XFER_OVERWRITE_MODE_SKIP = 3,
+	/* Replace dirs when have the same name*/
+	GNOME_VFS_XFER_OVERWRITE_MODE_MERGE = 4
 } GnomeVFSXferOverwriteMode;
 
 /**
@@ -80,6 +82,9 @@ typedef enum {
  * @GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP: don't copy over the existing file
  * @GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL: don't copy over the existing file, and all future
  * files without prompting the callback.
+ * @GNOME_VFS_XFER_OVERWRITE_ACTION_MERGE: merge the source file or dir with the distanation file or dir
+ * @GNOME_VFS_XFER_OVERWRITE_ACTION_MERGE_ALL: merge the source file or dir with the distanation file or dir,
+ * and all future files without prompting the callback.
  * 
  * This defines the actions to perform before a file is being overwritten
  * (i.e., these are the answers that can be given to a replace query).  
@@ -89,7 +94,9 @@ typedef enum {
 	GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE = 1,
 	GNOME_VFS_XFER_OVERWRITE_ACTION_REPLACE_ALL = 2,
 	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP = 3,
-	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL = 4
+	GNOME_VFS_XFER_OVERWRITE_ACTION_SKIP_ALL = 4,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_MERGE = 5,
+	GNOME_VFS_XFER_OVERWRITE_ACTION_MERGE_ALL = 6
 } GnomeVFSXferOverwriteAction;
 
 typedef enum {
cvs server: Diffing libcharset


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]