[nautilus] Add a way to create a new directory from a selection



commit 9402432b85c99cef8e57798915dec476bbbac9b7
Author: William Jon McCann <jmccann redhat com>
Date:   Sun May 20 13:37:16 2012 -0400

    Add a way to create a new directory from a selection
    
    https://bugzilla.gnome.org/show_bug.cgi?id=676432

 src/nautilus-actions.h             |    1 +
 src/nautilus-directory-view-ui.xml |    5 ++
 src/nautilus-view.c                |  141 +++++++++++++++++++++++++++++++-----
 3 files changed, 130 insertions(+), 17 deletions(-)
---
diff --git a/src/nautilus-actions.h b/src/nautilus-actions.h
index 05d45d1..d6c02d7 100644
--- a/src/nautilus-actions.h
+++ b/src/nautilus-actions.h
@@ -66,6 +66,7 @@
 #define NAUTILUS_ACTION_OTHER_APPLICATION1 "OtherApplication1"
 #define NAUTILUS_ACTION_OTHER_APPLICATION2 "OtherApplication2"
 #define NAUTILUS_ACTION_NEW_FOLDER "New Folder"
+#define NAUTILUS_ACTION_NEW_FOLDER_WITH_SELECTION "New Folder with Selection"
 #define NAUTILUS_ACTION_PROPERTIES "Properties"
 #define NAUTILUS_ACTION_PROPERTIES_ACCEL "PropertiesAccel"
 #define NAUTILUS_ACTION_LOCATION_PROPERTIES "LocationProperties"
diff --git a/src/nautilus-directory-view-ui.xml b/src/nautilus-directory-view-ui.xml
index 30dc7e2..97fadab 100644
--- a/src/nautilus-directory-view-ui.xml
+++ b/src/nautilus-directory-view-ui.xml
@@ -7,6 +7,7 @@
 	<menu action="File">
 		<placeholder name="New Items Placeholder">
 			<menuitem name="New Folder" action="New Folder"/>
+			<menuitem name="New Folder with Selection" action="New Folder with Selection"/>
 			<menu action="New Documents">
 			         <menuitem name="No Templates" action="No Templates"/>
 				 <placeholder name="New Documents Placeholder"/>
@@ -132,6 +133,10 @@
 
 </popup>
 <popup name="selection">
+        <placeholder name="New Object Items">
+	        <menuitem name="New Folder with Selection" action="New Folder with Selection"/>
+		<separator name="new folder with selection separator"/>
+	</placeholder>
 	<placeholder name="Open Placeholder">
 		<menuitem name="Open" action="Open"/>
 		<menuitem name="OpenInNewTab" action="OpenInNewTab"/>
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index 34a7191..ba25e71 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -1779,8 +1779,42 @@ reveal_newly_added_folder (NautilusView *view, NautilusFile *new_file,
 typedef struct {
 	NautilusView *directory_view;
 	GHashTable *added_locations;
+	GList *selection;
 } NewFolderData;
 
+typedef struct {
+	NautilusView *directory_view;
+	GHashTable *to_remove_locations;
+	NautilusFile *new_folder;
+} NewFolderSelectionData;
+
+static void
+rename_newly_added_folder (NautilusView *view, NautilusFile *removed_file,
+			   NautilusDirectory *directory, NewFolderSelectionData *data);
+
+static void
+rename_newly_added_folder (NautilusView *view, NautilusFile *removed_file,
+			   NautilusDirectory *directory, NewFolderSelectionData *data)
+{
+	GFile *location;
+
+	location = nautilus_file_get_location (removed_file);
+	if (!g_hash_table_remove (data->to_remove_locations, location)) {
+		g_assert_not_reached ();
+	}
+	g_object_unref (location);
+	if (g_hash_table_size (data->to_remove_locations) == 0) {
+		nautilus_view_set_selection (data->directory_view, NULL);
+		g_signal_handlers_disconnect_by_func (data->directory_view,
+						      G_CALLBACK (rename_newly_added_folder),
+						      (void *) data);
+
+		rename_file (data->directory_view, data->new_folder);
+		g_object_unref (data->new_folder);
+		g_hash_table_destroy (data->to_remove_locations);
+		g_free (data);
+	}
+}
 
 static void
 track_newly_added_locations (NautilusView *view, NautilusFile *new_file,
@@ -1830,21 +1864,65 @@ new_folder_done (GFile *new_folder,
 		 NULL,
 		 screen_string);
 
-	if (g_hash_table_lookup_extended (data->added_locations, new_folder, NULL, NULL)) {
-		/* The file was already added */
-		rename_file (directory_view, file);
-	} else {
-		/* We need to run after the default handler adds the folder we want to
-		 * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
-		 * must use connect_after.
-		 */
+	if (data->selection != NULL) {
+		NewFolderSelectionData *sdata;
+		GList *uris, *l;
+
+		sdata = g_new (NewFolderSelectionData, 1);
+		sdata->directory_view = directory_view;
+		sdata->to_remove_locations = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
+								    g_object_unref, NULL);
+		sdata->new_folder = g_object_ref (file);
+
+		uris = NULL;
+		for (l = data->selection; l != NULL; l = l->next) {
+			GFile *old_location;
+			GFile *new_location;
+			char *basename;
+
+			uris = g_list_prepend (uris, nautilus_file_get_uri ((NautilusFile *) l->data));
+
+			old_location = nautilus_file_get_location (l->data);
+			basename = g_file_get_basename (old_location);
+			new_location = g_file_resolve_relative_path (new_folder, basename);
+			g_hash_table_insert (sdata->to_remove_locations, new_location, NULL);
+			g_free (basename);
+			g_object_unref (old_location);
+		}
+		uris = g_list_reverse (uris);
+
 		g_signal_connect_data (directory_view,
-				       "add_file",
-				       G_CALLBACK (reveal_newly_added_folder),
-				       g_object_ref (new_folder),
-				       (GClosureNotify)g_object_unref,
+				       "remove_file",
+				       G_CALLBACK (rename_newly_added_folder),
+				       sdata,
+				       (GClosureNotify)NULL,
 				       G_CONNECT_AFTER);
+
+		nautilus_view_move_copy_items (directory_view,
+					       uris,
+					       NULL,
+					       nautilus_file_get_uri (file),
+					       GDK_ACTION_MOVE,
+					       0, 0);
+		g_list_free_full (uris, g_free);
+	} else {
+		if (g_hash_table_lookup_extended (data->added_locations, new_folder, NULL, NULL)) {
+			/* The file was already added */
+			rename_file (directory_view, file);
+		} else {
+			/* We need to run after the default handler adds the folder we want to
+			 * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
+			 * must use connect_after.
+			 */
+			g_signal_connect_data (directory_view,
+					       "add_file",
+					       G_CALLBACK (reveal_newly_added_folder),
+					       g_object_ref (new_folder),
+					       (GClosureNotify)g_object_unref,
+					       G_CONNECT_AFTER);
+		}
 	}
+
 	nautilus_file_unref (file);
 
  fail:
@@ -1855,12 +1933,14 @@ new_folder_done (GFile *new_folder,
 					      (gpointer *) &data->directory_view);
 	}
 
+        nautilus_file_list_free (data->selection);
 	g_free (data);
 }
 
 
 static NewFolderData *
-new_folder_data_new (NautilusView *directory_view)
+new_folder_data_new (NautilusView *directory_view,
+		     gboolean      with_selection)
 {
 	NewFolderData *data;
 
@@ -1868,6 +1948,11 @@ new_folder_data_new (NautilusView *directory_view)
 	data->directory_view = directory_view;
 	data->added_locations = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
 						       g_object_unref, NULL);
+	if (with_selection) {
+		data->selection = nautilus_view_get_selection_for_file_transfer (directory_view);
+	} else {
+		data->selection = NULL;
+	}
 	g_object_add_weak_pointer (G_OBJECT (data->directory_view),
 				   (gpointer *) &data->directory_view);
 
@@ -1891,13 +1976,14 @@ context_menu_to_file_operation_position (NautilusView *view)
 }
 
 static void
-nautilus_view_new_folder (NautilusView *directory_view)
+nautilus_view_new_folder (NautilusView *directory_view,
+			  gboolean      with_selection)
 {
 	char *parent_uri;
 	NewFolderData *data;
 	GdkPoint *pos;
 
-	data = new_folder_data_new (directory_view);
+	data = new_folder_data_new (directory_view, with_selection);
 
 	g_signal_connect_data (directory_view,
 			       "add_file",
@@ -1921,7 +2007,7 @@ setup_new_folder_data (NautilusView *directory_view)
 {
 	NewFolderData *data;
 
-	data = new_folder_data_new (directory_view);
+	data = new_folder_data_new (directory_view, FALSE);
 
 	g_signal_connect_data (directory_view,
 			       "add_file",
@@ -2009,7 +2095,16 @@ action_new_folder_callback (GtkAction *action,
 {                
         g_assert (NAUTILUS_IS_VIEW (callback_data));
 
-	nautilus_view_new_folder (NAUTILUS_VIEW (callback_data));
+	nautilus_view_new_folder (NAUTILUS_VIEW (callback_data), FALSE);
+}
+
+static void
+action_new_folder_with_selection_callback (GtkAction *action,
+					   gpointer callback_data)
+{                
+        g_assert (NAUTILUS_IS_VIEW (callback_data));
+
+	nautilus_view_new_folder (NAUTILUS_VIEW (callback_data), TRUE);
 }
 
 static void
@@ -6988,6 +7083,10 @@ static const GtkActionEntry directory_view_entries[] = {
   /* label, accelerator */       N_("Create New _Folder"), "<control><shift>N",
   /* tooltip */                  N_("Create a new empty folder inside this folder"),
 				 G_CALLBACK (action_new_folder_callback) },
+  /* name, stock id */         { NAUTILUS_ACTION_NEW_FOLDER_WITH_SELECTION, NULL,
+  /* label, accelerator */       N_("Create New Folder with Selection"), NULL,
+  /* tooltip */                  N_("Create a new folder containing the selected items"),
+				 G_CALLBACK (action_new_folder_with_selection_callback) },
   /* name, stock id, label */  { "No Templates", NULL, N_("No templates installed") },
   /* name, stock id */         { "New Empty Document", NULL,
     /* translators: this is used to indicate that a document doesn't contain anything */
@@ -8363,6 +8462,14 @@ real_update_menus (NautilusView *view)
 	gtk_action_set_sensitive (action, can_create_files);
 
 	action = gtk_action_group_get_action (view->details->dir_action_group,
+					      NAUTILUS_ACTION_NEW_FOLDER_WITH_SELECTION);
+	gtk_action_set_sensitive (action, can_create_files && can_delete_files && (selection_count > 1));
+	gtk_action_set_visible (action, selection_count > 1);
+	label_with_underscore = g_strdup_printf (_("Create New Folder with Selection (%d Items)"), selection_count);
+	g_object_set (action, "label", label_with_underscore, NULL);
+	g_free (label_with_underscore);
+
+	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      NAUTILUS_ACTION_OPEN);
 	gtk_action_set_sensitive (action, selection_count != 0);
 	



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