Index: libnautilus-private/nautilus-icon-container.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.c,v
retrieving revision 1.387
diff -u -p -r1.387 nautilus-icon-container.c
--- libnautilus-private/nautilus-icon-container.c	3 Jun 2005 07:48:01 -0000	1.387
+++ libnautilus-private/nautilus-icon-container.c	5 Jun 2005 12:02:29 -0000
@@ -4829,8 +4829,6 @@ get_icon_being_renamed (NautilusIconCont
 		return NULL;
 	}
 
-	g_assert (!has_multiple_selection (container));
-
 	rename_icon = get_first_selected_icon (container);
 	g_assert (rename_icon != NULL);
 
@@ -6099,8 +6097,8 @@ process_pending_icon_to_rename (Nautilus
 	pending_icon_to_rename = get_pending_icon_to_rename (container);
 	
 	if (pending_icon_to_rename != NULL) {
-		if (pending_icon_to_rename->is_selected && !has_multiple_selection (container)) {
-			nautilus_icon_container_start_renaming_selected_item (container, FALSE);
+		if (pending_icon_to_rename->is_selected) {
+			nautilus_icon_container_start_renaming_selected_items (container, FALSE);
 		} else {
 			set_pending_icon_to_rename (container, NULL);
 		}
@@ -6120,7 +6118,7 @@ is_renaming (NautilusIconContainer *cont
 }
 
 /**
- * nautilus_icon_container_start_renaming_selected_item
+ * nautilus_icon_container_start_renaming_selected_items
  * @container: An icon container widget.
  * @select_all: Whether the whole file should initially be selected, or
  *              only its basename (i.e. everything except its extension).
@@ -6128,8 +6126,8 @@ is_renaming (NautilusIconContainer *cont
  * Displays the edit name widget on the first selected icon
  **/
 void
-nautilus_icon_container_start_renaming_selected_item (NautilusIconContainer *container,
-						      gboolean select_all)
+nautilus_icon_container_start_renaming_selected_items (NautilusIconContainer *container,
+						       gboolean select_all)
 {
 	NautilusIconContainerDetails *details;
 	NautilusIcon *icon;
@@ -6151,9 +6149,6 @@ nautilus_icon_container_start_renaming_s
 	if (icon == NULL) {
 		return;
 	}
-
-	g_assert (!has_multiple_selection (container));
-
 
 	if (!icon_is_positioned (icon)) {
 		set_pending_icon_to_rename (container, icon);
Index: libnautilus-private/nautilus-icon-container.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-container.h,v
retrieving revision 1.86
diff -u -p -r1.86 nautilus-icon-container.h
--- libnautilus-private/nautilus-icon-container.h	2 Jun 2005 10:48:55 -0000	1.86
+++ libnautilus-private/nautilus-icon-container.h	5 Jun 2005 12:02:29 -0000
@@ -247,7 +247,7 @@ gboolean          nautilus_icon_containe
 gboolean          nautilus_icon_container_is_stretched                  (NautilusIconContainer  *container);
 void              nautilus_icon_container_show_stretch_handles          (NautilusIconContainer  *container);
 void              nautilus_icon_container_unstretch                     (NautilusIconContainer  *container);
-void              nautilus_icon_container_start_renaming_selected_item  (NautilusIconContainer  *container,
+void              nautilus_icon_container_start_renaming_selected_items (NautilusIconContainer  *container,
 									 gboolean                select_all);
 
 /* options */
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.684
diff -u -p -r1.684 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	4 Jun 2005 15:02:02 -0000	1.684
+++ src/file-manager/fm-directory-view.c	5 Jun 2005 12:02:34 -0000
@@ -336,7 +336,8 @@ static void     fm_directory_view_trash_
 								gboolean              state,
 								gpointer              callback_data);
 static void     fm_directory_view_select_file                  (FMDirectoryView      *view,
-								NautilusFile         *file);
+								NautilusFile         *file,
+								gboolean              exclusive_selection);
 static void     monitor_file_for_open_with                     (FMDirectoryView      *view,
 								NautilusFile         *file);
 static void     create_scripts_directory                       (void);
@@ -2907,6 +2908,29 @@ fm_directory_view_can_rename_file (FMDir
 }
 
 /**
+ * fm_directory_view_can_rename_files
+ *
+ * Determine whether all @files can be renamed.
+ * @file: A list of NautilusFiles
+ * 
+ * Return value: TRUE if all @files can be renamed, FALSE otherwise.
+ * 
+ **/
+static gboolean
+fm_directory_view_can_rename_files (FMDirectoryView *view, GList *files)
+{
+	while (files != NULL) {
+		if (fm_directory_view_can_rename_file (view, files->data)) {
+			return TRUE;
+		}
+
+		files = files->next;
+	}
+
+	return FALSE;
+}
+
+/**
  * fm_directory_view_can_zoom_out:
  *
  * Determine whether the view can be zoomed any further away.
@@ -3388,16 +3412,6 @@ can_rename_file (FMDirectoryView *view, 
 	return nautilus_file_can_rename (file);
 }
 
-static void
-start_renaming_file (FMDirectoryView *view,
-		     NautilusFile *file,
-		     gboolean select_all)
-{
-	if (file !=  NULL) {
-		fm_directory_view_select_file (view, file);
-	}
-}
-
 typedef struct {
 	FMDirectoryView *view;
 	NautilusFile *new_file;
@@ -3412,7 +3426,10 @@ delayed_rename_file_hack_callback (Renam
 	view = data->view;
 	new_file = data->new_file;
 
-	EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view, start_renaming_file, (view, new_file, FALSE));
+	fm_directory_view_select_file (view, new_file, FALSE);
+	EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view,
+			 start_renaming_selected_files,
+			 (view, FALSE));
 	fm_directory_view_reveal_selection (view);
 	
 	g_object_unref (data->view);
@@ -3438,7 +3455,7 @@ rename_file (FMDirectoryView *view, Naut
 	   file_changed. So, before we delay we select the row.
 	*/
 	if (FM_IS_LIST_VIEW (view)) {
-		fm_directory_view_select_file (view, new_file);
+		fm_directory_view_select_file (view, new_file, FALSE);
 		
 		data = g_new (RenameData, 1);
 		data->view = g_object_ref (view);
@@ -3453,10 +3470,10 @@ rename_file (FMDirectoryView *view, Naut
 		return;
 	}
 	
-	/* no need to select because start_renaming_file selects
-	 * fm_directory_view_select_file (view, new_file);
-	 */
-	EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view, start_renaming_file, (view, new_file, FALSE));
+	fm_directory_view_select_file (view, new_file, FALSE);
+	EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view,
+			 start_renaming_selected_files,
+			 (view, FALSE));
 	fm_directory_view_reveal_selection (view);
 }
 
@@ -5513,7 +5530,9 @@ real_action_rename (FMDirectoryView *vie
 			 * they are always pre-selected as a whole */
 			select_all = nautilus_file_is_directory (file);
 		}
-		EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view, start_renaming_file, (view, file, select_all));
+		EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view,
+				 start_renaming_selected_files,
+				 (view, select_all));
 	}
 
 	nautilus_file_list_free (selection);
@@ -6509,8 +6528,8 @@ real_update_menus (FMDirectoryView *view
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_RENAME);
 	gtk_action_set_sensitive (action,
-				  selection_count == 1 &&
-				  fm_directory_view_can_rename_file (view, selection->data));
+				  selection_count != 0 &&
+				  fm_directory_view_can_rename_files (view, selection));
 
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_NEW_FOLDER);
@@ -7666,15 +7685,38 @@ fm_directory_view_set_selection (FMDirec
 		 set_selection, (view, selection));
 }
 
+/**
+ * fm_directory_view_select_file:
+ *
+ * select the @file, unselecting any previously selected files
+ * if @exclusive_selection is TRUE. If @exclusive_selection is FALSE,
+ * @file is selected in addition to the current selection if it is
+ * not yet selected.
+ * 
+ **/
 static void
-fm_directory_view_select_file (FMDirectoryView *view, NautilusFile *file)
+fm_directory_view_select_file (FMDirectoryView *view,
+			       NautilusFile *file,
+			       gboolean exclusive_selection)
 {
 	GList file_list;
+	GList *selection;
+
+	if (exclusive_selection) {
+		file_list.data = file;
+		file_list.next = NULL;
+		file_list.prev = NULL;
+		fm_directory_view_set_selection (view, &file_list);
+	} else {
+		selection = fm_directory_view_get_selection (FM_DIRECTORY_VIEW (view));
+
+		if (g_list_find (selection, file) == NULL) {
+			selection = g_list_prepend (selection, file);
+			fm_directory_view_set_selection (FM_DIRECTORY_VIEW (view), selection);
+		}
 
-	file_list.data = file;
-	file_list.next = NULL;
-	file_list.prev = NULL;
-	fm_directory_view_set_selection (view, &file_list);
+		nautilus_file_list_free (selection);
+	}
 }
 
 /**
@@ -8591,7 +8633,6 @@ fm_directory_view_class_init (FMDirector
 	klass->load_error = real_load_error;
 	klass->sort_files = real_sort_files;
 	klass->can_rename_file = can_rename_file;
-	klass->start_renaming_file = start_renaming_file;
 	klass->supports_creating_files = real_supports_creating_files;
 	klass->supports_properties = real_supports_properties;
 	klass->supports_zooming = real_supports_zooming;
Index: src/file-manager/fm-directory-view.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.h,v
retrieving revision 1.138
diff -u -p -r1.138 fm-directory-view.h
--- src/file-manager/fm-directory-view.h	2 Jun 2005 10:48:55 -0000	1.138
+++ src/file-manager/fm-directory-view.h	5 Jun 2005 12:02:34 -0000
@@ -269,9 +269,8 @@ struct FMDirectoryViewClass {
 	/* select_all specifies whether the whole filename should be selected
 	 * or only its basename (i.e. everything except the extension)
 	 * */
-	void	 (* start_renaming_file)        (FMDirectoryView *view,
-					  	 NautilusFile *file,
-						 gboolean select_all);
+	void	 (* start_renaming_selected_files) (FMDirectoryView *view,
+						    gboolean select_all);
 
 	gboolean (* file_still_belongs)		(FMDirectoryView *view,
 						 NautilusFile	 *file);
Index: src/file-manager/fm-error-reporting.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-error-reporting.c,v
retrieving revision 1.38
diff -u -p -r1.38 fm-error-reporting.c
--- src/file-manager/fm-error-reporting.c	11 Dec 2003 10:38:16 -0000	1.38
+++ src/file-manager/fm-error-reporting.c	5 Jun 2005 12:02:34 -0000
@@ -322,3 +322,88 @@ fm_rename_file (NautilusFile *file,
 	nautilus_file_rename (file, new_name,
 			      rename_callback, NULL);
 }
+
+typedef struct {
+	char **split_filename;
+	int i;
+} MultiRenameData;
+
+static void
+foreach_assign_name (NautilusFile *file,
+		     MultiRenameData *rename_data)
+{
+	char *new_name_pattern;
+	char *new_name;
+
+	if (rename_data->i == 0) {
+		if (rename_data->split_filename[1]) {
+			new_name_pattern = "%s.%3$s";
+		} else {
+			new_name_pattern = "%s";
+		}
+	} else {
+		if (rename_data->split_filename[1]) {
+			new_name_pattern = "%s (%d).%s";
+		} else {
+			new_name_pattern = "%s (%d)";
+		}
+	}
+
+	new_name = g_strdup_printf (new_name_pattern,
+				    rename_data->split_filename[0],
+				    rename_data->i,
+				    rename_data->split_filename[1]);
+
+	/* Attach the new name to the file. */
+	g_object_set_data_full (G_OBJECT (file), NEW_NAME_TAG,
+				new_name, g_free);
+
+	rename_data->i++;
+}
+
+static void
+foreach_rename (NautilusFile *file)
+{
+	char *new_name;
+
+	new_name = g_object_get_data (G_OBJECT (file), NEW_NAME_TAG);
+	g_return_if_fail (new_name != NULL);
+
+	nautilus_file_rename (file, new_name,
+			      rename_callback, NULL);
+}
+
+void
+fm_rename_files (GList *files,
+		 const char *new_name)
+{
+	MultiRenameData rename_data;
+	int filename_parts;
+
+	g_return_if_fail (files != NULL && NAUTILUS_IS_FILE (files->data));
+	g_return_if_fail (new_name != NULL);
+
+	/* Stop any earlier rename that's already in progress. */
+	g_list_foreach (files,
+			(GFunc) cancel_rename,
+			NULL);
+
+	if (nautilus_file_is_directory (files->data)) {
+		filename_parts = 1;
+	} else {
+		filename_parts = 2;
+	}
+	rename_data.split_filename = g_strsplit (new_name, ".", filename_parts);
+	rename_data.i = 0;
+
+	g_list_foreach (files,
+			(GFunc) foreach_assign_name,
+			&rename_data);
+
+	g_strfreev (rename_data.split_filename);
+
+	/* Start the rename. */
+	g_list_foreach (files,
+			(GFunc) foreach_rename,
+			NULL);
+}
Index: src/file-manager/fm-error-reporting.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-error-reporting.h,v
retrieving revision 1.10
diff -u -p -r1.10 fm-error-reporting.h
--- src/file-manager/fm-error-reporting.h	21 Feb 2002 19:26:52 -0000	1.10
+++ src/file-manager/fm-error-reporting.h	5 Jun 2005 12:02:34 -0000
@@ -50,5 +50,7 @@ void fm_report_error_setting_group      
 /* FIXME bugzilla.gnome.org 42394: Should this file be renamed or should this function be moved? */
 void fm_rename_file                      (NautilusFile   *file,
 					  const char     *new_name);
+void fm_rename_files                     (GList          *files,
+					  const char     *new_name);
 
 #endif /* FM_ERROR_REPORTING_H */
Index: src/file-manager/fm-icon-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-icon-view.c,v
retrieving revision 1.309
diff -u -p -r1.309 fm-icon-view.c
--- src/file-manager/fm-icon-view.c	2 Jun 2005 16:16:55 -0000	1.309
+++ src/file-manager/fm-icon-view.c	5 Jun 2005 12:02:35 -0000
@@ -1377,16 +1377,13 @@ fm_icon_view_can_rename_file (FMDirector
 }
 
 static void
-fm_icon_view_start_renaming_file (FMDirectoryView *view,
-				  NautilusFile *file,
-				  gboolean select_all)
+fm_icon_view_start_renaming_selected_files (FMDirectoryView *view,
+					    gboolean select_all)
 {
-	/* call parent class to make sure the right icon is selected */
-	FM_DIRECTORY_VIEW_CLASS(fm_icon_view_parent_class)->start_renaming_file (view, file, select_all);
-	
 	/* start renaming */
-	nautilus_icon_container_start_renaming_selected_item
-		(get_icon_container (FM_ICON_VIEW (view)), select_all);
+	nautilus_icon_container_start_renaming_selected_items
+		(get_icon_container (FM_ICON_VIEW (view)),
+		 select_all);
 }
 
 static const GtkActionEntry icon_view_entries[] = {
@@ -2144,6 +2141,8 @@ fm_icon_view_icon_text_changed_callback 
 					 char *new_name,
 					 FMIconView *icon_view)
 {
+	GList *selection;
+
 	g_assert (NAUTILUS_IS_FILE (file));
 	g_assert (new_name != NULL);
 
@@ -2153,7 +2152,16 @@ fm_icon_view_icon_text_changed_callback 
 	if (new_name[0] == '\0') {
 		return;
 	}
-	fm_rename_file (file, new_name);
+
+	selection = fm_directory_view_get_selection (FM_DIRECTORY_VIEW (icon_view));
+
+	if (g_list_length (selection) > 1) {
+		fm_rename_files (selection, new_name);
+	} else {
+		fm_rename_file (file, new_name);
+	}
+
+	nautilus_file_list_free (selection);
 }
 
 static char *
@@ -2557,7 +2565,7 @@ fm_icon_view_class_init (FMIconViewClass
         fm_directory_view_class->image_display_policy_changed = fm_icon_view_image_display_policy_changed;
         fm_directory_view_class->merge_menus = fm_icon_view_merge_menus;
         fm_directory_view_class->sort_directories_first_changed = fm_icon_view_sort_directories_first_changed;
-        fm_directory_view_class->start_renaming_file = fm_icon_view_start_renaming_file;
+        fm_directory_view_class->start_renaming_selected_files = fm_icon_view_start_renaming_selected_files;
         fm_directory_view_class->text_attribute_names_changed = fm_icon_view_text_attribute_names_changed;
         fm_directory_view_class->update_menus = fm_icon_view_update_menus;
 
Index: src/file-manager/fm-list-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-list-view.c,v
retrieving revision 1.245
diff -u -p -r1.245 fm-list-view.c
--- src/file-manager/fm-list-view.c	2 Jun 2005 16:16:55 -0000	1.245
+++ src/file-manager/fm-list-view.c	5 Jun 2005 12:02:37 -0000
@@ -842,6 +842,7 @@ cell_renderer_edited (GtkCellRendererTex
 {
 	GtkTreePath *path;
 	NautilusFile *file;
+	GList *selection;
 	GtkTreeIter iter;
 	
 	/* Don't allow a rename with an empty string. Revert to original 
@@ -868,9 +869,17 @@ cell_renderer_edited (GtkCellRendererTex
 
 	/* Only rename if name actually changed */
 	if (strcmp (new_text, view->details->original_name) != 0) {
-		fm_rename_file (file, new_text);
+		selection = fm_directory_view_get_selection (FM_DIRECTORY_VIEW (view));
+		if (g_list_length (selection) > 2) {
+			fm_rename_files (selection, new_text);
+		} else {
+			fm_rename_file (file, new_text);
+		}
+
 		g_free (view->details->original_name);
 		view->details->original_name = g_strdup (new_text);
+
+		nautilus_file_list_free (selection);
 	}
 	
 	nautilus_file_unref (file);
@@ -1920,25 +1929,29 @@ fm_list_view_can_zoom_out (FMDirectoryVi
 }
 
 static void
-fm_list_view_start_renaming_file (FMDirectoryView *view,
-				  NautilusFile *file,
-				  gboolean select_all)
+fm_list_view_start_renaming_selected_files (FMDirectoryView *view,
+					    gboolean select_all)
 {
 	FMListView *list_view;
 	GtkTreeIter iter;
 	GtkTreePath *path;
 	GtkEntry *entry;
+	GList *selection;
 	int start_offset, end_offset;
 	
 	list_view = FM_LIST_VIEW (view);
+
+        selection = fm_directory_view_get_selection (view);
 	
 	/* Don't start renaming if another rename in this listview is
 	 * already in progress. */
 	if (list_view->details->file_name_column && list_view->details->file_name_column->editable_widget) {
+		g_list_free (selection);
 		return;
 	}
 
-	if (!fm_list_model_get_tree_iter_from_file (list_view->details->model, file, &iter)) {
+	if (!fm_list_model_get_tree_iter_from_file (list_view->details->model, selection->data, &iter)) {
+		g_list_free (selection);
 		return;
 	}
 
@@ -1983,6 +1996,8 @@ fm_list_view_start_renaming_file (FMDire
 		(GTK_EDITABLE (entry),
 		 fm_directory_view_get_ui_manager (view),
 		 FALSE);
+
+	g_list_free (selection);
 }
 
 static void
@@ -2254,7 +2269,7 @@ fm_list_view_class_init (FMListViewClass
 	fm_directory_view_class->set_selection = fm_list_view_set_selection;
 	fm_directory_view_class->sort_files = fm_list_view_sort_files;
 	fm_directory_view_class->sort_directories_first_changed = fm_list_view_sort_directories_first_changed;
-	fm_directory_view_class->start_renaming_file = fm_list_view_start_renaming_file;
+	fm_directory_view_class->start_renaming_selected_files = fm_list_view_start_renaming_selected_files;
 	fm_directory_view_class->get_zoom_level = fm_list_view_get_zoom_level;
 	fm_directory_view_class->zoom_to_level = fm_list_view_zoom_to_level;
         fm_directory_view_class->emblems_changed = fm_list_view_emblems_changed;
