File nautilus-name-length.patch of Package nautilus

Index: libnautilus-private/nautilus-file-operations.c
================================================================================
--- libnautilus-private/nautilus-file-operations.c
+++ libnautilus-private/nautilus-file-operations.c
@@ -1163,19 +1163,58 @@
 	}
 }
 
+
+static char *
+shorten_string (const char *base, int reduce_by)
+{
+	int len;
+	char *ret;
+	const char *p;
+	
+	len = strlen (base);
+	len -= reduce_by;
+	
+	if (len <= 0) {
+		return NULL;
+	}
+
+	ret = g_malloc (len + 1);
+
+	p = base;
+	while (len) {
+		char *next;
+		next = g_utf8_next_char (p);
+		if (next - p > len || *next == '\0') {
+			break;
+		}
+		
+		len -= next - p;
+		p = next;
+	}
+	
+	if (p - base == 0) {
+		g_free (ret);
+		return NULL;
+	} else {
+		memcpy (ret, base, p - base);
+		ret[p-base] = '\0';
+		return ret;
+	}
+}
+
 /* Note that we have these two separate functions with separate format
  * strings for ease of localization.
  */
 
 static char *
-get_link_name (char *name, int count) 
+get_link_name (char *name, int count, int max_length) 
 {
 	char *result;
 	char *unescaped_name;
 	char *unescaped_tmp_name;
 	char *unescaped_result;
 	char *new_file;
-
+	int unescaped_result_size;
 	const char *format;
 	
 	g_assert (name != NULL);
@@ -1210,6 +1249,17 @@
 			break;
 		}
 		unescaped_result = g_strdup_printf (format, unescaped_name);
+		if (max_length > 0 && (unescaped_result_size = strlen (unescaped_result)) > max_length) {
+			char *new_name;
+			
+			new_name = shorten_string (unescaped_name, unescaped_result_size - max_length);
+			if (new_name) {
+				g_free (unescaped_result);
+				unescaped_result = g_strdup_printf (format, new_name);
+				g_assert (strlen (unescaped_result) <= max_length);
+				g_free (new_name);
+			}
+		}
 
 	} else {
 		/* Handle special cases for the first few numbers of each ten.
@@ -1238,6 +1288,17 @@
 			break;
 		}
 		unescaped_result = g_strdup_printf (format, count, unescaped_name);
+		if (max_length > 0 && (unescaped_result_size = strlen (unescaped_result)) > max_length) {
+			char *new_name;
+			
+			new_name = shorten_string (unescaped_name, unescaped_result_size - max_length);
+			if (new_name) {
+				g_free (unescaped_result);
+				unescaped_result = g_strdup_printf (format, count, new_name);
+				g_assert (strlen (unescaped_result) <= max_length);
+				g_free (new_name);
+			}
+		}
 	}
 	new_file = g_filename_from_utf8 (unescaped_result, -1, NULL, NULL, NULL);
 	result = gnome_vfs_escape_path_string (new_file);
@@ -1434,11 +1495,11 @@
 }
 
 static char *
-make_next_duplicate_name (const char *base, const char *suffix, int count)
+make_next_duplicate_name (const char *base, const char *suffix, int count, int max_length)
 {
 	const char *format;
 	char *result;
-
+	int name_size;
 
 	if (count < 1) {
 		g_warning ("bad count %d in get_duplicate_name", count);
@@ -1463,6 +1524,18 @@
 
 		}
 		result = g_strdup_printf (format, base, suffix);
+
+		if (max_length > 0 && (name_size = strlen (result)) > max_length) {
+			char *new_base;
+			
+			new_base = shorten_string (base, name_size - max_length);
+			if (new_base) {
+				g_free (result);
+				result = g_strdup_printf (format, new_base, suffix);
+				g_assert (strlen (result) <= max_length);
+				g_free (new_base);
+			}
+		}
 	} else {
 
 		/* Handle special cases for the first few numbers of each ten.
@@ -1506,13 +1579,25 @@
 		}
 
 		result = g_strdup_printf (format, base, count, suffix);
+		if (max_length > 0 && (name_size = strlen (result)) > max_length) {
+			char *new_base;
+			
+			new_base = shorten_string (base, name_size - max_length);
+			if (new_base) {
+				g_free (result);
+				result = g_strdup_printf (format, new_base, count, suffix);
+				g_assert (strlen (result) <= max_length);
+				g_free (new_base);
+
+			}
+		}
 	}
 
 	return result;
 }
 
 static char *
-get_duplicate_name (const char *name, int count_increment)
+get_duplicate_name (const char *name, int count_increment, int max_length)
 {
 	char *result;
 	char *name_base;
@@ -1520,7 +1605,7 @@
 	int count;
 
 	parse_previous_duplicate_name (name, &name_base, &suffix, &count);
-	result = make_next_duplicate_name (name_base, suffix, count + count_increment);
+	result = make_next_duplicate_name (name_base, suffix, count + count_increment, max_length);
 
 	g_free (name_base);
 
@@ -1528,7 +1613,7 @@
 }
 
 static char *
-get_next_duplicate_name (char *name, int count_increment)
+get_next_duplicate_name (char *name, int count_increment, int max_length)
 {
 	char *unescaped_name;
 	char *unescaped_tmp_name;
@@ -1554,7 +1639,7 @@
 		
 	g_free (unescaped_tmp_name);
 	
-	unescaped_result = get_duplicate_name (unescaped_name, count_increment);
+	unescaped_result = get_duplicate_name (unescaped_name, count_increment, max_length);
 	g_free (unescaped_name);
 
 	new_file = g_filename_from_utf8 (unescaped_result, -1, NULL, NULL, NULL);
@@ -1565,21 +1650,74 @@
 }
 
 static int
+get_max_name_length (const char *text_uri)
+{
+	int max_length;
+	GnomeVFSURI *uri;
+	char *dir;
+	long max_path;
+	long max_name;
+
+	max_length = -1;
+
+	uri = gnome_vfs_uri_new (text_uri);
+	if (!uri) {
+		return max_length;
+	}
+
+	if (strcmp (gnome_vfs_uri_get_scheme (uri), "file") != 0) {
+		gnome_vfs_uri_unref (uri);
+		return max_length;
+	}
+	
+	dir = gnome_vfs_uri_extract_dirname (uri);
+	
+	max_path = pathconf (dir, _PC_PATH_MAX);
+	max_name = pathconf (dir, _PC_NAME_MAX);
+
+	if (max_name == -1 && max_path == -1) {
+		max_length = -1;
+	} else if (max_name == -1 && max_path != -1) {
+		max_length = max_path - (strlen (dir) + 1);
+	} else if (max_name != -1 && max_path == -1) {
+		max_length = max_name;
+	} else {
+		int leftover;
+
+		leftover = max_path - (strlen (dir) + 1);
+
+		max_length = MIN (leftover, max_name);
+	}
+	
+	g_free (dir);
+	
+	gnome_vfs_uri_unref (uri);
+	
+	return max_length;
+}
+
+static int
 handle_transfer_duplicate (GnomeVFSXferProgressInfo *progress_info,
 			   TransferInfo *transfer_info)
 {
+	int max_length;
+	
+	max_length = get_max_name_length (progress_info->target_name);
+	
 	switch (transfer_info->kind) {
 	case TRANSFER_LINK:
 		progress_info->duplicate_name = get_link_name
 			(progress_info->duplicate_name,
-			 progress_info->duplicate_count);
+			 progress_info->duplicate_count,
+			 max_length);
 		break;
 
 	case TRANSFER_COPY:
 	case TRANSFER_MOVE_TO_TRASH:
 		progress_info->duplicate_name = get_next_duplicate_name
 			(progress_info->duplicate_name,
-			 progress_info->duplicate_count);
+			 progress_info->duplicate_count,
+			 max_length);
 		break;
 	default:
 		break;
@@ -2722,47 +2860,47 @@
 	setlocale (LC_MESSAGES, "C");
 
 	/* test the next duplicate name generator */
-	EEL_CHECK_STRING_RESULT (get_duplicate_name (" (copy)", 1), " (another copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo", 1), "foo (copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name (".bashrc", 1), ".bashrc (copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name (".foo.txt", 1), ".foo (copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo", 1), "foo foo (copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo.txt", 1), "foo (copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo.txt", 1), "foo foo (copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo.txt txt", 1), "foo foo (copy).txt txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo...txt", 1), "foo (copy)...txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo...", 1), "foo (copy)...");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo. (copy)", 1), "foo. (another copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (copy)", 1), "foo (another copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (copy).txt", 1), "foo (another copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (another copy)", 1), "foo (3rd copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (another copy).txt", 1), "foo (3rd copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (another copy).txt", 1), "foo foo (3rd copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (13th copy)", 1), "foo (14th copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (13th copy).txt", 1), "foo (14th copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (21st copy)", 1), "foo (22nd copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (21st copy).txt", 1), "foo (22nd copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (22nd copy)", 1), "foo (23rd copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (22nd copy).txt", 1), "foo (23rd copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (23rd copy)", 1), "foo (24th copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (23rd copy).txt", 1), "foo (24th copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (24th copy)", 1), "foo (25th copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (24th copy).txt", 1), "foo (25th copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (24th copy)", 1), "foo foo (25th copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (24th copy).txt", 1), "foo foo (25th copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (100000000000000th copy).txt", 1), "foo foo (copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (10th copy)", 1), "foo (11th copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (10th copy).txt", 1), "foo (11th copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (11th copy)", 1), "foo (12th copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (11th copy).txt", 1), "foo (12th copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (12th copy)", 1), "foo (13th copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (12th copy).txt", 1), "foo (13th copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (110th copy)", 1), "foo (111th copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (110th copy).txt", 1), "foo (111th copy).txt");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (122nd copy)", 1), "foo (123rd copy)");
-	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (122nd copy).txt", 1), "foo (123rd copy).txt");
-	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 (" (copy)", 1, -1), " (another copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo", 1, -1), "foo (copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name (".bashrc", 1, -1), ".bashrc (copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name (".foo.txt", 1, -1), ".foo (copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo", 1, -1), "foo foo (copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo.txt", 1, -1), "foo (copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo.txt", 1, -1), "foo foo (copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo.txt txt", 1, -1), "foo foo (copy).txt txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo...txt", 1, -1), "foo (copy)...txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo...", 1, -1), "foo (copy)...");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo. (copy)", 1, -1), "foo. (another copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (copy)", 1, -1), "foo (another copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (copy).txt", 1, -1), "foo (another copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (another copy)", 1, -1), "foo (3rd copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (another copy).txt", 1, -1), "foo (3rd copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (another copy).txt", 1, -1), "foo foo (3rd copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (13th copy)", 1, -1), "foo (14th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (13th copy).txt", 1, -1), "foo (14th copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (21st copy)", 1, -1), "foo (22nd copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (21st copy).txt", 1, -1), "foo (22nd copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (22nd copy)", 1, -1), "foo (23rd copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (22nd copy).txt", 1, -1), "foo (23rd copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (23rd copy)", 1, -1), "foo (24th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (23rd copy).txt", 1, -1), "foo (24th copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (24th copy)", 1, -1), "foo (25th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (24th copy).txt", 1, -1), "foo (25th copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (24th copy)", 1, -1), "foo foo (25th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (24th copy).txt", 1, -1), "foo foo (25th copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo foo (100000000000000th copy).txt", 1, -1), "foo foo (copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (10th copy)", 1, -1), "foo (11th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (10th copy).txt", 1, -1), "foo (11th copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (11th copy)", 1, -1), "foo (12th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (11th copy).txt", 1, -1), "foo (12th copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (12th copy)", 1, -1), "foo (13th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (12th copy).txt", 1, -1), "foo (13th copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (110th copy)", 1, -1), "foo (111th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (110th copy).txt", 1, -1), "foo (111th copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (122nd copy)", 1, -1), "foo (123rd copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (122nd copy).txt", 1, -1), "foo (123rd copy).txt");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy)", 1, -1), "foo (124th copy)");
+	EEL_CHECK_STRING_RESULT (get_duplicate_name ("foo (123rd copy).txt", 1, -1), "foo (124th copy).txt");
 
 	setlocale (LC_MESSAGES, "");
 }
openSUSE Build Service is sponsored by