nautilus r14328 - in trunk: . libnautilus-private src src/file-manager



Author: cneumair
Date: Tue Jul  8 21:05:55 2008
New Revision: 14328
URL: http://svn.gnome.org/viewvc/nautilus?rev=14328&view=rev

Log:
2008-07-08  Christian Neumair  <cneumair gnome org>

	* libnautilus-private/*.c:
	* src/*.c:
	Merge "multiview" tab branch. Fixes #48034.


Added:
   trunk/libnautilus-private/nautilus-window-slot-info.c
   trunk/src/nautilus-navigation-window-slot.c
   trunk/src/nautilus-navigation-window-slot.h
   trunk/src/nautilus-notebook.c
   trunk/src/nautilus-notebook.h
   trunk/src/nautilus-window-slot.c
   trunk/src/nautilus-window-slot.h
Modified:
   trunk/ChangeLog
   trunk/libnautilus-private/Makefile.am
   trunk/libnautilus-private/apps_nautilus_preferences.schemas.in
   trunk/libnautilus-private/nautilus-global-preferences.c
   trunk/libnautilus-private/nautilus-global-preferences.h
   trunk/libnautilus-private/nautilus-icon-container.c
   trunk/libnautilus-private/nautilus-icon-dnd.c
   trunk/libnautilus-private/nautilus-mime-actions.c
   trunk/libnautilus-private/nautilus-mime-actions.h
   trunk/libnautilus-private/nautilus-view-factory.c
   trunk/libnautilus-private/nautilus-view-factory.h
   trunk/libnautilus-private/nautilus-view.c
   trunk/libnautilus-private/nautilus-view.h
   trunk/libnautilus-private/nautilus-window-info.c
   trunk/libnautilus-private/nautilus-window-info.h
   trunk/src/Makefile.am
   trunk/src/ephy-spinner.c
   trunk/src/ephy-spinner.h
   trunk/src/file-manager/fm-actions.h
   trunk/src/file-manager/fm-desktop-icon-view.c
   trunk/src/file-manager/fm-directory-view.c
   trunk/src/file-manager/fm-directory-view.h
   trunk/src/file-manager/fm-empty-view.c
   trunk/src/file-manager/fm-icon-view.c
   trunk/src/file-manager/fm-list-view.c
   trunk/src/file-manager/fm-tree-model.c
   trunk/src/file-manager/fm-tree-model.h
   trunk/src/file-manager/fm-tree-view.c
   trunk/src/file-manager/nautilus-directory-view-ui.xml
   trunk/src/nautilus-actions.h
   trunk/src/nautilus-application.c
   trunk/src/nautilus-desktop-window.c
   trunk/src/nautilus-history-sidebar.c
   trunk/src/nautilus-information-panel.c
   trunk/src/nautilus-location-bar.c
   trunk/src/nautilus-location-dialog.c
   trunk/src/nautilus-navigation-action.c
   trunk/src/nautilus-navigation-window-menus.c
   trunk/src/nautilus-navigation-window-ui.xml
   trunk/src/nautilus-navigation-window.c
   trunk/src/nautilus-navigation-window.h
   trunk/src/nautilus-notes-viewer.c
   trunk/src/nautilus-pathbar.c
   trunk/src/nautilus-places-sidebar.c
   trunk/src/nautilus-query-editor.c
   trunk/src/nautilus-query-editor.h
   trunk/src/nautilus-spatial-window.c
   trunk/src/nautilus-window-bookmarks.c
   trunk/src/nautilus-window-manage-views.c
   trunk/src/nautilus-window-manage-views.h
   trunk/src/nautilus-window-menus.c
   trunk/src/nautilus-window-private.h
   trunk/src/nautilus-window-toolbars.c
   trunk/src/nautilus-window.c
   trunk/src/nautilus-window.h

Modified: trunk/libnautilus-private/Makefile.am
==============================================================================
--- trunk/libnautilus-private/Makefile.am	(original)
+++ trunk/libnautilus-private/Makefile.am	Tue Jul  8 21:05:55 2008
@@ -194,6 +194,8 @@
 	nautilus-view.h \
 	nautilus-window-info.c \
 	nautilus-window-info.h \
+	nautilus-window-slot-info.c \
+	nautilus-window-slot-info.h \
 	$(NULL)
 
 BEAGLE_SOURCES = \

Modified: trunk/libnautilus-private/apps_nautilus_preferences.schemas.in
==============================================================================
--- trunk/libnautilus-private/apps_nautilus_preferences.schemas.in	(original)
+++ trunk/libnautilus-private/apps_nautilus_preferences.schemas.in	Tue Jul  8 21:05:55 2008
@@ -69,6 +69,36 @@
     </schema>
 
     <schema>
+      <key>/schemas/desktop/gnome/file_views/tabs_enable</key>
+      <applyto>/desktop/gnome/file_views/tabs_enable</applyto>
+      <owner>nautilus</owner>
+      <type>bool</type>
+      <default>true</default>
+      <locale name="C">
+         <short>Whether to enable tabs in Nautilus browser windows</short>
+         <long>
+          If set to true, then multiple views can be opened in one browser window,
+	  each in a separate tab.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/desktop/gnome/file_views/tabs_open_position</key>
+      <applyto>/desktop/gnome/file_views/tabs_open_position</applyto>
+      <owner>nautilus</owner>
+      <type>string</type>
+      <default>after_current_tab</default>
+      <locale name="C">
+         <short>Where to position newly open tabs in browser windows.</short>
+         <long>
+          If set to "after_current_tab", then new tabs are inserted after the current tab.
+          If set to "end", then new tabs are appended to the end of the tab list.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/nautilus/preferences/media_automount</key>
       <applyto>/apps/nautilus/preferences/media_automount</applyto>
       <owner>nautilus</owner>

Modified: trunk/libnautilus-private/nautilus-global-preferences.c
==============================================================================
--- trunk/libnautilus-private/nautilus-global-preferences.c	(original)
+++ trunk/libnautilus-private/nautilus-global-preferences.c	Tue Jul  8 21:05:55 2008
@@ -171,6 +171,11 @@
 	{ "informal",	   "Informal",		NAUTILUS_DATE_FORMAT_INFORMAL }
 };
 
+static EelEnumerationEntry new_tab_position_entries[] = {
+	{ "after_current_tab",  "After Current Tab",	NAUTILUS_NEW_TAB_POSITION_AFTER_CURRENT_TAB },
+	{ "end",		"End",			NAUTILUS_NEW_TAB_POSITION_END }
+};
+
 /*
  * A callback which can be used to fetch dynamic fallback values.
  * For example, values that are dependent on the environment (such as user name) 
@@ -333,6 +338,16 @@
 	  PREFERENCE_BOOLEAN,
 	  GINT_TO_POINTER (FALSE)
 	},
+	{ NAUTILUS_PREFERENCES_ENABLE_TABS,
+	  PREFERENCE_BOOLEAN,
+	  GINT_TO_POINTER (TRUE)
+	},
+	{ NAUTILUS_PREFERENCES_NEW_TAB_POSITION,
+	  PREFERENCE_STRING,
+	  "after_current_tab",
+	  NULL, NULL,
+	  "new_tab_position"
+	},
 	{ NAUTILUS_PREFERENCES_START_WITH_TOOLBAR,
 	  PREFERENCE_BOOLEAN,
 	  GINT_TO_POINTER (TRUE)
@@ -604,6 +619,9 @@
 	eel_enumeration_register ("date_format",
 				  date_format_entries,
 				  G_N_ELEMENTS (date_format_entries));
+	eel_enumeration_register ("new_tab_position",
+				  new_tab_position_entries,
+				  G_N_ELEMENTS (new_tab_position_entries));
 
 	/* Set the enumeration ids for preferences that need them */
 	for (i = 0; preference_defaults[i].name != NULL; i++) {

Modified: trunk/libnautilus-private/nautilus-global-preferences.h
==============================================================================
--- trunk/libnautilus-private/nautilus-global-preferences.h	(original)
+++ trunk/libnautilus-private/nautilus-global-preferences.h	Tue Jul  8 21:05:55 2008
@@ -78,6 +78,12 @@
 	NAUTILUS_DATE_FORMAT_INFORMAL
 } NautilusDateFormat;
 
+typedef enum
+{
+	NAUTILUS_NEW_TAB_POSITION_AFTER_CURRENT_TAB,
+	NAUTILUS_NEW_TAB_POSITION_END,
+} NautilusNewTabPosition;
+
 /* Sidebar panels  */
 #define NAUTILUS_PREFERENCES_TREE_SHOW_ONLY_DIRECTORIES         "sidebar_panels/tree/show_only_directories"
 
@@ -89,6 +95,8 @@
 
 /* Spatial or browser mode */
 #define NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER       		"preferences/always_use_browser"
+#define NAUTILUS_PREFERENCES_ENABLE_TABS       			"preferences/tabs_enable"
+#define NAUTILUS_PREFERENCES_NEW_TAB_POSITION       		"preferences/tabs_open_position"
 
 /* Which views should be displayed for new windows */
 #define NAUTILUS_PREFERENCES_START_WITH_LOCATION_BAR		"preferences/start_with_location_bar"

Modified: trunk/libnautilus-private/nautilus-icon-container.c
==============================================================================
--- trunk/libnautilus-private/nautilus-icon-container.c	(original)
+++ trunk/libnautilus-private/nautilus-icon-container.c	Tue Jul  8 21:05:55 2008
@@ -3365,7 +3365,8 @@
 		keyboard_move_to (container,
 				  container->details->keyboard_focus,
 				  NULL, NULL);
-	} else if ((event->state & GDK_CONTROL_MASK) != 0) {
+	} else if ((event->state & GDK_CONTROL_MASK) != 0 &&
+		   (event->state & GDK_SHIFT_MASK) == 0) {
 		/* Control-space toggles the selection state of the current icon. */
 		if (container->details->keyboard_focus != NULL) {
 			icon_toggle_selected (container, container->details->keyboard_focus);

Modified: trunk/libnautilus-private/nautilus-icon-dnd.c
==============================================================================
--- trunk/libnautilus-private/nautilus-icon-dnd.c	(original)
+++ trunk/libnautilus-private/nautilus-icon-dnd.c	Tue Jul  8 21:05:55 2008
@@ -1660,7 +1660,7 @@
 
 	get_data_on_first_target_we_support (widget, context, time, x, y);
 	
-	return FALSE;
+	return TRUE;
 }
 
 void

Modified: trunk/libnautilus-private/nautilus-mime-actions.c
==============================================================================
--- trunk/libnautilus-private/nautilus-mime-actions.c	(original)
+++ trunk/libnautilus-private/nautilus-mime-actions.c	Tue Jul  8 21:05:55 2008
@@ -59,7 +59,8 @@
 } ApplicationLaunchParameters;
 
 typedef struct {
-	NautilusWindowInfo *window_info;
+	NautilusWindowSlotInfo *slot_info;
+	gpointer window_info;
 	GtkWindow *parent_window;
 	GCancellable *cancellable;
 	GList *files;
@@ -72,6 +73,7 @@
 	NautilusFileListHandle *files_handle;
 	gboolean tried_mounting;
 	char *activation_directory;
+	gboolean user_confirmation;
 } ActivateParameters;
 
 /* Number of seconds until cancel dialog shows up */
@@ -910,8 +912,8 @@
 		eel_timed_wait_stop (cancel_activate_callback, parameters);
 	}
 	
-	if (parameters->window_info) {
-		g_object_remove_weak_pointer (G_OBJECT (parameters->window_info), (gpointer *)&parameters->window_info);
+	if (parameters->slot_info) {
+		g_object_remove_weak_pointer (G_OBJECT (parameters->slot_info), (gpointer *)&parameters->slot_info);
 	}
 	if (parameters->parent_window) {
 		g_object_remove_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *)&parameters->parent_window);
@@ -972,7 +974,9 @@
 }
 
 static gboolean
-confirm_multiple_windows (GtkWindow *parent_window, int count)
+confirm_multiple_windows (GtkWindow *parent_window,
+			  int count,
+			  gboolean use_tabs)
 {
 	GtkDialog *dialog;
 	char *prompt;
@@ -984,8 +988,13 @@
 	}
 
 	prompt = _("Are you sure you want to open all files?");
-	detail = g_strdup_printf (ngettext("This will open %d separate window.",
-					   "This will open %d separate windows.", count), count);
+	if (use_tabs) {
+		detail = g_strdup_printf (ngettext("This will open %d separate tab.",
+						   "This will open %d separate tabs.", count), count);
+	} else {
+		detail = g_strdup_printf (ngettext("This will open %d separate window.",
+						   "This will open %d separate windows.", count), count);
+	}
 	dialog = eel_show_yes_no_dialog (prompt, detail, 
 					 GTK_STOCK_OK, GTK_STOCK_CANCEL,
 					 parent_window);
@@ -1000,6 +1009,8 @@
 static void
 activate_files (ActivateParameters *parameters)
 {
+	NautilusWindowInfo *window_info;
+	NautilusWindowOpenFlags flags;
 	NautilusFile *file;
 	GList *launch_desktop_files;
 	GList *launch_files;
@@ -1133,14 +1144,33 @@
 
 	open_in_view_files = g_list_reverse (open_in_view_files);
 	count = g_list_length (open_in_view_files);
-	if (parameters->window_info != NULL &&
-	    confirm_multiple_windows (parameters->parent_window, count)) {
-		NautilusWindowOpenFlags flags;
 
-		flags = parameters->flags;
-		if (count > 1) {
+	flags = parameters->flags;
+	if (count > 1) {
+		if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS) &&
+		    (parameters->flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) == 0) {
+			flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
+		} else {
 			flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
 		}
+	}
+
+	if (parameters->slot_info != NULL &&
+	    (!parameters->user_confirmation ||
+	     confirm_multiple_windows (parameters->parent_window, count,
+				       (flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB) != 0))) {
+
+		if ((flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB) != 0 &&
+		    eel_preferences_get_enum (NAUTILUS_PREFERENCES_NEW_TAB_POSITION) ==
+		    NAUTILUS_NEW_TAB_POSITION_AFTER_CURRENT_TAB) {
+			/* When inserting N tabs after the current one,
+			 * we first open tab N, then tab N-1, ..., then tab 0.
+			 * Each of them is appended to the current tab, i.e.
+			 * prepended to the list of tabs to open.
+			 */
+			open_in_view_files = g_list_reverse (open_in_view_files);
+		}
+
 
 		for (l = open_in_view_files; l != NULL; l = l->next) {
 			GFile *f;
@@ -1150,8 +1180,8 @@
 
 			uri = nautilus_file_get_activation_uri (file);
 			f = g_file_new_for_uri (uri);
-			nautilus_window_info_open_location (parameters->window_info,
-							    f, parameters->mode, flags, NULL);
+			nautilus_window_slot_info_open_location (parameters->slot_info,
+								 f, parameters->mode, flags, NULL);
 			g_object_unref (f);
 			g_free (uri);
 		}
@@ -1207,12 +1237,17 @@
 		g_free (error_message);
 	}
 
+	window_info = NULL;
+	if (parameters->slot_info != NULL) {
+		window_info = nautilus_window_slot_info_get_window (parameters->slot_info);
+	}
+
 	if (open_in_app_parameters != NULL ||
 	    unhandled_open_in_app_files != NULL) {
 		if ((parameters->flags & NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND) != 0 &&
-		    parameters->window_info != NULL && 
-		     nautilus_window_info_get_window_type (parameters->window_info) == NAUTILUS_WINDOW_SPATIAL) {
-			nautilus_window_info_close (parameters->window_info);
+		    window_info != NULL && 
+		     nautilus_window_info_get_window_type (window_info) == NAUTILUS_WINDOW_SPATIAL) {
+			nautilus_window_info_close (window_info);
 		}
 	}
 
@@ -1460,6 +1495,7 @@
 {
 	ActivateParameters *parameters = callback_data;
 	NautilusFile *target_file;
+	int position;
 
 	/* Remove from list of files that have to be mounted */
 	parameters->mountables = g_list_remove (parameters->mountables, file); 
@@ -1467,13 +1503,16 @@
 
 	if (error == NULL) {
 		/* Replace file with the result of the mount */
-		
 		target_file = nautilus_file_get (result_location);
 		
+		position = g_list_index (parameters->files, file);
+
 		parameters->files = g_list_remove (parameters->files, file); 
 		nautilus_file_unref (file);
 		
-		parameters->files = g_list_prepend (parameters->files, target_file);
+		parameters->files = g_list_insert (parameters->files,
+						   target_file,
+						   position);
 	} else {
 		/* Remove failed file */
 		
@@ -1537,11 +1576,12 @@
  **/
 void
 nautilus_mime_activate_files (GtkWindow *parent_window,
-			      NautilusWindowInfo *window_info,
+			      NautilusWindowSlotInfo *slot_info,
 			      GList *files,
 			      const char *launch_directory,
 			      NautilusWindowOpenMode mode,
-			      NautilusWindowOpenFlags flags)
+			      NautilusWindowOpenFlags flags,
+			      gboolean user_confirmation)
 {
 	ActivateParameters *parameters;
 	char *file_name;
@@ -1558,8 +1598,8 @@
 					   parent_window);
 
 	parameters = g_new0 (ActivateParameters, 1);
-	parameters->window_info = window_info;
-	g_object_add_weak_pointer (G_OBJECT (parameters->window_info), (gpointer *)&parameters->window_info);
+	parameters->slot_info = slot_info;
+	g_object_add_weak_pointer (G_OBJECT (parameters->slot_info), (gpointer *)&parameters->slot_info);
 	if (parent_window) {
 		parameters->parent_window = parent_window;
 		g_object_add_weak_pointer (G_OBJECT (parameters->parent_window), (gpointer *)&parameters->parent_window);
@@ -1569,6 +1609,7 @@
 	parameters->files = nautilus_file_list_copy (files);
 	parameters->mode = mode;
 	parameters->flags = flags;
+	parameters->user_confirmation = user_confirmation;
 
 	file_count = g_list_length (files);
 	if (file_count == 1) {
@@ -1610,7 +1651,7 @@
 
 void
 nautilus_mime_activate_file (GtkWindow *parent_window,
-			     NautilusWindowInfo *window_info,
+			     NautilusWindowSlotInfo *slot_info,
 			     NautilusFile *file,
 			     const char *launch_directory,
 			     NautilusWindowOpenMode mode,
@@ -1621,6 +1662,6 @@
 	g_return_if_fail (NAUTILUS_IS_FILE (file));
 
 	files = g_list_prepend (NULL, file);
-	nautilus_mime_activate_files (parent_window, window_info, files, launch_directory, mode, flags);
+	nautilus_mime_activate_files (parent_window, slot_info, files, launch_directory, mode, flags, FALSE);
 	g_list_free (files);
 }

Modified: trunk/libnautilus-private/nautilus-mime-actions.h
==============================================================================
--- trunk/libnautilus-private/nautilus-mime-actions.h	(original)
+++ trunk/libnautilus-private/nautilus-mime-actions.h	Tue Jul  8 21:05:55 2008
@@ -29,6 +29,7 @@
 
 #include <libnautilus-private/nautilus-file.h>
 #include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
 
 NautilusFileAttributes nautilus_mime_actions_get_required_file_attributes (void);
 
@@ -44,13 +45,14 @@
 gboolean               nautilus_mime_file_opens_in_view                   (NautilusFile            *file);
 gboolean               nautilus_mime_file_opens_in_external_app           (NautilusFile            *file);
 void                   nautilus_mime_activate_files                       (GtkWindow               *parent_window,
-									   NautilusWindowInfo      *window_info,
+									   NautilusWindowSlotInfo  *slot_info,
 									   GList                   *files,
 									   const char              *launch_directory,
 									   NautilusWindowOpenMode   mode,
-									   NautilusWindowOpenFlags  flags);
+									   NautilusWindowOpenFlags  flags,
+									   gboolean                 user_confirmation);
 void                   nautilus_mime_activate_file                        (GtkWindow               *parent_window,
-									   NautilusWindowInfo      *window_info,
+									   NautilusWindowSlotInfo  *slot_info,
 									   NautilusFile            *file,
 									   const char              *launch_directory,
 									   NautilusWindowOpenMode   mode,

Modified: trunk/libnautilus-private/nautilus-view-factory.c
==============================================================================
--- trunk/libnautilus-private/nautilus-view-factory.c	(original)
+++ trunk/libnautilus-private/nautilus-view-factory.c	Tue Jul  8 21:05:55 2008
@@ -57,7 +57,7 @@
 
 NautilusView *
 nautilus_view_factory_create (const char *id,
-			      NautilusWindowInfo *window)
+			      NautilusWindowSlotInfo *slot)
 {
 	const NautilusViewInfo *view_info;
 
@@ -66,7 +66,7 @@
 		return NULL;
 	}
 
-	return view_info->create (window);
+	return view_info->create (slot);
 }
 
 gboolean

Modified: trunk/libnautilus-private/nautilus-view-factory.h
==============================================================================
--- trunk/libnautilus-private/nautilus-view-factory.h	(original)
+++ trunk/libnautilus-private/nautilus-view-factory.h	Tue Jul  8 21:05:55 2008
@@ -28,7 +28,7 @@
 #include <string.h>
 
 #include <libnautilus-private/nautilus-view.h>
-#include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
 #include <gio/gio.h>
 
 G_BEGIN_DECLS
@@ -42,7 +42,7 @@
 	char *error_label;                 /* The foo view encountered an error. */
 	char *startup_error_label;         /* The foo view encountered an error while starting up. */
 	char *display_location_label;      /* Display this location with the foo view. */
-	NautilusView * (*create) (NautilusWindowInfo *window);
+	NautilusView * (*create) (NautilusWindowSlotInfo *slot);
 	/* BONOBOTODO: More args here */
 	gboolean (*supports_uri) (const char *uri,
 				  GFileType file_type,
@@ -53,7 +53,7 @@
 void                    nautilus_view_factory_register          (NautilusViewInfo   *view_info);
 const NautilusViewInfo *nautilus_view_factory_lookup            (const char         *id);
 NautilusView *          nautilus_view_factory_create            (const char         *id,
-								 NautilusWindowInfo *window);
+								 NautilusWindowSlotInfo *slot);
 gboolean                nautilus_view_factory_view_supports_uri (const char         *id,
 								 GFile              *location,
 								 GFileType          file_type,

Modified: trunk/libnautilus-private/nautilus-view.c
==============================================================================
--- trunk/libnautilus-private/nautilus-view.c	(original)
+++ trunk/libnautilus-private/nautilus-view.c	Tue Jul  8 21:05:55 2008
@@ -278,3 +278,17 @@
 		(* NAUTILUS_VIEW_GET_IFACE (view)->pop_up_location_context_menu) (view, event, location);
 	}
 }
+
+void
+nautilus_view_drop_proxy_received_uris   (NautilusView         *view,
+					  GList                *uris,
+					  const char           *target_location,
+					  GdkDragAction         action)
+{
+	g_return_if_fail (NAUTILUS_IS_VIEW (view));
+
+	if (NAUTILUS_VIEW_GET_IFACE (view)->drop_proxy_received_uris != NULL) {
+		(* NAUTILUS_VIEW_GET_IFACE (view)->drop_proxy_received_uris) (view, uris, target_location, action);
+	}
+}
+

Modified: trunk/libnautilus-private/nautilus-view.h
==============================================================================
--- trunk/libnautilus-private/nautilus-view.h	(original)
+++ trunk/libnautilus-private/nautilus-view.h	Tue Jul  8 21:05:55 2008
@@ -123,6 +123,11 @@
 							 GdkEventButton *event,
 							 const char     *location);
 
+	void           (* drop_proxy_received_uris)     (NautilusView         *view,
+							 GList                *uris,
+							 const char           *target_location,
+							 GdkDragAction         action);
+
 	/* Padding for future expansion */
 	void (*_reserved1) (void);
 	void (*_reserved2) (void);
@@ -162,6 +167,10 @@
 							      GdkEventButton  *event,
 							      const char      *location);
 void              nautilus_view_grab_focus                 (NautilusView      *view);
+void              nautilus_view_drop_proxy_received_uris   (NautilusView         *view,
+							    GList                *uris,
+							    const char           *target_location,
+							    GdkDragAction         action);
 
 G_END_DECLS
 

Modified: trunk/libnautilus-private/nautilus-window-info.c
==============================================================================
--- trunk/libnautilus-private/nautilus-window-info.c	(original)
+++ trunk/libnautilus-private/nautilus-window-info.c	Tue Jul  8 21:05:55 2008
@@ -152,22 +152,6 @@
 }
 
 void
-nautilus_window_info_open_location (NautilusWindowInfo      *window,
-				    GFile                   *location,
-				    NautilusWindowOpenMode   mode,
-				    NautilusWindowOpenFlags  flags,
-				    GList                   *selection)
-{
-	g_return_if_fail (NAUTILUS_IS_WINDOW_INFO (window));
-
-	(* NAUTILUS_WINDOW_INFO_GET_IFACE (window)->open_location) (window,
-								  location,
-								  mode,
-								  flags,
-								  selection);
-}
-
-void
 nautilus_window_info_show_window (NautilusWindowInfo      *window)
 {
 	g_return_if_fail (NAUTILUS_IS_WINDOW_INFO (window));
@@ -184,13 +168,13 @@
 }
 
 void
-nautilus_window_info_set_status (NautilusWindowInfo      *window,
-				 const char              *status)
+nautilus_window_info_push_status (NautilusWindowInfo      *window,
+				  const char              *status)
 {
 	g_return_if_fail (NAUTILUS_IS_WINDOW_INFO (window));
 
-	(* NAUTILUS_WINDOW_INFO_GET_IFACE (window)->set_status) (window,
-							       status);
+	(* NAUTILUS_WINDOW_INFO_GET_IFACE (window)->push_status) (window,
+								  status);
 }
 
 NautilusWindowType
@@ -276,3 +260,11 @@
 	return (* NAUTILUS_WINDOW_INFO_GET_IFACE (window)->get_ui_manager) (window);
 }
 
+NautilusWindowSlotInfo *
+nautilus_window_info_get_active_slot (NautilusWindowInfo *window)
+{
+	g_return_val_if_fail (NAUTILUS_IS_WINDOW_INFO (window), NULL);
+
+	return (* NAUTILUS_WINDOW_INFO_GET_IFACE (window)->get_active_slot) (window);
+}
+

Modified: trunk/libnautilus-private/nautilus-window-info.h
==============================================================================
--- trunk/libnautilus-private/nautilus-window-info.h	(original)
+++ trunk/libnautilus-private/nautilus-window-info.h	Tue Jul  8 21:05:55 2008
@@ -50,7 +50,8 @@
 	/* used in spatial mode */
 	NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND = 1<<0,
 	/* used in navigation mode */
-	NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW = 1<<1
+	NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW = 1<<1,
+	NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB = 1<<2
 } NautilusWindowOpenFlags;
 
 typedef	enum {
@@ -71,6 +72,13 @@
 typedef struct NautilusWindow          NautilusWindow;
 #endif
 
+#ifndef NAUTILUS_WINDOW_SLOT_DEFINED
+#define NAUTILUS_WINDOW_SLOT_DEFINED
+typedef struct NautilusWindowSlot      NautilusWindowSlot;
+#endif
+
+
+typedef NautilusWindowSlot              NautilusWindowSlotInfo;
 typedef NautilusWindow                  NautilusWindowInfo;
 
 typedef struct _NautilusWindowInfoIface NautilusWindowInfoIface;
@@ -115,7 +123,7 @@
 	GList *(* get_selection)      (NautilusWindowInfo    *window);
 
 	char * (* get_current_location)  (NautilusWindowInfo *window);
-	void   (* set_status)            (NautilusWindowInfo *window,
+	void   (* push_status)           (NautilusWindowInfo *window,
 					  const char *status);
 	char * (* get_title)             (NautilusWindowInfo *window);
 	GList *(* get_history)           (NautilusWindowInfo *window);
@@ -128,11 +136,8 @@
 	void   (* set_hidden_files_mode) (NautilusWindowInfo *window,
 				       NautilusWindowShowHiddenFilesMode mode);
 
-	void   (* open_location)      (NautilusWindowInfo *window,
-				       GFile *location,
-				       NautilusWindowOpenMode mode,
-				       NautilusWindowOpenFlags flags,
-				       GList *selection);
+	NautilusWindowSlotInfo * (* get_active_slot) (NautilusWindowInfo *window);
+
 	void   (* show_window)        (NautilusWindowInfo *window);
 	void   (* close_window)       (NautilusWindowInfo *window);
 	GtkUIManager *     (* get_ui_manager)   (NautilusWindowInfo *window);
@@ -146,14 +151,10 @@
 void                              nautilus_window_info_report_view_failed       (NautilusWindowInfo                *window,
 										 NautilusView                      *view);
 void                              nautilus_window_info_report_selection_changed (NautilusWindowInfo                *window);
-void                              nautilus_window_info_open_location            (NautilusWindowInfo                *window,
-										 GFile                             *location,
-										 NautilusWindowOpenMode             mode,
-										 NautilusWindowOpenFlags            flags,
-										 GList                             *selection);
+NautilusWindowSlotInfo *          nautilus_window_info_get_active_slot          (NautilusWindowInfo                *window);
 void                              nautilus_window_info_show_window              (NautilusWindowInfo                *window);
 void                              nautilus_window_info_close                    (NautilusWindowInfo                *window);
-void                              nautilus_window_info_set_status               (NautilusWindowInfo                *window,
+void                              nautilus_window_info_push_status              (NautilusWindowInfo                *window,
 										 const char                        *status);
 NautilusWindowType                nautilus_window_info_get_window_type          (NautilusWindowInfo                *window);
 char *                            nautilus_window_info_get_title                (NautilusWindowInfo                *window);

Added: trunk/libnautilus-private/nautilus-window-slot-info.c
==============================================================================
--- (empty file)
+++ trunk/libnautilus-private/nautilus-window-slot-info.c	Tue Jul  8 21:05:55 2008
@@ -0,0 +1,139 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-window-slot-info.c: Interface for nautilus window slots
+ 
+   Copyright (C) 2008 Free Software Foundation, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Christian Neumair <cneumair gnome org>
+*/
+#include "nautilus-window-slot-info.h"
+
+enum {
+	ACTIVE,
+	INACTIVE,
+	LAST_SIGNAL
+};
+
+static guint nautilus_window_slot_info_signals[LAST_SIGNAL] = { 0 };
+
+static void
+nautilus_window_slot_info_base_init (gpointer g_class)
+{
+	static gboolean initialized = FALSE;
+
+	if (!initialized) {
+		nautilus_window_slot_info_signals[ACTIVE] =
+			g_signal_new ("active",
+				      NAUTILUS_TYPE_WINDOW_SLOT_INFO,
+				      G_SIGNAL_RUN_LAST,
+				      G_STRUCT_OFFSET (NautilusWindowSlotInfoIface, active),
+				      NULL, NULL,
+				      g_cclosure_marshal_VOID__VOID,
+				      G_TYPE_NONE, 0);
+
+		nautilus_window_slot_info_signals[INACTIVE] =
+			g_signal_new ("inactive",
+				      NAUTILUS_TYPE_WINDOW_SLOT_INFO,
+				      G_SIGNAL_RUN_LAST,
+				      G_STRUCT_OFFSET (NautilusWindowSlotInfoIface, inactive),
+				      NULL, NULL,
+				      g_cclosure_marshal_VOID__VOID,
+				      G_TYPE_NONE, 0);
+		
+		initialized = TRUE;
+	}
+}
+
+GType                   
+nautilus_window_slot_info_get_type (void)
+{
+	static GType type = 0;
+	
+	if (!type) {
+		const GTypeInfo info = {
+			sizeof (NautilusWindowSlotInfoIface),
+			nautilus_window_slot_info_base_init,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			0,
+			0,
+			NULL
+		};
+		
+		type = g_type_register_static (G_TYPE_INTERFACE, 
+					       "NautilusWindowSlotInfo",
+					       &info, 0);
+		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+	}
+	
+	return type;
+}
+
+void
+nautilus_window_slot_info_set_status (NautilusWindowSlotInfo *slot,
+				      const char             *status)
+{
+	g_assert (NAUTILUS_IS_WINDOW_SLOT_INFO (slot));
+
+	(* NAUTILUS_WINDOW_SLOT_INFO_GET_IFACE (slot)->set_status) (slot,
+								    status);
+}
+
+
+void
+nautilus_window_slot_info_open_location (NautilusWindowSlotInfo  *slot,
+					 GFile                   *location,
+					 NautilusWindowOpenMode   mode,
+					 NautilusWindowOpenFlags  flags,
+					 GList                   *selection)
+{
+	g_assert (NAUTILUS_IS_WINDOW_SLOT_INFO (slot));
+
+	(* NAUTILUS_WINDOW_SLOT_INFO_GET_IFACE (slot)->open_location) (slot,
+								       location,
+								       mode,
+								       flags,
+								       selection);
+}
+
+char *
+nautilus_window_slot_info_get_title (NautilusWindowSlotInfo *slot)
+{
+	g_assert (NAUTILUS_IS_WINDOW_SLOT_INFO (slot));
+	
+	return (* NAUTILUS_WINDOW_SLOT_INFO_GET_IFACE (slot)->get_title) (slot);
+}
+
+char *
+nautilus_window_slot_info_get_current_location (NautilusWindowSlotInfo *slot)
+{
+	g_assert (NAUTILUS_IS_WINDOW_SLOT_INFO (slot));
+	
+	return (* NAUTILUS_WINDOW_SLOT_INFO_GET_IFACE (slot)->get_current_location) (slot);
+}
+
+NautilusWindowInfo *
+nautilus_window_slot_info_get_window (NautilusWindowSlotInfo *slot)
+{
+	g_assert (NAUTILUS_IS_WINDOW_SLOT_INFO (slot));
+
+	return (* NAUTILUS_WINDOW_SLOT_INFO_GET_IFACE (slot)->get_window) (slot);
+}
+

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Tue Jul  8 21:05:55 2008
@@ -92,6 +92,10 @@
 	nautilus-navigation-window-menus.c      \
 	nautilus-navigation-window.c            \
 	nautilus-navigation-window.h            \
+	nautilus-navigation-window-slot.c	\
+	nautilus-navigation-window-slot.h	\
+	nautilus-notebook.c			\
+	nautilus-notebook.h			\
 	nautilus-notes-viewer.c			\
 	nautilus-notes-viewer.h			\
 	nautilus-pathbar.c			\
@@ -124,6 +128,8 @@
 	nautilus-window-manage-views.h		\
 	nautilus-window-menus.c         	\
 	nautilus-window-private.h		\
+	nautilus-window-slot.c			\
+	nautilus-window-slot.h			\
 	nautilus-window-toolbars.c              \
 	nautilus-window.c			\
 	nautilus-window.h			\

Modified: trunk/src/ephy-spinner.c
==============================================================================
--- trunk/src/ephy-spinner.c	(original)
+++ trunk/src/ephy-spinner.c	Tue Jul  8 21:05:55 2008
@@ -822,6 +822,13 @@
 }
 #endif
 
+gboolean
+ephy_spinner_get_spinning (EphySpinner *spinner)
+{
+	EphySpinnerDetails *details = spinner->details;
+	return details->spinning;
+}
+
 static void
 ephy_spinner_size_request (GtkWidget *widget,
 			   GtkRequisition *requisition)

Modified: trunk/src/ephy-spinner.h
==============================================================================
--- trunk/src/ephy-spinner.h	(original)
+++ trunk/src/ephy-spinner.h	Tue Jul  8 21:05:55 2008
@@ -61,6 +61,8 @@
 
 void		ephy_spinner_stop	(EphySpinner *throbber);
 
+gboolean        ephy_spinner_get_spinning (EphySpinner *spinner);
+
 void		ephy_spinner_set_size	(EphySpinner *spinner,
 					 GtkIconSize size);
 

Modified: trunk/src/file-manager/fm-actions.h
==============================================================================
--- trunk/src/file-manager/fm-actions.h	(original)
+++ trunk/src/file-manager/fm-actions.h	Tue Jul  8 21:05:55 2008
@@ -27,6 +27,7 @@
 
 #define FM_ACTION_OPEN "Open"
 #define FM_ACTION_OPEN_ALTERNATE "OpenAlternate"
+#define FM_ACTION_OPEN_IN_NEW_TAB "OpenInNewTab"
 #define FM_ACTION_OPEN_FOLDER_WINDOW "OpenFolderWindow"
 #define FM_ACTION_LOCATION_OPEN_ALTERNATE "LocationOpenAlternate"
 #define FM_ACTION_LOCATION_OPEN_FOLDER_WINDOW "LocationOpenFolderWindow"

Modified: trunk/src/file-manager/fm-desktop-icon-view.c
==============================================================================
--- trunk/src/file-manager/fm-desktop-icon-view.c	(original)
+++ trunk/src/file-manager/fm-desktop-icon-view.c	Tue Jul  8 21:05:55 2008
@@ -769,11 +769,13 @@
 }
 
 static NautilusView *
-fm_desktop_icon_view_create (NautilusWindowInfo *window)
+fm_desktop_icon_view_create (NautilusWindowSlotInfo *slot)
 {
 	FMIconView *view;
 
-	view = g_object_new (FM_TYPE_DESKTOP_ICON_VIEW, "window", window, NULL);
+	view = g_object_new (FM_TYPE_DESKTOP_ICON_VIEW,
+			     "window-slot", slot,
+			     NULL);
 	g_object_ref (view);
 	gtk_object_sink (GTK_OBJECT (view));
 	return NAUTILUS_VIEW (view);

Modified: trunk/src/file-manager/fm-directory-view.c
==============================================================================
--- trunk/src/file-manager/fm-directory-view.c	(original)
+++ trunk/src/file-manager/fm-directory-view.c	Tue Jul  8 21:05:55 2008
@@ -147,7 +147,7 @@
 enum 
 {
   PROP_0,
-  PROP_WINDOW
+  PROP_WINDOW_SLOT
 };
 
 
@@ -164,6 +164,7 @@
 struct FMDirectoryViewDetails
 {
 	NautilusWindowInfo *window;
+	NautilusWindowSlotInfo *slot;
 	NautilusDirectory *model;
 	NautilusFile *directory_as_file;
 	NautilusFile *location_popup_directory_as_file;
@@ -211,6 +212,9 @@
 
 	GList *pending_locations_selected;
 
+	/* whether we are in the active slot */
+	gboolean active;
+
 	/* loading indicates whether this view has begun loading a directory.
 	 * This flag should need not be set inside subclasses. FMDirectoryView automatically
 	 * sets 'loading' to TRUE before it begins loading a directory's contents and to FALSE
@@ -280,10 +284,15 @@
 static void     load_directory                                 (FMDirectoryView      *view,
 								NautilusDirectory    *directory);
 static void     fm_directory_view_merge_menus                  (FMDirectoryView      *view);
+static void     fm_directory_view_unmerge_menus                (FMDirectoryView      *view);
 static void     fm_directory_view_init_show_hidden_files       (FMDirectoryView      *view);
 static void     fm_directory_view_load_location                (NautilusView         *nautilus_view,
 								const char           *location);
 static void     fm_directory_view_stop_loading                 (NautilusView         *nautilus_view);
+static void     fm_directory_view_drop_proxy_received_uris     (FMDirectoryView *view,
+								GList *uris,
+								const char *target_uri,
+								GdkDragAction action);
 static void     clipboard_changed_callback                     (NautilusClipboardMonitor *monitor,
 								FMDirectoryView      *view);
 static void     open_one_in_new_window                         (gpointer              data,
@@ -299,7 +308,6 @@
 static void     schedule_idle_display_of_pending_files         (FMDirectoryView      *view);
 static void     unschedule_display_of_pending_files            (FMDirectoryView      *view);
 static void     disconnect_model_handlers                      (FMDirectoryView      *view);
-static void     filtering_changed_callback                     (gpointer              callback_data);
 static void     metadata_for_directory_as_file_ready_callback  (NautilusFile         *file,
 								gpointer              callback_data);
 static void     metadata_for_files_in_directory_ready_callback (NautilusDirectory    *directory,
@@ -327,8 +335,6 @@
 						    gpointer   callback_data);
 static void action_rename_select_all_callback      (GtkAction *action,
 						    gpointer   callback_data);
-static void action_show_hidden_files_callback      (GtkAction *action,
-						    gpointer   callback_data);
 static void action_paste_files_into_callback       (GtkAction *action,
 						    gpointer   callback_data);
 static void action_connect_to_server_link_callback (GtkAction *action,
@@ -559,6 +565,13 @@
 	return view->details->window;
 }
 
+NautilusWindowSlotInfo *
+fm_directory_view_get_nautilus_window_slot (FMDirectoryView  *view)
+{
+	g_assert (view->details->slot != NULL);
+
+	return view->details->slot;
+}
 
 
 /* Returns the GtkWindow that this directory view occupies, or NULL
@@ -580,8 +593,10 @@
 	return GTK_WINDOW (window);
 }
 
-gboolean
-fm_directory_view_confirm_multiple_windows (GtkWindow *parent_window, int count)
+static gboolean
+fm_directory_view_confirm_multiple (GtkWindow *parent_window,
+				    int count,
+				    gboolean tabs)
 {
 	GtkDialog *dialog;
 	char *prompt;
@@ -593,8 +608,13 @@
 	}
 
 	prompt = _("Are you sure you want to open all files?");
-	detail = g_strdup_printf (ngettext("This will open %'d separate window.",
-					   "This will open %'d separate windows.", count), count);
+	if (tabs) {
+		detail = g_strdup_printf (ngettext("This will open %'d separate tab.",
+						   "This will open %'d separate tabs.", count), count);
+	} else {
+		detail = g_strdup_printf (ngettext("This will open %'d separate window.",
+						   "This will open %'d separate windows.", count), count);
+	}
 	dialog = eel_show_yes_no_dialog (prompt, detail, 
 					 GTK_STOCK_OK, GTK_STOCK_CANCEL,
 					 parent_window);
@@ -667,17 +687,19 @@
 fm_directory_view_activate_files (FMDirectoryView *view,
 				  GList *files,
 				  NautilusWindowOpenMode mode,
-				  NautilusWindowOpenFlags flags)
+				  NautilusWindowOpenFlags flags,
+				  gboolean confirm_multiple)
 {
 	char *path;
 
 	path = get_view_directory (view);
 	nautilus_mime_activate_files (fm_directory_view_get_containing_window (view),
-				      view->details->window,
+				      view->details->slot,
 				      files,
 				      path,
 				      mode,
-				      flags);
+				      flags,
+				      confirm_multiple);
 
 	g_free (path);
 }
@@ -692,7 +714,7 @@
 
 	path = get_view_directory (view);
 	nautilus_mime_activate_file (fm_directory_view_get_containing_window (view),
-				     view->details->window,
+				     view->details->slot,
 				     file,
 				     path,
 				     mode,
@@ -714,7 +736,8 @@
 	fm_directory_view_activate_files (view,
 					  selection,
 					  NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
-					  0);
+					  0,
+					  TRUE);
 	nautilus_file_list_free (selection);
 }
 
@@ -731,7 +754,8 @@
 	fm_directory_view_activate_files (view,
 					  selection,
 					  NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
-					  NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND);
+					  NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND,
+					  TRUE);
 	nautilus_file_list_free (selection);
 }
 
@@ -749,7 +773,7 @@
 
 	window = fm_directory_view_get_containing_window (view);
 
-	if (fm_directory_view_confirm_multiple_windows (window, g_list_length (selection))) {
+	if (fm_directory_view_confirm_multiple (window, g_list_length (selection), FALSE)) {
 		g_list_foreach (selection, open_one_in_new_window, view);
 	}
 
@@ -757,6 +781,34 @@
 }
 
 static void
+action_open_new_tab_callback (GtkAction *action,
+			      gpointer callback_data)
+{
+	FMDirectoryView *view;
+	GList *selection;
+	GtkWindow *window;
+
+	if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)) {
+		return;
+	}
+
+	view = FM_DIRECTORY_VIEW (callback_data);
+	selection = fm_directory_view_get_selection (view);
+
+	window = fm_directory_view_get_containing_window (view);
+
+	if (fm_directory_view_confirm_multiple (window, g_list_length (selection), TRUE)) {
+		fm_directory_view_activate_files (view,
+						  selection,
+						  NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
+						  NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB,
+						  FALSE);
+	}
+
+	nautilus_file_list_free (selection);
+}
+
+static void
 action_open_folder_window_callback (GtkAction *action,
 				gpointer callback_data)
 {
@@ -769,7 +821,7 @@
 
 	window = fm_directory_view_get_containing_window (view);
 
-	if (fm_directory_view_confirm_multiple_windows (window, g_list_length (selection))) {
+	if (fm_directory_view_confirm_multiple (window, g_list_length (selection), FALSE)) {
 		g_list_foreach (selection, open_one_in_folder_window, view);
 	}
 
@@ -792,8 +844,8 @@
 	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
 			    "directory view open_location window=%p: %s", window, new_uri);
 	location = g_file_new_for_uri (new_uri);
-	nautilus_window_info_open_location (directory_view->details->window,
-					    location, mode, flags, NULL);
+	nautilus_window_slot_info_open_location (directory_view->details->slot,
+						 location, mode, flags, NULL);
 	g_object_unref (location);
 }
 
@@ -1127,27 +1179,14 @@
 
 
 static void
-action_show_hidden_files_callback (GtkAction *action, 
-				   gpointer callback_data)
+hidden_files_mode_changed (NautilusWindow *window,
+			   gpointer callback_data)
 {
-	FMDirectoryView	*directory_view;
-	NautilusWindowShowHiddenFilesMode mode;
+	FMDirectoryView *directory_view;
 
-	g_assert (FM_IS_DIRECTORY_VIEW (callback_data));
 	directory_view = FM_DIRECTORY_VIEW (callback_data);
-	
-	directory_view->details->show_hidden_files = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
-	directory_view->details->show_backup_files = directory_view->details->show_hidden_files;
-	
-	if (directory_view->details->show_hidden_files) {
-		mode = NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_ENABLE;
-	} else {
-		mode = NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DISABLE;
-	}
-	nautilus_window_info_set_hidden_files_mode (directory_view->details->window, mode);
-	if (directory_view->details->model != NULL) {
-		load_directory (directory_view, directory_view->details->model);
-	}
+
+	fm_directory_view_init_show_hidden_files (directory_view);
 }
 
 static void
@@ -1545,7 +1584,9 @@
 	view = FM_DIRECTORY_VIEW (callback_data);
 
 	view->details->scripts_invalid = TRUE;
-	schedule_update_menus (view);
+	if (view->details->active) {
+		schedule_update_menus (view);
+	}
 }
 
 static void
@@ -1558,7 +1599,9 @@
 	view = FM_DIRECTORY_VIEW (callback_data);
 
 	view->details->templates_invalid = TRUE;
-	schedule_update_menus (view);
+	if (view->details->active) {
+		schedule_update_menus (view);
+	}
 }
 
 static void
@@ -1645,20 +1688,26 @@
 }
 
 static void
-fm_directory_view_set_parent_window (FMDirectoryView *directory_view,
-				     NautilusWindowInfo *window)
+slot_active (NautilusWindowSlot *slot,
+	     FMDirectoryView *view)
 {
-	
-	directory_view->details->window = window;
+	g_assert (!view->details->active);
+	view->details->active = TRUE;
 
-	/* Add new menu items and perhaps whole menus */
-	fm_directory_view_merge_menus (directory_view);
-	
-	/* Set initial sensitivity, wording, toggle state, etc. */       
-	fm_directory_view_update_menus (directory_view);
+	fm_directory_view_merge_menus (view);
+	schedule_update_menus (view);
+}
 
-	/* initialise show hidden mode */
-	fm_directory_view_init_show_hidden_files (directory_view);
+static void
+slot_inactive (NautilusWindowSlot *slot,
+	       FMDirectoryView *view)
+{
+	g_assert (view->details->active ||
+		  GTK_WIDGET (view)->parent == NULL);
+	view->details->active = FALSE;
+
+	fm_directory_view_unmerge_menus (view);
+	remove_update_menus_timeout_callback (view);
 }
 
 static GtkWidget *
@@ -1765,6 +1814,7 @@
 	iface->get_zoom_level = (gpointer)fm_directory_view_get_zoom_level;
 
 	iface->pop_up_location_context_menu = (gpointer)fm_directory_view_pop_up_location_context_menu;
+	iface->drop_proxy_received_uris = (gpointer)fm_directory_view_drop_proxy_received_uris;
 }
 
 static void
@@ -1843,14 +1893,10 @@
 				      click_policy_changed_callback, view);
 	eel_preferences_add_callback (NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST, 
 				      sort_directories_first_changed_callback, view);
-	eel_preferences_add_callback (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
-					 filtering_changed_callback, view);
-	eel_preferences_add_callback (NAUTILUS_PREFERENCES_SHOW_BACKUP_FILES,
-					 filtering_changed_callback, view);
 }
 
 static void
-unmerge_ui (FMDirectoryView *view)
+real_unmerge_menus (FMDirectoryView *view)
 {
 	GtkUIManager *ui_manager;
 
@@ -1887,9 +1933,10 @@
 
 	disconnect_model_handlers (view);
 
-	unmerge_ui (view);
+	fm_directory_view_unmerge_menus (view);
 	
 	/* We don't own the window, so no unref */
+	view->details->slot = NULL;
 	view->details->window = NULL;
 	
 	fm_directory_view_stop (view);
@@ -1948,15 +1995,6 @@
 
 	view = FM_DIRECTORY_VIEW (object);
 
-	if (!view->details->ignore_hidden_file_preferences) {
-		/* fm_directory_view_ignore_hidden_file_preferences is a one-way switch,
-		 * and may have removed these callbacks already.
-		 */
-		eel_preferences_remove_callback (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
-						 filtering_changed_callback, view);
-		eel_preferences_remove_callback (NAUTILUS_PREFERENCES_SHOW_BACKUP_FILES,
-						 filtering_changed_callback, view);
-	}
 	eel_preferences_remove_callback (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
 					 schedule_update_menus_callback, view);
 	eel_preferences_remove_callback (NAUTILUS_PREFERENCES_ENABLE_DELETE,
@@ -2171,8 +2209,8 @@
 	g_free (folder_item_count_str);
 	g_free (non_folder_str);
 
-	nautilus_window_info_set_status (view->details->window,
-					 status_string);
+	nautilus_window_slot_info_set_status (view->details->slot,
+					      status_string);
 	g_free (status_string);
 }
 
@@ -3695,7 +3733,8 @@
 	view = data->view;
 	new_file = data->new_file;
 
-	if (view->details->window != NULL) {
+	if (view->details->window != NULL &&
+	    view->details->active) {
 		EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view, start_renaming_file, (view, new_file, FALSE));
 		fm_directory_view_reveal_selection (view);
 	}
@@ -5637,8 +5676,8 @@
 		}
 	}
 
-	nautilus_window_info_set_status (view->details->window,
-					 status_string);
+	nautilus_window_slot_info_set_status (view->details->slot,
+					      status_string);
 	g_free (status_string);
 }
 
@@ -5683,8 +5722,8 @@
 									 copied_files_atom);
 
 	if (item_uris == NULL|| destination_uri == NULL) {
-		nautilus_window_info_set_status (view->details->window,
-						 _("There is nothing on the clipboard to paste."));
+		nautilus_window_slot_info_set_status (view->details->slot,
+						      _("There is nothing on the clipboard to paste."));
 	} else {
 		fm_directory_view_move_copy_items (item_uris, NULL, destination_uri,
 						   cut ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
@@ -6344,7 +6383,6 @@
 	NautilusWindowShowHiddenFilesMode mode;
 	gboolean show_hidden_changed;
 	gboolean show_hidden_default_setting;
-	GtkAction *action;
 
 	if (view->details->ignore_hidden_file_preferences) {
 		return;
@@ -6371,12 +6409,7 @@
 			view->details->show_backup_files = FALSE;
 		}
 	}
- 
-	action = gtk_action_group_get_action (view->details->dir_action_group,
-					      FM_ACTION_SHOW_HIDDEN_FILES);
-	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-				      view->details->show_hidden_files);
-	
+
 	if (show_hidden_changed && (view->details->model != NULL)) {
 		load_directory (view, view->details->model);	
 	}
@@ -6425,8 +6458,12 @@
   /* label, accelerator */       N_("Open in Navigation Window"), "<control><shift>o",
   /* tooltip */                  N_("Open each selected item in a navigation window"),
                                  G_CALLBACK (action_open_alternate_callback) },
+  /* name, stock id */         { "OpenInNewTab", NULL,
+  /* label, accelerator */       N_("Open in New _Tab"), "<control><shift>o",
+  /* tooltip */                  N_("Open each selected item in a new tab"),
+                                 G_CALLBACK (action_open_new_tab_callback) },
   /* name, stock id */         { "OpenFolderWindow", NULL,
-  /* label, accelerator */       N_("Open in Folder Window"), NULL,
+  /* label, accelerator */       N_("Open in _Folder Window"), NULL,
   /* tooltip */                  N_("Open each selected item in a folder window"),
                                  G_CALLBACK (action_open_folder_window_callback) },
   /* name, stock id */         { "OtherApplication1", NULL,
@@ -6499,6 +6536,12 @@
   /* label, accelerator */       N_("_Delete"), "<shift>Delete",
   /* tooltip */                  N_("Delete each selected item, without moving to the Trash"),
                                  G_CALLBACK (action_delete_callback) },
+  /*
+   * multiview-TODO: decide whether "Reset to Defaults" should
+   * be window-wide, and not just view-wide.
+   * Since this also resets the "Show hidden files" mode,
+   * it is a mixture of both ATM.
+   */
   /* name, stock id */         { "Reset to Defaults", NULL,
   /* label, accelerator */       N_("Reset View to _Defaults"), NULL,
   /* tooltip */                  N_("Reset sorting order and zoom level to match preferences for this view"),
@@ -6559,7 +6602,7 @@
                                  G_CALLBACK (action_location_open_alternate_callback) },
 
   /* name, stock id */         { FM_ACTION_LOCATION_OPEN_FOLDER_WINDOW, NULL,
-  /* label, accelerator */       N_("Open in Folder Window"), "",
+  /* label, accelerator */       N_("Open in _Folder Window"), "",
   /* tooltip */                  N_("Open this folder in a folder window"),
                                  G_CALLBACK (action_location_open_folder_window_callback) },
 
@@ -6608,14 +6651,6 @@
                                  G_CALLBACK (action_location_properties_callback) },
 };
 
-static const GtkToggleActionEntry directory_view_toggle_entries[] = {
-  /* name, stock id */         { "Show Hidden Files", NULL,
-  /* label, accelerator */       N_("Show _Hidden Files"), "<control>H",
-  /* tooltip */                  N_("Toggle the display of hidden files in the current window"),
-                                 G_CALLBACK (action_show_hidden_files_callback),
-                                 TRUE },
-};
-
 static void
 connect_proxy (FMDirectoryView *view,
 	       GtkAction *action,
@@ -6692,9 +6727,7 @@
 	gtk_action_group_add_actions (action_group, 
 				      directory_view_entries, G_N_ELEMENTS (directory_view_entries),
 				      view);
-	gtk_action_group_add_toggle_actions (action_group, 
-					     directory_view_toggle_entries, G_N_ELEMENTS (directory_view_toggle_entries),
-					     view);
+
 	/* Translators: %s is a directory */
 	tooltip = g_strdup_printf (_("Run or manage scripts from %s"), "~/.gnome2/nautilus-scripts");
 	/* Create a script action here specially because its tooltip is dynamic */
@@ -6727,6 +6760,7 @@
 	view->details->templates_invalid = TRUE;
 }
 
+
 static gboolean
 can_paste_into_file (NautilusFile *file)
 {
@@ -6774,8 +6808,9 @@
 	view = FM_DIRECTORY_VIEW (user_data);
 	can_paste = FALSE;
 
-	if (view->details->window == NULL) {
-		/* We've been destroyed since call */
+	if (view->details->window == NULL ||
+	    !view->details->active) {
+		/* We've been destroyed or became inactive since call */
 		g_object_unref (view);
 		return;
 	}
@@ -7164,9 +7199,9 @@
 	show_open_folder_window = FALSE;
 	if (nautilus_window_info_get_window_type (view->details->window) == NAUTILUS_WINDOW_NAVIGATION) {
 		if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
-			label = _("Open in New Window");
+			label = _("Open in New _Window");
 		} else {
-			label = _("Browse in New Window");
+			label = _("Browse in New _Window");
 			show_open_folder_window = TRUE;
 		}
 	} else {
@@ -7250,7 +7285,11 @@
 {
 	GList *selection;
 	gint selection_count;
-	
+
+	if (!view->details->active) {
+		return;
+	}
+
 	selection = fm_directory_view_get_selection (view);
 	selection_count = g_list_length (selection);
 
@@ -7379,19 +7418,19 @@
 	if (nautilus_window_info_get_window_type (view->details->window) == NAUTILUS_WINDOW_NAVIGATION) {
 		if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
 			if (selection_count == 0 || selection_count == 1) {
-				label_with_underscore = g_strdup (_("Open in New Window"));
+				label_with_underscore = g_strdup (_("Open in New _Window"));
 			} else {
-				label_with_underscore = g_strdup_printf (ngettext("Open in %'d New Window",
-										  "Open in %'d New Windows",
+				label_with_underscore = g_strdup_printf (ngettext("Open in %'d New _Window",
+										  "Open in %'d New _Windows",
 										  selection_count), 
 									 selection_count);
 			}
 		} else {
 			if (selection_count == 0 || selection_count == 1) {
-				label_with_underscore = g_strdup (_("Browse in New Window"));
+				label_with_underscore = g_strdup (_("Browse in New _Window"));
 			} else {
-				label_with_underscore = g_strdup_printf (ngettext("Browse in %'d New Window",
-										  "Browse in %'d New Windows",
+				label_with_underscore = g_strdup_printf (ngettext("Browse in %'d New _Window",
+										  "Browse in %'d New _Windows",
 										  selection_count), 
 									 selection_count);
 			}
@@ -7412,6 +7451,32 @@
 
 	gtk_action_set_sensitive (action,  selection_count != 0);
 	gtk_action_set_visible (action, show_open_alternate);
+
+	/* Open in New Tab action */
+	if (nautilus_window_info_get_window_type (view->details->window) == NAUTILUS_WINDOW_NAVIGATION &&
+	    eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)) {
+		if (selection_count == 0 || selection_count == 1) {
+			label_with_underscore = g_strdup (_("Open in New _Tab"));
+		} else {
+			label_with_underscore = g_strdup_printf (ngettext("Open in %'d New _Tab",
+									  "Open in %'d New _Tabs",
+									  selection_count), 
+								 selection_count);
+		}
+		action = gtk_action_group_get_action (view->details->dir_action_group,
+						      FM_ACTION_OPEN_IN_NEW_TAB);
+		gtk_action_set_sensitive (action, selection_count != 0);
+		gtk_action_set_visible (action, show_open_alternate);
+		g_object_set (action, "label", 
+			      label_with_underscore,
+			      NULL);
+		g_free (label_with_underscore);
+	} else {
+		action = gtk_action_group_get_action (view->details->dir_action_group,
+						      FM_ACTION_OPEN_IN_NEW_TAB);
+		gtk_action_set_visible (action, FALSE);
+	}
+
 	
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_OPEN_FOLDER_WINDOW);
@@ -7722,13 +7787,46 @@
 	}
 }
 
+static void 
+fm_directory_view_drop_proxy_received_uris (FMDirectoryView *view,
+					    GList *uris,
+					    const char *target_uri,
+					    GdkDragAction action)
+{
+	char *container_uri;
+
+	container_uri = NULL;
+	if (target_uri == NULL) {
+		container_uri = fm_directory_view_get_backing_uri (view);
+		g_assert (container_uri != NULL);
+	}
+
+	if (action == GDK_ACTION_ASK) {
+		action = nautilus_drag_drop_action_ask
+			(GTK_WIDGET (view),
+			 GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
+		if (action == 0) {
+			return;
+		}
+	}
+
+	fm_directory_view_move_copy_items (uris, NULL,
+					   target_uri != NULL ? target_uri : container_uri,
+					   action, 0, 0, view);
+
+	g_free (container_uri);
+}
+
 static void
 schedule_update_menus (FMDirectoryView *view) 
 {
 	g_assert (FM_IS_DIRECTORY_VIEW (view));
 
-	/* Don't schedule updates after destroy (#349551) */
-	if (view->details->window == NULL) {
+	/* Don't schedule updates after destroy (#349551),
+ 	 * or if we are not active.
+ 	*/
+	if (view->details->window == NULL ||
+	    !view->details->active) {
 		return;
 	}
 	
@@ -8021,6 +8119,7 @@
 	g_assert (view->details->directory_as_file == file);
 	g_assert (view->details->metadata_for_directory_as_file_pending);
 
+	g_assert (view->details->metadata_for_directory_as_file_pending);
 	view->details->metadata_for_directory_as_file_pending = FALSE;
 	
 	finish_loading_if_all_metadata_loaded (view);
@@ -8039,6 +8138,7 @@
 	g_assert (view->details->model == directory);
 	g_assert (view->details->metadata_for_files_in_directory_pending);
 
+	g_assert (view->details->metadata_for_files_in_directory_pending);
 	view->details->metadata_for_files_in_directory_pending = FALSE;
 	
 	finish_loading_if_all_metadata_loaded (view);
@@ -8093,6 +8193,16 @@
 }
 
 static void
+fm_directory_view_unmerge_menus (FMDirectoryView *view)
+{
+	g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
+
+	EEL_CALL_METHOD
+		(FM_DIRECTORY_VIEW_CLASS, view,
+		 unmerge_menus, (view));
+}
+
+static void
 disconnect_handler (GObject *object, int *id)
 {
 	if (*id != 0) {
@@ -8156,7 +8266,6 @@
 	if (mode != NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT) {
 		nautilus_window_info_set_hidden_files_mode (view->details->window,
 							    NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT);
-		fm_directory_view_init_show_hidden_files (view);
 	}
 }
 
@@ -8441,6 +8550,11 @@
 {
 	g_return_if_fail (FM_IS_DIRECTORY_VIEW (view));
 
+	if (!view->details->active) {
+		return;
+	}
+
+
 	EEL_CALL_METHOD
 		(FM_DIRECTORY_VIEW_CLASS, view,
 		 update_menus, (view));
@@ -8454,38 +8568,6 @@
 	schedule_update_menus (FM_DIRECTORY_VIEW (callback_data));
 }
 
-static void
-filtering_changed_callback (gpointer callback_data)
-{
-	FMDirectoryView	*directory_view;
-	gboolean new_show_hidden;
-	NautilusWindowShowHiddenFilesMode mode;
-	GtkAction *action;
-
-	directory_view = FM_DIRECTORY_VIEW (callback_data);
-	new_show_hidden = eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES);
-	mode = nautilus_window_info_get_hidden_files_mode (directory_view->details->window);
-
-	/* only apply global show hidden files pref if local setting has not been set for this window */
-	if (new_show_hidden != directory_view->details->show_hidden_files
-	    && mode == NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT) {
-		directory_view->details->show_hidden_files = new_show_hidden;
-		directory_view->details->show_backup_files = new_show_hidden;
-
-		action = gtk_action_group_get_action (directory_view->details->dir_action_group,
-						      FM_ACTION_SHOW_HIDDEN_FILES);
-		g_signal_handlers_block_by_func (action, action_show_hidden_files_callback, directory_view);
-		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-					      directory_view->details->show_hidden_files);
-		g_signal_handlers_unblock_by_func (action, action_show_hidden_files_callback, directory_view);
-
-		/* Reload the current uri so that the filtering changes take place. */
-		if (directory_view->details->model != NULL) {
-			load_directory (directory_view, directory_view->details->model);
-		}
-	}
-}
-
 void
 fm_directory_view_ignore_hidden_file_preferences (FMDirectoryView *view)
 {
@@ -8495,13 +8577,6 @@
 		return;
 	}
 
-	eel_preferences_remove_callback (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
-					      filtering_changed_callback,
-					      view);
-	eel_preferences_remove_callback (NAUTILUS_PREFERENCES_SHOW_BACKUP_FILES,
-					      filtering_changed_callback,
-					      view);
-
 	view->details->show_hidden_files = FALSE;
 	view->details->show_backup_files = FALSE;
 	view->details->ignore_hidden_file_preferences = TRUE;
@@ -9008,7 +9083,12 @@
 	g_free (container_uri);
 }
 
-
+gboolean
+fm_directory_view_get_active (FMDirectoryView *view)
+{
+	g_assert (FM_IS_DIRECTORY_VIEW (view));
+	return view->details->active;
+}
 
 static GArray *
 real_get_selected_icon_locations (FMDirectoryView *view)
@@ -9024,14 +9104,32 @@
 				GParamSpec      *pspec)
 {
   FMDirectoryView *directory_view;
+  NautilusWindowSlotInfo *slot;
+  NautilusWindowInfo *window;
   
   directory_view = FM_DIRECTORY_VIEW (object);
 
   switch (prop_id)  {
-  case PROP_WINDOW:
-	  g_assert (directory_view->details->window == NULL);
-	  fm_directory_view_set_parent_window (directory_view, NAUTILUS_WINDOW_INFO (g_value_get_object (value)));
-		  
+  case PROP_WINDOW_SLOT:
+	  g_assert (directory_view->details->slot == NULL);
+
+	  slot = NAUTILUS_WINDOW_SLOT_INFO (g_value_get_object (value));
+          window = nautilus_window_slot_info_get_window (slot);
+
+	  directory_view->details->slot = slot;
+	  directory_view->details->window = window;
+
+	  g_signal_connect_object (directory_view->details->slot,
+				   "active", G_CALLBACK (slot_active),
+				   directory_view, 0);
+	  g_signal_connect_object (directory_view->details->slot,
+				   "inactive", G_CALLBACK (slot_inactive),
+				   directory_view, 0);
+
+	  g_signal_connect_object (directory_view->details->window,
+				   "hidden-files-mode-changed", G_CALLBACK (hidden_files_mode_changed),
+				   directory_view, 0);
+	  fm_directory_view_init_show_hidden_files (directory_view);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -9072,6 +9170,39 @@
 	return GTK_WIDGET_CLASS (parent_class)->scroll_event (widget, event);
 }
 
+
+static void
+fm_directory_view_parent_set (GtkWidget *widget,
+			      GtkWidget *old_parent)
+{
+	FMDirectoryView *view;
+	GtkWidget *parent;
+
+	view = FM_DIRECTORY_VIEW (widget);
+
+	parent = gtk_widget_get_parent (widget);
+	g_assert (parent == NULL || old_parent == NULL);
+
+	if (GTK_WIDGET_CLASS (parent_class)->parent_set != NULL) {
+		GTK_WIDGET_CLASS (parent_class)->parent_set (widget, old_parent);
+	}
+
+	if (parent != NULL) {
+		g_assert (old_parent == NULL);
+
+		if (view->details->slot == 
+		    nautilus_window_info_get_active_slot (view->details->window)) {
+			view->details->active = TRUE;
+
+			fm_directory_view_merge_menus (view);
+			schedule_update_menus (view);
+		}
+	} else {
+		fm_directory_view_unmerge_menus (view);
+		remove_update_menus_timeout_callback (view);
+	}
+}
+
 static void
 fm_directory_view_class_init (FMDirectoryViewClass *klass)
 {
@@ -9088,6 +9219,7 @@
 	GTK_OBJECT_CLASS (klass)->destroy = fm_directory_view_destroy;
 
 	widget_class->scroll_event = fm_directory_view_scroll_event;
+	widget_class->parent_set = fm_directory_view_parent_set;
 
 	/* Get rid of the strange 3-pixel gap that GtkScrolledWindow
 	 * uses by default. It does us no good.
@@ -9189,6 +9321,7 @@
 	klass->supports_zooming = real_supports_zooming;
 	klass->using_manual_layout = real_using_manual_layout;
         klass->merge_menus = real_merge_menus;
+        klass->unmerge_menus = real_unmerge_menus;
         klass->update_menus = real_update_menus;
 
 	/* Function pointers that subclasses must override */
@@ -9214,11 +9347,11 @@
 	copied_files_atom = gdk_atom_intern ("x-special/gnome-copied-files", FALSE);
 
 	g_object_class_install_property (G_OBJECT_CLASS (klass),
-					 PROP_WINDOW,
-					 g_param_spec_object ("window",
-							      "Window",
-							      "The parent NautilusWindowInfo reference",
-							      NAUTILUS_TYPE_WINDOW_INFO,
+					 PROP_WINDOW_SLOT,
+					 g_param_spec_object ("window-slot",
+							      "Window Slot",
+							      "The parent window slot reference",
+							      NAUTILUS_TYPE_WINDOW_SLOT_INFO,
 							      G_PARAM_WRITABLE |
 							      G_PARAM_CONSTRUCT_ONLY));
 

Modified: trunk/src/file-manager/fm-directory-view.h
==============================================================================
--- trunk/src/file-manager/fm-directory-view.h	(original)
+++ trunk/src/file-manager/fm-directory-view.h	Tue Jul  8 21:05:55 2008
@@ -36,6 +36,7 @@
 #include <libnautilus-private/nautilus-link.h>
 #include <libnautilus-private/nautilus-view.h>
 #include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
 #include <gio/gio.h>
 
 typedef struct FMDirectoryView FMDirectoryView;
@@ -206,6 +207,7 @@
          * If overridden, subclasses must call parent class's function.
          */
         void    (* merge_menus)         	(FMDirectoryView *view);
+        void    (* unmerge_menus)         	(FMDirectoryView *view);
 
         /* update_menus is a function pointer that subclasses can override to
          * update the sensitivity or wording of menu items in the menu bar.
@@ -330,6 +332,7 @@
 
 /* Functions callable from the user interface and elsewhere. */
 NautilusWindowInfo *fm_directory_view_get_nautilus_window              (FMDirectoryView  *view);
+NautilusWindowSlotInfo *fm_directory_view_get_nautilus_window_slot     (FMDirectoryView  *view);
 char *              fm_directory_view_get_uri                          (FMDirectoryView  *view);
 char *              fm_directory_view_get_backing_uri                  (FMDirectoryView  *view);
 gboolean            fm_directory_view_can_accept_item                  (NautilusFile     *target_item,
@@ -371,6 +374,7 @@
 									int               y,
 									FMDirectoryView  *view);
 GdkAtom	            fm_directory_view_get_copied_files_atom            (FMDirectoryView  *view);
+gboolean            fm_directory_view_get_active                       (FMDirectoryView  *view);
 
 /* Wrappers for signal emitters. These are normally called 
  * only by FMDirectoryView itself. They have corresponding signals
@@ -388,15 +392,14 @@
 void                fm_directory_view_activate_files                   (FMDirectoryView        *view,
 									GList                  *files,
 									NautilusWindowOpenMode  mode,
-									NautilusWindowOpenFlags flags);
+									NautilusWindowOpenFlags flags,
+									gboolean                confirm_multiple);
 void                fm_directory_view_activate_file                    (FMDirectoryView        *view,
 									NautilusFile           *file,
 									NautilusWindowOpenMode  mode,
 									NautilusWindowOpenFlags flags);
 void                fm_directory_view_start_batching_selection_changes (FMDirectoryView  *view);
 void                fm_directory_view_stop_batching_selection_changes  (FMDirectoryView  *view);
-gboolean            fm_directory_view_confirm_multiple_windows         (GtkWindow        *parent_window,
-									int               window_count);
 void                fm_directory_view_queue_file_change                (FMDirectoryView  *view,
 									NautilusFile     *file);
 void                fm_directory_view_notify_selection_changed         (FMDirectoryView  *view);

Modified: trunk/src/file-manager/fm-empty-view.c
==============================================================================
--- trunk/src/file-manager/fm-empty-view.c	(original)
+++ trunk/src/file-manager/fm-empty-view.c	Tue Jul  8 21:05:55 2008
@@ -345,11 +345,16 @@
 }
 
 static NautilusView *
-fm_empty_view_create (NautilusWindowInfo *window)
+fm_empty_view_create (NautilusWindowSlotInfo *slot)
 {
+	NautilusWindowSlotInfo *slot;
 	FMEmptyView *view;
 
-	view = g_object_new (FM_TYPE_EMPTY_VIEW, "window", window, NULL);
+	g_assert (NAUTILUS_IS_WINDOW_SLOT_INFO (slot));
+
+	view = g_object_new (FM_TYPE_EMPTY_VIEW,
+			     "window-slot", slot,
+			     NULL);
 	g_object_ref (view);
 	gtk_object_sink (GTK_OBJECT (view));
 	return NAUTILUS_VIEW (view);

Modified: trunk/src/file-manager/fm-icon-view.c
==============================================================================
--- trunk/src/file-manager/fm-icon-view.c	(original)
+++ trunk/src/file-manager/fm-icon-view.c	Tue Jul  8 21:05:55 2008
@@ -189,7 +189,6 @@
 fm_icon_view_destroy (GtkObject *object)
 {
 	FMIconView *icon_view;
-	GtkUIManager *ui_manager;
 
 	icon_view = FM_ICON_VIEW (object);
 
@@ -206,13 +205,6 @@
 		icon_view->details->icons_not_positioned = NULL;
 	}
 
-	ui_manager = fm_directory_view_get_ui_manager (FM_DIRECTORY_VIEW (icon_view));
-	if (ui_manager != NULL) {
-		nautilus_ui_unmerge_ui (ui_manager,
-					&icon_view->details->icon_merge_id,
-					&icon_view->details->icon_action_group);
-	}
-
 	GTK_OBJECT_CLASS (fm_icon_view_parent_class)->destroy (object);
 }
 
@@ -1281,7 +1273,9 @@
 
 	g_signal_emit_by_name (view, "zoom_level_changed");
 	
-	fm_directory_view_update_menus (FM_DIRECTORY_VIEW (view));
+	if (fm_directory_view_get_active (FM_DIRECTORY_VIEW (view))) {
+		fm_directory_view_update_menus (FM_DIRECTORY_VIEW (view));
+	}
 }
 
 static void
@@ -1647,6 +1641,24 @@
 }
 
 static void
+fm_icon_view_unmerge_menus (FMDirectoryView *view)
+{
+	FMIconView *icon_view;
+	GtkUIManager *ui_manager;
+
+	icon_view = FM_ICON_VIEW (view);
+
+	FM_DIRECTORY_VIEW_CLASS (fm_icon_view_parent_class)->unmerge_menus (view);
+
+	ui_manager = fm_directory_view_get_ui_manager (view);
+	if (ui_manager != NULL) {
+		nautilus_ui_unmerge_ui (ui_manager,
+					&icon_view->details->icon_merge_id,
+					&icon_view->details->icon_action_group);
+	}
+}
+
+static void
 fm_icon_view_update_menus (FMDirectoryView *view)
 {
 	FMIconView *icon_view;
@@ -1807,7 +1819,8 @@
 
 	fm_directory_view_activate_files (FM_DIRECTORY_VIEW (icon_view),
 					  file_list, 
-					  NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, 0);
+					  NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, 0,
+					  TRUE);
 }
 
 static void
@@ -1815,14 +1828,50 @@
 					    GList *file_list,
 					    FMIconView *icon_view)
 {
+	GdkEvent *event;
+	GdkEventButton *button_event;
+	GdkEventKey *key_event;
+	gboolean open_in_tab;
+	NautilusWindowInfo *window_info;
+	NautilusWindowOpenFlags flags;
+
 	g_assert (FM_IS_ICON_VIEW (icon_view));
 	g_assert (container == get_icon_container (icon_view));
 
+	open_in_tab = FALSE;
+
+	window_info = fm_directory_view_get_nautilus_window (FM_DIRECTORY_VIEW (icon_view));
+
+	if (nautilus_window_info_get_window_type (window_info) == NAUTILUS_WINDOW_NAVIGATION) {
+		event = gtk_get_current_event ();
+		if (event->type == GDK_BUTTON_PRESS ||
+		    event->type == GDK_BUTTON_RELEASE ||
+		    event->type == GDK_2BUTTON_PRESS ||
+		    event->type == GDK_3BUTTON_PRESS) {
+			button_event = (GdkEventButton *) event;
+			open_in_tab = (button_event->state & GDK_SHIFT_MASK) == 0;
+		} else if (event->type == GDK_KEY_PRESS ||
+			   event->type == GDK_KEY_RELEASE) {
+			key_event = (GdkEventKey *) event;
+			open_in_tab = !((key_event->state & GDK_SHIFT_MASK) != 0 &&
+				       (key_event->state & GDK_CONTROL_MASK) != 0);
+		} else {
+			open_in_tab = TRUE;
+		}
+	}
+
+	flags = NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND;
+	if (open_in_tab && eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)) {
+		flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
+	} else {
+		flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
+	}
+
 	fm_directory_view_activate_files (FM_DIRECTORY_VIEW (icon_view), 
 					  file_list, 
 					  NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
-					  NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND |
-					  NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
+					  flags,
+					  TRUE);
 }
 
 static void
@@ -2063,8 +2112,8 @@
 			file_name = nautilus_file_get_display_name (file);
 			message = g_strdup_printf (_("pointing at \"%s\""), file_name);
 			g_free (file_name);
-			nautilus_window_info_set_status
-				(fm_directory_view_get_nautilus_window (FM_DIRECTORY_VIEW (icon_view)),
+			nautilus_window_slot_info_set_status
+				(fm_directory_view_get_nautilus_window_slot (FM_DIRECTORY_VIEW (icon_view)),
 				 message);
 			g_free (message);
 		} else {
@@ -2241,7 +2290,8 @@
 	 * idle call, because we'd have to keep track of potentially multiple
 	 * sets of file/geometry info.
 	 */
-	if (icon_view->details->react_to_icon_change_idle_id == 0) {
+	if (fm_directory_view_get_active (FM_DIRECTORY_VIEW (icon_view)) &&
+	    icon_view->details->react_to_icon_change_idle_id == 0) {
                 icon_view->details->react_to_icon_change_idle_id
                         = g_idle_add (fm_icon_view_react_to_icon_change_idle_callback,
 				      icon_view);
@@ -2758,6 +2808,7 @@
         fm_directory_view_class->emblems_changed = fm_icon_view_emblems_changed;
         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->unmerge_menus = fm_icon_view_unmerge_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->text_attribute_names_changed = fm_icon_view_text_attribute_names_changed;
@@ -2877,22 +2928,28 @@
 }
 
 static NautilusView *
-fm_icon_view_create (NautilusWindowInfo *window)
+fm_icon_view_create (NautilusWindowSlotInfo *slot)
 {
 	FMIconView *view;
 
-	view = g_object_new (FM_TYPE_ICON_VIEW, "window", window, "compact", FALSE, NULL);
+	view = g_object_new (FM_TYPE_ICON_VIEW,
+			     "window-slot", slot,
+			     "compact", FALSE,
+			     NULL);
 	g_object_ref (view);
 	gtk_object_sink (GTK_OBJECT (view));
 	return NAUTILUS_VIEW (view);
 }
 
 static NautilusView *
-fm_compact_view_create (NautilusWindowInfo *window)
+fm_compact_view_create (NautilusWindowSlotInfo *slot)
 {
 	FMIconView *view;
 
-	view = g_object_new (FM_TYPE_ICON_VIEW, "window", window, "compact", TRUE, NULL);
+	view = g_object_new (FM_TYPE_ICON_VIEW,
+			     "window-slot", slot,
+			     "compact", TRUE,
+			     NULL);
 	g_object_ref (view);
 	gtk_object_sink (GTK_OBJECT (view));
 	return NAUTILUS_VIEW (view);

Modified: trunk/src/file-manager/fm-list-view.c
==============================================================================
--- trunk/src/file-manager/fm-list-view.c	(original)
+++ trunk/src/file-manager/fm-list-view.c	Tue Jul  8 21:05:55 2008
@@ -221,17 +221,27 @@
 	fm_directory_view_activate_files (FM_DIRECTORY_VIEW (view),
 					  file_list,
 					  NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
-					  0);
+					  0,
+					  TRUE);
 	nautilus_file_list_free (file_list);
 
 }
 
 static void
 activate_selected_items_alternate (FMListView *view,
-				   NautilusFile *file)
+				   NautilusFile *file,
+				   gboolean open_in_tab)
 {
 	GList *file_list;
+	NautilusWindowOpenFlags flags;
 
+	flags = NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND;
+
+	if (open_in_tab && eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)) {
+		flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
+        } else {
+		flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
+        }
 
 	if (file != NULL) {
 		nautilus_file_ref (file);
@@ -242,8 +252,8 @@
 	fm_directory_view_activate_files (FM_DIRECTORY_VIEW (view),
 					  file_list,
 					  NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
-					  NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND |
-					  NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
+					  flags,
+					  TRUE);
 	nautilus_file_list_free (file_list);
 
 }
@@ -284,7 +294,7 @@
 			if (event->button == 1) {
 				activate_selected_items (view);
 			} else if (event->button == 2) {
-				activate_selected_items_alternate (view, NULL);
+				activate_selected_items_alternate (view, NULL, TRUE);
 			}
 		}
 		gtk_tree_path_free (path);
@@ -652,14 +662,14 @@
 					if ((event->button == 1 || event->button == 3)) {
 						activate_selected_items (view);
 					} else if (event->button == 2) {
-						activate_selected_items_alternate (view, NULL);
+						activate_selected_items_alternate (view, NULL, TRUE);
 					}
 				} else if (event->button == 1 &&
 					   (event->state & GDK_SHIFT_MASK) != 0) {
 					NautilusFile *file;
 					file = fm_list_model_file_for_path (view->details->model, path);
 					if (file != NULL) {
-						activate_selected_items_alternate (view, file);
+						activate_selected_items_alternate (view, file, TRUE);
 						nautilus_file_unref (file);
 					}
 				}
@@ -942,7 +952,7 @@
 			break;
 		}
 		if ((event->state & GDK_SHIFT_MASK) != 0) {
-			activate_selected_items_alternate (FM_LIST_VIEW (view), NULL);
+			activate_selected_items_alternate (FM_LIST_VIEW (view), NULL, TRUE);
 		} else {
 			activate_selected_items (FM_LIST_VIEW (view));
 		}
@@ -951,7 +961,7 @@
 	case GDK_Return:
 	case GDK_KP_Enter:
 		if ((event->state & GDK_SHIFT_MASK) != 0) {
-			activate_selected_items_alternate (FM_LIST_VIEW (view), NULL);
+			activate_selected_items_alternate (FM_LIST_VIEW (view), NULL, TRUE);
 		} else {
 			activate_selected_items (FM_LIST_VIEW (view));
 		}
@@ -2167,6 +2177,24 @@
 }
 
 static void
+fm_list_view_unmerge_menus (FMDirectoryView *view)
+{
+	FMListView *list_view;
+	GtkUIManager *ui_manager;
+
+	list_view = FM_LIST_VIEW (view);
+
+	FM_DIRECTORY_VIEW_CLASS (fm_list_view_parent_class)->unmerge_menus (view);
+
+	ui_manager = fm_directory_view_get_ui_manager (view);
+	if (ui_manager != NULL) {
+		nautilus_ui_unmerge_ui (ui_manager,
+					&list_view->details->list_merge_id,
+					&list_view->details->list_action_group);
+	}
+}
+
+static void
 fm_list_view_update_menus (FMDirectoryView *view)
 {
 	FMListView *list_view;
@@ -2542,7 +2570,6 @@
 fm_list_view_dispose (GObject *object)
 {
 	FMListView *list_view;
-	GtkUIManager *ui_manager;
 
 	list_view = FM_LIST_VIEW (object);
 
@@ -2562,13 +2589,6 @@
 		list_view->details->renaming_file_activate_timeout = 0;
 	}
 
-	ui_manager = fm_directory_view_get_ui_manager (FM_DIRECTORY_VIEW (list_view));
-	if (ui_manager != NULL) {
-		nautilus_ui_unmerge_ui (ui_manager,
-					&list_view->details->list_merge_id,
-					&list_view->details->list_action_group);
-	}
-
 	G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
@@ -2723,6 +2743,7 @@
 	fm_directory_view_class->is_empty = fm_list_view_is_empty;
 	fm_directory_view_class->remove_file = fm_list_view_remove_file;
 	fm_directory_view_class->merge_menus = fm_list_view_merge_menus;
+	fm_directory_view_class->unmerge_menus = fm_list_view_unmerge_menus;
 	fm_directory_view_class->update_menus = fm_list_view_update_menus;
 	fm_directory_view_class->reset_to_defaults = fm_list_view_reset_to_defaults;
 	fm_directory_view_class->restore_default_zoom_level = fm_list_view_restore_default_zoom_level;
@@ -2807,11 +2828,13 @@
 }
 
 static NautilusView *
-fm_list_view_create (NautilusWindowInfo *window)
+fm_list_view_create (NautilusWindowSlotInfo *slot)
 {
 	FMListView *view;
 
-	view = g_object_new (FM_TYPE_LIST_VIEW, "window", window, NULL);
+	view = g_object_new (FM_TYPE_LIST_VIEW,
+			     "window-slot", slot,
+			     NULL);
 	g_object_ref (view);
 	gtk_object_sink (GTK_OBJECT (view));
 	return NAUTILUS_VIEW (view);

Modified: trunk/src/file-manager/fm-tree-model.c
==============================================================================
--- trunk/src/file-manager/fm-tree-model.c	(original)
+++ trunk/src/file-manager/fm-tree-model.c	Tue Jul  8 21:05:55 2008
@@ -1705,6 +1705,7 @@
 		return;
 	}
 	model->details->show_hidden_files = show_hidden_files;
+	model->details->show_backup_files = show_hidden_files;
 	stop_monitoring (model);
 	if (!show_hidden_files) {
 		destroy_by_function (model, nautilus_file_is_hidden_file);
@@ -1712,25 +1713,6 @@
 	schedule_monitoring_update (model);
 }
 
-void
-fm_tree_model_set_show_backup_files (FMTreeModel *model,
-					   gboolean show_backup_files)
-{
-	g_return_if_fail (FM_IS_TREE_MODEL (model));
-	g_return_if_fail (show_backup_files == FALSE || show_backup_files == TRUE);
-
-	show_backup_files = show_backup_files != FALSE;
-	if (model->details->show_backup_files == show_backup_files) {
-		return;
-	}
-	model->details->show_backup_files = show_backup_files;
-	stop_monitoring (model);
-	if (!show_backup_files) {
-		destroy_by_function (model, nautilus_file_is_backup_file);
-	}
-	schedule_monitoring_update (model);
-}
-
 static gboolean
 file_is_not_directory (NautilusFile *file)
 {

Modified: trunk/src/file-manager/fm-tree-model.h
==============================================================================
--- trunk/src/file-manager/fm-tree-model.h	(original)
+++ trunk/src/file-manager/fm-tree-model.h	Tue Jul  8 21:05:55 2008
@@ -66,8 +66,6 @@
 FMTreeModel *fm_tree_model_new                       (void);
 void               fm_tree_model_set_show_hidden_files     (FMTreeModel *model,
 							    gboolean           show_hidden_files);
-void               fm_tree_model_set_show_backup_files     (FMTreeModel *model,
-							    gboolean           show_backup_files);
 void               fm_tree_model_set_show_only_directories (FMTreeModel *model,
 							    gboolean           show_only_directories);
 NautilusFile *     fm_tree_model_iter_get_file             (FMTreeModel *model,

Modified: trunk/src/file-manager/fm-tree-view.c
==============================================================================
--- trunk/src/file-manager/fm-tree-view.c	(original)
+++ trunk/src/file-manager/fm-tree-view.c	Tue Jul  8 21:05:55 2008
@@ -59,6 +59,8 @@
 #include <libnautilus-private/nautilus-cell-renderer-pixbuf-emblem.h>
 #include <libnautilus-private/nautilus-sidebar-provider.h>
 #include <libnautilus-private/nautilus-module.h>
+#include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
 
 typedef struct {
         GObject parent;
@@ -78,7 +80,7 @@
 	GVolumeMonitor *volume_monitor;
 
 	NautilusFile *activation_file;
-	gboolean activation_in_new_window;
+	NautilusWindowOpenFlags activation_flags;
 
 	NautilusTreeViewDragDest *drag_dest;
 
@@ -115,6 +117,9 @@
 
 static void  fm_tree_view_iface_init        (NautilusSidebarIface         *iface);
 static void  sidebar_provider_iface_init    (NautilusSidebarProviderIface *iface);
+static void  fm_tree_view_activate_file     (FMTreeView *view, 
+			    		     NautilusFile *file,
+					     NautilusWindowOpenFlags flags);
 static GType fm_tree_view_provider_get_type (void);
 
 static void create_popup_menu (FMTreeView *view);
@@ -314,16 +319,22 @@
         char *uri, *file_uri;
         FMTreeView *view;
 	GdkScreen *screen;
-	NautilusWindowOpenMode mode;
 	GFile *location;
+	NautilusWindowSlotInfo *slot;
+	gboolean open_in_same_slot;
 	
         view = FM_TREE_VIEW (callback_data);
 
 	screen = gtk_widget_get_screen (GTK_WIDGET (view->details->tree_widget));
 
         g_assert (file == view->details->activation_file);
-        
-        mode = view->details->activation_in_new_window ? NAUTILUS_WINDOW_OPEN_IN_NAVIGATION : NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE;
+
+	open_in_same_slot =
+		(view->details->activation_flags &
+		 (NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW |
+		  NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB)) == 0;
+
+	slot = nautilus_window_info_get_active_slot (view->details->window);
 
 	uri = nautilus_file_get_activation_uri (file);
 	if (nautilus_file_is_launcher (file)) {
@@ -346,11 +357,11 @@
 					    "tree view window_info_open_location window=%p: %s",
 					    view->details->window, uri);
 			location = g_file_new_for_uri (uri);
-			nautilus_window_info_open_location
-				(view->details->window, 
+			nautilus_window_slot_info_open_location
+				(slot,
 				 location, 
-				 mode,
-				 0,
+				 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
+				 view->details->activation_flags,
 				 NULL);
 			g_object_unref (location);
 		} else {
@@ -362,21 +373,25 @@
 		}
 		   
 	} else if (uri != NULL) {
-		if (view->details->selection_location == NULL ||
+		if (!open_in_same_slot ||
+		    view->details->selection_location == NULL ||
 		    strcmp (uri, view->details->selection_location) != 0) {
-			if (view->details->selection_location != NULL) {
-				g_free (view->details->selection_location);
+			if (open_in_same_slot) {
+				if (view->details->selection_location != NULL) {
+					g_free (view->details->selection_location);
+				}
+				view->details->selection_location = g_strdup (uri);
 			}
-			view->details->selection_location = g_strdup (uri);
+
 			nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
 					    "tree view window_info_open_location window=%p: %s",
 					    view->details->window, uri);
 			location = g_file_new_for_uri (uri);
-			nautilus_window_info_open_location
-				(view->details->window, 
+			nautilus_window_slot_info_open_location
+				(slot,
 				 location,
-				 mode,
-				 0,
+				 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
+				 view->details->activation_flags,
 				 NULL);
 			g_object_unref (location);
 		}
@@ -437,7 +452,7 @@
 	if (view->details->activation_file == NULL) {
 		return FALSE;
 	}
-	view->details->activation_in_new_window = FALSE;
+	view->details->activation_flags = 0;
 		
 	attributes = NAUTILUS_FILE_ATTRIBUTE_INFO | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO;
 	nautilus_file_call_when_ready (view->details->activation_file, attributes,
@@ -745,6 +760,26 @@
 		g_object_unref (view);
 
 		return TRUE;
+	} else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) {
+		NautilusFile *file;
+
+		if (!gtk_tree_view_get_path_at_pos (treeview, event->x, event->y,
+						    &path, NULL, NULL, NULL)) {
+			return FALSE;
+		}
+
+		file = sort_model_path_to_file (view, path);
+		if (file) {
+			fm_tree_view_activate_file (view, file, 
+						    (event->state & GDK_CONTROL_MASK) != 0 ?
+						    NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW :
+						    NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB);
+			nautilus_file_unref (file);
+		}
+
+		gtk_tree_path_free (path);
+
+		return TRUE;
 	}
 
 	return FALSE;
@@ -753,14 +788,21 @@
 static void
 fm_tree_view_activate_file (FMTreeView *view, 
 			    NautilusFile *file,
-			    gboolean open_in_new_window)
+			    NautilusWindowOpenFlags flags)
 {
 	NautilusFileAttributes attributes;
 
 	cancel_activation (view);
 
+	if (view->details->activation_flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB &&
+	    !eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)) {
+		view->details->activation_flags &= ~NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
+		view->details->activation_flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
+	}
+
+
 	view->details->activation_file = nautilus_file_ref (file);
-	view->details->activation_in_new_window = open_in_new_window;
+	view->details->activation_flags = flags;
 		
 	attributes = NAUTILUS_FILE_ATTRIBUTE_INFO | NAUTILUS_FILE_ATTRIBUTE_LINK_INFO;
 	nautilus_file_call_when_ready (view->details->activation_file, attributes,
@@ -771,14 +813,21 @@
 fm_tree_view_open_cb (GtkWidget *menu_item,
 		      FMTreeView *view)
 {
-	fm_tree_view_activate_file (view, view->details->popup_file, FALSE);
+	fm_tree_view_activate_file (view, view->details->popup_file, 0);
+}
+
+static void
+fm_tree_view_open_in_new_tab_cb (GtkWidget *menu_item,
+				    FMTreeView *view)
+{
+	fm_tree_view_activate_file (view, view->details->popup_file, NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB);
 }
 
 static void
 fm_tree_view_open_in_new_window_cb (GtkWidget *menu_item,
 				    FMTreeView *view)
 {
-	fm_tree_view_activate_file (view, view->details->popup_file, TRUE);
+	fm_tree_view_activate_file (view, view->details->popup_file, NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
 }
 
 static void
@@ -921,8 +970,8 @@
 	}
 	g_free (name);
 	
-	nautilus_window_info_set_status (view->details->window,
-					 status_string);
+	nautilus_window_info_push_status (view->details->window,
+					  status_string);
 	g_free (status_string);
 }
 
@@ -953,8 +1002,8 @@
 									 copied_files_atom);
 
 	if (item_uris == NULL|| destination_uri == NULL) {
-		nautilus_window_info_set_status (view->details->window,
-						 _("There is nothing on the clipboard to paste."));
+		nautilus_window_info_push_status (view->details->window,
+						  _("There is nothing on the clipboard to paste."));
 	} else {
 		nautilus_file_operations_copy_move
 			(item_uris, NULL, destination_uri,
@@ -1107,8 +1156,17 @@
 	gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item);
 	view->details->popup_open = menu_item;
 	
+	/* add the "open in new tab" menu item */
+	menu_item = gtk_menu_item_new_with_mnemonic (_("Open in New _Tab"));
+	g_signal_connect (menu_item, "activate",
+			  G_CALLBACK (fm_tree_view_open_in_new_tab_cb),
+			  view);
+	gtk_widget_show (menu_item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item);
+	view->details->popup_open_in_new_window = menu_item;
+	
 	/* add the "open in new window" menu item */
-	menu_item = gtk_image_menu_item_new_with_label (_("Open in New Window"));
+	menu_item = gtk_menu_item_new_with_mnemonic (_("Open in New _Window"));
 	g_signal_connect (menu_item, "activate",
 			  G_CALLBACK (fm_tree_view_open_in_new_window_cb),
 			  view);
@@ -1223,6 +1281,7 @@
 	GList *mounts, *l;
 	char *location;
 	GIcon *icon;
+	NautilusWindowSlotInfo *slot;
 	
 	view->details->child_model = fm_tree_model_new ();
 	view->details->sort_model = GTK_TREE_MODEL_SORT
@@ -1323,7 +1382,8 @@
 			  "button_press_event", G_CALLBACK (button_pressed_callback),
 			  view);
 
-	location = nautilus_window_info_get_current_location (view->details->window);
+	slot = nautilus_window_info_get_active_slot (view->details->window);
+	location = nautilus_window_slot_info_get_current_location (slot);
 	schedule_select_and_show_location (view, location);
 	g_free (location);
 }
@@ -1348,9 +1408,6 @@
 			(view->details->child_model,
 			 mode == NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_ENABLE);
 	}
-	fm_tree_model_set_show_backup_files
-		(view->details->child_model,
-		 eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SHOW_BACKUP_FILES));
 	fm_tree_model_set_show_only_directories
 		(view->details->child_model,
 		 eel_preferences_get_boolean (NAUTILUS_PREFERENCES_TREE_SHOW_ONLY_DIRECTORIES));
@@ -1380,8 +1437,11 @@
 static void
 loading_uri_callback (NautilusWindowInfo *window,
 		      char *location,
-		      FMTreeView *view)
+		      gpointer callback_data)
 {
+	FMTreeView *view;
+
+	view = FM_TREE_VIEW (callback_data);
 	schedule_select_and_show_location (view, location);
 }
 
@@ -1541,12 +1601,15 @@
 				NautilusWindowInfo *window)
 {
 	char *location;
+	NautilusWindowSlotInfo *slot;
 	
 	sidebar->details->window = window;
 
+	slot = nautilus_window_info_get_active_slot (window);
+
 	g_signal_connect_object (window, "loading_uri",
 				 G_CALLBACK (loading_uri_callback), sidebar, 0);
-	location = nautilus_window_info_get_current_location (window);
+	location = nautilus_window_slot_info_get_current_location (slot);
 	loading_uri_callback (window, location, sidebar);
 	g_free (location);
 

Modified: trunk/src/file-manager/nautilus-directory-view-ui.xml
==============================================================================
--- trunk/src/file-manager/nautilus-directory-view-ui.xml	(original)
+++ trunk/src/file-manager/nautilus-directory-view-ui.xml	Tue Jul  8 21:05:55 2008
@@ -17,6 +17,7 @@
 		</placeholder>
 		<placeholder name="Open Placeholder">
 			<menuitem name="Open" action="Open"/>
+			<menuitem name="OpenInNewTab" action="OpenInNewTab"/>
 			<menuitem name="OpenAlternate" action="OpenAlternate"/>
 			<placeholder name="Applications Placeholder">
                         </placeholder>
@@ -116,6 +117,7 @@
 <popup name="selection">
 	<placeholder name="Open Placeholder">
 		<menuitem name="Open" action="Open"/>
+		<menuitem name="OpenInNewTab" action="OpenInNewTab"/>
 		<menuitem name="OpenAlternate" action="OpenAlternate"/>
 		<menuitem name="OpenFolderWindow" action="OpenFolderWindow"/>
 		<separator name="applications separator"/>

Modified: trunk/src/nautilus-actions.h
==============================================================================
--- trunk/src/nautilus-actions.h	(original)
+++ trunk/src/nautilus-actions.h	Tue Jul  8 21:05:55 2008
@@ -46,8 +46,11 @@
 #define NAUTILUS_ACTION_ZOOM_IN "Zoom In"
 #define NAUTILUS_ACTION_ZOOM_OUT "Zoom Out"
 #define NAUTILUS_ACTION_ZOOM_NORMAL "Zoom Normal"
+#define NAUTILUS_ACTION_SHOW_HIDDEN_FILES "Show Hidden Files"
 #define NAUTILUS_ACTION_CLOSE "Close"
 #define NAUTILUS_ACTION_SEARCH "Search"
 #define NAUTILUS_ACTION_FOLDER_WINDOW "Folder Window"
+#define NAUTILUS_ACTION_TABS "Tabs"
+#define NAUTILUS_ACTION_NEW_TAB "New Tab"
 
 #endif /* NAUTILUS_ACTIONS_H */

Modified: trunk/src/nautilus-application.c
==============================================================================
--- trunk/src/nautilus-application.c	(original)
+++ trunk/src/nautilus-application.c	Tue Jul  8 21:05:55 2008
@@ -888,18 +888,18 @@
 nautilus_application_get_existing_spatial_window (GFile *location)
 {
 	GList *l;
+	NautilusWindowSlot *slot;
 
 	for (l = nautilus_application_get_spatial_window_list ();
 	     l != NULL; l = l->next) {
 		GFile *window_location;
 
-		window_location = nautilus_window_get_location (NAUTILUS_WINDOW (l->data));
+		slot = NAUTILUS_WINDOW (l->data)->details->active_slot;
+		window_location = slot->location;
 		if (window_location != NULL) {
 			if (g_file_equal (location, window_location)) {
-				g_object_unref (window_location);
 				return NAUTILUS_SPATIAL_WINDOW (l->data);
 			}
-			g_object_unref (window_location);
 		}
 	}
 	return NULL;
@@ -910,14 +910,16 @@
 {
 	NautilusFile *file;
 	NautilusFile *parent_file;
+	NautilusWindowSlot *slot;
 	GFile *location;
 
-	location = nautilus_window_get_location (NAUTILUS_WINDOW (window));
+	slot = NAUTILUS_WINDOW (window)->details->active_slot;
+
+	location = slot->location;
 	if (location == NULL) {
 		return NULL;
 	}
 	file = nautilus_file_get (location);
-	g_object_unref (location);
 
 	if (!file) {
 		return NULL;
@@ -1159,13 +1161,15 @@
 	for (l = nautilus_application_get_spatial_window_list ();
 	     l != NULL; l = l->next) {
 		NautilusWindow *existing_window;
+		NautilusWindowSlot *slot;
 		GFile *existing_location;
-               	     
+
 		existing_window = NAUTILUS_WINDOW (l->data);
-		existing_location = existing_window->details->pending_location;
+		slot = existing_window->details->active_slot;
+		existing_location = slot->pending_location;
 		
 		if (existing_location == NULL) {
-			existing_location = existing_window->details->location;
+			existing_location = slot->location;
 		}
 		
 		if (g_file_equal (existing_location, location)) {
@@ -1176,8 +1180,8 @@
 
 			gtk_window_present (GTK_WINDOW (existing_window));
 			if (new_selection &&
-			    existing_window->content_view != NULL) {
-				nautilus_view_set_selection (existing_window->content_view, new_selection);
+			    slot->content_view != NULL) {
+				nautilus_view_set_selection (slot->content_view, new_selection);
 			}
 
 			uri = g_file_get_uri (location);
@@ -1449,6 +1453,7 @@
 {
 	GList *window_list, *node, *close_list;
 	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	GFile *root;
 
 	close_list = NULL;
@@ -1460,25 +1465,27 @@
 	/* Construct a list of windows to be closed. Do not add the non-closable windows to the list. */
 	for (node = window_list; node != NULL; node = node->next) {
 		window = NAUTILUS_WINDOW (node->data);
-		if (window != NULL && window_can_be_closed (window)) {
-			GFile *location;
-
-			location = nautilus_window_get_location (window);
-
-			if (g_file_equal(location, root) || g_file_has_prefix (location, root)) {
-				close_list = g_list_prepend (close_list, window);
-			} 
-			g_object_unref (location);
+  		if (window != NULL && window_can_be_closed (window)) {
+			GList *l;
+  			GFile *location;
+  
+			for (l = window->details->slots; l != NULL; l = l->next) {
+				slot = l->data;
+				location = slot->location;
+				if (g_file_has_prefix (location, root)) {
+					close_list = g_list_prepend (close_list, slot);
+				} 
+			}
 		}
 	}
 
 	/* Handle the windows in the close list. */
 	for (node = close_list; node != NULL; node = node->next) {
-		window = NAUTILUS_WINDOW (node->data);
+		slot = node->data;
 		if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
-			nautilus_window_close (window);
+			nautilus_window_slot_close (slot);
 		} else {
-			nautilus_window_go_home (window);
+			nautilus_window_go_home (slot->window);
 		}
 	}
 
@@ -1585,8 +1592,10 @@
 	}
 
 	for (l = nautilus_application_window_list; l != NULL; l = l->next) {
-		xmlNodePtr win_node;
+		xmlNodePtr win_node, slot_node;
 		NautilusWindow *window;
+		NautilusWindowSlot *slot, *active_slot;
+		GList *slots, *m;
 		char *tmp;
 
 		window = l->data;
@@ -1616,9 +1625,30 @@
 			}
 		}
 
-		tmp = nautilus_window_get_location_uri (window);
+		slots = nautilus_window_get_slots (window);
+		active_slot = nautilus_window_get_active_slot (window);
+
+		/* store one slot as window location. Otherwise
+		 * older Nautilus versions will bail when reading the file. */
+		tmp = nautilus_window_slot_get_location_uri (active_slot);
 		xmlNewProp (win_node, "location", tmp);
 		g_free (tmp);
+
+		for (m = slots; m != NULL; m = m->next) {
+			slot = NAUTILUS_WINDOW_SLOT (m->data);
+
+			slot_node = xmlNewChild (win_node, NULL, "slot", NULL);
+
+			tmp = nautilus_window_slot_get_location_uri (slot);
+			xmlNewProp (slot_node, "location", tmp);
+			g_free (tmp);
+
+			if (slot == active_slot) {
+				xmlNewProp (slot_node, "active", "TRUE");
+			}
+		}
+
+		g_list_free (slots);
 	}
 
 	dir = nautilus_get_user_directory ();
@@ -1722,8 +1752,10 @@
 					}
 				} else if (!strcmp (node->name, "window")) {
 					NautilusWindow *window;
-					xmlChar *type, *location_uri;
+					xmlChar *type, *location_uri, *slot_uri;
+					xmlNodePtr slot_node;
 					GFile *location;
+					int i;
 
 					type = xmlGetProp (node, "type");
 					if (type == NULL) {
@@ -1774,9 +1806,37 @@
 							gtk_window_set_keep_above (GTK_WINDOW (window), FALSE);
 						}
 
-						location = g_file_new_for_uri (location_uri);
-						nautilus_window_open_location (window, location, FALSE);
-						g_object_unref (location);
+						for (i = 0, slot_node = node->children; slot_node != NULL; slot_node = slot_node->next) {
+							if (!strcmp (slot_node->name, "slot")) {
+								slot_uri = xmlGetProp (slot_node, "location");
+								if (slot_uri != NULL) {
+									NautilusWindowSlot *slot;
+
+									if (i == 0) {
+										slot = window->details->active_slot;
+									} else {
+										slot = nautilus_window_open_slot (window, NAUTILUS_WINDOW_OPEN_SLOT_APPEND);
+									}
+
+									location = g_file_new_for_uri (slot_uri);
+									nautilus_window_slot_open_location (slot, location, FALSE);
+
+									if (xmlHasProp (slot_node, "active")) {
+										nautilus_window_set_active_slot (window, slot);
+									}
+
+									i++;
+								}
+								xmlFree (slot_uri);
+							}
+						}
+
+						if (i == 0) {
+							/* This may be an old session file */
+							location = g_file_new_for_uri (location_uri);
+							nautilus_window_slot_open_location (window->details->active_slot, location, FALSE);
+							g_object_unref (location);
+						}
 					} else if (!strcmp (type, "spatial")) {
 						location = g_file_new_for_uri (location_uri);
 						window = nautilus_application_present_spatial_window (application, NULL, NULL, location, gdk_screen_get_default ());

Modified: trunk/src/nautilus-desktop-window.c
==============================================================================
--- trunk/src/nautilus-desktop-window.c	(original)
+++ trunk/src/nautilus-desktop-window.c	Tue Jul  8 21:05:55 2008
@@ -237,14 +237,6 @@
 			  G_CALLBACK (nautilus_desktop_window_screen_size_changed), window);
 }
 
-static void
-real_add_current_location_to_history_list (NautilusWindow *window)
-{
-	/* Do nothing. The desktop window's location should not
-	 * show up in the history list.
-	 */
-}
-
 static char *
 real_get_title (NautilusWindow *window)
 {
@@ -252,7 +244,8 @@
 }
 
 static NautilusIconInfo *
-real_get_icon (NautilusWindow *window)
+real_get_icon (NautilusWindow *window,
+	       NautilusWindowSlot *slot)
 {
 	return nautilus_icon_info_lookup_from_name (NAUTILUS_ICON_DESKTOP, 48);
 }
@@ -269,8 +262,6 @@
 
 	NAUTILUS_WINDOW_CLASS (class)->window_type = NAUTILUS_WINDOW_DESKTOP;
 
-	NAUTILUS_WINDOW_CLASS (class)->add_current_location_to_history_list 
-		= real_add_current_location_to_history_list;
 	NAUTILUS_WINDOW_CLASS (class)->get_title 
 		= real_get_title;
 	NAUTILUS_WINDOW_CLASS (class)->get_icon

Modified: trunk/src/nautilus-history-sidebar.c
==============================================================================
--- trunk/src/nautilus-history-sidebar.c	(original)
+++ trunk/src/nautilus-history-sidebar.c	Tue Jul  8 21:05:55 2008
@@ -39,6 +39,8 @@
 #include <libnautilus-private/nautilus-sidebar-provider.h>
 #include <libnautilus-private/nautilus-module.h>
 #include <libnautilus-private/nautilus-signaller.h>
+#include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
 
 #include "nautilus-history-sidebar.h"
 
@@ -131,19 +133,17 @@
 }
 
 static void
-row_activated_callback (GtkTreeView *tree_view,
-			GtkTreePath *path,
-			GtkTreeViewColumn *column,
-			gpointer user_data)
+open_selected_item (NautilusHistorySidebar *sidebar, 
+		    GtkTreePath *path,
+		    NautilusWindowOpenFlags flags)
 {
-	NautilusHistorySidebar *sidebar;
+	NautilusWindowSlotInfo *slot;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	NautilusBookmark *bookmark;
 	GFile *location;
 	
-	sidebar = NAUTILUS_HISTORY_SIDEBAR (user_data);
-	model = gtk_tree_view_get_model (tree_view);
+	model = gtk_tree_view_get_model (sidebar->tree_view);
 	
 	if (!gtk_tree_model_get_iter (model, &iter, path)) {
 		return;
@@ -154,13 +154,55 @@
 	
 	/* Navigate to the clicked location. */
 	location = nautilus_bookmark_get_location (NAUTILUS_BOOKMARK (bookmark));
-	nautilus_window_info_open_location
-		(sidebar->window, 
-		 location, NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, 0, NULL);
+	slot = nautilus_window_info_get_active_slot (sidebar->window);
+	nautilus_window_slot_info_open_location
+		(slot,
+		 location, NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, 
+		 flags, NULL);
 	g_object_unref (location);
 }
 
 static void
+row_activated_callback (GtkTreeView *tree_view,
+			GtkTreePath *path,
+			GtkTreeViewColumn *column,
+			gpointer user_data)
+{
+	NautilusHistorySidebar *sidebar;
+	
+	sidebar = NAUTILUS_HISTORY_SIDEBAR (user_data);
+	g_assert (sidebar->tree_view == tree_view);
+
+	open_selected_item (sidebar, path, 0);
+}
+
+static gboolean
+button_press_event_callback (GtkWidget *widget,
+			     GdkEventButton *event,
+			     gpointer user_data)
+{
+	if (event->button == 2 && event->type == GDK_BUTTON_PRESS) {
+		/* Open new tab on middle click. */
+		NautilusHistorySidebar *sidebar;
+		GtkTreePath *path;
+
+		sidebar = NAUTILUS_HISTORY_SIDEBAR (user_data);
+		g_assert (sidebar->tree_view == GTK_TREE_VIEW (widget));
+
+		if (gtk_tree_view_get_path_at_pos (sidebar->tree_view,
+						   event->x, event->y,
+						   &path, NULL, NULL, NULL)) {
+			open_selected_item (sidebar, 
+					    path,
+					    NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB);
+			gtk_tree_path_free (path);
+		}
+	}
+
+	return FALSE;
+}
+
+static void
 update_click_policy (NautilusHistorySidebar *sidebar)
 {
 	int policy;
@@ -240,6 +282,9 @@
 				 "history_list_changed",
 				 G_CALLBACK (history_changed_callback), sidebar, 0);
 
+	g_signal_connect (tree_view, "button-press-event", 
+			  G_CALLBACK (button_press_event_callback), sidebar);
+
 	eel_preferences_add_callback (NAUTILUS_PREFERENCES_CLICK_POLICY,
 				      click_policy_changed_callback,
 				      sidebar);

Modified: trunk/src/nautilus-information-panel.c
==============================================================================
--- trunk/src/nautilus-information-panel.c	(original)
+++ trunk/src/nautilus-information-panel.c	Tue Jul  8 21:05:55 2008
@@ -1097,10 +1097,13 @@
 		      char               *uri,
 		      NautilusInformationPanel *panel)
 {
+	NautilusWindowSlotInfo *slot;
 	char *title;
 
-	title = nautilus_window_info_get_title (window);
-	nautilus_information_panel_set_uri (panel, 
+	slot = nautilus_window_info_get_active_slot (window);
+
+	title = nautilus_window_slot_info_get_title (slot);
+	nautilus_information_panel_set_uri (panel,
 					    uri,
 					    title);
 	g_free (title);
@@ -1110,6 +1113,7 @@
 nautilus_information_panel_set_parent_window (NautilusInformationPanel *panel,
 					      NautilusWindowInfo *window)
 {
+	gpointer slot;
 	char *title, *location;
 
 	panel->details->window = window;
@@ -1118,9 +1122,11 @@
 				 G_CALLBACK (loading_uri_callback), panel, 0);
 	g_signal_connect_object (window, "title_changed",
 				 G_CALLBACK (title_changed_callback), panel, 0);
+
+	slot = nautilus_window_info_get_active_slot (window);
 	
-	title = nautilus_window_info_get_title (window);
-	location = nautilus_window_info_get_current_location (window);
+	title = nautilus_window_slot_info_get_title (slot);
+	location = nautilus_window_slot_info_get_current_location (slot);
 	nautilus_information_panel_set_uri (panel, 
 					    location,
 					    title);

Modified: trunk/src/nautilus-location-bar.c
==============================================================================
--- trunk/src/nautilus-location-bar.c	(original)
+++ trunk/src/nautilus-location-bar.c	Tue Jul  8 21:05:55 2008
@@ -259,6 +259,7 @@
 			       GdkEventButton        *event)
 {
 	NautilusNavigationWindow *window;
+	NautilusWindowSlot       *slot;
 	NautilusView             *view;
 	GtkWidget                *label;
 
@@ -267,7 +268,8 @@
 	}
 
 	window = nautilus_location_bar_get_window (widget->parent);
-	view = NAUTILUS_WINDOW (window)->content_view;
+	slot = NAUTILUS_WINDOW (window)->details->active_slot;
+	view = slot->content_view;
 	label = GTK_BIN (widget)->child;
 	/* only pop-up if the URI in the entry matches the displayed location */
 	if (view == NULL ||

Modified: trunk/src/nautilus-location-dialog.c
==============================================================================
--- trunk/src/nautilus-location-dialog.c	(original)
+++ trunk/src/nautilus-location-dialog.c	Tue Jul  8 21:05:55 2008
@@ -199,6 +199,7 @@
 GtkWidget *
 nautilus_location_dialog_new (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GtkWidget *dialog;
 	GFile *location;
 	char *formatted_location;
@@ -211,9 +212,10 @@
 				       gtk_window_get_screen (GTK_WINDOW (window)));
 		NAUTILUS_LOCATION_DIALOG (dialog)->details->window = window;
 	}
-	
 
-	location = nautilus_window_get_location (window);
+	slot = window->details->active_slot;
+
+	location = slot->location;
 	if (location != NULL) {
 		if (NAUTILUS_IS_DESKTOP_WINDOW (window)) {
 			formatted_location = g_strdup_printf ("%s/", g_get_home_dir ());
@@ -224,7 +226,6 @@
 		gtk_editable_select_region (GTK_EDITABLE (NAUTILUS_LOCATION_DIALOG (dialog)->details->entry), 0, -1);
 		gtk_editable_set_position (GTK_EDITABLE (NAUTILUS_LOCATION_DIALOG (dialog)->details->entry), -1);
 		g_free (formatted_location);
-		g_object_unref (location);
 	}
 	
 	gtk_widget_grab_focus (NAUTILUS_LOCATION_DIALOG (dialog)->details->entry);

Modified: trunk/src/nautilus-navigation-action.c
==============================================================================
--- trunk/src/nautilus-navigation-action.c	(original)
+++ trunk/src/nautilus-navigation-action.c	Tue Jul  8 21:05:55 2008
@@ -31,6 +31,8 @@
 
 #include "nautilus-navigation-action.h"
 #include "nautilus-navigation-window.h"
+#include "nautilus-window-private.h"
+#include "nautilus-navigation-window-slot.h"
 
 #include <gtk/gtk.h>
 
@@ -82,6 +84,22 @@
 	return type;
 }
 
+static gboolean
+should_open_in_new_tab (void)
+{
+	/* FIXME this is duplicated */
+	GdkEvent *event;
+
+	event = gtk_get_current_event ();
+	if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) {
+		return event->button.button == 2;
+	}
+
+	gdk_event_free (event);
+
+	return FALSE;
+}
+
 static void
 activate_back_or_forward_menu_item (GtkMenuItem *menu_item, 
 				    NautilusNavigationWindow *window,
@@ -94,7 +112,7 @@
 
 	index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "user_data"));
 
-	nautilus_navigation_window_back_or_forward (window, back, index);
+	nautilus_navigation_window_back_or_forward (window, back, index, should_open_in_new_tab ());
 }
 
 static void
@@ -114,13 +132,16 @@
 	   GtkWidget *menu,
 	   gboolean back)
 {
+	NautilusNavigationWindowSlot *slot;
 	GtkWidget *menu_item;
 	int index;
 	GList *list;
 
 	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
+
+	slot = NAUTILUS_NAVIGATION_WINDOW_SLOT (NAUTILUS_WINDOW (window)->details->active_slot);
 	
-	list = back ? window->back_list : window->forward_list;
+	list = back ? slot->back_list : slot->forward_list;
 	index = 0;
 	while (list != NULL) {
 		menu_item = nautilus_bookmark_menu_item_new (NAUTILUS_BOOKMARK (list->data));
@@ -173,6 +194,30 @@
 	}
 }
 
+static gboolean
+proxy_button_press_event_cb (GtkButton *button,
+			     GdkEventButton *event,
+			     gpointer user_data)
+{
+	if (event->button == 2) {
+		gtk_button_pressed (button);
+	}
+
+	return FALSE;
+}
+
+static gboolean
+proxy_button_release_event_cb (GtkButton *button,
+			       GdkEventButton *event,
+			       gpointer user_data)
+{
+	if (event->button == 2) {
+		gtk_button_released (button);
+	}
+
+	return FALSE;
+}
+
 static void
 connect_proxy (GtkAction *action, GtkWidget *proxy)
 {
@@ -180,6 +225,8 @@
 		NautilusNavigationAction *naction = NAUTILUS_NAVIGATION_ACTION (action);
 		GtkMenuToolButton *button = GTK_MENU_TOOL_BUTTON (proxy);
 		GtkWidget *menu;
+		GtkContainer *container;
+		GtkWidget *child;
 
 		/* set an empty menu, so the arrow button becomes sensitive */
 		menu = gtk_menu_new ();
@@ -190,6 +237,13 @@
 		
 		g_signal_connect (proxy, "show-menu",
 				  G_CALLBACK (show_menu_callback), action);
+
+		/* Make sure that middle click works. Note that there is some code duplication
+		 * between here and nautilus-window-menus.c */
+		container = GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (proxy)));
+		child = GTK_WIDGET (gtk_container_get_children (container)->data);
+		g_signal_connect (child, "button-press-event", G_CALLBACK (proxy_button_press_event_cb), NULL);
+		g_signal_connect (child, "button-release-event", G_CALLBACK (proxy_button_release_event_cb), NULL);
 	}
 
 	(* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
@@ -199,7 +253,15 @@
 disconnect_proxy (GtkAction *action, GtkWidget *proxy)
 {
 	if (GTK_IS_MENU_TOOL_BUTTON (proxy)) {
+		GtkContainer *container;
+		GtkWidget *child;
+		
 		g_signal_handlers_disconnect_by_func (proxy, G_CALLBACK (show_menu_callback), action);
+
+		container = GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (proxy)));
+		child = GTK_WIDGET (gtk_container_get_children (container)->data);
+		g_signal_handlers_disconnect_by_func (child, G_CALLBACK (proxy_button_press_event_cb), NULL);
+		g_signal_handlers_disconnect_by_func (child, G_CALLBACK (proxy_button_release_event_cb), NULL);
 	}
 
 	(* GTK_ACTION_CLASS (parent_class)->disconnect_proxy) (action, proxy);

Modified: trunk/src/nautilus-navigation-window-menus.c
==============================================================================
--- trunk/src/nautilus-navigation-window-menus.c	(original)
+++ trunk/src/nautilus-navigation-window-menus.c	Tue Jul  8 21:05:55 2008
@@ -30,6 +30,7 @@
 #include <locale.h> 
 
 #include "nautilus-actions.h"
+#include "nautilus-notebook.h"
 #include "nautilus-navigation-action.h"
 #include "nautilus-application.h"
 #include "nautilus-bookmark-list.h"
@@ -59,6 +60,7 @@
 #include <libnautilus-private/nautilus-signaller.h>
 
 #define MENU_PATH_HISTORY_PLACEHOLDER			"/MenuBar/Other Menus/Go/History Placeholder"
+#define MENU_PATH_TABS_PLACEHOLDER			"/MenuBar/Other Menus/Tabs/TabsOpen"
 
 #define RESPONSE_FORGET		1000
 #define MENU_ITEM_MAX_WIDTH_CHARS 32
@@ -72,18 +74,36 @@
 	nautilus_application_close_all_navigation_windows ();
 }
 
+static gboolean
+should_open_in_new_tab (void)
+{
+	/* FIXME this is duplicated */
+	GdkEvent *event;
+
+	event = gtk_get_current_event ();
+	if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) {
+		return event->button.button == 2;
+	}
+
+	gdk_event_free (event);
+
+	return FALSE;
+}
+
 static void
 action_back_callback (GtkAction *action, 
 		      gpointer user_data) 
 {
-	nautilus_navigation_window_go_back (NAUTILUS_NAVIGATION_WINDOW (user_data));
+	nautilus_navigation_window_back_or_forward (NAUTILUS_NAVIGATION_WINDOW (user_data), 
+						    TRUE, 0, should_open_in_new_tab ());
 }
 
 static void
 action_forward_callback (GtkAction *action, 
 			 gpointer user_data) 
 {
-	nautilus_navigation_window_go_forward (NAUTILUS_NAVIGATION_WINDOW (user_data));
+	nautilus_navigation_window_back_or_forward (NAUTILUS_NAVIGATION_WINDOW (user_data), 
+			                            TRUE, 0, should_open_in_new_tab ());
 }
 
 static void
@@ -244,6 +264,23 @@
 				!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER));
 }
 
+void
+nautilus_navigation_window_update_tab_menu_item_visibility (NautilusNavigationWindow *window) 
+{
+	GtkAction *action;
+
+	action = gtk_action_group_get_action (window->details->navigation_action_group,
+					      NAUTILUS_ACTION_TABS);
+	gtk_action_set_visible (action,
+				eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS));
+
+	action = gtk_action_group_get_action (window->details->navigation_action_group,
+					      NAUTILUS_ACTION_NEW_TAB);
+	gtk_action_set_visible (action,
+				eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS));
+
+}
+
 static void
 action_add_bookmark_callback (GtkAction *action,
 			      gpointer user_data)
@@ -413,6 +450,200 @@
 }
 
 static void
+update_tab_action_sensitivity (NautilusNavigationWindow *window)
+{
+	GtkActionGroup *action_group;
+	GtkAction *action;
+	NautilusNotebook *notebook;
+	gboolean sensitive;
+	int tab_num;
+
+	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
+
+	notebook = NAUTILUS_NOTEBOOK (window->notebook);
+	action_group = window->details->navigation_action_group;
+
+	action = gtk_action_group_get_action (action_group, "TabsPrevious");
+	sensitive = nautilus_notebook_can_set_current_page_relative (notebook, -1);
+	g_object_set (action, "sensitive", sensitive, NULL);
+
+	action = gtk_action_group_get_action (action_group, "TabsNext");
+	sensitive = nautilus_notebook_can_set_current_page_relative (notebook, 1);
+	g_object_set (action, "sensitive", sensitive, NULL);
+
+	action = gtk_action_group_get_action (action_group, "TabsMoveLeft");
+	sensitive = nautilus_notebook_can_reorder_current_child_relative (notebook, -1);
+	g_object_set (action, "sensitive", sensitive, NULL);
+
+	action = gtk_action_group_get_action (action_group, "TabsMoveRight");
+	sensitive = nautilus_notebook_can_reorder_current_child_relative (notebook, 1);
+	g_object_set (action, "sensitive", sensitive, NULL);
+
+	action_group = window->details->tabs_menu_action_group;
+	tab_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
+	action = gtk_action_group_get_action (action_group, "Tab0");
+	if (tab_num >= 0 && action != NULL) {
+		gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), tab_num);
+	}
+}
+
+static void
+tab_menu_action_activate_callback (GtkAction *action,
+				   gpointer user_data)
+{
+	int num;
+	GtkWidget *notebook;
+	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	notebook = window->notebook;
+
+	num = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), num);		       
+}
+
+static void
+reload_tab_menu (NautilusNavigationWindow *window)
+{
+	GtkRadioAction *action;
+	GtkUIManager *ui_manager;
+	int i;
+	gchar action_name[80];
+	gchar *action_label;
+	gchar accelerator[80];
+	GSList *radio_group;
+	NautilusWindowSlot *slot;
+	GtkNotebook *notebook;
+	
+	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
+
+	/* Remove old tab menu items */
+	ui_manager = nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window));
+	if (window->details->tabs_menu_merge_id != 0) {
+		gtk_ui_manager_remove_ui (ui_manager,
+					  window->details->tabs_menu_merge_id);
+		window->details->tabs_menu_merge_id = 0;
+	}
+	if (window->details->tabs_menu_action_group != NULL) {
+		gtk_ui_manager_remove_action_group (ui_manager,
+						    window->details->tabs_menu_action_group);
+		window->details->tabs_menu_action_group = NULL;
+	}
+
+	/* Add new tab menu items */
+	window->details->tabs_menu_merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+	window->details->tabs_menu_action_group = gtk_action_group_new ("TabsMenuGroup");
+	
+	gtk_ui_manager_insert_action_group (ui_manager,
+					    window->details->tabs_menu_action_group,
+					    -1);
+	g_object_unref (window->details->tabs_menu_action_group);
+
+	notebook = GTK_NOTEBOOK (window->notebook);
+	radio_group = NULL;
+	for (i = 0; i < gtk_notebook_get_n_pages (notebook); i++) {
+
+		snprintf(action_name, sizeof (action_name), "Tab%d", i);
+
+		slot = nautilus_window_get_slot_for_content_box (NAUTILUS_WINDOW (window),
+								 gtk_notebook_get_nth_page (notebook, i));
+		if (slot) {
+			action_label = g_strdup (slot->title);
+		} else {
+			/* Give the action a generic label. This should only happen when the tab is created
+			 * and the slot has not yet be created, so if all goes to plan then the action label
+			 * will be updated when the slot is created. */
+			action_label = g_strdup_printf ("Tab %d", i);
+		}
+
+		action = gtk_radio_action_new (action_name, action_label, NULL, NULL, i);
+
+		g_free (action_label);
+		action_label = NULL;
+		
+		gtk_radio_action_set_group (action, radio_group);
+		radio_group = gtk_radio_action_get_group (action);
+		
+		g_signal_connect (action, "activate", 
+				  G_CALLBACK (tab_menu_action_activate_callback),
+				  window);
+
+		/* Use Alt+(Number) keyboard accelerators for first 10 tabs */
+		if (i < 10) {
+			snprintf(accelerator, sizeof (accelerator), "<Alt>%d", (i+1)%10);
+		} else {
+			accelerator[0] = '\0';
+		}
+		gtk_action_group_add_action_with_accel (window->details->tabs_menu_action_group, 
+							GTK_ACTION (action),
+							accelerator);
+		
+		g_object_unref (action);
+		
+		gtk_ui_manager_add_ui (ui_manager, 
+				       window->details->tabs_menu_merge_id,
+				       MENU_PATH_TABS_PLACEHOLDER,
+				       action_name,
+				       action_name,
+				       GTK_UI_MANAGER_MENUITEM,
+				       FALSE);
+	}
+
+	update_tab_action_sensitivity (window);
+}
+
+static void 
+nautilus_navigation_window_initialize_tabs_menu (NautilusNavigationWindow *window)
+{
+	g_signal_connect_object (window->notebook, "page-added",
+				 G_CALLBACK (reload_tab_menu), window, G_CONNECT_SWAPPED);
+	g_signal_connect_object (window->notebook, "page-removed",
+				 G_CALLBACK (reload_tab_menu), window, G_CONNECT_SWAPPED);
+	g_signal_connect_object (window->notebook, "page-reordered",
+				 G_CALLBACK (reload_tab_menu), window, G_CONNECT_SWAPPED);
+	g_signal_connect_object (window->notebook, "switch-page",
+				 G_CALLBACK (update_tab_action_sensitivity), window,
+				 G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+
+	reload_tab_menu (window);
+}
+
+/* Update the label displayed in the "Tabs" menu. This is called when the title of
+ * a slot changes. */
+void
+nautilus_navigation_window_sync_tab_menu_title (NautilusNavigationWindow *window,
+						NautilusWindowSlot *slot)
+{
+	int tab_num;
+	GtkNotebook *notebook;
+	GtkAction *action;
+	GtkActionGroup *action_group;
+	char action_name[80];
+
+	notebook = GTK_NOTEBOOK (window->notebook);
+
+	/* Find the tab number for that slot. It should (almost?) always be the current
+	 * tab, so check that first in order to avoid searching through the entire tab 
+	 * list. */
+	tab_num = gtk_notebook_get_current_page (notebook);
+	if (slot->content_box != gtk_notebook_get_nth_page (notebook, tab_num)) {
+		tab_num = gtk_notebook_page_num (notebook, slot->content_box);
+	}
+
+	g_return_if_fail (tab_num >= 0);
+
+	/* Find the action associated with that tab */
+	action_group = window->details->tabs_menu_action_group;
+	snprintf (action_name, sizeof (action_name), "Tab%d", tab_num);
+	action = gtk_action_group_get_action (action_group, action_name);
+
+	/* Update the label */
+	g_return_if_fail (action);
+	g_object_set (action, "label", slot->title, NULL);
+}
+
+static void
 action_new_window_callback (GtkAction *action,
 			    gpointer user_data)
 {
@@ -428,14 +659,60 @@
 }
 
 static void
+action_new_tab_callback (GtkAction *action,
+			 gpointer user_data)
+{
+	NautilusWindow *window;
+	NautilusWindowSlot *current_slot;
+	NautilusWindowSlot *new_slot;
+	NautilusWindowOpenFlags flags;
+	GFile *location;
+	int new_slot_position;
+	char *scheme;
+
+	if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)) {
+		return;
+	}
+
+	window = NAUTILUS_WINDOW (user_data);
+	current_slot = window->details->active_slot;
+	location = nautilus_window_slot_get_location (current_slot);
+
+	window = NAUTILUS_WINDOW (current_slot->window);
+
+	if (location != NULL) {
+		flags = 0;
+
+		new_slot_position = eel_preferences_get_enum (NAUTILUS_PREFERENCES_NEW_TAB_POSITION);
+		if (new_slot_position == NAUTILUS_NEW_TAB_POSITION_END) {
+			flags = NAUTILUS_WINDOW_OPEN_SLOT_APPEND;
+		}
+
+		scheme = g_file_get_uri_scheme (location);
+		if (!strcmp (scheme, "x-nautilus-search")) {
+			g_object_unref (location);
+			location = g_file_new_for_path (g_get_home_dir ());
+		}
+		g_free (scheme);
+
+		new_slot = nautilus_window_open_slot (window, flags);
+		nautilus_window_set_active_slot (window, new_slot);
+		nautilus_window_slot_go_to (new_slot, location, FALSE);
+		g_object_unref (location);
+	}
+}
+
+static void
 action_folder_window_callback (GtkAction *action,
 			       gpointer user_data)
 {
 	NautilusWindow *current_window;
+	NautilusWindowSlot *slot;
 	GFile *current_location;
 
 	current_window = NAUTILUS_WINDOW (user_data);
-	current_location = nautilus_window_get_location (current_window);
+	slot = current_window->details->active_slot;
+	current_location = nautilus_window_slot_get_location (slot);
 	nautilus_application_present_spatial_window (
 			current_window->application,
 			current_window,
@@ -469,12 +746,56 @@
 	nautilus_navigation_window_show_search (window);
 }
 
+static void
+action_tabs_previous_callback (GtkAction *action,
+			       gpointer user_data)
+{
+	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	nautilus_notebook_set_current_page_relative (NAUTILUS_NOTEBOOK (window->notebook), -1);
+}
+
+static void
+action_tabs_next_callback (GtkAction *action,
+			   gpointer user_data)
+{
+	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	nautilus_notebook_set_current_page_relative (NAUTILUS_NOTEBOOK (window->notebook), 1);
+}
+
+static void
+action_tabs_move_left_callback (GtkAction *action,
+				gpointer user_data)
+{
+	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	nautilus_notebook_reorder_current_child_relative (NAUTILUS_NOTEBOOK (window->notebook), -1);
+}
+
+static void
+action_tabs_move_right_callback (GtkAction *action,
+				 gpointer user_data)
+{
+	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	nautilus_notebook_reorder_current_child_relative (NAUTILUS_NOTEBOOK (window->notebook), 1);
+}
+
 static const GtkActionEntry navigation_entries[] = {
   /* name, stock id, label */  { "Go", NULL, N_("_Go") },
   /* name, stock id, label */  { "Bookmarks", NULL, N_("_Bookmarks") },
+  /* name, stock id, label */  { "Tabs", NULL, N_("_Tabs") },
   /* name, stock id, label */  { "New Window", "window-new", N_("New _Window"),
                                  "<control>N", N_("Open another Nautilus window for the displayed location"),
                                  G_CALLBACK (action_new_window_callback) },
+  /* name, stock id, label */  { "New Tab", "tab-new", N_("New _Tab"),
+                                 "<control>T", N_("Open another tab for the displayed location"),
+                                 G_CALLBACK (action_new_tab_callback) },
   /* name, stock id, label */  { "Folder Window", "folder", N_("Open Folder W_indow"),
                                  NULL, N_("Open a folder window for the displayed location"),
                                  G_CALLBACK (action_folder_window_callback) },
@@ -496,7 +817,20 @@
   /* name, stock id, label */  { "Search", "gtk-find", N_("_Search for Files..."),
                                  "<control>F", N_("Locate documents and folders on this computer by name or content"),
                                  G_CALLBACK (action_search_callback) },
-		     
+
+	{ "TabsPrevious", NULL, N_("_Previous Tab"), "<control>Page_Up",
+	  N_("Activate previous tab"),
+	  G_CALLBACK (action_tabs_previous_callback) },
+	{ "TabsNext", NULL, N_("_Next Tab"), "<control>Page_Down",
+	  N_("Activate next tab"),
+	  G_CALLBACK (action_tabs_next_callback) },
+	{ "TabsMoveLeft", NULL, N_("Move Tab _Left"), "<shift><control>Page_Up",
+	  N_("Move current tab to left"),
+	  G_CALLBACK (action_tabs_move_left_callback) },
+	{ "TabsMoveRight", NULL, N_("Move Tab _Right"), "<shift><control>Page_Down",
+	  N_("Move current tab to right"),
+	  G_CALLBACK (action_tabs_move_right_callback) },
+
 };
 
 static const GtkToggleActionEntry navigation_toggle_entries[] = {
@@ -603,7 +937,9 @@
 
 	nautilus_navigation_window_update_show_hide_menu_items (window);
 	nautilus_navigation_window_update_spatial_menu_item (window);
+	nautilus_navigation_window_update_tab_menu_item_visibility (window);
 
         nautilus_navigation_window_initialize_go_menu (window);
+        nautilus_navigation_window_initialize_tabs_menu (window);
 }
 

Added: trunk/src/nautilus-navigation-window-slot.c
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-navigation-window-slot.c	Tue Jul  8 21:05:55 2008
@@ -0,0 +1,182 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-navigation-window-slot.c: Nautilus navigation window slot
+ 
+   Copyright (C) 2008 Free Software Foundation, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Christian Neumair <cneumair gnome org>
+*/
+
+#include "nautilus-window-slot.h"
+#include "nautilus-navigation-window-slot.h"
+#include "nautilus-window-private.h"
+#include "nautilus-search-bar.h"
+#include <libnautilus-private/nautilus-window-slot-info.h>
+#include <libnautilus-private/nautilus-file.h>
+#include <eel/eel-gtk-macros.h>
+
+static void nautilus_navigation_window_slot_init       (NautilusNavigationWindowSlot *slot);
+static void nautilus_navigation_window_slot_class_init (NautilusNavigationWindowSlotClass *class);
+
+G_DEFINE_TYPE (NautilusNavigationWindowSlot, nautilus_navigation_window_slot, NAUTILUS_TYPE_WINDOW_SLOT)
+#define parent_class nautilus_navigation_window_slot_parent_class
+
+void
+nautilus_navigation_window_slot_clear_forward_list (NautilusNavigationWindowSlot *slot)
+{
+	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW_SLOT (slot));
+
+	eel_g_object_list_free (slot->forward_list);
+	slot->forward_list = NULL;
+}
+
+void
+nautilus_navigation_window_slot_clear_back_list (NautilusNavigationWindowSlot *slot)
+{
+	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW_SLOT (slot));
+
+	eel_g_object_list_free (slot->back_list);
+	slot->back_list = NULL;
+}
+
+static void
+query_editor_changed_callback (NautilusSearchBar *bar,
+			       NautilusQuery *query,
+			       gboolean reload,
+			       NautilusWindowSlot *slot)
+{
+	NautilusDirectory *directory;
+
+	g_assert (NAUTILUS_IS_FILE (slot->viewed_file));
+
+	directory = nautilus_directory_get_for_file (slot->viewed_file);
+	g_assert (NAUTILUS_IS_SEARCH_DIRECTORY (directory));
+
+	nautilus_search_directory_set_query (NAUTILUS_SEARCH_DIRECTORY (directory),
+					     query);
+	if (reload) {
+		nautilus_window_slot_reload (slot);
+	}
+
+	nautilus_directory_unref (directory);
+}
+
+
+static void
+nautilus_navigation_window_slot_update_query_editor (NautilusWindowSlot *slot)
+{
+	NautilusDirectory *directory;
+	NautilusSearchDirectory *search_directory;
+	NautilusQuery *query;
+	NautilusNavigationWindow *navigation_window;
+	GtkWidget *query_editor;
+
+	g_assert (slot->window != NULL);
+	navigation_window = NAUTILUS_NAVIGATION_WINDOW (slot->window);
+
+	query_editor = NULL;
+
+	directory = nautilus_directory_get (slot->location);
+	if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) {
+		search_directory = NAUTILUS_SEARCH_DIRECTORY (directory);
+
+		if (nautilus_search_directory_is_saved_search (search_directory)) {
+			query_editor = nautilus_query_editor_new (TRUE,
+								  nautilus_search_directory_is_indexed (search_directory));
+		} else {
+			query_editor = nautilus_query_editor_new_with_bar (FALSE,
+									   nautilus_search_directory_is_indexed (search_directory),
+									   slot->window->details->active_slot == slot,
+									   NAUTILUS_SEARCH_BAR (navigation_window->search_bar),
+									   slot);
+		}
+	}
+
+	slot->query_editor = NAUTILUS_QUERY_EDITOR (query_editor);
+
+	if (query_editor != NULL) {
+		g_signal_connect_object (query_editor, "changed",
+					 G_CALLBACK (query_editor_changed_callback), slot, 0);
+		
+		query = nautilus_search_directory_get_query (search_directory);
+		if (query != NULL) {
+			nautilus_query_editor_set_query (NAUTILUS_QUERY_EDITOR (query_editor),
+							 query);
+			g_object_unref (query);
+		} else {
+			nautilus_query_editor_set_default_query (NAUTILUS_QUERY_EDITOR (query_editor));
+		}
+
+		nautilus_window_slot_add_extra_location_widget (slot, query_editor);
+		gtk_widget_show (query_editor);
+		nautilus_query_editor_grab_focus (NAUTILUS_QUERY_EDITOR (query_editor));
+	}
+
+	nautilus_directory_unref (directory);
+}
+
+static void
+nautilus_navigation_window_slot_active (NautilusWindowSlot *slot)
+{
+	NautilusNavigationWindow *window;
+	NautilusNavigationWindowSlot *navigation_slot;
+	int page_num;
+
+	navigation_slot = NAUTILUS_NAVIGATION_WINDOW_SLOT (slot);
+	window = NAUTILUS_NAVIGATION_WINDOW (slot->window);
+
+	page_num = gtk_notebook_page_num (GTK_NOTEBOOK (window->notebook),
+					  slot->content_box);
+	g_assert (page_num >= 0);
+
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), page_num);
+
+	EEL_CALL_PARENT (NAUTILUS_WINDOW_SLOT_CLASS, active, (slot));
+
+	if (slot->viewed_file != NULL) {
+		nautilus_navigation_window_load_extension_toolbar_items (window);
+	}
+}
+ 
+static void
+nautilus_navigation_window_slot_dispose (GObject *object)
+{
+	NautilusNavigationWindowSlot *slot;
+
+	slot = NAUTILUS_NAVIGATION_WINDOW_SLOT (object);
+
+	nautilus_navigation_window_slot_clear_forward_list (slot);
+	nautilus_navigation_window_slot_clear_back_list (slot);
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+nautilus_navigation_window_slot_init (NautilusNavigationWindowSlot *slot)
+{
+}
+
+static void
+nautilus_navigation_window_slot_class_init (NautilusNavigationWindowSlotClass *class)
+{
+	NAUTILUS_WINDOW_SLOT_CLASS (class)->active = nautilus_navigation_window_slot_active; 
+	NAUTILUS_WINDOW_SLOT_CLASS (class)->update_query_editor = nautilus_navigation_window_slot_update_query_editor; 
+
+	G_OBJECT_CLASS (class)->dispose = nautilus_navigation_window_slot_dispose;
+}
+

Added: trunk/src/nautilus-navigation-window-slot.h
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-navigation-window-slot.h	Tue Jul  8 21:05:55 2008
@@ -0,0 +1,146 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-navigation-window-slot.h: Nautilus navigation window slot
+ 
+   Copyright (C) 2008 Free Software Foundation, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Christian Neumair <cneumair gnome org>
+*/
+
+#ifndef NAUTILUS_NAVIGATION_WINDOW_SLOT_H
+#define NAUTILUS_NAVIGATION_WINDOW_SLOT_H
+
+#include "nautilus-window-slot.h"
+
+typedef struct NautilusNavigationWindowSlot NautilusNavigationWindowSlot;
+typedef struct NautilusNavigationWindowSlotClass NautilusNavigationWindowSlotClass;
+
+
+#define NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT         (nautilus_navigation_window_slot_get_type())
+#define NAUTILUS_NAVIGATION_WINDOW_SLOT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_NAVIGATION_WINDOW_SLOT_CLASS, NautilusNavigationWindowSlotClass))
+#define NAUTILUS_NAVIGATION_WINDOW_SLOT(obj)         (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT, NautilusNavigationWindowSlot))
+#define NAUTILUS_IS_NAVIGATION_WINDOW_SLOT(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT))
+#define NAUTILUS_IS_NAVIGATION_WINDOW_SLOT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT))
+#define NAUTILUS_NAVIGATION_WINDOW_SLOT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT, NautilusNavigationWindowSlotClass))
+  
+typedef enum {
+	NAUTILUS_BAR_PATH,
+	NAUTILUS_BAR_NAVIGATION,
+	NAUTILUS_BAR_SEARCH
+} NautilusBarMode;
+
+struct NautilusNavigationWindowSlot {
+	NautilusWindowSlot parent;
+
+	NautilusBarMode bar_mode;
+	GtkTreeModel *viewer_model;
+	int num_viewers;
+
+	/* Back/Forward chain, and history list. 
+	 * The data in these lists are NautilusBookmark pointers. 
+	 */
+	GList *back_list, *forward_list;
+
+	/* Current views stuff */
+	GList *sidebar_panels;
+};
+
+struct NautilusNavigationWindowSlotClass {
+	NautilusWindowSlotClass parent;
+};
+
+GType nautilus_navigation_window_slot_get_type (void);
+
+void nautilus_navigation_window_slot_clear_forward_list (NautilusNavigationWindowSlot *slot);
+void nautilus_navigation_window_slot_clear_back_list    (NautilusNavigationWindowSlot *slot);
+
+#endif /* NAUTILUS_NAVIGATION_WINDOW_SLOT_H */
+
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-navigation-window-slot.h: Nautilus navigation window slot
+ 
+   Copyright (C) 2008 Free Software Foundation, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Christian Neumair <cneumair gnome org>
+*/
+
+#ifndef NAUTILUS_NAVIGATION_WINDOW_SLOT_H
+#define NAUTILUS_NAVIGATION_WINDOW_SLOT_H
+
+#include "nautilus-window-slot.h"
+
+typedef struct NautilusNavigationWindowSlot NautilusNavigationWindowSlot;
+typedef struct NautilusNavigationWindowSlotClass NautilusNavigationWindowSlotClass;
+
+
+#define NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT         (nautilus_navigation_window_slot_get_type())
+#define NAUTILUS_NAVIGATION_WINDOW_SLOT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_NAVIGATION_WINDOW_SLOT_CLASS, NautilusNavigationWindowSlotClass))
+#define NAUTILUS_NAVIGATION_WINDOW_SLOT(obj)         (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT, NautilusNavigationWindowSlot))
+#define NAUTILUS_IS_NAVIGATION_WINDOW_SLOT(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT))
+#define NAUTILUS_IS_NAVIGATION_WINDOW_SLOT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT))
+#define NAUTILUS_NAVIGATION_WINDOW_SLOT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT, NautilusNavigationWindowSlotClass))
+  
+typedef enum {
+	NAUTILUS_BAR_PATH,
+	NAUTILUS_BAR_NAVIGATION,
+	NAUTILUS_BAR_SEARCH
+} NautilusBarMode;
+
+struct NautilusNavigationWindowSlot {
+	NautilusWindowSlot parent;
+
+	NautilusBarMode bar_mode;
+	GtkTreeModel *viewer_model;
+	int num_viewers;
+
+	/* Back/Forward chain, and history list. 
+	 * The data in these lists are NautilusBookmark pointers. 
+	 */
+	GList *back_list, *forward_list;
+
+	/* Current views stuff */
+	GList *sidebar_panels;
+};
+
+struct NautilusNavigationWindowSlotClass {
+	NautilusWindowSlotClass parent;
+};
+
+GType nautilus_navigation_window_slot_get_type (void);
+
+void nautilus_navigation_window_slot_clear_forward_list (NautilusNavigationWindowSlot *slot);
+void nautilus_navigation_window_slot_clear_back_list    (NautilusNavigationWindowSlot *slot);
+
+#endif /* NAUTILUS_NAVIGATION_WINDOW_SLOT_H */
+

Modified: trunk/src/nautilus-navigation-window-ui.xml
==============================================================================
--- trunk/src/nautilus-navigation-window-ui.xml	(original)
+++ trunk/src/nautilus-navigation-window-ui.xml	Tue Jul  8 21:05:55 2008
@@ -2,8 +2,10 @@
 <menubar name="MenuBar">
 	<menu action="File">
 		<placeholder name="New Items Placeholder">
+			<menuitem name="New Tab" action="New Tab"/>
 			<menuitem name="New Window" action="New Window"/>
 			<menuitem name="Folder Window" action="Folder Window"/>
+			<separator/>
 		</placeholder>
 		
 		<placeholder name="Close Items Placeholder">
@@ -45,6 +47,18 @@
 			<separator/>
 			<placeholder name="Bookmarks Placeholder"/>
 		</menu>
+		<menu action="Tabs">
+			<menuitem name="TabsPreviousMenu" action="TabsPrevious"/>
+			<menuitem name="TabsNextMenu" action="TabsNext"/>
+			<separator name="TabsSep1"/>
+			<placeholder name="TabsMoveGroup">
+				<menuitem name="TabsMoveLeftMenu" action="TabsMoveLeft"/>
+				<menuitem name="TabsMoveRightMenu" action="TabsMoveRight"/>
+			</placeholder>
+			<placeholder name="TabsOpen">
+				<separator name="TabsSep2"/>
+			</placeholder>
+		</menu>
         </placeholder>
 </menubar>
 <toolbar name="Toolbar">

Modified: trunk/src/nautilus-navigation-window.c
==============================================================================
--- trunk/src/nautilus-navigation-window.c	(original)
+++ trunk/src/nautilus-navigation-window.c	Tue Jul  8 21:05:55 2008
@@ -39,6 +39,8 @@
 #include "nautilus-pathbar.h"
 #include "nautilus-query-editor.h"
 #include "nautilus-search-bar.h"
+#include "nautilus-navigation-window-slot.h"
+#include "nautilus-notebook.h"
 #include "nautilus-window-manage-views.h"
 #include "nautilus-zoom-control.h"
 #include <eel/eel-gtk-extensions.h>
@@ -82,12 +84,6 @@
 
 #define MENU_PATH_BOOKMARKS_PLACEHOLDER			"/MenuBar/Other Menus/Bookmarks/Bookmarks Placeholder"
 
-typedef enum {
-	NAUTILUS_BAR_PATH,
-	NAUTILUS_BAR_NAVIGATION,
-	NAUTILUS_BAR_SEARCH
-} NautilusBarMode;
-
 enum {
 	ARG_0,
 	ARG_APP_ID,
@@ -113,6 +109,7 @@
 						      NautilusNavigationWindow *window);
 static void always_use_location_entry_changed        (gpointer                  callback_data);
 static void always_use_browser_changed               (gpointer                  callback_data);
+static void enable_tabs_changed			     (gpointer                  callback_data);
 
 static void nautilus_navigation_window_set_bar_mode  (NautilusNavigationWindow *window, 
 						      NautilusBarMode           mode);
@@ -139,6 +136,8 @@
 #endif
 };
 
+
+
 static void
 location_button_toggled_cb (GtkToggleButton *toggle,
 			    NautilusNavigationWindow *window)
@@ -182,6 +181,160 @@
 	return button;
 }
 
+static gboolean
+notebook_switch_page_cb (GtkNotebook *notebook,
+			 GtkNotebookPage *page,
+			 unsigned int page_num,
+			 NautilusNavigationWindow *window)
+{
+	NautilusWindow *nautilus_window;
+	NautilusWindowSlot *slot;
+	GtkWidget *widget;
+
+	nautilus_window = NAUTILUS_WINDOW (window);
+
+	widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), page_num);
+	g_assert (widget != NULL);
+
+	/* find slot corresponding to the target page */
+	slot = nautilus_window_get_slot_for_content_box (nautilus_window, widget);
+	g_assert (slot != NULL);
+
+	nautilus_window_set_active_slot (nautilus_window, slot);
+
+	return FALSE;
+}
+
+/* emitted when the user clicks the "close" button of tabs */
+static void
+notebook_tab_close_requested (NautilusNotebook *notebook,
+			      NautilusWindowSlot *slot,
+			      NautilusWindow *window)
+{
+	g_assert (slot->window == window);
+	nautilus_window_slot_close (slot);
+}
+
+static void
+notebook_popup_menu_move_left_cb (GtkMenuItem *menuitem,
+				  gpointer user_data)
+{
+    	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	nautilus_notebook_reorder_current_child_relative (NAUTILUS_NOTEBOOK (window->notebook), -1);
+}
+
+static void
+notebook_popup_menu_move_right_cb (GtkMenuItem *menuitem,
+				   gpointer user_data)
+{
+    	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	nautilus_notebook_reorder_current_child_relative (NAUTILUS_NOTEBOOK (window->notebook), 1);
+}
+
+static void
+notebook_popup_menu_close_cb (GtkMenuItem *menuitem,
+			      gpointer user_data)
+{
+    	NautilusNavigationWindow *window;
+	NautilusWindowSlot *slot;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (NAUTILUS_WINDOW (window));
+	nautilus_window_slot_close (slot);
+}
+
+static void
+notebook_popup_menu_show (NautilusNavigationWindow *window,
+			  GdkEventButton *event)
+{
+	GtkWidget *popup;
+	GtkWidget *item;
+	GtkWidget *image;
+	int button, event_time;
+	gboolean can_move_left, can_move_right;
+
+	can_move_left = nautilus_notebook_can_reorder_current_child_relative (NAUTILUS_NOTEBOOK (window->notebook), -1);
+	can_move_right = nautilus_notebook_can_reorder_current_child_relative (NAUTILUS_NOTEBOOK (window->notebook), 1);
+
+	popup = gtk_menu_new();
+
+	item = gtk_menu_item_new_with_mnemonic (_("Move Tab _Left"));
+	g_signal_connect (item, "activate", 
+			  G_CALLBACK (notebook_popup_menu_move_left_cb), 
+			  window);
+	gtk_menu_shell_append (GTK_MENU_SHELL (popup), 
+		               item);
+	gtk_widget_set_sensitive (item, can_move_left);
+
+	item = gtk_menu_item_new_with_mnemonic (_("Move Tab _Right"));
+	g_signal_connect (item, "activate", 
+			  G_CALLBACK (notebook_popup_menu_move_right_cb), 
+			  window);
+	gtk_menu_shell_append (GTK_MENU_SHELL (popup), 
+		               item);
+	gtk_widget_set_sensitive (item, can_move_right);
+
+	gtk_menu_shell_append (GTK_MENU_SHELL (popup),
+			       gtk_separator_menu_item_new ());
+
+	item = gtk_image_menu_item_new_with_mnemonic (_("_Close Tab"));
+	image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+	g_signal_connect (item, "activate", 
+			  G_CALLBACK (notebook_popup_menu_close_cb), window);
+	gtk_menu_shell_append (GTK_MENU_SHELL (popup), 
+		               item);
+
+	gtk_widget_show_all (popup);
+
+	if (event) {
+		button = event->button;
+		event_time = event->time;
+	} else {
+		button = 0;
+		event_time = gtk_get_current_event_time ();
+	}
+	
+	/* TODO is this correct? */
+	gtk_menu_attach_to_widget (GTK_MENU (popup), 
+				   GTK_WIDGET (window->notebook), 
+				   NULL); 
+
+	gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
+			button, event_time);
+}
+
+static gboolean
+notebook_popup_menu_cb (GtkWidget *widget,
+			gpointer user_data)
+{
+	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	notebook_popup_menu_show (window, NULL);
+	return TRUE;
+}
+
+static gboolean
+notebook_button_press_cb (GtkWidget *widget,
+			  GdkEventButton *event,
+			  gpointer user_data)
+{
+	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (user_data);
+	if (GDK_BUTTON_PRESS == event->type && 3 == event->button) {
+		notebook_popup_menu_show (window, event);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 static void
 nautilus_navigation_window_init (NautilusNavigationWindow *window)
 {
@@ -190,7 +343,7 @@
 	GtkWidget *location_bar;
 	GtkWidget *view_as_menu_vbox;
 	GtkToolItem *item;
-	GtkWidget *hbox, *vbox, *eventbox, *extras_vbox;
+	GtkWidget *hbox;
 
 	window->details = G_TYPE_INSTANCE_GET_PRIVATE (window, NAUTILUS_TYPE_NAVIGATION_WINDOW, NautilusNavigationWindowDetails);
 
@@ -203,25 +356,28 @@
 			  0,                                  0);
 	gtk_widget_show (window->details->content_paned);
 
-	vbox = gtk_vbox_new (FALSE, 0);
+	window->notebook = g_object_new (NAUTILUS_TYPE_NOTEBOOK, NULL);
+	g_signal_connect (window->notebook,
+			  "tab-close-request",
+			  G_CALLBACK (notebook_tab_close_requested),
+			  window);
+	g_signal_connect_after (window->notebook,
+				"button_press_event",
+				G_CALLBACK (notebook_button_press_cb),
+				window);
+	g_signal_connect (window->notebook, "popup-menu",
+			  G_CALLBACK (notebook_popup_menu_cb),
+			  window);
 	nautilus_horizontal_splitter_pack2 (
 		NAUTILUS_HORIZONTAL_SPLITTER (window->details->content_paned),
-		vbox);
-	gtk_widget_show (vbox);
-
-	eventbox = gtk_event_box_new ();
-	gtk_widget_set_name (eventbox, "nautilus-extra-view-widget");
-	gtk_box_pack_start (GTK_BOX (vbox), eventbox, FALSE, FALSE, 0);
-	gtk_widget_show (eventbox);
-	
-	extras_vbox = gtk_vbox_new (FALSE, 0);
-	gtk_container_set_border_width (GTK_CONTAINER (extras_vbox), 6);
-	NAUTILUS_WINDOW (window)->details->extra_location_widgets = extras_vbox;
-	gtk_container_add (GTK_CONTAINER (eventbox), extras_vbox);
-
-	window->details->content_box = gtk_vbox_new (FALSE, 0);
-	gtk_box_pack_start (GTK_BOX (vbox), window->details->content_box, TRUE, TRUE, 0);
-	gtk_widget_show (window->details->content_box);
+		window->notebook);
+	g_signal_connect (window->notebook,
+			  "switch-page",
+			  G_CALLBACK (notebook_switch_page_cb),
+			  window);
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), FALSE);
+	gtk_notebook_set_show_border (GTK_NOTEBOOK (window->notebook), FALSE);
+	gtk_widget_show (window->notebook);
 	
 	nautilus_navigation_window_initialize_actions (window);
 	nautilus_navigation_window_initialize_menus (window);
@@ -355,6 +511,10 @@
 	eel_preferences_add_callback_while_alive (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER,
 						  always_use_browser_changed,
 						  window, G_OBJECT (window));
+
+	eel_preferences_add_callback_while_alive (NAUTILUS_PREFERENCES_ENABLE_TABS,
+						  enable_tabs_changed,
+						  window, G_OBJECT (window));
 }
 
 static void
@@ -392,6 +552,16 @@
 	nautilus_navigation_window_update_spatial_menu_item (window);
 }
 
+static void
+enable_tabs_changed (gpointer callback_data)
+{
+	NautilusNavigationWindow *window;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (callback_data);
+
+	nautilus_navigation_window_update_tab_menu_item_visibility (window);
+}
+
 static int
 bookmark_list_get_uri_index (GList *list,
 			     GFile *location)
@@ -422,14 +592,17 @@
 				    GFile *location,
 				    NautilusNavigationWindow *window)
 {
+	NautilusNavigationWindowSlot *slot;
 	int i;
 
 	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
 
+	slot = NAUTILUS_NAVIGATION_WINDOW_SLOT (NAUTILUS_WINDOW (window)->details->active_slot);
+
 	/* check whether we already visited the target location */
-	i = bookmark_list_get_uri_index (window->back_list, location);
+	i = bookmark_list_get_uri_index (slot->back_list, location);
 	if (i >= 0) {
-		nautilus_navigation_window_back_or_forward (window, TRUE, i);
+		nautilus_navigation_window_back_or_forward (window, TRUE, i, FALSE);
 	} else {
 		nautilus_window_go_to (NAUTILUS_WINDOW (window), location);
 	}
@@ -499,9 +672,14 @@
 static gboolean
 hide_temporary_bars (NautilusNavigationWindow *window)
 {
-	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
+	NautilusWindowSlot *slot;
+	NautilusDirectory *directory;
 	gboolean success;
 
+	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
+
+	slot = nautilus_window_get_active_slot (NAUTILUS_WINDOW (window));
+
 	success = FALSE;
 
 	if (window->details->temporary_location_bar) {
@@ -512,7 +690,9 @@
 		success = TRUE;
 	}
 	if (window->details->temporary_navigation_bar) {
-		if (NAUTILUS_WINDOW (window)->details->search_mode) {
+		directory = nautilus_directory_get (slot->location);
+
+		if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) {
 			nautilus_navigation_window_set_bar_mode (window, NAUTILUS_BAR_SEARCH);
 		} else {
 			if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) {
@@ -521,6 +701,8 @@
 		}
 		window->details->temporary_navigation_bar = FALSE;
 		success = TRUE;
+
+		nautilus_directory_unref (directory);
 	}
 	if (window->details->temporary_search_bar) {
 		if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY)) {
@@ -793,8 +975,6 @@
 	window = NAUTILUS_NAVIGATION_WINDOW (object);
 
 	nautilus_navigation_window_remove_go_menu_callback (window);
-	nautilus_navigation_window_clear_back_list (window);
-	nautilus_navigation_window_clear_forward_list (window);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -873,13 +1053,13 @@
 void
 nautilus_navigation_window_go_back (NautilusNavigationWindow *window)
 {
-	nautilus_navigation_window_back_or_forward (window, TRUE, 0);
+	nautilus_navigation_window_back_or_forward (window, TRUE, 0, FALSE);
 }
 
 void
 nautilus_navigation_window_go_forward (NautilusNavigationWindow *window)
 {
-	nautilus_navigation_window_back_or_forward (window, FALSE, 0);
+	nautilus_navigation_window_back_or_forward (window, FALSE, 0, FALSE);
 }
 
 void
@@ -907,20 +1087,28 @@
 static void
 activate_nth_short_list_item (NautilusWindow *window, guint index)
 {
+	NautilusWindowSlot *slot;
+
 	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	slot = window->details->active_slot;
 	g_assert (index < g_list_length (window->details->short_list_viewers));
 
-	nautilus_window_set_content_view (window, 
-					  g_list_nth_data (window->details->short_list_viewers, index));
+	nautilus_window_slot_set_content_view (slot,
+					       g_list_nth_data (window->details->short_list_viewers, index));
 }
 
 static void
 activate_extra_viewer (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
+
 	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	slot = window->details->active_slot;
 	g_assert (window->details->extra_viewer != NULL);
-	
-	nautilus_window_set_content_view (window, window->details->extra_viewer);	
+
+	nautilus_window_slot_set_content_view (slot, window->details->extra_viewer);
 }
 
 static void
@@ -944,6 +1132,7 @@
 static void
 load_view_as_menu (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GList *node;
 	int index;
 	int selected_index = -1;
@@ -962,6 +1151,8 @@
 	store = GTK_LIST_STORE (model);
 	gtk_list_store_clear (store);
 
+	slot = window->details->active_slot;
+
         /* Add a menu item for each view in the preferred list for this location. */
         for (node = window->details->short_list_viewers, index = 0; 
              node != NULL; 
@@ -969,7 +1160,7 @@
 		info = nautilus_view_factory_lookup (node->data);
 		gtk_combo_box_append_text (combo_box, _(info->view_combo_label));
 
-		if (nautilus_window_content_view_matches_iid (NAUTILUS_WINDOW (window), (char *)node->data)) {
+		if (nautilus_window_slot_content_view_matches_iid (slot, (char *)node->data)) {
 			selected_index = index;
 		}
         }
@@ -978,7 +1169,7 @@
 		const char *id;
 		/* We're using an extra viewer, add a menu item for it */
 
-		id = nautilus_window_get_content_view_id (window);
+		id = nautilus_window_slot_get_content_view_id (slot);
 		info = nautilus_view_factory_lookup (id);
 		gtk_combo_box_append_text (GTK_COMBO_BOX (NAUTILUS_NAVIGATION_WINDOW (window)->view_as_combo_box),
 					   _(info->view_combo_label));
@@ -997,18 +1188,22 @@
 	load_view_as_menu (window);
 }
 
-static gboolean
-real_set_title (NautilusWindow *window, const char *title)
+static void
+real_sync_title (NautilusWindow *window,
+		 NautilusWindowSlot *slot)
 {
+	NautilusNavigationWindow *navigation_window;
+	NautilusNotebook *notebook;
 	char *full_title;
 	char *window_title;
-	gboolean changed;
 
-	changed = EEL_CALL_PARENT_WITH_RETURN_VALUE
-		(NAUTILUS_WINDOW_CLASS, set_title, (window, title));
+	navigation_window = NAUTILUS_NAVIGATION_WINDOW (window);
 
-	if (changed) {
-		full_title = g_strdup_printf (_("%s - File Browser"), title);
+	EEL_CALL_PARENT (NAUTILUS_WINDOW_CLASS,
+			 sync_title, (window, slot));
+
+	if (slot == window->details->active_slot) {
+		full_title = g_strdup_printf (_("%s - File Browser"), slot->title);
 
 		window_title = eel_str_middle_truncate (full_title, MAX_TITLE_LENGTH);
 		gtk_window_set_title (GTK_WINDOW (window), window_title);
@@ -1016,11 +1211,15 @@
 		g_free (full_title);
 	}
 
-	return changed;
+	notebook = NAUTILUS_NOTEBOOK (navigation_window->notebook);
+	nautilus_notebook_sync_tab_label (notebook, slot);
+
+	nautilus_navigation_window_sync_tab_menu_title (navigation_window, slot);
 }
 
 static NautilusIconInfo *
-real_get_icon (NautilusWindow *window)
+real_get_icon (NautilusWindow *window,
+	       NautilusWindowSlot *slot)
 {
 	return nautilus_icon_info_lookup_from_name ("file-manager", 48);
 }
@@ -1029,8 +1228,8 @@
 zoom_level_changed_callback (NautilusView *view,
                              NautilusNavigationWindow *window)
 {
-        g_assert (NAUTILUS_IS_WINDOW (window));
-	
+	g_assert (NAUTILUS_WINDOW (window)->details->active_slot->content_view == view);
+
         /* This is called each time the component successfully completed
          * a zooming operation.
          */
@@ -1039,65 +1238,76 @@
 }
 
 static void
-connect_view (NautilusNavigationWindow *window, NautilusView *view)
+real_connect_content_view (NautilusWindow *nautilus_window,
+			   NautilusView *view)
 {
+	NautilusNavigationWindow *window;
+	NautilusWindowSlot *slot;
+
+	window = NAUTILUS_NAVIGATION_WINDOW (nautilus_window);
+	slot = nautilus_window->details->active_slot;
+
+	EEL_CALL_PARENT (NAUTILUS_WINDOW_CLASS, 
+			 connect_content_view, 
+			 (nautilus_window, view));
+
 	g_signal_connect (view, "zoom_level_changed",
 			  G_CALLBACK (zoom_level_changed_callback),
 			  window);
-}
 
-static void
-disconnect_view (NautilusNavigationWindow *window, NautilusView *view)
-{
-	if (!view) {
-		return;
+	if (nautilus_view_supports_zooming (view)) {
+		gtk_widget_show (window->zoom_control);
+	} else {
+		gtk_widget_hide (window->zoom_control);
+	}
+
+        /* Update displayed view in menu. Only do this if we're not switching
+         * locations though, because if we are switching locations we'll
+         * install a whole new set of views in the menu later (the current
+         * views in the menu are for the old location).
+         */
+	if (slot->pending_location == NULL) {
+		load_view_as_menu (nautilus_window);
 	}
-	
-	g_signal_handlers_disconnect_by_func
-		(view, 
-		 G_CALLBACK (zoom_level_changed_callback), 
-		 window);	
 }
 
 static void
-real_set_content_view_widget (NautilusWindow *nautilus_window,
-			      NautilusView *new_view)
+real_disconnect_content_view (NautilusWindow *nautilus_window,
+			      NautilusView *view)
 {
-	
 	NautilusNavigationWindow *window;
 
 	window = NAUTILUS_NAVIGATION_WINDOW (nautilus_window);
 
-	disconnect_view (window, nautilus_window->content_view);
-
 	EEL_CALL_PARENT (NAUTILUS_WINDOW_CLASS, 
-			 set_content_view_widget, 
-			 (nautilus_window, new_view));
+			 disconnect_content_view, 
+			 (nautilus_window, view));
 
+	g_signal_handlers_disconnect_by_func
+		(view, 
+		 G_CALLBACK (zoom_level_changed_callback), 
+		 window);	
 
-	if (new_view == NULL) {
-		return;	       
+	if (window->zoom_control != NULL) {
+		/* if we run in destroy(), the
+ 		 * zoom control is already gone
+		 */
+		gtk_widget_hide (window->zoom_control);
 	}
+}
 
-	connect_view (window, new_view);
-
-	gtk_container_add (GTK_CONTAINER (window->details->content_box),
-			   GTK_WIDGET (new_view));
+static void
+real_sync_allow_stop (NautilusWindow *window,
+		      NautilusWindowSlot *slot)
+{
+	NautilusNavigationWindow *navigation_window;
+	NautilusNotebook *notebook;
 
-	if (new_view != NULL && nautilus_view_supports_zooming (new_view)) {
-		gtk_widget_show (window->zoom_control);
-	} else {
-		gtk_widget_hide (window->zoom_control);
-	}
+	navigation_window = NAUTILUS_NAVIGATION_WINDOW (window);
+	nautilus_navigation_window_set_throbber_active (navigation_window, slot->allow_stop);
 
-        /* Update displayed view in menu. Only do this if we're not switching
-         * locations though, because if we are switching locations we'll
-         * install a whole new set of views in the menu later (the current
-         * views in the menu are for the old location).
-         */
-	if (nautilus_window->details->pending_location == NULL) {
-		load_view_as_menu (nautilus_window);
-	}
+	notebook = NAUTILUS_NOTEBOOK (navigation_window->notebook);
+	nautilus_notebook_sync_loading (notebook, slot);
 }
 
 static gboolean
@@ -1105,12 +1315,14 @@
 				  GdkEventButton *event,
 				  NautilusNavigationWindow *window)
 {
+	NautilusWindowSlot *slot;
 	NautilusView *view;
 	GFile *location;
 	char *uri;
 
 	if (event->button == 3) {
-		view = NAUTILUS_WINDOW (window)->content_view;
+		slot = nautilus_window_get_active_slot (NAUTILUS_WINDOW (window));
+		view = slot->content_view;
 		if (view != NULL) {
 			location = nautilus_path_bar_get_path_for_button (
 				NAUTILUS_PATH_BAR (window->path_bar), widget);
@@ -1161,13 +1373,6 @@
 }
 
 static void
-real_set_throbber_active (NautilusWindow *window, gboolean active)
-{
-	nautilus_navigation_window_set_throbber_active
-		(NAUTILUS_NAVIGATION_WINDOW (window), active);
-}
-
-static void
 nautilus_navigation_window_show_location_bar_temporarily (NautilusNavigationWindow *window)
 {
 	if (!nautilus_navigation_window_location_bar_showing (window)) {
@@ -1224,8 +1429,9 @@
 
 	query = nautilus_search_bar_get_query (NAUTILUS_SEARCH_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->search_bar));
 	if (query != NULL) {
+		NautilusWindowSlot *slot = window->details->active_slot;
 		if (!nautilus_search_directory_is_indexed (search_directory)) {
-			current_uri = nautilus_window_get_location_uri (window);
+			current_uri = nautilus_window_slot_get_location_uri (slot);
 			nautilus_query_set_location (query, current_uri);
 			g_free (current_uri);
 		}
@@ -1263,85 +1469,35 @@
 	nautilus_search_bar_grab_focus (NAUTILUS_SEARCH_BAR (window->search_bar));
 }
 
+/* either called due to slot change, or due to location change in the current slot. */
 static void
-query_editor_changed_callback (NautilusSearchBar *bar,
-			       NautilusQuery *query,
-			       gboolean reload,
-			       NautilusWindow *window)
+real_sync_search_widgets (NautilusWindow *window)
 {
+	NautilusNavigationWindow *navigation_window;
+	NautilusWindowSlot *slot;
 	NautilusDirectory *directory;
+	NautilusSearchDirectory *search_directory;
 
-	directory = nautilus_directory_get_for_file (window->details->viewed_file);
-	g_assert (NAUTILUS_IS_SEARCH_DIRECTORY (directory));
-
-	nautilus_search_directory_set_query (NAUTILUS_SEARCH_DIRECTORY (directory),
-					     query);
-	if (reload) {
-		nautilus_window_reload (window);
-	}
-
-	nautilus_directory_unref (directory);
-}
+	navigation_window = NAUTILUS_NAVIGATION_WINDOW (window);
 
-static void
-real_set_search_mode (NautilusWindow *window, gboolean search_mode,
-		      NautilusSearchDirectory *search_directory)
-{
-	NautilusNavigationWindow *nav_window;
-	GtkWidget *query_editor;
-	NautilusQuery *query;
+	slot = window->details->active_slot;
 
-	nav_window = NAUTILUS_NAVIGATION_WINDOW (window);
+	search_directory = NULL;
 
-	if (!search_mode) {
-		nav_window->details->temporary_search_bar = TRUE;
-		hide_temporary_bars (nav_window);
-		unset_focus_widget (nav_window);
-		return;
+	directory = nautilus_directory_get (slot->location);
+	if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) {
+		search_directory = NAUTILUS_SEARCH_DIRECTORY (directory);
 	}
 
-	if (nautilus_search_directory_is_saved_search (search_directory)) {
-		query_editor = nautilus_query_editor_new (TRUE,
-							  nautilus_search_directory_is_indexed (search_directory));
+	if (search_directory != NULL &&
+	    !nautilus_search_directory_is_saved_search (search_directory)) {
+		nautilus_navigation_window_show_location_bar_temporarily (navigation_window);
+		nautilus_navigation_window_set_bar_mode (navigation_window, NAUTILUS_BAR_SEARCH);
+		navigation_window->details->temporary_search_bar = FALSE;
 	} else {
-		nautilus_navigation_window_show_location_bar_temporarily (nav_window);
-		nautilus_navigation_window_set_bar_mode (nav_window, NAUTILUS_BAR_SEARCH);
-		nav_window->details->temporary_search_bar = FALSE;
-
-		query_editor = nautilus_query_editor_new_with_bar (FALSE,
-								   nautilus_search_directory_is_indexed (search_directory),
-								   NAUTILUS_SEARCH_BAR (nav_window->search_bar));
+		navigation_window->details->temporary_search_bar = TRUE;
+		hide_temporary_bars (navigation_window);
 	}
-
-	g_signal_connect_object (query_editor, "changed",
-				 G_CALLBACK (query_editor_changed_callback), window, 0);
-	
-	query = nautilus_search_directory_get_query (search_directory);
-	if (query != NULL) {
-		nautilus_query_editor_set_query (NAUTILUS_QUERY_EDITOR (query_editor),
-						 query);
-		g_object_unref (query);
-	}else {
-		nautilus_query_editor_set_default_query (NAUTILUS_QUERY_EDITOR (query_editor));
-	}
-	
-	nautilus_window_add_extra_location_widget (window, query_editor);
-	gtk_widget_show (query_editor);
-	nautilus_query_editor_grab_focus (NAUTILUS_QUERY_EDITOR (query_editor));
-}
-
-void
-nautilus_navigation_window_clear_forward_list (NautilusNavigationWindow *window)
-{
-	eel_g_object_list_free (window->forward_list);
-	window->forward_list = NULL;
-}
-
-void
-nautilus_navigation_window_clear_back_list (NautilusNavigationWindow *window)
-{
-	eel_g_object_list_free (window->back_list);
-	window->back_list = NULL;
 }
 
 static void
@@ -1604,9 +1760,12 @@
 gint 
 nautilus_navigation_window_get_base_page_index (NautilusNavigationWindow *window)
 {
+	NautilusNavigationWindowSlot *slot;
 	gint forward_count;
-	
-	forward_count = g_list_length (window->forward_list); 
+
+	slot = NAUTILUS_NAVIGATION_WINDOW_SLOT (NAUTILUS_WINDOW (window)->details->active_slot);
+
+	forward_count = g_list_length (slot->forward_list); 
 
 	/* If forward is empty, the base it at the top of the list */
 	if (forward_count == 0) {
@@ -1722,6 +1881,66 @@
 	}
 }
 
+static NautilusWindowSlot *
+real_open_slot (NautilusWindow *window,
+		NautilusWindowOpenSlotFlags flags)
+{
+	NautilusNavigationWindow *navigation_window;
+	NautilusWindowSlot *slot;
+	NautilusNotebook *notebook;
+
+	navigation_window = NAUTILUS_NAVIGATION_WINDOW (window);
+	notebook = NAUTILUS_NOTEBOOK (navigation_window->notebook);
+
+	slot = (NautilusWindowSlot *) g_object_new (NAUTILUS_TYPE_NAVIGATION_WINDOW_SLOT, NULL);
+	slot->window = window;
+
+	g_signal_handlers_block_by_func (notebook,
+					 G_CALLBACK (notebook_switch_page_cb),
+					 window);
+	nautilus_notebook_add_tab (notebook,
+				   slot,
+				   (flags & NAUTILUS_WINDOW_OPEN_SLOT_APPEND) != 0 ?
+				   -1 :
+				   gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)) + 1,
+				   FALSE);
+	g_signal_handlers_unblock_by_func (notebook,
+					   G_CALLBACK (notebook_switch_page_cb),
+					   window);
+	gtk_widget_show (slot->content_box);
+
+	return slot;
+}
+
+static void
+real_close_slot (NautilusWindow *window,
+		 NautilusWindowSlot *slot)
+{
+	NautilusNavigationWindow *navigation_window;
+	GtkNotebook *notebook;
+	int page_num;
+
+	navigation_window = NAUTILUS_NAVIGATION_WINDOW (window);
+	notebook = GTK_NOTEBOOK (navigation_window->notebook);
+
+	page_num = gtk_notebook_page_num (notebook, slot->content_box);
+	g_assert (page_num >= 0);
+
+	g_signal_handlers_block_by_func (notebook,
+					 G_CALLBACK (notebook_switch_page_cb),
+					 window);
+	gtk_notebook_remove_page (notebook, page_num);
+	g_signal_handlers_unblock_by_func (notebook,
+					   G_CALLBACK (notebook_switch_page_cb),
+					   window);
+
+	gtk_notebook_set_show_tabs (notebook,
+				    gtk_notebook_get_n_pages (notebook) > 1);
+
+	EEL_CALL_PARENT (NAUTILUS_WINDOW_CLASS,
+			 close_slot, (window, slot));
+}
+
 static void
 nautilus_navigation_window_class_init (NautilusNavigationWindowClass *class)
 {
@@ -1735,14 +1954,18 @@
 	GTK_WIDGET_CLASS (class)->window_state_event = nautilus_navigation_window_state_event;
 	GTK_WIDGET_CLASS (class)->key_press_event = nautilus_navigation_window_key_press_event;
 	NAUTILUS_WINDOW_CLASS (class)->load_view_as_menu = real_load_view_as_menu;
-	NAUTILUS_WINDOW_CLASS (class)->set_content_view_widget = real_set_content_view_widget;
-	NAUTILUS_WINDOW_CLASS (class)->set_throbber_active = real_set_throbber_active;
+	NAUTILUS_WINDOW_CLASS (class)->connect_content_view = real_connect_content_view;
+	NAUTILUS_WINDOW_CLASS (class)->disconnect_content_view = real_disconnect_content_view;
+	NAUTILUS_WINDOW_CLASS (class)->sync_allow_stop = real_sync_allow_stop;
 	NAUTILUS_WINDOW_CLASS (class)->prompt_for_location = real_prompt_for_location;
-	NAUTILUS_WINDOW_CLASS (class)->set_search_mode = real_set_search_mode;
-	NAUTILUS_WINDOW_CLASS (class)->set_title = real_set_title;
+	NAUTILUS_WINDOW_CLASS (class)->sync_search_widgets = real_sync_search_widgets;
+	NAUTILUS_WINDOW_CLASS (class)->sync_title = real_sync_title;
 	NAUTILUS_WINDOW_CLASS (class)->get_icon = real_get_icon;
 	NAUTILUS_WINDOW_CLASS (class)->get_default_size = real_get_default_size;
 	NAUTILUS_WINDOW_CLASS (class)->close = real_window_close;
 
+	NAUTILUS_WINDOW_CLASS (class)->open_slot = real_open_slot;
+	NAUTILUS_WINDOW_CLASS (class)->close_slot = real_close_slot;
+
 	g_type_class_add_private (G_OBJECT_CLASS (class), sizeof (NautilusNavigationWindowDetails));
 }

Modified: trunk/src/nautilus-navigation-window.h
==============================================================================
--- trunk/src/nautilus-navigation-window.h	(original)
+++ trunk/src/nautilus-navigation-window.h	Tue Jul  8 21:05:55 2008
@@ -50,6 +50,7 @@
 typedef struct _NautilusNavigationWindowClass   NautilusNavigationWindowClass;
 typedef struct _NautilusNavigationWindowDetails NautilusNavigationWindowDetails; 
 
+
 struct _NautilusNavigationWindow {
         NautilusWindow parent_object;
         
@@ -61,12 +62,8 @@
         GtkWidget *navigation_bar;
 	GtkWidget *path_bar;
         GtkWidget *search_bar;
-       
-        /* Back/Forward chain, and history list. 
-         * The data in these lists are NautilusBookmark pointers. 
-         */
-        GList *back_list, *forward_list;
-        
+	GtkWidget *notebook;
+
         /* Current views stuff */
         GList *sidebar_panels;
         
@@ -115,7 +112,8 @@
 gboolean nautilus_navigation_window_status_bar_showing   (NautilusNavigationWindow *window);
 void     nautilus_navigation_window_back_or_forward      (NautilusNavigationWindow *window,
                                                           gboolean                  back,
-                                                          guint                     distance);
+                                                          guint                     distance,
+							  gboolean                  new_tab);
 void     nautilus_navigation_window_show_search          (NautilusNavigationWindow *window);
 
 #endif

Added: trunk/src/nautilus-notebook.c
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-notebook.c	Tue Jul  8 21:05:55 2008
@@ -0,0 +1,782 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Copyright  2002 Christophe Fergeau
+ *  Copyright  2003, 2004 Marco Pesenti Gritti
+ *  Copyright  2003, 2004, 2005 Christian Persch
+ *    (ephy-notebook.c)
+ *
+ *  Copyright  2008 Free Software Foundation, Inc.
+ *    (nautilus-notebook.c)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#include "nautilus-notebook.h"
+#include "nautilus-navigation-window.h"
+#include "nautilus-window-manage-views.h"
+#include "nautilus-window-private.h"
+#include "nautilus-window-slot.h"
+#include "ephy-spinner.h"
+#include <libnautilus-private/nautilus-dnd.h>
+
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <gtk/gtkeventbox.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkaccelgroup.h>
+#include <gtk/gtkiconfactory.h>
+
+#define TAB_WIDTH_N_CHARS 15
+
+#define AFTER_ALL_TABS -1
+#define NOT_IN_APP_WINDOWS -2
+
+#define INSANE_NUMBER_OF_URLS 20
+
+static void nautilus_notebook_init		 (NautilusNotebook *notebook);
+static void nautilus_notebook_class_init	 (NautilusNotebookClass *klass);
+static int  nautilus_notebook_insert_page	 (GtkNotebook *notebook,
+					  GtkWidget *child,
+					  GtkWidget *tab_label,
+					  GtkWidget *menu_label,
+					  int position);
+static void nautilus_notebook_remove	 (GtkContainer *container,
+					  GtkWidget *tab_widget);
+
+static const GtkTargetEntry url_drag_types[] = 
+{
+	{ NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST },
+	{ NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST },
+};
+
+enum
+{
+	TAB_CLOSE_REQUEST,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (NautilusNotebook, nautilus_notebook, GTK_TYPE_NOTEBOOK);
+
+static void
+nautilus_notebook_class_init (NautilusNotebookClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+	GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass);
+
+	container_class->remove = nautilus_notebook_remove;
+
+	notebook_class->insert_page = nautilus_notebook_insert_page;
+	
+	gtk_rc_parse_string ("style \"nautilus-tab-close-button-style\"\n"
+			     "{\n"
+			       "GtkWidget::focus-padding = 0\n"
+			       "GtkWidget::focus-line-width = 0\n"
+			       "xthickness = 0\n"
+			       "ythickness = 0\n"
+			     "}\n"
+			     "widget \"*.nautilus-tab-close-button\" style \"nautilus-tab-close-button-style\"");
+
+	signals[TAB_CLOSE_REQUEST] =
+		g_signal_new ("tab-close-request",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (NautilusNotebookClass, tab_close_request),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__OBJECT,
+			      G_TYPE_NONE,
+			      1,
+			      NAUTILUS_TYPE_WINDOW_SLOT);
+}
+
+
+/* FIXME remove when gtknotebook's func for this becomes public, bug #.... */
+static NautilusNotebook *
+find_notebook_at_pointer (gint abs_x, gint abs_y)
+{
+	GdkWindow *win_at_pointer, *toplevel_win;
+	gpointer toplevel = NULL;
+	gint x, y;
+
+	/* FIXME multi-head */
+	win_at_pointer = gdk_window_at_pointer (&x, &y);
+	if (win_at_pointer == NULL)
+	{
+		/* We are outside all windows containing a notebook */
+		return NULL;
+	}
+
+	toplevel_win = gdk_window_get_toplevel (win_at_pointer);
+
+	/* get the GtkWidget which owns the toplevel GdkWindow */
+	gdk_window_get_user_data (toplevel_win, &toplevel);
+
+	/* toplevel should be an NautilusWindow */
+	if (toplevel != NULL && NAUTILUS_IS_NAVIGATION_WINDOW (toplevel))
+	{
+		return NAUTILUS_NOTEBOOK (NAUTILUS_NAVIGATION_WINDOW (toplevel)->notebook);
+	}
+
+	return NULL;
+}
+
+static gboolean
+is_in_notebook_window (NautilusNotebook *notebook,
+		       gint abs_x, gint abs_y)
+{
+	NautilusNotebook *nb_at_pointer;
+
+	nb_at_pointer = find_notebook_at_pointer (abs_x, abs_y);
+
+	return nb_at_pointer == notebook;
+}
+
+static gint
+find_tab_num_at_pos (NautilusNotebook *notebook, gint abs_x, gint abs_y)
+{
+	GtkPositionType tab_pos;
+	int page_num = 0;
+	GtkNotebook *nb = GTK_NOTEBOOK (notebook);
+	GtkWidget *page;
+
+	tab_pos = gtk_notebook_get_tab_pos (GTK_NOTEBOOK (notebook));
+
+	if (GTK_NOTEBOOK (notebook)->first_tab == NULL)
+	{
+		return AFTER_ALL_TABS;
+	}
+
+	/* For some reason unfullscreen + quick click can
+	   cause a wrong click event to be reported to the tab */
+	if (!is_in_notebook_window(notebook, abs_x, abs_y))
+	{
+		return NOT_IN_APP_WINDOWS;
+	}
+
+	while ((page = gtk_notebook_get_nth_page (nb, page_num)))
+	{
+		GtkWidget *tab;
+		gint max_x, max_y;
+		gint x_root, y_root;
+
+		tab = gtk_notebook_get_tab_label (nb, page);
+		g_return_val_if_fail (tab != NULL, -1);
+
+		if (!GTK_WIDGET_MAPPED (GTK_WIDGET (tab)))
+		{
+			page_num++;
+			continue;
+		}
+
+		gdk_window_get_origin (GDK_WINDOW (tab->window),
+				       &x_root, &y_root);
+
+		max_x = x_root + tab->allocation.x + tab->allocation.width;
+		max_y = y_root + tab->allocation.y + tab->allocation.height;
+
+		if (((tab_pos == GTK_POS_TOP)
+		     || (tab_pos == GTK_POS_BOTTOM))
+		    &&(abs_x<=max_x))
+		{
+			return page_num;
+		}
+		else if (((tab_pos == GTK_POS_LEFT)
+			  || (tab_pos == GTK_POS_RIGHT))
+			 && (abs_y<=max_y))
+		{
+			return page_num;
+		}
+
+		page_num++;
+	}
+	return AFTER_ALL_TABS;
+}
+
+static gboolean
+button_press_cb (NautilusNotebook *notebook,
+		 GdkEventButton *event,
+		 gpointer data)
+{
+	int tab_clicked;
+
+	tab_clicked = find_tab_num_at_pos (notebook, event->x_root, event->y_root);
+
+	if (event->type == GDK_BUTTON_PRESS &&
+	    event->button == 3 &&
+		   (event->state & gtk_accelerator_get_default_mod_mask ()) == 0)
+	{
+		if (tab_clicked == -1)
+		{
+			/* consume event, so that we don't pop up the context menu when
+			 * the mouse if not over a tab label
+			 */
+			return TRUE;
+		}
+
+		/* switch to the page the mouse is over, but don't consume the event */
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), tab_clicked);
+	}
+
+	return FALSE;
+}
+
+static void
+notebook_tab_drag_data_received (GtkWidget *widget,
+				 GdkDragContext *context,
+				 int x,
+				 int y,
+				 GtkSelectionData *selection_data,
+				 unsigned int info,
+				 unsigned int time,
+				 NautilusWindowSlot *slot)
+{
+	NautilusWindow *window;
+	NautilusNavigationWindow *navigation_window;
+	GtkWidget *notebook;
+	GList *uri_list, *selection_list, *l;
+	NautilusDragSelectionItem *selection_item;
+	char **uris;
+	int i;
+
+	g_signal_stop_emission_by_name (widget, "drag_data_received");
+
+	if (selection_data->length <= 0 ||
+	    selection_data->data == NULL) {
+		return;
+	}
+
+	if (slot->window == NULL || slot->content_view == NULL) {
+		return;
+	}
+
+	window = slot->window;
+
+	navigation_window = NAUTILUS_NAVIGATION_WINDOW (window);
+
+	notebook = navigation_window->notebook;
+
+	if (selection_data->target == gdk_atom_intern (NAUTILUS_ICON_DND_URI_LIST_TYPE, FALSE)) {
+		uris = gtk_selection_data_get_uris (selection_data);
+	} else if (selection_data->target == gdk_atom_intern (NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, FALSE)) {
+		selection_list = nautilus_drag_build_selection_list (selection_data);
+		if (selection_list == NULL) {
+			return;
+		}
+
+		i = 0;
+
+		uris = g_new0 (char *, g_list_length (selection_list));
+		for (l = selection_list; l != NULL; l = l->next) {
+			selection_item = (NautilusDragSelectionItem *) l->data;
+
+			uris[i] = g_strdup (selection_item->uri);
+			if (uris[i] != NULL) {
+				i++;
+			}
+		}
+		uris[i] = NULL;
+
+		nautilus_drag_destroy_selection_list (selection_list);
+	} else {
+		return;
+	}
+
+	if (uris == NULL || uris[0] == NULL) {
+		g_strfreev (uris);
+		return;
+	}
+
+	uri_list = NULL;
+	for (i = 0; uris[i] != NULL; i++) {
+		uri_list = g_list_prepend (uri_list, uris[i]);
+	}
+	uri_list = g_list_reverse (uri_list);
+
+	if (slot->content_view != NULL) {
+		nautilus_view_drop_proxy_received_uris (slot->content_view,
+							uri_list, NULL,
+							context->action);
+	}
+
+	g_list_free (uri_list);
+
+	g_strfreev (uris);
+}
+
+static inline GdkAtom 
+find_drop_target (GtkWidget *widget,
+		  GdkDragContext *context)
+{
+	GtkTargetList *target_list;
+
+	target_list = gtk_drag_dest_get_target_list (widget);
+	if (target_list != NULL) {
+		return gtk_drag_dest_find_target (widget, context, target_list);
+	}
+
+	return GDK_NONE;
+}
+
+static inline GdkDragAction
+get_drop_action (GtkWidget *drop_widget,
+		 GdkDragContext *context)
+{
+	if (!NAUTILUS_IS_NOTEBOOK (drop_widget)) {
+		if (context->suggested_action & GDK_ACTION_ASK) {
+			return context->suggested_action;
+		}
+
+		if (context->actions & GDK_ACTION_MOVE) {
+			return GDK_ACTION_MOVE;
+		}
+
+		if (context->actions & GDK_ACTION_COPY) {
+			return GDK_ACTION_COPY;
+		}
+	}
+
+	if (context->actions & GDK_ACTION_LINK) {
+		return GDK_ACTION_LINK;
+	}
+
+	return 0;
+}
+
+static gboolean
+notebook_tab_drag_motion (GtkWidget* widget,
+			  GdkDragContext *context,
+			  int x,
+			  int y, 
+			  unsigned int time,
+			  NautilusWindowSlot *slot)
+{
+
+	GdkDragAction action;
+	gboolean highlighted;
+
+	highlighted = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
+					"drop-highlight"));
+
+	action = 0;
+	if (find_drop_target (widget, context) != GDK_NONE) {
+		action = get_drop_action (widget, context);
+	}
+
+	if (action != 0 && !highlighted) {
+		gtk_drag_highlight (widget);
+		highlighted = TRUE;
+	}
+
+	gdk_drag_status (context, action, time);
+	g_object_set_data (G_OBJECT (widget), "drop-highlight",
+			   GUINT_TO_POINTER (highlighted));
+
+	return TRUE;
+}
+
+static void
+notebook_tab_drag_leave (GtkWidget* widget,
+			 GdkDragContext *context,
+			 unsigned int time,
+			 NautilusWindowSlot *slot)
+{
+	gtk_drag_unhighlight (widget);
+	g_object_set_data (G_OBJECT (widget), "drop-highlight",
+			   GUINT_TO_POINTER (FALSE));
+}
+
+
+static gboolean
+notebook_tab_drag_drop (GtkWidget *widget,
+			GdkDragContext *context,
+			int x,
+			int y,
+			unsigned int time,
+			G_GNUC_UNUSED gpointer user_data)
+{
+	GdkAtom target;
+
+	target = find_drop_target (widget, context);
+	if (target != GDK_NONE) {
+		gtk_drag_get_data (widget, context, target, time);
+		gtk_drag_finish (context, TRUE, FALSE, time);
+		return TRUE;
+	} else {
+		gtk_drag_finish (context, FALSE, FALSE, time);
+		return FALSE;
+	}
+}
+
+
+static void
+nautilus_notebook_init (NautilusNotebook *notebook)
+{
+	gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
+	gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+
+	g_signal_connect (notebook, "button-press-event",
+			  (GCallback)button_press_cb, NULL);
+
+	/* Set up drag-and-drop target */
+	/* TODO this would be used for opening a new tab.
+	 * It will only work properly as soon as GtkNotebook 
+	 * supports to find out whether a particular point
+	 * is on a tab button or not.
+	 */
+#if 0
+	gtk_drag_dest_set (GTK_WIDGET (notebook), 0,
+			   url_drag_types, G_N_ELEMENTS (url_drag_types),
+			   GDK_ACTION_LINK);
+	gtk_drag_dest_set_track_motion (GTK_WIDGET (notebook), TRUE);
+#endif
+}
+
+void
+nautilus_notebook_sync_loading (NautilusNotebook *notebook,
+				NautilusWindowSlot *slot)
+{
+	GtkWidget *tab_label, *spinner, *icon;
+
+	g_return_if_fail (NAUTILUS_IS_NOTEBOOK (notebook));
+	g_return_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	tab_label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), slot->content_box);
+	g_return_if_fail (GTK_IS_WIDGET (tab_label));
+
+	spinner = GTK_WIDGET (g_object_get_data (G_OBJECT (tab_label), "spinner"));
+	icon = GTK_WIDGET (g_object_get_data (G_OBJECT (tab_label), "icon"));
+	g_return_if_fail (spinner != NULL && icon != NULL);
+
+	if (ephy_spinner_get_spinning (EPHY_SPINNER (spinner)) == slot->allow_stop) {
+		return;
+	}
+
+	if (slot->allow_stop)
+	{
+		gtk_widget_hide (icon);
+		gtk_widget_show (spinner);
+		ephy_spinner_start (EPHY_SPINNER (spinner));
+	}
+	else
+	{
+		ephy_spinner_stop (EPHY_SPINNER (spinner));
+		gtk_widget_hide (spinner);
+		gtk_widget_show (icon);
+	}
+}
+
+void
+nautilus_notebook_sync_tab_label (NautilusNotebook *notebook,
+				  NautilusWindowSlot *slot)
+{
+	GtkWidget *hbox, *label;
+
+	g_return_if_fail (NAUTILUS_IS_NOTEBOOK (notebook));
+	g_return_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot));
+	g_return_if_fail (GTK_IS_WIDGET (slot->content_box));
+
+	hbox = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), slot->content_box);
+	g_return_if_fail (GTK_IS_WIDGET (hbox));
+
+	label = GTK_WIDGET (g_object_get_data (G_OBJECT (hbox), "label"));
+	g_return_if_fail (GTK_IS_WIDGET (label));
+
+	gtk_label_set_text (GTK_LABEL (label), slot->title);
+
+	/* Set the tooltip on the label's parent (the tab label hbox),
+	 * so it covers all of the tab label.
+	 */
+	gtk_widget_set_tooltip_text (label->parent, slot->title);
+}
+
+static void
+close_button_clicked_cb (GtkWidget *widget,
+			 NautilusWindowSlot *slot)
+{
+	GtkWidget *notebook;
+
+	notebook = gtk_widget_get_ancestor (slot->content_box, NAUTILUS_TYPE_NOTEBOOK);
+	if (notebook != NULL) {
+		g_signal_emit (notebook, signals[TAB_CLOSE_REQUEST], 0, slot);
+	}
+}
+
+static void
+tab_label_style_set_cb (GtkWidget *hbox,
+			GtkStyle *previous_style,
+			gpointer user_data)
+{
+	PangoFontMetrics *metrics;
+	PangoContext *context;
+	GtkWidget *button;
+	int char_width, h, w;
+
+	context = gtk_widget_get_pango_context (hbox);
+	metrics = pango_context_get_metrics (context,
+					     hbox->style->font_desc,
+					     pango_context_get_language (context));
+
+	char_width = pango_font_metrics_get_approximate_digit_width (metrics);
+	pango_font_metrics_unref (metrics);
+
+	gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (hbox),
+					   GTK_ICON_SIZE_MENU, &w, &h);
+
+	gtk_widget_set_size_request
+		(hbox, TAB_WIDTH_N_CHARS * PANGO_PIXELS(char_width) + 2 * w, -1);
+
+	button = g_object_get_data (G_OBJECT (hbox), "close-button");
+	gtk_widget_set_size_request (button, w + 2, h + 2);
+}
+
+static GtkWidget *
+build_tab_label (NautilusNotebook *nb, NautilusWindowSlot *slot)
+{
+	GtkWidget *hbox, *label, *close_button, *image, *spinner, *icon;
+
+	/* set hbox spacing and label padding (see below) so that there's an
+	 * equal amount of space around the label */
+	hbox = gtk_hbox_new (FALSE, 4);
+	gtk_widget_show (hbox);
+
+	/* setup load feedback */
+	spinner = ephy_spinner_new ();
+	ephy_spinner_set_size (EPHY_SPINNER (spinner), GTK_ICON_SIZE_MENU);
+	gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, FALSE, 0);
+
+	/* setup site icon, empty by default */
+	icon = gtk_image_new ();
+	gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+	/* don't show the icon */
+
+	/* setup label */
+	label = gtk_label_new (NULL);
+	gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+	gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_misc_set_padding (GTK_MISC (label), 0, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+	gtk_widget_show (label);
+
+	/* setup close button */
+	close_button = gtk_button_new ();
+	gtk_button_set_relief (GTK_BUTTON (close_button),
+			       GTK_RELIEF_NONE);
+	/* don't allow focus on the close button */
+	gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
+
+	gtk_widget_set_name (close_button, "nautilus-tab-close-button");
+
+	image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
+	gtk_widget_set_tooltip_text (close_button, _("Close tab"));
+	g_signal_connect_object (close_button, "clicked",
+				 G_CALLBACK (close_button_clicked_cb), slot, 0);
+
+	gtk_container_add (GTK_CONTAINER (close_button), image);
+	gtk_widget_show (image);
+
+	gtk_box_pack_start (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
+	gtk_widget_show (close_button);
+
+	/* Set minimal size */
+	g_signal_connect (hbox, "style-set",
+			  G_CALLBACK (tab_label_style_set_cb), NULL);
+
+	/* Set up drag-and-drop target */
+	g_signal_connect_object (hbox, "drag-data-received",
+				 G_CALLBACK (notebook_tab_drag_data_received), slot, 0);
+	g_signal_connect_object (hbox, "drag-motion",
+				 G_CALLBACK (notebook_tab_drag_motion), slot, 0);
+	g_signal_connect_object (hbox, "drag-leave",
+				 G_CALLBACK (notebook_tab_drag_leave), slot, 0);
+	g_signal_connect_object (hbox, "drag-drop",
+				 G_CALLBACK (notebook_tab_drag_drop), slot, 0);
+
+	gtk_drag_dest_set (hbox, 0,
+			   url_drag_types, G_N_ELEMENTS (url_drag_types),
+			   GDK_ACTION_MOVE | GDK_ACTION_COPY |
+			   GDK_ACTION_LINK | GDK_ACTION_ASK);
+	gtk_drag_dest_set_track_motion (hbox, TRUE);
+
+	g_object_set_data (G_OBJECT (hbox), "label", label);
+	g_object_set_data (G_OBJECT (hbox), "spinner", spinner);
+	g_object_set_data (G_OBJECT (hbox), "icon", icon);
+	g_object_set_data (G_OBJECT (hbox), "close-button", close_button);
+
+	return hbox;
+}
+
+static int
+nautilus_notebook_insert_page (GtkNotebook *gnotebook,
+			       GtkWidget *tab_widget,
+			       GtkWidget *tab_label,
+			       GtkWidget *menu_label,
+			       int position)
+{
+	g_assert (GTK_IS_WIDGET (tab_widget));
+
+	position = GTK_NOTEBOOK_CLASS (nautilus_notebook_parent_class)->insert_page (gnotebook,
+										     tab_widget,
+										     tab_label,
+										     menu_label,
+										     position);
+
+	gtk_notebook_set_show_tabs (gnotebook,
+				    gtk_notebook_get_n_pages (gnotebook) > 1);
+	gtk_notebook_set_tab_reorderable (gnotebook, tab_widget, TRUE);
+
+	return position;
+}
+
+int
+nautilus_notebook_add_tab (NautilusNotebook *notebook,
+			   NautilusWindowSlot *slot,
+			   int position,
+			   gboolean jump_to)
+{
+	GtkNotebook *gnotebook = GTK_NOTEBOOK (notebook);
+	GtkWidget *tab_label;
+
+	g_return_val_if_fail (NAUTILUS_IS_NOTEBOOK (notebook), -1);
+	g_return_val_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot), -1);
+
+	tab_label = build_tab_label (notebook, slot);
+
+	position = gtk_notebook_insert_page (GTK_NOTEBOOK (notebook),
+					     slot->content_box,
+					     tab_label,
+					     position);
+
+	nautilus_notebook_sync_tab_label (notebook, slot);
+	nautilus_notebook_sync_loading (notebook, slot);
+
+
+	/* FIXME gtk bug! */
+	/* FIXME: this should be fixed in gtk 2.12; check & remove this! */
+	/* The signal handler may have reordered the tabs */
+	position = gtk_notebook_page_num (gnotebook, slot->content_box);
+
+	if (jump_to)
+	{
+		gtk_notebook_set_current_page (gnotebook, position);
+
+	}
+
+	return position;
+}
+
+static void
+nautilus_notebook_remove (GtkContainer *container,
+			  GtkWidget *tab_widget)
+{
+	GtkNotebook *gnotebook = GTK_NOTEBOOK (container);
+	GTK_CONTAINER_CLASS (nautilus_notebook_parent_class)->remove (container, tab_widget);
+
+	gtk_notebook_set_show_tabs (gnotebook,
+				    gtk_notebook_get_n_pages (gnotebook) > 1);
+
+}
+
+void
+nautilus_notebook_reorder_current_child_relative (NautilusNotebook *notebook,
+						  int offset)
+{
+	GtkNotebook *gnotebook;
+	GtkWidget *child;
+	int page;
+
+	g_return_if_fail (NAUTILUS_IS_NOTEBOOK (notebook));
+
+	if (!nautilus_notebook_can_reorder_current_child_relative (notebook, offset)) {
+		return;
+	}
+
+	gnotebook = GTK_NOTEBOOK (notebook);
+
+	page = gtk_notebook_get_current_page (gnotebook);
+	child = gtk_notebook_get_nth_page (gnotebook, page);
+	gtk_notebook_reorder_child (gnotebook, child, page + offset);
+}
+
+void
+nautilus_notebook_set_current_page_relative (NautilusNotebook *notebook,
+					     int offset)
+{
+	GtkNotebook *gnotebook;
+	int page;
+
+	g_return_if_fail (NAUTILUS_IS_NOTEBOOK (notebook));
+
+	if (!nautilus_notebook_can_set_current_page_relative (notebook, offset)) {
+		return;
+	}
+
+	gnotebook = GTK_NOTEBOOK (notebook);
+
+	page = gtk_notebook_get_current_page (gnotebook);
+	gtk_notebook_set_current_page (gnotebook, page + offset);
+
+}
+
+static gboolean
+nautilus_notebook_is_valid_relative_position (NautilusNotebook *notebook,
+					      int offset)
+{
+	GtkNotebook *gnotebook;
+	int page;
+	int n_pages;
+
+	gnotebook = GTK_NOTEBOOK (notebook);
+
+	page = gtk_notebook_get_current_page (gnotebook);
+	n_pages = gtk_notebook_get_n_pages (gnotebook) - 1;
+	if (page < 0 ||
+	    (offset < 0 && page < -offset) ||
+	    (offset > 0 && page > n_pages - offset)) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+gboolean
+nautilus_notebook_can_reorder_current_child_relative (NautilusNotebook *notebook,
+						      int offset)
+{
+	g_return_val_if_fail (NAUTILUS_IS_NOTEBOOK (notebook), FALSE);
+
+	return nautilus_notebook_is_valid_relative_position (notebook, offset);
+}
+
+gboolean
+nautilus_notebook_can_set_current_page_relative (NautilusNotebook *notebook,
+						 int offset)
+{
+	g_return_val_if_fail (NAUTILUS_IS_NOTEBOOK (notebook), FALSE);
+
+	return nautilus_notebook_is_valid_relative_position (notebook, offset);
+}
+

Added: trunk/src/nautilus-notebook.h
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-notebook.h	Tue Jul  8 21:05:55 2008
@@ -0,0 +1,186 @@
+/*
+ *  Copyright  2002 Christophe Fergeau
+ *  Copyright  2003 Marco Pesenti Gritti
+ *  Copyright  2003, 2004 Christian Persch
+ *    (ephy-notebook.c)
+ *
+ *  Copyright  2008 Free Software Foundation, Inc.
+ *    (nautilus-notebook.c)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *  $Id: nautilus-notebook.h 8210 2008-04-11 20:05:25Z chpe $
+ */
+
+#ifndef NAUTILUS_NOTEBOOK_H
+#define NAUTILUS_NOTEBOOK_H
+
+#include <glib.h>
+#include <gtk/gtknotebook.h>
+#include "nautilus-window-slot.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_NOTEBOOK		(nautilus_notebook_get_type ())
+#define NAUTILUS_NOTEBOOK(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_NOTEBOOK, NautilusNotebook))
+#define NAUTILUS_NOTEBOOK_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_TYPE_NOTEBOOK, NautilusNotebookClass))
+#define NAUTILUS_IS_NOTEBOOK(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_NOTEBOOK))
+#define NAUTILUS_IS_NOTEBOOK_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_NOTEBOOK))
+#define NAUTILUS_NOTEBOOK_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_NOTEBOOK, NautilusNotebookClass))
+
+typedef struct _NautilusNotebookClass	NautilusNotebookClass;
+typedef struct _NautilusNotebook		NautilusNotebook;
+typedef struct _NautilusNotebookPrivate	NautilusNotebookPrivate;
+
+struct _NautilusNotebook
+{
+	GtkNotebook parent;
+
+	/*< private >*/
+        NautilusNotebookPrivate *priv;
+};
+
+struct _NautilusNotebookClass
+{
+        GtkNotebookClass parent_class;
+
+	/* Signals */
+	void	 (* tab_close_request)  (NautilusNotebook *notebook,
+					 NautilusWindowSlot *slot);
+};
+
+GType		nautilus_notebook_get_type		(void);
+
+int		nautilus_notebook_add_tab	(NautilusNotebook *nb,
+						 NautilusWindowSlot *slot,
+						 int position,
+						 gboolean jump_to);
+	
+void		nautilus_notebook_set_show_tabs	(NautilusNotebook *nb,
+						 gboolean show_tabs);
+
+void		nautilus_notebook_set_dnd_enabled (NautilusNotebook *nb,
+						   gboolean enabled);
+void		nautilus_notebook_sync_tab_label (NautilusNotebook *nb,
+						  NautilusWindowSlot *slot);
+void		nautilus_notebook_sync_loading   (NautilusNotebook *nb,
+						  NautilusWindowSlot *slot);
+
+void		nautilus_notebook_reorder_current_child_relative (NautilusNotebook *notebook,
+								  int offset);
+void		nautilus_notebook_set_current_page_relative (NautilusNotebook *notebook,
+							     int offset);
+
+gboolean        nautilus_notebook_can_reorder_current_child_relative (NautilusNotebook *notebook,
+								      int offset);
+gboolean        nautilus_notebook_can_set_current_page_relative (NautilusNotebook *notebook,
+								 int offset);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_NOTEBOOK_H */
+/*
+ *  Copyright  2002 Christophe Fergeau
+ *  Copyright  2003 Marco Pesenti Gritti
+ *  Copyright  2003, 2004 Christian Persch
+ *    (ephy-notebook.c)
+ *
+ *  Copyright  2008 Free Software Foundation, Inc.
+ *    (nautilus-notebook.c)
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *  $Id: nautilus-notebook.h 8210 2008-04-11 20:05:25Z chpe $
+ */
+
+#ifndef NAUTILUS_NOTEBOOK_H
+#define NAUTILUS_NOTEBOOK_H
+
+#include <glib.h>
+#include <gtk/gtknotebook.h>
+#include "nautilus-window-slot.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_NOTEBOOK		(nautilus_notebook_get_type ())
+#define NAUTILUS_NOTEBOOK(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_NOTEBOOK, NautilusNotebook))
+#define NAUTILUS_NOTEBOOK_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_TYPE_NOTEBOOK, NautilusNotebookClass))
+#define NAUTILUS_IS_NOTEBOOK(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_NOTEBOOK))
+#define NAUTILUS_IS_NOTEBOOK_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_NOTEBOOK))
+#define NAUTILUS_NOTEBOOK_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_NOTEBOOK, NautilusNotebookClass))
+
+typedef struct _NautilusNotebookClass	NautilusNotebookClass;
+typedef struct _NautilusNotebook		NautilusNotebook;
+typedef struct _NautilusNotebookPrivate	NautilusNotebookPrivate;
+
+struct _NautilusNotebook
+{
+	GtkNotebook parent;
+
+	/*< private >*/
+        NautilusNotebookPrivate *priv;
+};
+
+struct _NautilusNotebookClass
+{
+        GtkNotebookClass parent_class;
+
+	/* Signals */
+	void	 (* tab_close_request)  (NautilusNotebook *notebook,
+					 NautilusWindowSlot *slot);
+};
+
+GType		nautilus_notebook_get_type		(void);
+
+int		nautilus_notebook_add_tab	(NautilusNotebook *nb,
+						 NautilusWindowSlot *slot,
+						 int position,
+						 gboolean jump_to);
+	
+void		nautilus_notebook_set_show_tabs	(NautilusNotebook *nb,
+						 gboolean show_tabs);
+
+void		nautilus_notebook_set_dnd_enabled (NautilusNotebook *nb,
+						   gboolean enabled);
+void		nautilus_notebook_sync_tab_label (NautilusNotebook *nb,
+						  NautilusWindowSlot *slot);
+void		nautilus_notebook_sync_loading   (NautilusNotebook *nb,
+						  NautilusWindowSlot *slot);
+
+void		nautilus_notebook_reorder_current_child_relative (NautilusNotebook *notebook,
+								  int offset);
+void		nautilus_notebook_set_current_page_relative (NautilusNotebook *notebook,
+							     int offset);
+
+gboolean        nautilus_notebook_can_reorder_current_child_relative (NautilusNotebook *notebook,
+								      int offset);
+gboolean        nautilus_notebook_can_set_current_page_relative (NautilusNotebook *notebook,
+								 int offset);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_NOTEBOOK_H */

Modified: trunk/src/nautilus-notes-viewer.c
==============================================================================
--- trunk/src/nautilus-notes-viewer.c	(original)
+++ trunk/src/nautilus-notes-viewer.c	Tue Jul  8 21:05:55 2008
@@ -42,6 +42,8 @@
 #include <libnautilus-private/nautilus-clipboard.h>
 #include <libnautilus-private/nautilus-module.h>
 #include <libnautilus-private/nautilus-sidebar-provider.h>
+#include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
 #include <libnautilus-extension/nautilus-property-page-provider.h>
 
 #define SAVE_TIMEOUT (3 * 1000)
@@ -274,7 +276,7 @@
 }
 
 static void
-loading_uri_callback (NautilusSidebar *sidebar,
+loading_uri_callback (NautilusWindowInfo *window,
                       const char *location,
                       NautilusNotesViewer *notes)
 {
@@ -425,11 +427,15 @@
 nautilus_notes_viewer_set_parent_window (NautilusNotesViewer *sidebar,
                                           NautilusWindowInfo *window)
 {
+	NautilusWindowSlotInfo *slot;
+
+	slot = nautilus_window_info_get_active_slot (window);
+
 	g_signal_connect_object (window, "loading_uri",
 				 G_CALLBACK (loading_uri_callback), sidebar, 0);
         
         g_free (sidebar->details->uri);
-        sidebar->details->uri = nautilus_window_info_get_current_location (window);
+	sidebar->details->uri = nautilus_window_slot_info_get_current_location (slot);
         notes_load_metainfo (sidebar);
 
 	nautilus_clipboard_set_up_text_view

Modified: trunk/src/nautilus-pathbar.c
==============================================================================
--- trunk/src/nautilus-pathbar.c	(original)
+++ trunk/src/nautilus-pathbar.c	Tue Jul  8 21:05:55 2008
@@ -1478,6 +1478,10 @@
 	if (name == NULL) {
 		name = g_file_get_basename (location);
 	}
+		if (!strcmp (name, "chris")) {
+			g_free (name);
+			name = g_strdup ("cneumair");
+		}
 	return name;
 }
 

Modified: trunk/src/nautilus-places-sidebar.c
==============================================================================
--- trunk/src/nautilus-places-sidebar.c	(original)
+++ trunk/src/nautilus-places-sidebar.c	Tue Jul  8 21:05:55 2008
@@ -46,6 +46,8 @@
 #include <libnautilus-private/nautilus-trash-monitor.h>
 #include <libnautilus-private/nautilus-icon-names.h>
 #include <libnautilus-private/nautilus-autorun.h>
+#include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
 #include <gio/gio.h>
 
 #include "nautilus-bookmark-list.h"
@@ -146,7 +148,7 @@
 static void  open_selected_bookmark                    (NautilusPlacesSidebar        *sidebar,
 							GtkTreeModel                 *model,
 							GtkTreePath                  *path,
-							gboolean                      open_in_new_window);
+							NautilusWindowOpenFlags flags);
 static void  nautilus_places_sidebar_style_set         (GtkWidget                    *widget,
 							GtkStyle                     *previous_style);
 static gboolean eject_or_unmount_bookmark              (NautilusPlacesSidebar *sidebar,
@@ -281,11 +283,13 @@
 	char *location, *mount_uri, *name, *desktop_path;
 	GIcon *icon;
 	GFile *root;
-	
-		
+	NautilusWindowSlotInfo *slot;
+
 	selection = gtk_tree_view_get_selection (sidebar->tree_view);
 	gtk_list_store_clear (sidebar->store);
-	location = nautilus_window_info_get_current_location (sidebar->window);
+
+	slot = nautilus_window_info_get_active_slot (sidebar->window);
+	location = nautilus_window_slot_info_get_current_location (slot);
 
 	/* add built in bookmarks */
 	desktop_path = nautilus_get_desktop_directory ();
@@ -301,7 +305,7 @@
 				       mount_uri, NULL, NULL, NULL, 0);
 		g_object_unref (icon);
 		g_free (display_name);
-		if (strcmp (location, mount_uri) == 0) {
+		if (eel_strcmp (location, mount_uri) == 0) {
 			gtk_tree_selection_select_iter (selection, &last_iter);
 		}	
 		g_free (mount_uri);
@@ -313,7 +317,7 @@
 			       _("Desktop"), icon,
 			       mount_uri, NULL, NULL, NULL, 0);
 	g_object_unref (icon);
-	if (strcmp (location, mount_uri) == 0) {
+	if (eel_strcmp (location, mount_uri) == 0) {
 		gtk_tree_selection_select_iter (selection, &last_iter);
 	}	
 	g_free (mount_uri);
@@ -325,7 +329,7 @@
 			       _("File System"), icon,
 			       mount_uri, NULL, NULL, NULL, 0);
 	g_object_unref (icon);
-	if (strcmp (location, mount_uri) == 0) {
+	if (eel_strcmp (location, mount_uri) == 0) {
 		gtk_tree_selection_select_iter (selection, &last_iter);
 	}
 
@@ -361,7 +365,7 @@
 					last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
 							       name, icon, mount_uri,
 							       drive, volume, mount, 0);
-					if (strcmp (location, mount_uri) == 0) {
+					if (eel_strcmp (location, mount_uri) == 0) {
 						gtk_tree_selection_select_iter (selection, &last_iter);
 					}
 					g_object_unref (mount);
@@ -431,7 +435,7 @@
 			last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
 					       name, icon, mount_uri,
 					       NULL, volume, mount, 0);
-			if (strcmp (location, mount_uri) == 0) {
+			if (eel_strcmp (location, mount_uri) == 0) {
 				gtk_tree_selection_select_iter (selection, &last_iter);
 			}
 			g_object_unref (mount);
@@ -470,7 +474,7 @@
 		last_iter = add_place (sidebar, PLACES_MOUNTED_VOLUME,
 				       name, icon, mount_uri,
 				       NULL, NULL, mount, 0);
-		if (strcmp (location, mount_uri) == 0) {
+		if (eel_strcmp (location, mount_uri) == 0) {
 			gtk_tree_selection_select_iter (selection, &last_iter);
 		}
 		g_object_unref (mount);
@@ -485,7 +489,7 @@
 	last_iter = add_place (sidebar, PLACES_BUILT_IN,
 			       _("Trash"), icon, mount_uri,
 			       NULL, NULL, NULL, 0);
-	if (strcmp (location, mount_uri) == 0) {
+	if (eel_strcmp (location, mount_uri) == 0) {
 		gtk_tree_selection_select_iter (selection, &last_iter);
 	}
 	g_object_unref (icon);
@@ -513,7 +517,7 @@
 		last_iter = add_place (sidebar, PLACES_BOOKMARK,
 				       name, icon, mount_uri,
 				       NULL, NULL, NULL, index);
-		if (strcmp (location, mount_uri) == 0) {
+		if (eel_strcmp (location, mount_uri) == 0) {
 			gtk_tree_selection_select_iter (selection, &last_iter);
 		}
 		g_free (name);
@@ -649,7 +653,7 @@
 	open_selected_bookmark (NAUTILUS_PLACES_SIDEBAR (user_data),
 				gtk_tree_view_get_model (tree_view),
 				path,
-				FALSE);
+				0);
 }
 
 static void
@@ -1340,8 +1344,9 @@
 open_selected_bookmark (NautilusPlacesSidebar *sidebar,
 			GtkTreeModel	      *model,
 			GtkTreePath	      *path,
-			gboolean	      open_in_new_window)
+			NautilusWindowOpenFlags	      flags)
 {
+	NautilusWindowSlot *slot;
 	GtkTreeIter iter;
 	GFile *location;
 	char *uri;
@@ -1354,6 +1359,12 @@
 		return;
 	}
 
+	if (flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB &&
+	    !eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)) {
+		flags &= ~NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
+		flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW;
+	}
+
 	gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1);
 
 	if (uri != NULL) {
@@ -1362,10 +1373,11 @@
 				    sidebar->window, uri);
 		location = g_file_new_for_uri (uri);
 		/* Navigate to the clicked location */
-		if (!open_in_new_window) {
-			nautilus_window_info_open_location (sidebar->window, location,
-							    NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
-							    0, NULL);
+		if ((flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) == 0) {
+			slot = nautilus_window_info_get_active_slot (sidebar->window);
+			nautilus_window_slot_info_open_location (slot, location,
+								 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
+								 flags, NULL);
 		} else {
 			NautilusWindow *cur, *new;
 			
@@ -1390,7 +1402,7 @@
 
 static void
 open_shortcut_from_menu (NautilusPlacesSidebar *sidebar,
-			 gboolean	       open_in_new_window)
+			 NautilusWindowOpenFlags	       flags)
 {
 	GtkTreeModel *model;
 	GtkTreePath *path;
@@ -1398,7 +1410,7 @@
 	model = gtk_tree_view_get_model (sidebar->tree_view);
 	gtk_tree_view_get_cursor (sidebar->tree_view, &path, NULL);
 
-	open_selected_bookmark (sidebar, model, path, open_in_new_window);
+	open_selected_bookmark (sidebar, model, path, flags);
 
 	gtk_tree_path_free (path);
 }
@@ -1407,14 +1419,21 @@
 open_shortcut_cb (GtkMenuItem		*item,
 		  NautilusPlacesSidebar	*sidebar)
 {
-	open_shortcut_from_menu (sidebar, FALSE);
+	open_shortcut_from_menu (sidebar, 0);
 }
 
 static void
 open_shortcut_in_new_window_cb (GtkMenuItem	      *item,
 				NautilusPlacesSidebar *sidebar)
 {
-	open_shortcut_from_menu (sidebar, TRUE);
+	open_shortcut_from_menu (sidebar, NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
+}
+
+static void
+open_shortcut_in_new_tab_cb (GtkMenuItem	      *item,
+				NautilusPlacesSidebar *sidebar)
+{
+	open_shortcut_from_menu (sidebar, NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB);
 }
 
 /* Rename the selected bookmark */
@@ -1830,6 +1849,12 @@
 	gtk_widget_show (item);
 	gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
 
+	item = gtk_menu_item_new_with_mnemonic (_("Open in New _Tab"));
+	g_signal_connect (item, "activate",
+			  G_CALLBACK (open_shortcut_in_new_tab_cb), sidebar);
+	gtk_widget_show (item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (sidebar->popup_menu), item);
+
 	item = gtk_menu_item_new_with_mnemonic (_("Open in New _Window"));
 	g_signal_connect (item, "activate",
 			  G_CALLBACK (open_shortcut_in_new_window_cb), sidebar);
@@ -1931,7 +1956,8 @@
 }
 
 /* Callback used when a button is pressed on the shortcuts list.  
- * We trap button 3 to bring up a popup menu.
+ * We trap button 3 to bring up a popup menu, and button 2 to
+ * open in a new tab.
  */
 static gboolean
 bookmarks_button_press_event_cb (GtkWidget             *widget,
@@ -1954,6 +1980,28 @@
 
 	if (event->button == 3) {
 		bookmarks_popup_menu (sidebar, event);
+	} else if (event->button == 2) {
+		GtkTreeModel *model;
+		GtkTreePath *path;
+		GtkTreeView *tree_view;
+
+		tree_view = GTK_TREE_VIEW (widget);
+		g_assert (tree_view == sidebar->tree_view);
+
+		model = gtk_tree_view_get_model (tree_view);
+
+		gtk_tree_view_get_path_at_pos (tree_view, (int) event->x, (int) event->y, 
+					       &path, NULL, NULL, NULL);
+
+		open_selected_bookmark (sidebar, model, path,
+					event->state & GDK_CONTROL_MASK ?
+					NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW :
+					NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB);
+
+		if (path != NULL) {
+			gtk_tree_path_free (path);
+			return TRUE;
+		}
 	}
 
 	return FALSE;
@@ -2238,11 +2286,15 @@
 static void
 nautilus_places_sidebar_set_parent_window (NautilusPlacesSidebar *sidebar,
 					   NautilusWindowInfo *window)
-{	
+{
+	NautilusWindowSlotInfo *slot;
+
 	sidebar->window = window;
-	
+
+	slot = nautilus_window_info_get_active_slot (window);
+
 	sidebar->bookmarks = nautilus_window_info_get_bookmark_list (window);
-	sidebar->uri = nautilus_window_info_get_current_location (window);
+	sidebar->uri = nautilus_window_slot_info_get_current_location (slot);
 
 	g_signal_connect_object (sidebar->bookmarks, "contents_changed",
 				 G_CALLBACK (update_places),

Modified: trunk/src/nautilus-query-editor.c
==============================================================================
--- trunk/src/nautilus-query-editor.c	(original)
+++ trunk/src/nautilus-query-editor.c	Tue Jul  8 21:05:55 2008
@@ -23,6 +23,7 @@
 
 #include <config.h>
 #include "nautilus-query-editor.h"
+#include "nautilus-window-slot.h"
 
 #include <string.h>
 #include <libnautilus-private/nautilus-marshal.h>
@@ -72,8 +73,10 @@
 	GtkWidget *visible_vbox;
 
 	GList *rows;
+	char *last_set_query_text;
 	
 	NautilusSearchBar *bar;
+	NautilusWindowSlot *slot;
 };
 
 enum {
@@ -1174,11 +1177,16 @@
 {
 	editor->details->change_frozen = TRUE;
 	gtk_entry_set_text (GTK_ENTRY (editor->details->entry), "");
+
+	g_free (editor->details->last_set_query_text);
+	editor->details->last_set_query_text = g_strdup ("");
+
 	editor->details->change_frozen = FALSE;
 }
 
 GtkWidget *
-nautilus_query_editor_new (gboolean start_hidden, gboolean is_indexed)
+nautilus_query_editor_new (gboolean start_hidden,
+			   gboolean is_indexed)
 {
 	GtkWidget *editor;
 
@@ -1194,10 +1202,45 @@
 	return editor;
 }
 
+static void
+detach_from_external_entry (NautilusQueryEditor *editor)
+{
+	if (editor->details->bar != NULL) {
+		nautilus_search_bar_return_entry (editor->details->bar);
+		g_signal_handlers_block_by_func (editor->details->entry,
+						 entry_activate_cb,
+						 editor);
+		g_signal_handlers_block_by_func (editor->details->entry,
+						 entry_changed_cb,
+						 editor);
+	}
+}
+
+static void
+attach_to_external_entry (NautilusQueryEditor *editor)
+{
+	if (editor->details->bar != NULL) {
+		nautilus_search_bar_borrow_entry (editor->details->bar);
+		g_signal_handlers_unblock_by_func (editor->details->entry,
+						   entry_activate_cb,
+						   editor);
+		g_signal_handlers_unblock_by_func (editor->details->entry,
+						   entry_changed_cb,
+						   editor);
+
+		editor->details->change_frozen = TRUE;
+		gtk_entry_set_text (GTK_ENTRY (editor->details->entry),
+				    editor->details->last_set_query_text);
+		editor->details->change_frozen = FALSE;
+	}
+}
+
 GtkWidget*
 nautilus_query_editor_new_with_bar (gboolean start_hidden,
 				    gboolean is_indexed,
-				    NautilusSearchBar *bar)
+				    gboolean start_attached,
+				    NautilusSearchBar *bar,
+				    NautilusWindowSlot *slot)
 {
 	GtkWidget *entry;
 	NautilusQueryEditor *editor;
@@ -1209,9 +1252,21 @@
 
 	editor->details->bar = bar;
 	eel_add_weak_pointer (&editor->details->bar);
-	
+
+	editor->details->slot = slot;
+
 	entry = nautilus_search_bar_borrow_entry (bar);
 	setup_external_entry (editor, entry);
+	if (!start_attached) {
+		detach_from_external_entry (editor);
+	}
+
+	g_signal_connect_object (slot, "active",
+				 G_CALLBACK (attach_to_external_entry),
+				 editor, G_CONNECT_SWAPPED);
+	g_signal_connect_object (slot, "inactive",
+				 G_CALLBACK (detach_from_external_entry),
+				 editor, G_CONNECT_SWAPPED);
 	
 	return GTK_WIDGET (editor);
 }
@@ -1220,7 +1275,7 @@
 nautilus_query_editor_set_query (NautilusQueryEditor *editor, NautilusQuery *query)
 {
 	NautilusQueryEditorRowType type;
-	const char *text;
+	char *text;
 
 	if (!query) {
 		nautilus_query_editor_clear_query (editor);
@@ -1228,8 +1283,9 @@
 	}
 
 	text = nautilus_query_get_text (query);
+
 	if (!text) {
-		text = "";
+		text = g_strdup ("");
 	}
 
 	editor->details->change_frozen = TRUE;
@@ -1240,4 +1296,7 @@
 	}
 	
 	editor->details->change_frozen = FALSE;
+
+	g_free (editor->details->last_set_query_text);
+	editor->details->last_set_query_text = text;
 }

Modified: trunk/src/nautilus-query-editor.h
==============================================================================
--- trunk/src/nautilus-query-editor.h	(original)
+++ trunk/src/nautilus-query-editor.h	Tue Jul  8 21:05:55 2008
@@ -27,6 +27,7 @@
 #include <gtk/gtk.h>
 #include <libnautilus-private/nautilus-query.h>
 #include <nautilus-search-bar.h>
+#include "nautilus-window-info.h"
 
 #define NAUTILUS_TYPE_QUERY_EDITOR (nautilus_query_editor_get_type ())
 #define NAUTILUS_QUERY_EDITOR(obj) GTK_CHECK_CAST (obj, NAUTILUS_TYPE_QUERY_EDITOR, NautilusQueryEditor)
@@ -54,7 +55,9 @@
 						    gboolean is_indexed);
 GtkWidget* nautilus_query_editor_new_with_bar      (gboolean start_hidden,
 						    gboolean is_indexed,
-						    NautilusSearchBar *bar);
+						    gboolean start_attached,
+						    NautilusSearchBar *bar,
+						    NautilusWindowSlot *slot);
 void       nautilus_query_editor_set_default_query (NautilusQueryEditor *editor);
 
 void	   nautilus_query_editor_grab_focus (NautilusQueryEditor *editor);

Modified: trunk/src/nautilus-spatial-window.c
==============================================================================
--- trunk/src/nautilus-spatial-window.c	(original)
+++ trunk/src/nautilus-spatial-window.c	Tue Jul  8 21:05:55 2008
@@ -44,6 +44,7 @@
 #include "nautilus-zoom-control.h"
 #include <eel/eel-glib-extensions.h>
 #include <eel/eel-gtk-extensions.h>
+#include <eel/eel-gtk-macros.h>
 #include <eel/eel-string.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gdk/gdkkeysyms.h>
@@ -82,8 +83,6 @@
 	GtkWidget *location_button;
 	GtkWidget *location_label;
 	GtkWidget *location_icon;
-
-	GtkWidget *query_editor;
 };
 
 static const GtkTargetEntry location_button_drag_types[] = {
@@ -92,6 +91,7 @@
 };
 
 G_DEFINE_TYPE(NautilusSpatialWindow, nautilus_spatial_window, NAUTILUS_TYPE_WINDOW)
+#define parent_class nautilus_spatial_window_parent_class
 
 static gboolean
 save_window_geometry_timeout (gpointer callback_data)
@@ -173,27 +173,35 @@
 nautilus_spatial_window_state_event (GtkWidget *widget,
 				     GdkEventWindowState *event)
 {
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
+	NautilusFile *viewed_file;
+
+	window = NAUTILUS_WINDOW (widget);
+	slot = window->details->active_slot;
+	viewed_file = slot->viewed_file;
+
 	if (!NAUTILUS_IS_DESKTOP_WINDOW (widget)) {
 		
 		if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED &&
-		    NAUTILUS_WINDOW (widget)->details->viewed_file != NULL) {
-			nautilus_file_set_boolean_metadata (NAUTILUS_WINDOW (widget)->details->viewed_file,
+		    viewed_file != NULL) {
+			nautilus_file_set_boolean_metadata (viewed_file,
 							    NAUTILUS_METADATA_KEY_WINDOW_MAXIMIZED,
 							    FALSE,
 							    event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED);
 		}
 		
 		if (event->changed_mask & GDK_WINDOW_STATE_STICKY &&
-		    NAUTILUS_WINDOW (widget)->details->viewed_file != NULL) {
-			nautilus_file_set_boolean_metadata (NAUTILUS_WINDOW (widget)->details->viewed_file,
+		    viewed_file != NULL) {
+			nautilus_file_set_boolean_metadata (viewed_file,
 							    NAUTILUS_METADATA_KEY_WINDOW_STICKY,
 							    FALSE,
 							    event->new_window_state & GDK_WINDOW_STATE_STICKY);
 		}
 		
 		if (event->changed_mask & GDK_WINDOW_STATE_ABOVE &&
-		    NAUTILUS_WINDOW (widget)->details->viewed_file != NULL) {
-			nautilus_file_set_boolean_metadata (NAUTILUS_WINDOW (widget)->details->viewed_file,
+		    viewed_file != NULL) {
+			nautilus_file_set_boolean_metadata (viewed_file,
 							    NAUTILUS_METADATA_KEY_WINDOW_KEEP_ABOVE,
 							    FALSE,
 							    event->new_window_state & GDK_WINDOW_STATE_ABOVE);
@@ -235,13 +243,19 @@
 }
 
 void
-nautilus_spatial_window_save_geometry (NautilusSpatialWindow *window)
+nautilus_spatial_window_save_geometry (NautilusSpatialWindow *spatial_window)
 {
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
+	NautilusFile *viewed_file;
 	char *geometry_string;
 
-	g_assert (NAUTILUS_IS_WINDOW (window));
+	window = NAUTILUS_WINDOW (spatial_window);
+
+	slot = window->details->active_slot;
+	viewed_file = slot->viewed_file;
 
-	if (NAUTILUS_WINDOW (window)->details->viewed_file == NULL) {
+	if (viewed_file == NULL) {
 		/* We never showed a file */
 		return;
 	}
@@ -250,7 +264,7 @@
 	    !(gdk_window_get_state (GTK_WIDGET(window)->window) & GDK_WINDOW_STATE_MAXIMIZED)) {
 		geometry_string = eel_gtk_window_get_geometry_string (GTK_WINDOW (window));
 		
-		nautilus_file_set_metadata (NAUTILUS_WINDOW (window)->details->viewed_file,
+		nautilus_file_set_metadata (viewed_file,
 					    NAUTILUS_METADATA_KEY_WINDOW_GEOMETRY,
 					    NULL,
 					    geometry_string);
@@ -262,17 +276,19 @@
 void
 nautilus_spatial_window_save_scroll_position (NautilusSpatialWindow *window)
 {
-	NautilusWindow *parent;
+	NautilusWindow *nautilus_window;
+	NautilusWindowSlot *slot;
 	char *scroll_string;
 
-	parent = NAUTILUS_WINDOW(window);
-	
-	if (parent->content_view == NULL) {
+	nautilus_window = NAUTILUS_WINDOW (window);
+	slot = nautilus_window_get_active_slot (nautilus_window);
+
+	if (slot->content_view == NULL) {
 		return;
 	}
 	
-	scroll_string = nautilus_view_get_first_visible_file (parent->content_view);
-	nautilus_file_set_metadata (parent->details->viewed_file,
+	scroll_string = nautilus_view_get_first_visible_file (slot->content_view);
+	nautilus_file_set_metadata (slot->viewed_file,
 				    NAUTILUS_METADATA_KEY_WINDOW_SCROLL_POSITION,
 				    NULL,
 				    scroll_string);
@@ -282,9 +298,12 @@
 void
 nautilus_spatial_window_save_show_hidden_files_mode (NautilusSpatialWindow *window)
 {
+	NautilusWindowSlot *slot;
 	char *show_hidden_file_setting;
 	NautilusWindowShowHiddenFilesMode mode;
 
+	slot = nautilus_window_get_active_slot (NAUTILUS_WINDOW (window));
+
 	mode = NAUTILUS_WINDOW (window)->details->show_hidden_files_mode;
 	if (mode != NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT) {
 		if (mode == NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_ENABLE) {
@@ -292,7 +311,7 @@
 		} else {
 			show_hidden_file_setting = "0";
 		}
-		nautilus_file_set_metadata (NAUTILUS_WINDOW (window)->details->viewed_file,
+		nautilus_file_set_metadata (slot->viewed_file,
 			 		    NAUTILUS_METADATA_KEY_WINDOW_SHOW_HIDDEN_FILES,
 				    	    NULL,
 				    	    show_hidden_file_setting);
@@ -302,15 +321,16 @@
 static void
 nautilus_spatial_window_show (GtkWidget *widget)
 {	
-	NautilusSpatialWindow *window;
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
+
+	window = NAUTILUS_WINDOW (widget);
+	slot = nautilus_window_get_active_slot (window);
 
-	window = NAUTILUS_SPATIAL_WINDOW (widget);
-	
 	GTK_WIDGET_CLASS (nautilus_spatial_window_parent_class)->show (widget);
 
-	if (NAUTILUS_WINDOW (window)->details->search_mode &&
-	    window->details->query_editor != NULL) {
-		nautilus_query_editor_grab_focus (NAUTILUS_QUERY_EDITOR (window->details->query_editor));
+	if (slot != NULL && slot->query_editor != NULL) {
+		nautilus_query_editor_grab_focus (NAUTILUS_QUERY_EDITOR (slot->query_editor));
 	}
 }
 
@@ -343,99 +363,39 @@
 	gtk_widget_show (dialog);
 }
 
-static void
-query_editor_changed_callback (NautilusSearchBar *bar,
-			       NautilusQuery *query,
-			       gboolean reload,
-			       NautilusWindow *window)
-{
-	NautilusDirectory *directory;
-
-	directory = nautilus_directory_get_for_file (window->details->viewed_file);
-	g_assert (NAUTILUS_IS_SEARCH_DIRECTORY (directory));
-
-	nautilus_search_directory_set_query (NAUTILUS_SEARCH_DIRECTORY (directory),
-					     query);
-	if (reload) {
-		nautilus_window_reload (window);
-	}
-
-	nautilus_directory_unref (directory);
-}
-
-static void
-real_set_search_mode (NautilusWindow *window, gboolean search_mode,
-		      NautilusSearchDirectory *search_directory)
-{
-	NautilusSpatialWindow *spatial_window;
-	GtkWidget *query_editor;
-	NautilusQuery *query;
-
-	spatial_window = NAUTILUS_SPATIAL_WINDOW (window);
-
-	spatial_window->details->query_editor = NULL;
-	
-	if (search_mode) {
-		query_editor = nautilus_query_editor_new (nautilus_search_directory_is_saved_search (search_directory),
-							  nautilus_search_directory_is_indexed (search_directory));
-		spatial_window->details->query_editor = query_editor;
-		
-		nautilus_window_add_extra_location_widget (window, query_editor);
-		gtk_widget_show (query_editor);
-		nautilus_query_editor_grab_focus (NAUTILUS_QUERY_EDITOR (query_editor));
-		g_signal_connect_object (query_editor, "changed",
-					 G_CALLBACK (query_editor_changed_callback), window, 0);
-		
-		query = nautilus_search_directory_get_query (search_directory);
-		if (query != NULL) {
-			nautilus_query_editor_set_query (NAUTILUS_QUERY_EDITOR (query_editor),
-							 query);
-			g_object_unref (query);
-		} else {
-			nautilus_query_editor_set_default_query (NAUTILUS_QUERY_EDITOR (query_editor));
-		}
-	} 
-}
-
 static NautilusIconInfo *
-real_get_icon (NautilusWindow *window)
+real_get_icon (NautilusWindow *window,
+	       NautilusWindowSlot *slot)
 {
-	return nautilus_file_get_icon (window->details->viewed_file, 48,
+	return nautilus_file_get_icon (slot->viewed_file, 48,
 				       NAUTILUS_FILE_ICON_FLAGS_IGNORE_VISITING);
 }
 
-static gboolean
-real_set_title (NautilusWindow *window, const char *title)
+static void
+sync_window_title (NautilusWindow *window)
 {
-	gboolean changed;
+	NautilusWindowSlot *slot;
 
-	changed = NAUTILUS_WINDOW_CLASS (nautilus_spatial_window_parent_class)->set_title (window, title);
+	slot = nautilus_window_get_active_slot (window);
 
-	if (changed && title[0] == '\0') {
+	if (slot->title == NULL || slot->title[0] == '\0') {
 		gtk_window_set_title (GTK_WINDOW (window), _("Nautilus"));
-	} else if (changed) {
+	} else {
 		char *window_title;
 
-		window_title = eel_str_middle_truncate (title, MAX_TITLE_LENGTH);
+		window_title = eel_str_middle_truncate (slot->title, MAX_TITLE_LENGTH);
 		gtk_window_set_title (GTK_WINDOW (window), window_title);
 		g_free (window_title);
 	}
-
-	return changed;
 }
 
 static void
-real_set_content_view_widget (NautilusWindow *window,
-			      NautilusView *new_view)
+real_sync_title (NautilusWindow *window,
+		 NautilusWindowSlot *slot)
 {
-	GtkWidget *widget;
-
-	NAUTILUS_WINDOW_CLASS (nautilus_spatial_window_parent_class)->set_content_view_widget (window, new_view);
+	g_assert (slot == nautilus_window_get_active_slot (window));
 
-	widget = nautilus_view_get_widget (new_view);
-
-	gtk_container_add (GTK_CONTAINER (NAUTILUS_SPATIAL_WINDOW (window)->details->content_box),
-			   widget);
+	sync_window_title (window);
 }
 
 static void
@@ -459,7 +419,8 @@
 }
 
 static void
-real_set_throbber_active (NautilusWindow *window, gboolean active)
+real_sync_allow_stop (NautilusWindow *window,
+		      NautilusWindowSlot *slot)
 {
 }
 
@@ -478,16 +439,51 @@
 	NAUTILUS_WINDOW_CLASS (nautilus_spatial_window_parent_class)->set_allow_up (window, allow);
 }
 
+static NautilusWindowSlot *
+real_open_slot (NautilusWindow *window,
+		NautilusWindowOpenSlotFlags flags)
+{
+	NautilusWindowSlot *slot;
+	GList *slots;
+
+	g_assert (nautilus_window_get_active_slot (window) == NULL);
+
+	slots = nautilus_window_get_slots (window);
+	g_assert (slots == NULL);
+	g_list_free (slots);
+
+	slot = g_object_new (NAUTILUS_TYPE_WINDOW_SLOT, NULL);
+	slot->window = window;
+	gtk_container_add (GTK_CONTAINER (NAUTILUS_SPATIAL_WINDOW (window)->details->content_box),
+			   slot->content_box);
+	gtk_widget_show (slot->content_box);
+	return slot;
+}
+
+static void
+real_close_slot (NautilusWindow *window,
+		 NautilusWindowSlot *slot)
+{
+	g_assert (g_list_length (window->details->slots) == 1);
+
+	/* nothing to do */
+	EEL_CALL_PARENT (NAUTILUS_WINDOW_CLASS,
+			 close_slot, (window, slot));
+}
+
 static void
 location_menu_item_activated_callback (GtkWidget *menu_item,
-				       NautilusSpatialWindow *window)
+				       NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	char *location;
 	GFile *current;
 	GFile *dest;
 	GdkEvent *event;
 
-	location = nautilus_window_get_location_uri (NAUTILUS_WINDOW (window));
+	slot = window->details->active_slot;
+
+	location = nautilus_window_slot_get_location_uri (slot);
 	current = g_file_new_for_uri (location);
 	g_free (location);
 
@@ -516,8 +512,8 @@
 			close_behind = TRUE;
 		}
 
-		nautilus_window_open_location_with_selection (NAUTILUS_WINDOW (window),
-							      dest, selection, close_behind);
+		nautilus_window_slot_open_location_with_selection
+			(slot, dest, selection, close_behind);
 
 		eel_g_object_list_free (selection);
 	}
@@ -609,9 +605,12 @@
 				  GdkEventButton *event,
 				  NautilusWindow *window)
 {
-	if (event->button == 3 &&
-	    window->content_view != NULL) {
-		nautilus_view_pop_up_location_context_menu (window->content_view, event, NULL);
+	NautilusView *view;
+
+	view = window->details->active_slot->content_view;
+
+	if (event->button == 3 && view != NULL) {
+		nautilus_view_pop_up_location_context_menu (view, event, NULL);
 	}
 
 	return FALSE;
@@ -621,16 +620,19 @@
 location_button_clicked_callback (GtkWidget             *widget,
 				  NautilusSpatialWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GtkWidget *popup, *menu_item, *first_item = NULL;
 	char *location;
 	GFile *uri;
 	GFile *child_uri;
 	GMainLoop *loop;
 
+	slot = NAUTILUS_WINDOW (window)->details->active_slot;
+
 	popup = gtk_menu_new ();
 	first_item = NULL;
 
-	location = nautilus_window_get_location_uri (NAUTILUS_WINDOW (window));
+	location = nautilus_window_slot_get_location_uri (slot);
 	g_return_if_fail (location != NULL);
 
 	uri = g_file_new_for_uri (location);
@@ -711,14 +713,16 @@
 get_dnd_icon_size (NautilusSpatialWindow *window)
 {
 	NautilusWindow *parent;
+	NautilusView *view;
 	NautilusZoomLevel zoom_level;
 
 	parent = NAUTILUS_WINDOW(window);
+	view = parent->details->active_slot->content_view;
 
-	if (parent->content_view == NULL) {
+	if (view == NULL) {
 		return NAUTILUS_ICON_SIZE_STANDARD;
 	} else {
-		zoom_level = nautilus_view_get_zoom_level (parent->content_view);
+		zoom_level = nautilus_view_get_zoom_level (view);
 		return nautilus_get_icon_size_for_zoom_level (zoom_level);
 	}
 	
@@ -729,9 +733,12 @@
 				     GdkDragContext        *context,
 				     NautilusSpatialWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GdkPixbuf *pixbuf;
 
-	pixbuf = nautilus_file_get_icon_pixbuf (NAUTILUS_WINDOW (window)->details->viewed_file,
+	slot = NAUTILUS_WINDOW (window)->details->active_slot;
+
+	pixbuf = nautilus_file_get_icon_pixbuf (slot->viewed_file,
 						get_dnd_icon_size (window),
 						FALSE,
 						NAUTILUS_FILE_ICON_FLAGS_IGNORE_VISITING | NAUTILUS_FILE_ICON_FLAGS_FOR_DRAG_ACCEPT);
@@ -750,13 +757,16 @@
 		 gpointer                            data)
 {
 	NautilusSpatialWindow *window;
+	NautilusWindowSlot *slot;
 	char *location;
 	int icon_size;
 
 	g_assert (NAUTILUS_IS_SPATIAL_WINDOW (iterator_context));
 	window = NAUTILUS_SPATIAL_WINDOW (iterator_context);
 
-	location = nautilus_window_get_location_uri (NAUTILUS_WINDOW (window));
+	slot = NAUTILUS_WINDOW (window)->details->active_slot;
+
+	location = nautilus_window_slot_get_location_uri (slot);
 	icon_size = get_dnd_icon_size (window);
 
 	iteratee (location,
@@ -900,7 +910,7 @@
 {
 	GtkRcStyle *rc_style;
 	GtkWidget *arrow;
-	GtkWidget *hbox, *vbox, *eventbox, *extras_vbox;
+	GtkWidget *hbox, *vbox;
 	GtkActionGroup *action_group;
 	GtkUIManager *ui_manager;
 	GtkTargetList *targets;
@@ -920,21 +930,8 @@
 			  GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_EXPAND | GTK_FILL | GTK_SHRINK,
 			  0,                                  0);
 	gtk_widget_show (vbox);
+	window->details->content_box = vbox;
 
-	eventbox = gtk_event_box_new ();
-	gtk_widget_set_name (eventbox, "nautilus-extra-view-widget");
-	gtk_box_pack_start (GTK_BOX (vbox), eventbox, FALSE, FALSE, 0);
-	gtk_widget_show (eventbox);
-	
-	extras_vbox = gtk_vbox_new (FALSE, 6);
-	gtk_container_set_border_width (GTK_CONTAINER (extras_vbox), 6);
-	NAUTILUS_WINDOW (window)->details->extra_location_widgets = extras_vbox;
-	gtk_container_add (GTK_CONTAINER (eventbox), extras_vbox);
-
-	window->details->content_box = gtk_vbox_new (FALSE, 0);
-	gtk_box_pack_start (GTK_BOX (vbox), window->details->content_box, TRUE, TRUE, 0);
-	gtk_widget_show (window->details->content_box);
-	
 	window->details->location_button = gtk_button_new ();
 	g_signal_connect (window->details->location_button,
 			  "button-press-event",
@@ -1028,23 +1025,22 @@
 
 	NAUTILUS_WINDOW_CLASS (class)->prompt_for_location = 
 		real_prompt_for_location;
-	NAUTILUS_WINDOW_CLASS (class)->set_search_mode = 
-		real_set_search_mode;
 	NAUTILUS_WINDOW_CLASS (class)->get_icon =
 		real_get_icon;
-	NAUTILUS_WINDOW_CLASS (class)->set_title = 
-		real_set_title;
-	NAUTILUS_WINDOW_CLASS (class)->set_content_view_widget = 
-		real_set_content_view_widget;
+	NAUTILUS_WINDOW_CLASS (class)->sync_title = 
+		real_sync_title;
 	NAUTILUS_WINDOW_CLASS (class)->close = 
 		real_window_close;
 	NAUTILUS_WINDOW_CLASS(class)->get_default_size = real_get_default_size;
 
-	NAUTILUS_WINDOW_CLASS(class)->set_throbber_active =
-		real_set_throbber_active;
+	NAUTILUS_WINDOW_CLASS(class)->sync_allow_stop =
+		real_sync_allow_stop;
 	NAUTILUS_WINDOW_CLASS(class)->set_allow_up =
 		real_set_allow_up;
 
+	NAUTILUS_WINDOW_CLASS (class)->open_slot = real_open_slot;
+	NAUTILUS_WINDOW_CLASS (class)->close_slot = real_close_slot;
+
 	binding_set = gtk_binding_set_by_class (class);
 	gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_SHIFT_MASK,
 				      "go_up", 1,

Modified: trunk/src/nautilus-window-bookmarks.c
==============================================================================
--- trunk/src/nautilus-window-bookmarks.c	(original)
+++ trunk/src/nautilus-window-bookmarks.c	Tue Jul  8 21:05:55 2008
@@ -153,10 +153,12 @@
 nautilus_window_add_bookmark_for_current_location (NautilusWindow *window)
 {
 	NautilusBookmark *bookmark;
+	NautilusWindowSlot *slot;
 
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+	g_assert (NAUTILUS_IS_WINDOW (window));
 
-	bookmark = window->current_location_bookmark;
+	slot = window->details->active_slot;
+	bookmark = slot->current_location_bookmark;
 
 	if (!nautilus_bookmark_list_contains (nautilus_get_bookmark_list (), bookmark)) {
 		nautilus_bookmark_list_append (nautilus_get_bookmark_list (), bookmark); 

Modified: trunk/src/nautilus-window-manage-views.c
==============================================================================
--- trunk/src/nautilus-window-manage-views.c	(original)
+++ trunk/src/nautilus-window-manage-views.c	Tue Jul  8 21:05:55 2008
@@ -35,6 +35,8 @@
 #include "nautilus-pathbar.h"
 #include "nautilus-main.h"
 #include "nautilus-window-private.h"
+#include "nautilus-window-slot.h"
+#include "nautilus-navigation-window-slot.h"
 #include "nautilus-trash-bar.h"
 #include "nautilus-x-content-bar.h"
 #include "nautilus-zoom-control.h"
@@ -43,6 +45,7 @@
 #include <eel/eel-gdk-extensions.h>
 #include <eel/eel-glib-extensions.h>
 #include <eel/eel-gtk-extensions.h>
+#include <eel/eel-gtk-macros.h>
 #include <eel/eel-stock-dialogs.h>
 #include <eel/eel-string.h>
 #include <eel/eel-mount-operation.h>
@@ -63,6 +66,7 @@
 #include <libnautilus-private/nautilus-search-directory.h>
 #include <libnautilus-private/nautilus-view-factory.h>
 #include <libnautilus-private/nautilus-window-info.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
 #include <libnautilus-private/nautilus-autorun.h>
 
 /* FIXME bugzilla.gnome.org 41243: 
@@ -78,38 +82,36 @@
  */
 #define MAX_URI_IN_DIALOG_LENGTH 60
 
-static void connect_view                              (NautilusWindow             *window,
+static void slot_connect_view                         (NautilusWindowSlot         *slot,
 						       NautilusView               *view);
-static void disconnect_view                           (NautilusWindow             *window,
+static void slot_disconnect_view                      (NautilusWindowSlot         *slot,
 						       NautilusView               *view);
-static void begin_location_change                     (NautilusWindow             *window,
+static void begin_location_change                     (NautilusWindowSlot         *slot,
 						       GFile                      *location,
 						       GList                      *new_selection,
 						       NautilusLocationChangeType  type,
 						       guint                       distance,
 						       const char                 *scroll_pos);
-static void free_location_change                      (NautilusWindow             *window);
-static void end_location_change                       (NautilusWindow             *window);
-static void cancel_location_change                    (NautilusWindow             *window);
+static void free_location_change                      (NautilusWindowSlot         *slot);
+static void end_location_change                       (NautilusWindowSlot         *slot);
+static void cancel_location_change                    (NautilusWindowSlot         *slot);
 static void got_file_info_for_view_selection_callback (NautilusFile               *file,
 						       gpointer                    callback_data);
-static void create_content_view                       (NautilusWindow             *window,
+static void create_content_view                       (NautilusWindowSlot         *slot,
 						       const char                 *view_id);
 static void display_view_selection_failure            (NautilusWindow             *window,
 						       NautilusFile               *file,
 						       GFile                      *location,
 						       GError                     *error);
-static void load_new_location                         (NautilusWindow             *window,
+static void load_new_location                         (NautilusWindowSlot         *slot,
 						       GFile                      *location,
 						       GList                      *selection,
 						       gboolean                    tell_current_content_view,
 						       gboolean                    tell_new_content_view);
-static void location_has_really_changed               (NautilusWindow             *window);
-static void update_for_new_location                   (NautilusWindow             *window);
+static void location_has_really_changed               (NautilusWindowSlot         *slot);
+static void update_for_new_location                   (NautilusWindowSlot         *slot);
 static void zoom_parameters_changed_callback          (NautilusView               *view,
-						       NautilusWindow             *window);
-static void update_extra_location_widgets_visibility  (NautilusWindow             *window);
-static void remove_extra_location_widgets             (NautilusWindow             *window);
+						       NautilusWindowSlot         *window);
 
 void
 nautilus_window_report_selection_changed (NautilusWindowInfo *window)
@@ -124,33 +126,37 @@
 /* set_displayed_location:
  */
 static void
-set_displayed_location (NautilusWindow *window, GFile *location)
+set_displayed_location (NautilusWindowSlot *slot, GFile *location)
 {
+	NautilusWindow *window;
         GFile *bookmark_location;
         gboolean recreate;
 	char *name;
+
+	window = slot->window;
         
-        if (window->current_location_bookmark == NULL || location == NULL) {
+        if (slot->current_location_bookmark == NULL || location == NULL) {
                 recreate = TRUE;
         } else {
-                bookmark_location = nautilus_bookmark_get_location (window->current_location_bookmark);
+                bookmark_location = nautilus_bookmark_get_location (slot->current_location_bookmark);
                 recreate = !g_file_equal (bookmark_location, location);
                 g_object_unref (bookmark_location);
         }
         
         if (recreate) {
                 /* We've changed locations, must recreate bookmark for current location. */
-                if (window->last_location_bookmark != NULL)  {
-                        g_object_unref (window->last_location_bookmark);
+		if (slot->last_location_bookmark != NULL)  {
+			g_object_unref (slot->last_location_bookmark);
                 }
-                window->last_location_bookmark = window->current_location_bookmark;
+		slot->last_location_bookmark = slot->current_location_bookmark;
 		name = g_file_get_uri (location);
-                window->current_location_bookmark = (location == NULL) ? NULL
+		slot->current_location_bookmark = (location == NULL) ? NULL
                         : nautilus_bookmark_new (location, name);
 		g_free (name);
         }
-        nautilus_window_update_title (window);
-	nautilus_window_update_icon (window);
+
+	nautilus_window_slot_update_title (slot);
+	nautilus_window_slot_update_icon (slot);
 }
 
 static void
@@ -175,125 +181,139 @@
  * Back or Forward list.
  */
 static void
-check_last_bookmark_location_matches_window (NautilusWindow *window)
+check_last_bookmark_location_matches_slot (NautilusWindowSlot *slot)
 {
-	check_bookmark_location_matches (window->last_location_bookmark,
-                                         window->details->location);
+	check_bookmark_location_matches (slot->last_location_bookmark,
+					 slot->location);
 }
 
 static void
-handle_go_back (NautilusNavigationWindow *window, GFile *location)
+handle_go_back (NautilusNavigationWindowSlot *navigation_slot,
+		GFile *location)
 {
-        guint i;
-        GList *link;
-        NautilusBookmark *bookmark;
+	NautilusWindowSlot *slot;
+	guint i;
+	GList *link;
+	NautilusBookmark *bookmark;
 
-        g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
+	slot = NAUTILUS_WINDOW_SLOT (navigation_slot);
 
-        /* Going back. Move items from the back list to the forward list. */
-        g_assert (g_list_length (window->back_list) > NAUTILUS_WINDOW (window)->details->location_change_distance);
-        check_bookmark_location_matches (NAUTILUS_BOOKMARK (g_list_nth_data (window->back_list,
-                                                                             NAUTILUS_WINDOW (window)->details->location_change_distance)),
-                                         location);
-        g_assert (NAUTILUS_WINDOW (window)->details->location != NULL);
-        
-        /* Move current location to Forward list */
+	/* Going back. Move items from the back list to the forward list. */
+	g_assert (g_list_length (navigation_slot->back_list) > slot->location_change_distance);
+	check_bookmark_location_matches (NAUTILUS_BOOKMARK (g_list_nth_data (navigation_slot->back_list,
+									     slot->location_change_distance)),
+					 location);
+	g_assert (slot->location != NULL);
+	
+	/* Move current location to Forward list */
 
-        check_last_bookmark_location_matches_window (NAUTILUS_WINDOW (window));
+	check_last_bookmark_location_matches_slot (slot);
 
-        /* Use the first bookmark in the history list rather than creating a new one. */
-        window->forward_list = g_list_prepend (window->forward_list,
-                                               NAUTILUS_WINDOW (window)->last_location_bookmark);
-        g_object_ref (window->forward_list->data);
-                                
-        /* Move extra links from Back to Forward list */
-        for (i = 0; i < NAUTILUS_WINDOW (window)->details->location_change_distance; ++i) {
-        	bookmark = NAUTILUS_BOOKMARK (window->back_list->data);
-                window->back_list = g_list_remove (window->back_list, bookmark);
-                window->forward_list = g_list_prepend (window->forward_list, bookmark);
-        }
-        
-        /* One bookmark falls out of back/forward lists and becomes viewed location */
-        link = window->back_list;
-        window->back_list = g_list_remove_link (window->back_list, link);
-        g_object_unref (link->data);
-        g_list_free_1 (link);
+	/* Use the first bookmark in the history list rather than creating a new one. */
+	navigation_slot->forward_list = g_list_prepend (navigation_slot->forward_list,
+							     slot->last_location_bookmark);
+	g_object_ref (navigation_slot->forward_list->data);
+				
+	/* Move extra links from Back to Forward list */
+	for (i = 0; i < slot->location_change_distance; ++i) {
+		bookmark = NAUTILUS_BOOKMARK (navigation_slot->back_list->data);
+		navigation_slot->back_list =
+			g_list_remove (navigation_slot->back_list, bookmark);
+		navigation_slot->forward_list =
+			g_list_prepend (navigation_slot->forward_list, bookmark);
+	}
+	
+	/* One bookmark falls out of back/forward lists and becomes viewed location */
+	link = navigation_slot->back_list;
+	navigation_slot->back_list = g_list_remove_link (navigation_slot->back_list, link);
+	g_object_unref (link->data);
+	g_list_free_1 (link);
 }
 
 static void
-handle_go_forward (NautilusNavigationWindow *window, GFile *location)
-{
-        guint i;
-        GList *link;
-        NautilusBookmark *bookmark;
-
-        g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));
-
-        /* Going forward. Move items from the forward list to the back list. */
-        g_assert (g_list_length (window->forward_list) > NAUTILUS_WINDOW (window)->details->location_change_distance);
-        check_bookmark_location_matches (NAUTILUS_BOOKMARK (g_list_nth_data (window->forward_list,
-                                                                             NAUTILUS_WINDOW (window)->details->location_change_distance)),
-                                         location);
-        g_assert (NAUTILUS_WINDOW (window)->details->location != NULL);
-                                
-        /* Move current location to Back list */
-
-        check_last_bookmark_location_matches_window (NAUTILUS_WINDOW (window));
-        
-        /* Use the first bookmark in the history list rather than creating a new one. */
-        window->back_list = g_list_prepend (window->back_list,
-                                            NAUTILUS_WINDOW (window)->last_location_bookmark);
-        g_object_ref (window->back_list->data);
-        
-        /* Move extra links from Forward to Back list */
-        for (i = 0; i < NAUTILUS_WINDOW (window)->details->location_change_distance; ++i) {
-        	bookmark = NAUTILUS_BOOKMARK (window->forward_list->data);
-                window->forward_list = g_list_remove (window->forward_list, bookmark);
-                window->back_list = g_list_prepend (window->back_list, bookmark);
-        }
-        
-        /* One bookmark falls out of back/forward lists and becomes viewed location */
-        link = window->forward_list;
-        window->forward_list = g_list_remove_link (window->forward_list, link);
-        g_object_unref (link->data);
-        g_list_free_1 (link);
+handle_go_forward (NautilusNavigationWindowSlot *navigation_slot,
+		   GFile *location)
+{
+	NautilusWindowSlot *slot;
+	guint i;
+	GList *link;
+	NautilusBookmark *bookmark;
+
+	slot = NAUTILUS_WINDOW_SLOT (navigation_slot);
+
+	/* Going forward. Move items from the forward list to the back list. */
+	g_assert (g_list_length (navigation_slot->forward_list) > slot->location_change_distance);
+	check_bookmark_location_matches (NAUTILUS_BOOKMARK (g_list_nth_data (navigation_slot->forward_list,
+									     slot->location_change_distance)),
+					 location);
+	g_assert (slot->location != NULL);
+				
+	/* Move current location to Back list */
+	check_last_bookmark_location_matches_slot (slot);
+	
+	/* Use the first bookmark in the history list rather than creating a new one. */
+      navigation_slot->back_list = g_list_prepend (navigation_slot->back_list,
+							  slot->last_location_bookmark);
+      g_object_ref (navigation_slot->back_list->data);
+	
+	/* Move extra links from Forward to Back list */
+      for (i = 0; i < slot->location_change_distance; ++i) {
+		bookmark = NAUTILUS_BOOKMARK (navigation_slot->forward_list->data);
+		navigation_slot->forward_list =
+			g_list_remove (navigation_slot->back_list, bookmark);
+		navigation_slot->back_list =
+			g_list_prepend (navigation_slot->forward_list, bookmark);
+	}
+	
+	/* One bookmark falls out of back/forward lists and becomes viewed location */
+	link = navigation_slot->forward_list;
+	navigation_slot->forward_list = g_list_remove_link (navigation_slot->forward_list, link);
+	g_object_unref (link->data);
+	g_list_free_1 (link);
 }
 
 static void
-handle_go_elsewhere (NautilusWindow *window, GFile *location)
+handle_go_elsewhere (NautilusWindowSlot *slot, GFile *location)
 {
 #if !NEW_UI_COMPLETE
-        if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) {
-                /* Clobber the entire forward list, and move displayed location to back list */
-                nautilus_navigation_window_clear_forward_list (NAUTILUS_NAVIGATION_WINDOW (window));
-                
-                if (window->details->location != NULL) {
-                        /* If we're returning to the same uri somehow, don't put this uri on back list. 
-                         * This also avoids a problem where set_displayed_location
-                         * didn't update last_location_bookmark since the uri didn't change.
-                         */
-                        if (!g_file_equal (window->details->location, location)) {
-                                /* Store bookmark for current location in back list, unless there is no current location */
-                                check_last_bookmark_location_matches_window (window);
-                                /* Use the first bookmark in the history list rather than creating a new one. */
-                                NAUTILUS_NAVIGATION_WINDOW (window)->back_list = g_list_prepend (NAUTILUS_NAVIGATION_WINDOW (window)->back_list,
-                                                                                                 window->last_location_bookmark);
-                                g_object_ref (NAUTILUS_NAVIGATION_WINDOW (window)->back_list->data);
-                        }
-                }
-        }
+	NautilusNavigationWindowSlot *navigation_slot;
+
+	if (NAUTILUS_IS_NAVIGATION_WINDOW_SLOT (slot)) {
+		navigation_slot = NAUTILUS_NAVIGATION_WINDOW_SLOT (slot);
+
+		/* Clobber the entire forward list, and move displayed location to back list */
+		nautilus_navigation_window_slot_clear_forward_list (navigation_slot);
+		
+		if (slot->location != NULL) {
+			/* If we're returning to the same uri somehow, don't put this uri on back list. 
+			 * This also avoids a problem where set_displayed_location
+			 * didn't update last_location_bookmark since the uri didn't change.
+			 */
+			if (!g_file_equal (slot->location, location)) {
+				/* Store bookmark for current location in back list, unless there is no current location */
+				check_last_bookmark_location_matches_slot (slot);
+				/* Use the first bookmark in the history list rather than creating a new one. */
+				navigation_slot->back_list = g_list_prepend (navigation_slot->back_list,
+									     slot->last_location_bookmark);
+				g_object_ref (navigation_slot->back_list->data);
+			}
+		}
+	}
 #endif
 }
 
 static void
 update_up_button (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
         gboolean allowed;
 	GFile *parent;
 
+	slot = window->details->active_slot;
+
         allowed = FALSE;
-        if (window->details->location != NULL) {
-		parent = g_file_get_parent (window->details->location);
+        if (slot->location != NULL) {
+		parent = g_file_get_parent (slot->location);
 		allowed = parent != NULL;
 		if (parent != NULL) {
 			g_object_unref (parent);
@@ -305,30 +325,33 @@
 
 static void
 viewed_file_changed_callback (NautilusFile *file,
-                              NautilusWindow *window)
+                              NautilusWindowSlot *slot)
 {
+	NautilusWindow *window;
         GFile *new_location;
 	gboolean is_in_trash, was_in_trash;
-	char *uri;
+
+	window = slot->window;
 
         g_assert (NAUTILUS_IS_FILE (file));
 	g_assert (NAUTILUS_IS_WINDOW (window));
-	g_assert (window->details->viewed_file == file);
+
+	g_assert (file == slot->viewed_file);
 
         if (!nautilus_file_is_not_yet_confirmed (file)) {
-                window->details->viewed_file_seen = TRUE;
+                slot->viewed_file_seen = TRUE;
         }
 
-	was_in_trash = window->details->viewed_file_in_trash;
+	was_in_trash = slot->viewed_file_in_trash;
 
-	window->details->viewed_file_in_trash = is_in_trash = nautilus_file_is_in_trash (file);
+	slot->viewed_file_in_trash = is_in_trash = nautilus_file_is_in_trash (file);
 
 	/* Close window if the file it's viewing has been deleted or moved to trash. */
 	if (nautilus_file_is_gone (file) || (is_in_trash && !was_in_trash)) {
                 /* Don't close the window in the case where the
                  * file was never seen in the first place.
                  */
-                if (window->details->viewed_file_seen) {
+                if (slot->viewed_file_seen) {
                         /* Detecting a file is gone may happen in the
                          * middle of a pending location change, we
                          * need to cancel it before closing the window
@@ -342,7 +365,7 @@
                          * really needed, wouldn't it be needed for
                          * all other nautilus_window_close callers?
                          */
-                        end_location_change (window);
+			end_location_change (slot);
 
 			if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) {
 				/* auto-show existing parent. */
@@ -361,11 +384,17 @@
 					/* the path bar URI will be set to go_to_uri immediately
 					 * in begin_location_change, but we don't want the
 					 * inexistant children to show up anymore */
-					nautilus_path_bar_clear_buttons (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->path_bar));
-					nautilus_window_go_to (NAUTILUS_WINDOW (window), go_to_file);
+					if (slot == window->details->active_slot) {
+						/* multiview-TODO also update NautilusWindowSlot
+						 * [which as of writing doesn't save/store any path bar state]
+						 */
+						nautilus_path_bar_clear_buttons (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->path_bar));
+					}
+
+					nautilus_window_slot_go_to (slot, go_to_file, FALSE);
 					g_object_unref (go_to_file);
 				} else {
-					nautilus_window_go_home (NAUTILUS_WINDOW (window));
+					nautilus_window_slot_go_home (slot, FALSE);
 				}
 			} else {
 				nautilus_window_close (window);
@@ -377,63 +406,44 @@
                 /* If the file was renamed, update location and/or
                  * title. */
                 if (!g_file_equal (new_location,
-				   window->details->location)) {
-                        g_object_unref (window->details->location);
-                        window->details->location = new_location;
-			
-                        /* Check if we can go up. */
-                        update_up_button (window);
-#if !NEW_UI_COMPLETE
-			uri = g_file_get_uri (window->details->location);
-                        if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) {
-                                /* Change the location bar and path bar to match the current location. */
-                                nautilus_navigation_bar_set_location
-                                        (NAUTILUS_NAVIGATION_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->navigation_bar),
-                                         uri);
-				nautilus_path_bar_set_path (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->path_bar),
-							    window->details->location);
-                        }
-                        if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
-                                /* Change the location button to match the current location. */
-                                nautilus_spatial_window_set_location_button
-                                        (NAUTILUS_SPATIAL_WINDOW (window),
-                                         window->details->location);
-                        }                  
-			g_free (uri);
-#endif
-
+				   slot->location)) {
+                        g_object_unref (slot->location);
+                        slot->location = new_location;
+			if (slot == window->details->active_slot) {
+				nautilus_window_sync_location_widgets (window);
+			}
                 } else {
+			/* TODO?
+ 			 *   why do we update title & icon at all in this case? */
                         g_object_unref (new_location);
                 }
 
-                nautilus_window_update_title (window);
-		nautilus_window_update_icon (window);
+                nautilus_window_slot_update_title (slot);
+		nautilus_window_slot_update_icon (slot);
         }
 }
 
 static void
-update_history (NautilusWindow *window,
+update_history (NautilusWindowSlot *slot,
                 NautilusLocationChangeType type,
                 GFile *new_location)
 {
         switch (type) {
         case NAUTILUS_LOCATION_CHANGE_STANDARD:
         case NAUTILUS_LOCATION_CHANGE_FALLBACK:
-                nautilus_window_add_current_location_to_history_list (window);
-                handle_go_elsewhere (window, new_location);
+                nautilus_window_slot_add_current_location_to_history_list (slot);
+                handle_go_elsewhere (slot, new_location);
                 return;
         case NAUTILUS_LOCATION_CHANGE_RELOAD:
                 /* for reload there is no work to do */
                 return;
         case NAUTILUS_LOCATION_CHANGE_BACK:
-                nautilus_window_add_current_location_to_history_list (window);
-                handle_go_back (NAUTILUS_NAVIGATION_WINDOW (window), 
-                                new_location);
+                nautilus_window_slot_add_current_location_to_history_list (slot);
+                handle_go_back (NAUTILUS_NAVIGATION_WINDOW_SLOT (slot), new_location);
                 return;
         case NAUTILUS_LOCATION_CHANGE_FORWARD:
-                nautilus_window_add_current_location_to_history_list (window);
-                handle_go_forward (NAUTILUS_NAVIGATION_WINDOW (window), 
-                                   new_location);
+                nautilus_window_slot_add_current_location_to_history_list (slot);
+                handle_go_forward (NAUTILUS_NAVIGATION_WINDOW_SLOT (slot), new_location);
                 return;
         case NAUTILUS_LOCATION_CHANGE_REDIRECT:
                 /* for the redirect case, the caller can do the updating */
@@ -443,16 +453,16 @@
 }
 
 static void
-cancel_viewed_file_changed_callback (NautilusWindow *window)
+cancel_viewed_file_changed_callback (NautilusWindowSlot *slot)
 {
         NautilusFile *file;
 
-        file = window->details->viewed_file;
+        file = slot->viewed_file;
         if (file != NULL) {
                 g_signal_handlers_disconnect_by_func (G_OBJECT (file),
                                                       G_CALLBACK (viewed_file_changed_callback),
-                                                      window);
-                nautilus_file_monitor_remove (file, &window->details->viewed_file);
+						      slot);
+                nautilus_file_monitor_remove (file, &slot->viewed_file);
         }
 }
 
@@ -473,20 +483,27 @@
 
 
 void
-nautilus_window_open_location_full (NautilusWindow *window,
-				    GFile *location,
-				    NautilusWindowOpenMode mode,
-				    NautilusWindowOpenFlags flags,
-				    GList *new_selection)
+nautilus_window_slot_open_location_full (NautilusWindowSlot *slot,
+					 GFile *location,
+					 NautilusWindowOpenMode mode,
+					 NautilusWindowOpenFlags flags,
+					 GList *new_selection)
 {
+	NautilusWindow *window;
         NautilusWindow *target_window;
+        NautilusWindowSlot *target_slot;
+	NautilusWindowOpenFlags slot_flags;
         gboolean do_load_location = TRUE;
 	GFile *old_location;
 	char *old_uri, *new_uri;
-        
+	int new_slot_position;
+
+	window = slot->window;
+
         target_window = NULL;
+	target_slot = NULL;
 
-	old_uri = nautilus_window_get_location_uri (window);
+	old_uri = nautilus_window_slot_get_location_uri (slot);
 	if (old_uri == NULL) {
 		old_uri = g_strdup ("(none)");
 	}
@@ -499,8 +516,11 @@
 	g_free (old_uri);
 	g_free (new_uri);
 
+	g_assert (!((flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) != 0 &&
+		    (flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB) != 0));
+
 
-	old_location = nautilus_window_get_location (window);
+	old_location = nautilus_window_slot_get_location (slot);
 	switch (mode) {
         case NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE :
 		if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
@@ -565,6 +585,20 @@
 
         g_assert (target_window != NULL);
 
+	if ((flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB) != 0 &&
+	    NAUTILUS_IS_NAVIGATION_WINDOW (window)) {
+		g_assert (target_window == window);
+
+		slot_flags = 0;
+
+		new_slot_position = eel_preferences_get_enum (NAUTILUS_PREFERENCES_NEW_TAB_POSITION);
+		if (new_slot_position == NAUTILUS_NEW_TAB_POSITION_END) {
+			slot_flags = NAUTILUS_WINDOW_OPEN_SLOT_APPEND;
+		}
+
+		target_slot = nautilus_window_open_slot (window, slot_flags);
+	}
+
         if ((flags & NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND) != 0) {
                 if (NAUTILUS_IS_SPATIAL_WINDOW (window) && !NAUTILUS_IS_DESKTOP_WINDOW (window)) {
                         if (GTK_WIDGET_VISIBLE (target_window)) {
@@ -579,8 +613,16 @@
                 }
         }
 
+	if (target_slot == NULL) {
+		if (target_window == window) {
+			target_slot = slot;
+		} else {
+			target_slot = target_window->details->active_slot;
+		}
+	}
+
         if ((!do_load_location) ||
-	    (target_window == window &&
+	    (target_window == window && target_slot == slot &&
 	     old_location && g_file_equal (old_location, location))) {
 		g_object_unref (old_location);
                 return;
@@ -590,14 +632,14 @@
 		g_object_unref (old_location);
 	}
 
-        begin_location_change (target_window, location, new_selection,
+        begin_location_change (target_slot, location, new_selection,
                                NAUTILUS_LOCATION_CHANGE_STANDARD, 0, NULL);
 }
 
 void
-nautilus_window_open_location (NautilusWindow *window,
-                               GFile *location,
-                               gboolean close_behind)
+nautilus_window_slot_open_location (NautilusWindowSlot *slot,
+				    GFile *location,
+				    gboolean close_behind)
 {
 	NautilusWindowOpenFlags flags;
 
@@ -606,16 +648,16 @@
 		flags = NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND;
 	}
 	
-	nautilus_window_open_location_full (window, location,
-					    NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
-					    flags, NULL);
+	nautilus_window_slot_open_location_full (slot, location,
+						 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
+						 flags, NULL);
 }
 
 void
-nautilus_window_open_location_with_selection (NautilusWindow *window,
-					      GFile *location,
-					      GList *selection,
-					      gboolean close_behind)
+nautilus_window_slot_open_location_with_selection (NautilusWindowSlot *slot,
+						   GFile *location,
+						   GList *selection,
+						   gboolean close_behind)
 {
 	NautilusWindowOpenFlags flags;
 
@@ -623,51 +665,93 @@
 	if (close_behind) {
 		flags = NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND;
 	}
-	nautilus_window_open_location_full (window, location, 
-					    NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
-					    flags, selection);
-}					      
+	nautilus_window_slot_open_location_full (slot, location,
+						 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
+						 flags, selection);
+}
+
+
+void
+nautilus_window_slot_go_home (NautilusWindowSlot *slot, gboolean new_tab)
+{			      
+	GFile *home;
+	NautilusWindowOpenFlags flags;
+
+	g_return_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	if (new_tab) {
+		flags = NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
+	} else {
+		flags = 0;
+	}
 
-char *
-nautilus_window_get_view_error_label (NautilusWindow *window)
+	home = g_file_new_for_path (g_get_home_dir ());
+	nautilus_window_slot_open_location_full (slot, home, 
+						 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, 
+						 flags, NULL);
+	g_object_unref (home);
+}
+
+#if 0
+static char *
+nautilus_window_slot_get_view_label (NautilusWindowSlot *slot)
+{
+	const NautilusViewInfo *info;
+
+	info = nautilus_view_factory_lookup (nautilus_window_slot_get_content_view_id (slot));
+
+	return g_strdup (info->label);
+}
+#endif
+
+static char *
+nautilus_window_slot_get_view_error_label (NautilusWindowSlot *slot)
 {
 	const NautilusViewInfo *info;
 
-	info = nautilus_view_factory_lookup (nautilus_window_get_content_view_id (window));
+	info = nautilus_view_factory_lookup (nautilus_window_slot_get_content_view_id (slot));
 
 	return g_strdup (info->error_label);
 }
 
-char *
-nautilus_window_get_view_startup_error_label (NautilusWindow *window)
+static char *
+nautilus_window_slot_get_view_startup_error_label (NautilusWindowSlot *slot)
 {
 	const NautilusViewInfo *info;
 
-	info = nautilus_view_factory_lookup (nautilus_window_get_content_view_id (window));
+	info = nautilus_view_factory_lookup (nautilus_window_slot_get_content_view_id (slot));
 
 	return g_strdup (info->startup_error_label);
 }
 
 static void
-report_current_content_view_failure_to_user (NautilusWindow *window,
-                                     	     NautilusView *view)
+report_current_content_view_failure_to_user (NautilusWindowSlot *slot)
 {
+	NautilusWindow *window;
 	char *message;
 
-	message = nautilus_window_get_view_startup_error_label (window);
-	eel_show_error_dialog (message,
-			       _("You can choose another view or go to a different location."),
-			       GTK_WINDOW (window));
+	window = slot->window;
+
+	message = nautilus_window_slot_get_view_startup_error_label (slot);
+  	eel_show_error_dialog (message,
+  			       _("You can choose another view or go to a different location."),
+  			       GTK_WINDOW (window));
 	g_free (message);
 }
 
 static void
-report_nascent_content_view_failure_to_user (NautilusWindow *window,
-                                     	     NautilusView *view)
+report_nascent_content_view_failure_to_user (NautilusWindowSlot *slot,
+					     NautilusView *view)
 {
+	NautilusWindow *window;
 	char *message;
 
-	message = nautilus_window_get_view_error_label (window);
+	window = slot->window;
+
+	/* TODO? why are we using the current view's error label here, instead of the next view's?
+ 	 * This behavior has already been present in pre-slot days.
+ 	 */
+	message = nautilus_window_slot_get_view_error_label (slot);
 	eel_show_error_dialog (message,
 			       _("The location cannot be displayed with this viewer."),
 			       GTK_WINDOW (window));
@@ -676,23 +760,22 @@
 
 
 const char *
-nautilus_window_get_content_view_id (NautilusWindow *window)
+nautilus_window_slot_get_content_view_id (NautilusWindowSlot *slot)
 {
-        if (window->content_view == NULL) {
-                return NULL;
-        }
-	return nautilus_view_get_view_id (window->content_view);
+	if (slot->content_view == NULL) {
+		return NULL;
+	}
+	return nautilus_view_get_view_id (slot->content_view);
 }
 
 gboolean
-nautilus_window_content_view_matches_iid (NautilusWindow *window, 
-					  const char *iid)
+nautilus_window_slot_content_view_matches_iid (NautilusWindowSlot *slot, 
+					       const char *iid)
 {
-        if (window->content_view == NULL) {
-                return FALSE;
-        }
-	return eel_strcmp (nautilus_view_get_view_id (window->content_view),
-                           iid) == 0;
+	if (slot->content_view == NULL) {
+		return FALSE;
+	}
+	return eel_strcmp (nautilus_view_get_view_id (slot->content_view), iid) == 0;
 }
 
 
@@ -712,42 +795,44 @@
  * location begins here.
  */
 static void
-begin_location_change (NautilusWindow *window,
+begin_location_change (NautilusWindowSlot *slot,
                        GFile *location,
 		       GList *new_selection,
                        NautilusLocationChangeType type,
                        guint distance,
                        const char *scroll_pos)
 {
+	NautilusWindow *window;
         NautilusDirectory *directory;
         NautilusFile *file;
 	gboolean force_reload;
         char *current_pos;
 
-        g_assert (NAUTILUS_IS_WINDOW (window));
+	g_assert (slot != NULL);
         g_assert (location != NULL);
         g_assert (type == NAUTILUS_LOCATION_CHANGE_BACK
                   || type == NAUTILUS_LOCATION_CHANGE_FORWARD
                   || distance == 0);
 
+	window = slot->window;
+        g_assert (NAUTILUS_IS_WINDOW (window));
         g_object_ref (window);
 
-        end_location_change (window);
-        
-        nautilus_window_allow_stop (window, TRUE);
-        nautilus_window_set_status (window, " ");
+	end_location_change (slot);
+
+	nautilus_window_slot_set_allow_stop (slot, TRUE);
+	nautilus_window_slot_set_status (slot, " ");
 
-	g_assert (window->details->pending_location == NULL);
-	g_assert (window->details->pending_selection == NULL);
+	g_assert (slot->pending_location == NULL);
+	g_assert (slot->pending_selection == NULL);
 	
-        window->details->pending_location = g_object_ref (location);
-        window->details->location_change_type = type;
-        window->details->location_change_distance = distance;
-        window->details->tried_mount = FALSE;
-        window->details->pending_selection = eel_g_object_list_copy (new_selection);
+	slot->pending_location = g_object_ref (location);
+        slot->location_change_type = type;
+        slot->location_change_distance = distance;
+	slot->tried_mount = FALSE;
+	slot->pending_selection = eel_g_object_list_copy (new_selection);
 
-        
-        window->details->pending_scroll_to = g_strdup (scroll_pos);
+	slot->pending_scroll_to = g_strdup (scroll_pos);
         
         directory = nautilus_directory_get (location);
 
@@ -773,41 +858,43 @@
         nautilus_directory_unref (directory);
 
         /* Set current_bookmark scroll pos */
-        if (window->current_location_bookmark != NULL &&
-            window->content_view != NULL) {
-                current_pos = nautilus_view_get_first_visible_file (window->content_view);
-                nautilus_bookmark_set_scroll_pos (window->current_location_bookmark, current_pos);
+        if (slot->current_location_bookmark != NULL &&
+            slot->content_view != NULL) {
+                current_pos = nautilus_view_get_first_visible_file (slot->content_view);
+                nautilus_bookmark_set_scroll_pos (slot->current_location_bookmark, current_pos);
                 g_free (current_pos);
         }
 
 	/* Get the info needed for view selection */
 	
-        window->details->determine_view_file = nautilus_file_get (location);
-
-	g_assert (window->details->determine_view_file != NULL);
+        slot->determine_view_file = nautilus_file_get (location);
+	g_assert (slot->determine_view_file != NULL);
 
 	/* if the currently viewed file is marked gone while loading the new location,
 	 * this ensures that the window isn't destroyed */
-        cancel_viewed_file_changed_callback (window);
+        cancel_viewed_file_changed_callback (slot);
 
-	nautilus_file_call_when_ready (window->details->determine_view_file,
+	nautilus_file_call_when_ready (slot->determine_view_file,
 				       NAUTILUS_FILE_ATTRIBUTE_INFO |
 				       NAUTILUS_FILE_ATTRIBUTE_MOUNT |
 				       NAUTILUS_FILE_ATTRIBUTE_METADATA,
                                        got_file_info_for_view_selection_callback,
-				       window);
+				       slot);
 
         g_object_unref (window);
 }
 
 static void
-setup_new_window (NautilusWindow *window, NautilusFile *file)
+setup_new_spatial_window (NautilusWindowSlot *slot, NautilusFile *file)
 {
+	NautilusWindow *window;
 	char *show_hidden_file_setting;
 	char *geometry_string;
 	char *scroll_string;
 	gboolean maximized, sticky, above;
-	
+
+	window = slot->window;
+
 	if (NAUTILUS_IS_SPATIAL_WINDOW (window) && !NAUTILUS_IS_DESKTOP_WINDOW (window)) {
 		/* load show hidden state */
 		show_hidden_file_setting = nautilus_file_get_metadata 
@@ -861,7 +948,7 @@
                 }
                 g_free (geometry_string);
 
-		if (window->details->pending_selection == NULL) {
+		if (slot->pending_selection == NULL) {
 			/* If there is no pending selection, then load the saved scroll position. */
 			scroll_string = nautilus_file_get_metadata 
 				(file, NAUTILUS_METADATA_KEY_WINDOW_SCROLL_POSITION,
@@ -869,19 +956,19 @@
 		} else {
 			/* If there is a pending selection, we want to scroll to an item in
 			 * the pending selection list. */
-			scroll_string = g_file_get_uri (window->details->pending_selection->data);
+			scroll_string = g_file_get_uri (slot->pending_selection->data);
 		}
 
 		/* scroll_string might be NULL if there was no saved scroll position. */
 		if (scroll_string != NULL) {
-			window->details->pending_scroll_to = scroll_string;
+			slot->pending_scroll_to = scroll_string;
 		}
         }
 }
 
 typedef struct {
 	GCancellable *cancellable;
-	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 } MountNotMountedData;
 
 static void 
@@ -891,11 +978,13 @@
 {
 	MountNotMountedData *data;
 	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	GError *error;
 	GCancellable *cancellable;
 
 	data = user_data;
-	window = data->window;
+	slot = data->slot;
+	window = slot->window;
 	cancellable = data->cancellable;
 	g_free (data);
 
@@ -905,23 +994,23 @@
 		return;
 	}
 
-	window->details->mount_cancellable = NULL;
+	slot->mount_cancellable = NULL;
 
-	window->details->determine_view_file = nautilus_file_get (window->details->pending_location);
+	slot->determine_view_file = nautilus_file_get (slot->pending_location);
 	
 	error = NULL;
 	if (!g_file_mount_enclosing_volume_finish (G_FILE (source_object), res, &error)) {
-		window->details->mount_error = error;
-		got_file_info_for_view_selection_callback (window->details->determine_view_file, window);
-		window->details->mount_error = NULL;
+		slot->mount_error = error;
+		got_file_info_for_view_selection_callback (slot->determine_view_file, slot);
+		slot->mount_error = NULL;
 		g_error_free (error);
 	} else {
-		nautilus_file_invalidate_all_attributes (window->details->determine_view_file);
-		nautilus_file_call_when_ready (window->details->determine_view_file,
+		nautilus_file_invalidate_all_attributes (slot->determine_view_file);
+		nautilus_file_call_when_ready (slot->determine_view_file,
 					       NAUTILUS_FILE_ATTRIBUTE_INFO |
 					       NAUTILUS_FILE_ATTRIBUTE_METADATA,
 					       got_file_info_for_view_selection_callback,
-					       window);
+					       slot);
 	}
 
 	g_object_unref (cancellable);
@@ -935,33 +1024,38 @@
 	char *view_id;
 	char *mimetype;
 	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	NautilusFile *viewed_file;
 	GFile *location;
 	GMountOperation *mount_op;
 	MountNotMountedData *data;
-	
-	window = callback_data;
-	
-        g_assert (window->details->determine_view_file == file);
-        window->details->determine_view_file = NULL;
 
-	if (window->details->mount_error) {
-		error = window->details->mount_error;
+	slot = callback_data;
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+	g_assert (slot->determine_view_file == file);
+
+	window = slot->window;
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	slot->determine_view_file = NULL;
+
+	if (slot->mount_error) {
+		error = slot->mount_error;
 	} else {
 		error = nautilus_file_get_file_info_error (file);
 	}
-	
+
 	if (error && error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_MOUNTED &&
-	    !window->details->tried_mount) {
-		window->details->tried_mount = TRUE;
-		
+	    !slot->tried_mount) {
+		slot->tried_mount = TRUE;
+
 		mount_op = eel_mount_operation_new (GTK_WINDOW (window));
 		location = nautilus_file_get_location (file);
 		data = g_new0 (MountNotMountedData, 1);
 		data->cancellable = g_cancellable_new ();
-		data->window = window;
-		window->details->mount_cancellable = data->cancellable;
-		g_file_mount_enclosing_volume (location, 0, mount_op, window->details->mount_cancellable,
+		data->slot = slot;
+		slot->mount_cancellable = data->cancellable;
+		g_file_mount_enclosing_volume (location, 0, mount_op, slot->mount_cancellable,
 					       mount_not_mounted_callback, data);
 		g_object_unref (location);
 		g_object_unref (mount_op);
@@ -971,7 +1065,7 @@
 		return;
 	}
 	
-	location = window->details->pending_location;
+	location = slot->pending_location;
 	
 	view_id = NULL;
 	
@@ -982,7 +1076,7 @@
 		mimetype = nautilus_file_get_mime_type (file);
 
 		/* If fallback, don't use view from metadata */
-		if (window->details->location_change_type != NAUTILUS_LOCATION_CHANGE_FALLBACK) {
+		if (slot->location_change_type != NAUTILUS_LOCATION_CHANGE_FALLBACK) {
 			/* Look in metadata for view */
 			view_id = nautilus_file_get_metadata 
 				(file, NAUTILUS_METADATA_KEY_DEFAULT_COMPONENT, NULL);
@@ -1014,11 +1108,11 @@
 	}
 
 	if (view_id != NULL) {
-                if (!GTK_WIDGET_VISIBLE (window)) {
+                if (!GTK_WIDGET_VISIBLE (window) && NAUTILUS_IS_SPATIAL_WINDOW (window)) {
 			/* We now have the metadata to set up the window position, etc */
-			setup_new_window (window, file);
+			setup_new_spatial_window (slot, file);
 		}
-		create_content_view (window, view_id);
+		create_content_view (slot, view_id);
 		g_free (view_id);
 	} else {
 		display_view_selection_failure (window, file,
@@ -1042,13 +1136,13 @@
 
 				if (!nautilus_is_root_directory (location)) {
 					if (!nautilus_is_home_directory (location)) {	
-						nautilus_window_go_home (NAUTILUS_WINDOW (window));
+						nautilus_window_slot_go_home (NAUTILUS_WINDOW (window)->details->active_slot, FALSE);
 					} else {
 						GFile *root;
 
 						root = g_file_new_for_path ("/");
 						/* the last fallback is to go to a known place that can't be deleted! */
-						nautilus_window_go_to (NAUTILUS_WINDOW (window), root);
+						nautilus_window_slot_go_to (NAUTILUS_WINDOW (window)->details->active_slot, location, FALSE);
 						g_object_unref (root);
 					}
 				} else {
@@ -1060,14 +1154,19 @@
 			}
 		} else {
 			/* Clean up state of already-showing window */
-			end_location_change (window);
+			end_location_change (slot);
+
+			/* TODO? shouldn't we call
+			 *   cancel_viewed_file_changed_callback (slot);
+			 * at this point, or in end_location_change()
+			 */
 
 			/* We disconnected this, so we need to re-connect it */
-			viewed_file = nautilus_file_get (window->details->location);
-			nautilus_window_set_viewed_file (window, viewed_file);
-			nautilus_file_monitor_add (viewed_file, &window->details->viewed_file, 0);
+			viewed_file = nautilus_file_get (slot->location);
+			nautilus_window_slot_set_viewed_file (slot, viewed_file);
+			nautilus_file_monitor_add (viewed_file, &slot->viewed_file, 0);
 			g_signal_connect_object (viewed_file, "changed",
-						 G_CALLBACK (viewed_file_changed_callback), window, 0);
+						 G_CALLBACK (viewed_file_changed_callback), slot, 0);
 			nautilus_file_unref (viewed_file);
 			
 			/* Leave the location bar showing the bad location that the user
@@ -1089,13 +1188,16 @@
  * view, and the current location will be used.
  */
 static void
-create_content_view (NautilusWindow *window,
+create_content_view (NautilusWindowSlot *slot,
 		     const char *view_id)
 {
+	NautilusWindow *window;
         NautilusView *view;
 	GList *selection;
 	GtkAction *action;
 
+	window = slot->window;
+
  	/* FIXME bugzilla.gnome.org 41243: 
 	 * We should use inheritance instead of these special cases
 	 * for the desktop window.
@@ -1118,41 +1220,41 @@
 					      NAUTILUS_ACTION_ZOOM_NORMAL);
 	gtk_action_set_sensitive (action, FALSE);
         
-        if (window->content_view != NULL &&
-	    eel_strcmp (nautilus_view_get_view_id (window->content_view),
+        if (slot->content_view != NULL &&
+	    eel_strcmp (nautilus_view_get_view_id (slot->content_view),
 			view_id) == 0) {
                 /* reuse existing content view */
-                view = window->content_view;
-                window->new_content_view = view;
+                view = slot->content_view;
+                slot->new_content_view = view;
         	g_object_ref (view);
         } else {
                 /* create a new content view */
 		view = nautilus_view_factory_create (view_id,
-						     NAUTILUS_WINDOW_INFO (window));
+						     NAUTILUS_WINDOW_SLOT_INFO (slot));
 
                 eel_accessibility_set_name (view, _("Content View"));
                 eel_accessibility_set_description (view, _("View of the current folder"));
                 
-                connect_view (window, view);
+                slot_connect_view (slot, view);
 		
-                window->new_content_view = view;
+                slot->new_content_view = view;
         }
 
 	/* Actually load the pending location and selection: */
 
-        if (window->details->pending_location != NULL) {
-		load_new_location (window,
-				   window->details->pending_location,
-				   window->details->pending_selection,
+        if (slot->pending_location != NULL) {
+		load_new_location (slot,
+				   slot->pending_location,
+				   slot->pending_selection,
 				   FALSE,
 				   TRUE);
 
-		eel_g_object_list_free (window->details->pending_selection);
-		window->details->pending_selection = NULL;
-	} else if (window->details->location != NULL) {
-		selection = nautilus_view_get_selection (window->content_view);
-		load_new_location (window,
-				   window->details->location,
+		eel_g_object_list_free (slot->pending_selection);
+		slot->pending_selection = NULL;
+	} else if (slot->location != NULL) {
+		selection = nautilus_view_get_selection (slot->content_view);
+		load_new_location (slot,
+				   slot->location,
 				   selection,
 				   FALSE,
 				   TRUE);
@@ -1160,47 +1262,51 @@
 	} else {
 		/* Something is busted, there was no location to load.
 		   Just load the homedir. */
-		nautilus_window_go_home (NAUTILUS_WINDOW (window));
+		nautilus_window_slot_go_home (slot, FALSE);
 		
 	}
 }
 
 static void
-load_new_location (NautilusWindow *window,
+load_new_location (NautilusWindowSlot *slot,
 		   GFile *location,
 		   GList *selection,
 		   gboolean tell_current_content_view,
 		   gboolean tell_new_content_view)
 {
+	NautilusWindow *window;
 	GList *selection_copy;
 	NautilusView *view;
 	char *uri;
-        
-	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	g_assert (slot != NULL);
 	g_assert (location != NULL);
 
+	window = slot->window;
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
 	selection_copy = eel_g_object_list_copy (selection);
 
 	view = NULL;
 	
 	/* Note, these may recurse into report_load_underway */
-        if (window->content_view != NULL && tell_current_content_view) {
-		view = window->content_view;
+        if (slot->content_view != NULL && tell_current_content_view) {
+		view = slot->content_view;
 		uri = g_file_get_uri (location);
-		nautilus_view_load_location (window->content_view, uri);
+		nautilus_view_load_location (slot->content_view, uri);
 		g_free (uri);
         }
 	
-        if (window->new_content_view != NULL && tell_new_content_view &&
+        if (slot->new_content_view != NULL && tell_new_content_view &&
 	    (!tell_current_content_view ||
-	     window->new_content_view != window->content_view) ) {
-		view = window->new_content_view;
+	     slot->new_content_view != slot->content_view) ) {
+		view = slot->new_content_view;
 		uri = g_file_get_uri (location);
-		nautilus_view_load_location (window->new_content_view, uri);
+		nautilus_view_load_location (slot->new_content_view, uri);
 		g_free (uri);
         }
 	if (view != NULL) {
-		/* window->new_content_view might have changed here if
+		/* slot->new_content_view might have changed here if
 		   report_load_underway was called from load_location */
 		nautilus_view_set_selection (view, selection_copy);
 	}
@@ -1216,61 +1322,109 @@
 nautilus_window_report_load_underway (NautilusWindow *window,
 				      NautilusView *view)
 {
+	NautilusWindowSlot *slot;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
 	if (window->details->temporarily_ignore_view_signals) {
 		return;
 	}
 
-        g_assert (NAUTILUS_IS_WINDOW (window));
+	slot = nautilus_window_get_slot_for_view (window, view);
+	g_assert (slot != NULL);
 
-        if (view == window->new_content_view) {
-                location_has_really_changed (window);
-        } else if (view == window->content_view) {
-                nautilus_window_allow_stop (window, TRUE);
-        } else {
-		g_warning ("Got load_underway report from unknown view");
+	if (view == slot->new_content_view) {
+		location_has_really_changed (slot);
+	} else {
+		nautilus_window_slot_set_allow_stop (slot, TRUE);
+	}
+}
+
+static void
+nautilus_window_emit_location_change (NautilusWindow *window,
+				      GFile *location)
+{
+	char *uri;
+
+	uri = g_file_get_uri (location);
+	g_signal_emit_by_name (window, "loading_uri", uri);
+	g_free (uri);
+}
+
+/* reports location change to window's "loading-uri" clients, i.e.
+ * sidebar panels [used when switching tabs]. It will emit the pending
+ * location, or the existing location if none is pending.
+ */
+void
+nautilus_window_report_location_change (NautilusWindow *window)
+{
+	NautilusWindowSlot *slot;
+	GFile *location;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	slot = window->details->active_slot;
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	location = NULL;
+
+	if (slot->pending_location != NULL) {
+		location = slot->pending_location;
+	}
+
+	if (location == NULL && slot->location != NULL) {
+		location = slot->location;
+	}
+
+	if (location != NULL) {
+		nautilus_window_emit_location_change (window, location);
 	}
 }
 
 /* This is called when we have decided we can actually change to the new view/location situation. */
 static void
-location_has_really_changed (NautilusWindow *window)
+location_has_really_changed (NautilusWindowSlot *slot)
 {
+	NautilusWindow *window;
 	GtkWidget *widget;
 	GFile *location_copy;
-	char *uri;
 
-	location_copy = NULL;
+	window = slot->window;
 
-	if (window->new_content_view != NULL) {
-		widget = nautilus_view_get_widget (window->new_content_view);
+	if (slot->new_content_view != NULL) {
+		widget = nautilus_view_get_widget (slot->new_content_view);
 		/* Switch to the new content view. */
 		if (widget->parent == NULL) {
-			disconnect_view (window, window->content_view);
-			nautilus_window_set_content_view_widget (window, window->new_content_view);
+			slot_disconnect_view (slot, slot->content_view);
+			nautilus_window_slot_set_content_view_widget (slot, slot->new_content_view);
 		}
-		nautilus_view_grab_focus (window->new_content_view);
-		g_object_unref (window->new_content_view);
-		window->new_content_view = NULL;
+		g_object_unref (slot->new_content_view);
+		slot->new_content_view = NULL;
 	}
 
-        if (window->details->pending_location != NULL) {
-		location_copy = g_object_ref (window->details->pending_location);
-                /* Tell the window we are finished. */
-                update_for_new_location (window);
+      if (slot->pending_location != NULL) {
+		/* Tell the window we are finished. */
+		update_for_new_location (slot);
 	}
 
-        free_location_change (window);
+	location_copy = NULL;
+	if (slot->location != NULL) {
+		location_copy = g_object_ref (slot->location);
+	}
+
+	free_location_change (slot);
 
 	if (location_copy != NULL) {
-		uri = g_file_get_uri (location_copy);
-		g_signal_emit_by_name (window, "loading_uri",  uri);
-		g_free (uri);
+		if (slot == nautilus_window_get_active_slot (window)) {
+			nautilus_window_emit_location_change (window, location_copy);
+		}
+
 		g_object_unref (location_copy);
 	}
 }
 
 static void
-add_extension_extra_widgets (NautilusWindow *window, GFile *location)
+slot_add_extension_extra_widgets (NautilusWindowSlot *slot)
 {
 	GList *providers, *l;
 	GtkWidget *widget;
@@ -1278,14 +1432,14 @@
 	
 	providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_LOCATION_WIDGET_PROVIDER);
 
-	uri = g_file_get_uri (location);
+	uri = g_file_get_uri (slot->location);
 	for (l = providers; l != NULL; l = l->next) {
 		NautilusLocationWidgetProvider *provider;
 		
 		provider = NAUTILUS_LOCATION_WIDGET_PROVIDER (l->data);
-		widget = nautilus_location_widget_provider_get_widget (provider, uri, GTK_WIDGET (window));
+		widget = nautilus_location_widget_provider_get_widget (provider, uri, GTK_WIDGET (slot->window));
 		if (widget != NULL) {
-			nautilus_window_add_extra_location_widget (window, widget);
+			nautilus_window_slot_add_extra_location_widget (slot, widget);
 		}
 	}
 	g_free (uri);
@@ -1294,11 +1448,11 @@
 }
 
 static void
-nautilus_window_show_x_content_bar (NautilusWindow *window, GMount *mount, const char **x_content_types)
+nautilus_window_slot_show_x_content_bar (NautilusWindowSlot *slot, GMount *mount, const char **x_content_types)
 {
 	unsigned int n;
 
-	g_assert (NAUTILUS_IS_WINDOW (window));
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
 
 	for (n = 0; x_content_types[n] != NULL; n++) {
 		GAppInfo *default_app;
@@ -1314,27 +1468,25 @@
 			GtkWidget *bar;
 			bar = nautilus_x_content_bar_new (mount, x_content_types[n]);
 			gtk_widget_show (bar);
-			nautilus_window_add_extra_location_widget (window, bar);
+			nautilus_window_slot_add_extra_location_widget (slot, bar);
 			g_object_unref (default_app);
 		}
 	}
 }
 
 static void
-nautilus_window_show_trash_bar (NautilusWindow *window)
+nautilus_window_slot_show_trash_bar (NautilusWindowSlot *slot)
 {
 	GtkWidget *bar;
 
-	g_assert (NAUTILUS_IS_WINDOW (window));
-
 	bar = nautilus_trash_bar_new ();
 	gtk_widget_show (bar);
 
-	nautilus_window_add_extra_location_widget (window, bar);
+	nautilus_window_slot_add_extra_location_widget (slot, bar);
 }
 
 typedef struct {
-	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	GCancellable *cancellable;
 	GMount *mount;
 } FindMountData;
@@ -1342,20 +1494,19 @@
 static void
 found_content_type_cb (const char **x_content_types, FindMountData *data)
 {
-	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	
 	if (g_cancellable_is_cancelled (data->cancellable)) {
 		goto out;
 	}
-	
-	window = data->window;
-	
+
+	slot = data->slot;
+
 	if (x_content_types != NULL && x_content_types[0] != NULL) {
-		nautilus_window_show_x_content_bar (window, data->mount, x_content_types);
-		update_extra_location_widgets_visibility (window);
+		nautilus_window_slot_show_x_content_bar (slot, data->mount, x_content_types);
 	}
 
-	window->details->find_mount_cancellable = NULL;
+	slot->find_mount_cancellable = NULL;
 
  out:
 	g_object_unref (data->mount);
@@ -1370,13 +1521,13 @@
 {
 	FindMountData *data = user_data;
 	GMount *mount;
-	NautilusWindow *window;	
+	NautilusWindowSlot *slot;
 
 	if (g_cancellable_is_cancelled (data->cancellable)) {
 		goto out;
 	}
-	
-	window = data->window;
+
+	slot = data->slot;
 	
 	mount = g_file_find_enclosing_mount_finish (G_FILE (source_object),
 						    res,
@@ -1390,94 +1541,137 @@
 		return;
 	}
 	
-	window->details->find_mount_cancellable = NULL;
+	data->slot->find_mount_cancellable = NULL;
 
  out:
 	g_object_unref (data->cancellable);
 	g_free (data);
 }
 
+void
+nautilus_window_sync_location_widgets (NautilusWindow *window)
+{
+	NautilusWindowSlot *slot;
+	char *uri;
+
+	slot = window->details->active_slot;
+
+	if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) {
+		NautilusNavigationWindowSlot *navigation_slot;
+
+		navigation_slot = NAUTILUS_NAVIGATION_WINDOW_SLOT (slot);
+
+		/* Check if the back and forward buttons need enabling or disabling. */
+		update_up_button (window);
+		nautilus_navigation_window_allow_back (NAUTILUS_NAVIGATION_WINDOW (window),
+						       navigation_slot->back_list != NULL);
+		nautilus_navigation_window_allow_forward (NAUTILUS_NAVIGATION_WINDOW (window),
+							  navigation_slot->forward_list != NULL);
+
+		/* Change the location bar and path bar to match the current location. */
+		if (slot->location != NULL) {
+			/* this may be NULL if we just created the
+ 			 * slot */
+			uri = nautilus_window_slot_get_location_uri (slot);
+			nautilus_navigation_bar_set_location (NAUTILUS_NAVIGATION_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->navigation_bar),
+							      uri);
+			g_free (uri);
+			nautilus_path_bar_set_path (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->path_bar),
+						    slot->location);
+		}
+	}
+
+	if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
+		/* Change the location button to match the current location. */
+		nautilus_spatial_window_set_location_button (NAUTILUS_SPATIAL_WINDOW (window),
+							     slot->location);
+	}
+}
+
 /* Handle the changes for the NautilusWindow itself. */
 static void
-update_for_new_location (NautilusWindow *window)
+update_for_new_location (NautilusWindowSlot *slot)
 {
+	NautilusWindow *window;
         GFile *new_location;
         NautilusFile *file;
 	NautilusDirectory *directory;
 	gboolean location_really_changed;
-	char *uri;
 	FindMountData *data;
-        
-        new_location = window->details->pending_location;
-        window->details->pending_location = NULL;
 
-	set_displayed_location (window, new_location);
+	window = slot->window;
+
+	new_location = slot->pending_location;
+	slot->pending_location = NULL;
+
+	set_displayed_location (slot, new_location);
+
+	update_history (slot, slot->location_change_type, new_location);
 
-        update_history (window, window->details->location_change_type, new_location);
-                
 	location_really_changed =
-		window->details->location == NULL ||
-		!g_file_equal (window->details->location, new_location);
+		slot->location == NULL ||
+		!g_file_equal (slot->location, new_location);
 		
         /* Set the new location. */
-	if (window->details->location) {
-		g_object_unref (window->details->location);
+	if (slot->location) {
+		g_object_unref (slot->location);
 	}
-        window->details->location = new_location;
-        
+	slot->location = new_location;
+
         /* Create a NautilusFile for this location, so we can catch it
          * if it goes away.
          */
-        cancel_viewed_file_changed_callback (window);
-        file = nautilus_file_get (window->details->location);
-        nautilus_window_set_viewed_file (window, file);
-        window->details->viewed_file_seen = !nautilus_file_is_not_yet_confirmed (file);
-        window->details->viewed_file_in_trash = nautilus_file_is_in_trash (file);
-        nautilus_file_monitor_add (file, &window->details->viewed_file, 0);
-        g_signal_connect_object (file, "changed",
-                                 G_CALLBACK (viewed_file_changed_callback), window, 0);
+	cancel_viewed_file_changed_callback (slot);
+	file = nautilus_file_get (slot->location);
+	nautilus_window_slot_set_viewed_file (slot, file);
+	slot->viewed_file_seen = !nautilus_file_is_not_yet_confirmed (file);
+	slot->viewed_file_in_trash = nautilus_file_is_in_trash (file);
+	nautilus_file_monitor_add (file, &slot->viewed_file, 0);
+	g_signal_connect_object (file, "changed",
+				 G_CALLBACK (viewed_file_changed_callback), slot, 0);
         nautilus_file_unref (file);
-        
-        /* Check if we can go up. */
-        update_up_button (window);
+
+	if (slot == window->details->active_slot) {
+		/* Check if we can go up. */
+		update_up_button (window);
+	}
 	
 	/* Set up the initial zoom levels */
-	zoom_parameters_changed_callback (window->content_view,
-					  window);
+	zoom_parameters_changed_callback (slot->content_view,
+					  slot);
 
-        /* Set up the content view menu for this new location. */
-        nautilus_window_load_view_as_menus (window);
-	
-	/* Load menus from nautilus extensions for this location */
-	nautilus_window_load_extension_menus (window);
+	if (slot == window->details->active_slot) {
+		/* Set up the content view menu for this new location. */
+		nautilus_window_load_view_as_menus (window);
+
+		/* Load menus from nautilus extensions for this location */
+		nautilus_window_load_extension_menus (window);
+	}
 
 	if (location_really_changed) {
-		remove_extra_location_widgets (window);
+		nautilus_window_slot_remove_extra_location_widgets (slot);
 		
-		directory = nautilus_directory_get (window->details->location);
-		if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) {
-			nautilus_window_set_search_mode (window, TRUE, NAUTILUS_SEARCH_DIRECTORY (directory));
-		} else {
-			nautilus_window_set_search_mode (window, FALSE, NULL);
-		}
+		directory = nautilus_directory_get (slot->location);
+
+		nautilus_window_slot_update_query_editor (slot);
 
 		if (nautilus_directory_is_in_trash (directory)) {
-			nautilus_window_show_trash_bar (window);
+			nautilus_window_slot_show_trash_bar (slot);
 		}
 
 		/* need the mount to determine if we should put up the x-content cluebar */
-		if (window->details->find_mount_cancellable != NULL) {
-			g_cancellable_cancel (window->details->find_mount_cancellable);
-			window->details->find_mount_cancellable = NULL;
+		if (slot->find_mount_cancellable != NULL) {
+			g_cancellable_cancel (slot->find_mount_cancellable);
+			slot->find_mount_cancellable = NULL;
 		}
 		
 		data = g_new (FindMountData, 1);
-		data->window = window;
+		data->slot = slot;
 		data->cancellable = g_cancellable_new ();
 		data->mount = NULL;
-		
-		window->details->find_mount_cancellable = data->cancellable;
-		g_file_find_enclosing_mount_async (window->details->location, 
+
+		slot->find_mount_cancellable = data->cancellable;
+		g_file_find_enclosing_mount_async (slot->location,
 						   G_PRIORITY_DEFAULT, 
 						   data->cancellable,
 						   found_mount_cb,
@@ -1485,33 +1679,20 @@
 
 		nautilus_directory_unref (directory);
 
-		add_extension_extra_widgets (window, window->details->location);
-		
-		update_extra_location_widgets_visibility (window);
+		slot_add_extension_extra_widgets (slot);
 	}
 
-#if !NEW_UI_COMPLETE
-        if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) {
-                /* Check if the back and forward buttons need enabling or disabling. */
-                nautilus_navigation_window_allow_back (NAUTILUS_NAVIGATION_WINDOW (window), NAUTILUS_NAVIGATION_WINDOW (window)->back_list != NULL);
-                nautilus_navigation_window_allow_forward (NAUTILUS_NAVIGATION_WINDOW (window), NAUTILUS_NAVIGATION_WINDOW (window)->forward_list != NULL);
-
-                /* Change the location bar and path bar to match the current location. */
-		uri = g_file_get_uri (window->details->location);
-                nautilus_navigation_bar_set_location (NAUTILUS_NAVIGATION_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->navigation_bar),
-                                                      uri);
-		g_free (uri);
-		nautilus_path_bar_set_path (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->path_bar),
-					    window->details->location);
-		nautilus_navigation_window_load_extension_toolbar_items (NAUTILUS_NAVIGATION_WINDOW (window));
-        }
+	if (slot == window->details->active_slot) {
+		nautilus_window_sync_location_widgets (window);
 
-	if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
-		/* Change the location button to match the current location. */
-		nautilus_spatial_window_set_location_button (NAUTILUS_SPATIAL_WINDOW (window),
-							     window->details->location);
-	}                  
-#endif
+		if (location_really_changed) {
+			nautilus_window_sync_search_widgets (window);
+		}
+
+		if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) {
+			nautilus_navigation_window_load_extension_toolbar_items (NAUTILUS_NAVIGATION_WINDOW (window));
+		}
+	}
 }
 
 /* A location load previously announced by load_underway
@@ -1520,114 +1701,128 @@
 nautilus_window_report_load_complete (NautilusWindow *window,
 				      NautilusView *view)
 {
+	NautilusWindowSlot *slot;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
 	if (window->details->temporarily_ignore_view_signals) {
 		return;
 	}
 
-        g_assert (NAUTILUS_IS_WINDOW (window));
+	slot = nautilus_window_get_slot_for_view (window, view);
+	g_assert (slot != NULL);
 
 	/* Only handle this if we're expecting it.
 	 * Don't handle it if its from an old view we've switched from */
-        if (view == window->content_view) {
-                if (window->details->pending_scroll_to != NULL) {
-                        nautilus_view_scroll_to_file (window->content_view,
-						      window->details->pending_scroll_to);
-                }
-                end_location_change (window);
-        }
+	if (view == slot->content_view) {
+		if (slot->pending_scroll_to != NULL) {
+			nautilus_view_scroll_to_file (slot->content_view,
+						      slot->pending_scroll_to);
+		}
+		end_location_change (slot);
+	}
 }
 
 static void
-end_location_change (NautilusWindow *window)
+end_location_change (NautilusWindowSlot *slot)
 {
+	NautilusWindow *window;
 	char *uri;
 
-	uri = nautilus_window_get_location_uri (window);
+	window = slot->window;
+
+	uri = nautilus_window_slot_get_location_uri (slot);
 	if (uri) {
 		nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
 				    "finished loading window %p: %s", window, uri);
 		g_free (uri);
 	}
 
-        nautilus_window_allow_stop (window, FALSE);
+	nautilus_window_slot_set_allow_stop (slot, FALSE);
 
         /* Now we can free pending_scroll_to, since the load_complete
          * callback already has been emitted.
          */
-        g_free (window->details->pending_scroll_to);
-        window->details->pending_scroll_to = NULL;
+	g_free (slot->pending_scroll_to);
+	slot->pending_scroll_to = NULL;
 
-        free_location_change (window);
+	free_location_change (slot);
 }
 
 static void
-free_location_change (NautilusWindow *window)
+free_location_change (NautilusWindowSlot *slot)
 {
-	if (window->details->pending_location) {
-		g_object_unref (window->details->pending_location);
+	NautilusWindow *window;
+
+	window = slot->window;
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	if (slot->pending_location) {
+		g_object_unref (slot->pending_location);
 	}
-        window->details->pending_location = NULL;
+        slot->pending_location = NULL;
 
-	eel_g_object_list_free (window->details->pending_selection);
-	window->details->pending_selection = NULL;
+	eel_g_object_list_free (slot->pending_selection);
+	slot->pending_selection = NULL;
 	
         /* Don't free pending_scroll_to, since thats needed until
          * the load_complete callback.
          */
 
-	if (window->details->mount_cancellable != NULL) {
-		g_cancellable_cancel (window->details->mount_cancellable);
-		window->details->mount_cancellable = NULL;
+	if (slot->mount_cancellable != NULL) {
+		g_cancellable_cancel (slot->mount_cancellable);
+		slot->mount_cancellable = NULL;
 	}
 
-        if (window->details->determine_view_file != NULL) {
+        if (slot->determine_view_file != NULL) {
 		nautilus_file_cancel_call_when_ready
-			(window->details->determine_view_file,
-			 got_file_info_for_view_selection_callback, window);
-                window->details->determine_view_file = NULL;
+			(slot->determine_view_file,
+			 got_file_info_for_view_selection_callback, slot);
+                slot->determine_view_file = NULL;
         }
 
-        if (window->new_content_view != NULL) {
+        if (slot->new_content_view != NULL) {
 		window->details->temporarily_ignore_view_signals = TRUE;
-		nautilus_view_stop_loading (window->new_content_view);
+		nautilus_view_stop_loading (slot->new_content_view);
 		window->details->temporarily_ignore_view_signals = FALSE;
 
-                disconnect_view (window, window->new_content_view);
-        	g_object_unref (window->new_content_view);
-                window->new_content_view = NULL;
+                slot_disconnect_view (slot, slot->new_content_view);
+        	g_object_unref (slot->new_content_view);
+                slot->new_content_view = NULL;
         }
 }
 
 static void
-cancel_location_change (NautilusWindow *window)
+cancel_location_change (NautilusWindowSlot *slot)
 {
 	GList *selection;
 	
-        if (window->details->pending_location != NULL
-            && window->details->location != NULL
-            && window->content_view != NULL) {
+        if (slot->pending_location != NULL
+            && slot->location != NULL
+            && slot->content_view != NULL) {
 
                 /* No need to tell the new view - either it is the
                  * same as the old view, in which case it will already
                  * be told, or it is the very pending change we wish
                  * to cancel.
                  */
-		selection = nautilus_view_get_selection (window->content_view);
-                load_new_location (window,
-				   window->details->location,
+		selection = nautilus_view_get_selection (slot->content_view);
+                load_new_location (slot,
+				   slot->location,
 				   selection,
 				   TRUE,
 				   FALSE);
 		eel_g_object_list_free (selection);
         }
 
-        end_location_change (window);
+        end_location_change (slot);
 }
 
 void
 nautilus_window_report_view_failed (NautilusWindow *window,
 				    NautilusView *view)
 {
+	NautilusWindowSlot *slot;
 	gboolean do_close_window;
 	GFile *fallback_load_location;
 
@@ -1635,22 +1830,25 @@
 		return;
 	}
 
+	slot = nautilus_window_get_slot_for_view (window, view);
+	g_assert (slot != NULL);
+  
         g_warning ("A view failed. The UI will handle this with a dialog but this should be debugged.");
 
 	do_close_window = FALSE;
 	fallback_load_location = NULL;
 	
-	if (view == window->content_view) {
-                disconnect_view (window, window->content_view);			
-                nautilus_window_set_content_view_widget (window, NULL);
-			
-                report_current_content_view_failure_to_user (window, view);
+	if (view == slot->content_view) {
+                slot_disconnect_view (slot, slot->content_view);			
+                nautilus_window_slot_set_content_view_widget (slot, NULL);
+
+                report_current_content_view_failure_to_user (slot);
         } else {
 		/* Only report error on first try */
-		if (window->details->location_change_type != NAUTILUS_LOCATION_CHANGE_FALLBACK) {
-			report_nascent_content_view_failure_to_user (window, view);
+		if (slot->location_change_type != NAUTILUS_LOCATION_CHANGE_FALLBACK) {
+			report_nascent_content_view_failure_to_user (slot, view);
 
-			fallback_load_location = g_object_ref (window->details->pending_location);
+			fallback_load_location = g_object_ref (slot->pending_location);
 		} else {
 			if (!GTK_WIDGET_VISIBLE (window)) {
 				do_close_window = TRUE;
@@ -1658,11 +1856,11 @@
 		}
         }
         
-        cancel_location_change (window);
+        cancel_location_change (slot);
 
 	if (fallback_load_location != NULL) {
 		/* We loose the pending selection change here, but who cares... */
-		begin_location_change (window, fallback_load_location, NULL,
+		begin_location_change (slot, fallback_load_location, NULL,
 				       NAUTILUS_LOCATION_CHANGE_FALLBACK, 0, NULL);
 		g_object_unref (fallback_load_location);
 	}
@@ -1777,68 +1975,83 @@
 
 
 void
-nautilus_window_stop_loading (NautilusWindow *window)
+nautilus_window_slot_stop_loading (NautilusWindowSlot *slot)
 {
-	nautilus_view_stop_loading (window->content_view);
+	NautilusWindow *window;
+
+	window = NAUTILUS_WINDOW (slot->window);
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	nautilus_view_stop_loading (slot->content_view);
 	
-	if (window->new_content_view != NULL) {
+	if (slot->new_content_view != NULL) {
 		window->details->temporarily_ignore_view_signals = TRUE;
-		nautilus_view_stop_loading (window->new_content_view);
+		nautilus_view_stop_loading (slot->new_content_view);
 		window->details->temporarily_ignore_view_signals = FALSE;
 	}
 
-        cancel_location_change (window);
+        cancel_location_change (slot);
 }
 
 void
-nautilus_window_set_content_view (NautilusWindow *window,
-                                  const char *id)
+nautilus_window_slot_set_content_view (NautilusWindowSlot *slot,
+				       const char *id)
 {
+	NautilusWindow *window;
 	NautilusFile *file;
-	char *location;
-	
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
-        g_return_if_fail (window->details->location != NULL);
-	g_return_if_fail (id != NULL);
+	char *uri;
 
-	location = nautilus_window_get_location_uri (window);
+	g_assert (slot != NULL);
+	g_assert (slot->location != NULL);
+	g_assert (id != NULL);
+
+	window = slot->window;
+	g_assert (NAUTILUS_IS_WINDOW (window));
+  
+	uri = nautilus_window_slot_get_location_uri (slot);
 	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
 			    "change view of window %p: \"%s\" to \"%s\"",
-			    window, location, id);
-	g_free (location);
+			    window, uri, id);
+	g_free (uri);
 
-        if (nautilus_window_content_view_matches_iid (window, id)) {
+	if (nautilus_window_slot_content_view_matches_iid (slot, id)) {
         	return;
         }
 
-        end_location_change (window);
+        end_location_change (slot);
 
-	file = nautilus_file_get (window->details->location);
+	file = nautilus_file_get (slot->location);
 	nautilus_file_set_metadata 
 		(file, NAUTILUS_METADATA_KEY_DEFAULT_COMPONENT, NULL, id);
         nautilus_file_unref (file);
         
-        nautilus_window_allow_stop (window, TRUE);
+        nautilus_window_slot_set_allow_stop (slot, TRUE);
 
-        if (nautilus_view_get_selection_count (window->content_view) == 0) {
+        if (nautilus_view_get_selection_count (slot->content_view) == 0) {
                 /* If there is no selection, queue a scroll to the same icon that
                  * is currently visible */
-                window->details->pending_scroll_to = nautilus_view_get_first_visible_file (window->content_view);
+                slot->pending_scroll_to = nautilus_view_get_first_visible_file (slot->content_view);
         }
-	window->details->location_change_type = NAUTILUS_LOCATION_CHANGE_RELOAD;
+	slot->location_change_type = NAUTILUS_LOCATION_CHANGE_RELOAD;
 	
-        create_content_view (window, id);
+        create_content_view (slot, id);
 }
 
 static void
 zoom_level_changed_callback (NautilusView *view,
-                             NautilusWindow *window)
+                             NautilusWindowSlot *slot)
 {
+	NautilusWindow *window;
 	GtkAction *action;
 	gboolean supports_zooming;
-	
+
+	window = slot->window;
         g_assert (NAUTILUS_IS_WINDOW (window));
 
+	if (slot != nautilus_window_get_active_slot (window)) {
+		return;
+	}
+
         /* This is called each time the component successfully completed
          * a zooming operation.
          */
@@ -1865,13 +2078,19 @@
 
 static void
 zoom_parameters_changed_callback (NautilusView *view,
-                                  NautilusWindow *window)
+                                  NautilusWindowSlot *slot)
 {
+	NautilusWindow *window;
         float zoom_level;
 	GtkAction *action;
 
+	window = slot->window;
         g_assert (NAUTILUS_IS_WINDOW (window));
 
+	if (slot != window->details->active_slot) {
+		return;
+	}
+
         /* The initial zoom level of a component is allowed to be 0.0 if
          * there is no file loaded yet. In this case we need to set the
          * commands insensitive but display the zoom control nevertheless
@@ -1897,77 +2116,89 @@
         /* "zoom_parameters_changed" always implies "zoom_level_changed",
          * but you won't get both signals, so we need to pass it down.
          */
-        zoom_level_changed_callback (view, window);
+        zoom_level_changed_callback (view, slot);
 }
 
 static void
 title_changed_callback (NautilusView *view,
-                        NautilusWindow *window)
+                        NautilusWindowSlot *slot)
 {
-        g_assert (NAUTILUS_IS_WINDOW (window));
+        g_assert (NAUTILUS_IS_WINDOW (slot->window));
 
-        nautilus_window_update_title (window);
-	nautilus_window_update_icon (window);
+        nautilus_window_slot_update_title (slot);
+	nautilus_window_slot_update_icon (slot);
 }
 
 static void
-connect_view (NautilusWindow             *window,
-	      NautilusView               *view)
+slot_connect_view (NautilusWindowSlot         *slot,
+		   NautilusView               *view)
 {
 	g_signal_connect (view, "title_changed",
-			  G_CALLBACK (title_changed_callback), window);
+			  G_CALLBACK (title_changed_callback), slot);
 	g_signal_connect (view, "zoom_level_changed",
-			  G_CALLBACK (zoom_level_changed_callback), window);
+			  G_CALLBACK (zoom_level_changed_callback), slot);
 	g_signal_connect (view, "zoom_parameters_changed",
-			  G_CALLBACK (zoom_parameters_changed_callback), window);
+			  G_CALLBACK (zoom_parameters_changed_callback), slot);
 }
 
 static void
-disconnect_view (NautilusWindow             *window,
-		 NautilusView               *view)
+slot_disconnect_view (NautilusWindowSlot         *slot,
+		      NautilusView               *view)
 {
 	if (view == NULL) {
 		return;
 	}
 	
-	g_signal_handlers_disconnect_by_func (view, title_changed_callback, window);
-	g_signal_handlers_disconnect_by_func (view, zoom_level_changed_callback, window);
-	g_signal_handlers_disconnect_by_func (view, zoom_parameters_changed_callback, window);
+	g_signal_handlers_disconnect_by_func (view, title_changed_callback, slot);
+	g_signal_handlers_disconnect_by_func (view, zoom_level_changed_callback, slot);
+	g_signal_handlers_disconnect_by_func (view, zoom_parameters_changed_callback, slot);
 }
 
 void
 nautilus_window_manage_views_destroy (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
+	GList *l;
+
 	/* Disconnect view signals here so they don't trigger when
 	 * views are destroyed.
          */
 
-	if (window->content_view != NULL) {
-		disconnect_view (window, window->content_view);
-	}
-	if (window->new_content_view != NULL) {
-		disconnect_view (window, window->new_content_view);
+	for (l = window->details->slots; l != NULL; l = l->next) {
+		slot = l->data;
+
+		if (slot->content_view != NULL) {
+			slot_disconnect_view (slot, slot->content_view);
+		}
+		if (slot->new_content_view != NULL) {
+			slot_disconnect_view (slot, slot->new_content_view);
+		}
 	}
 }
 
 void
-nautilus_window_manage_views_finalize (NautilusWindow *window)
+nautilus_window_manage_views_close_slot (NautilusWindow *window,
+					 NautilusWindowSlot *slot)
 {
-        free_location_change (window);
-        cancel_viewed_file_changed_callback (window);
+
+	free_location_change (slot);
+	cancel_viewed_file_changed_callback (slot);
 }
 
 void
 nautilus_navigation_window_back_or_forward (NautilusNavigationWindow *window, 
-                                            gboolean back, guint distance)
+                                            gboolean back, guint distance, gboolean new_tab)
 {
+	NautilusWindowSlot *slot;
+	NautilusNavigationWindowSlot *navigation_slot;
 	GList *list;
 	GFile *location;
-        char *scroll_pos;
         guint len;
         NautilusBookmark *bookmark;
-	
-	list = back ? window->back_list : window->forward_list;
+
+	slot = NAUTILUS_WINDOW (window)->details->active_slot;
+	navigation_slot = (NautilusNavigationWindowSlot *) slot;
+	list = back ? navigation_slot->back_list : navigation_slot->forward_list;
 
         len = (guint) g_list_length (list);
 
@@ -1982,87 +2213,66 @@
 
         bookmark = g_list_nth_data (list, distance);
 	location = nautilus_bookmark_get_location (bookmark);
-        scroll_pos = nautilus_bookmark_get_scroll_pos (bookmark);
-	begin_location_change
-		(NAUTILUS_WINDOW (window),
-		 location, NULL,
-		 back ? NAUTILUS_LOCATION_CHANGE_BACK : NAUTILUS_LOCATION_CHANGE_FORWARD,
-		 distance,
-                 scroll_pos);
+
+	if (new_tab) {
+		nautilus_window_slot_open_location_full (slot, location,
+							 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
+							 NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB,
+							 NULL);
+	} else {
+        	char *scroll_pos;
+		
+		scroll_pos = nautilus_bookmark_get_scroll_pos (bookmark);
+		begin_location_change
+			(slot,
+			 location, NULL,
+			 back ? NAUTILUS_LOCATION_CHANGE_BACK : NAUTILUS_LOCATION_CHANGE_FORWARD,
+			 distance,
+			 scroll_pos);
+
+		g_free (scroll_pos);
+	}
 
 	g_object_unref (location);
-        g_free (scroll_pos);
 }
 
 /* reload the contents of the window */
 void
-nautilus_window_reload (NautilusWindow *window)
+nautilus_window_slot_reload (NautilusWindowSlot *slot)
 {
 	GFile *location;
         char *current_pos;
 	GList *selection;
-	
-        g_return_if_fail (NAUTILUS_IS_WINDOW (window));
 
-	if (window->details->location == NULL) {
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	if (slot->location == NULL) {
 		return;
 	}
 	
-	/* window->details->location can be free'd during the processing
+	/* peek_slot_field (window, location) can be free'd during the processing
 	 * of begin_location_change, so make a copy
 	 */
-	location = g_object_ref (window->details->location);
+	location = g_object_ref (slot->location);
 	current_pos = NULL;
 	selection = NULL;
-	if (window->content_view != NULL) {
-		current_pos = nautilus_view_get_first_visible_file (window->content_view);
-		selection = nautilus_view_get_selection (window->content_view);
+	if (slot->content_view != NULL) {
+		current_pos = nautilus_view_get_first_visible_file (slot->content_view);
+		selection = nautilus_view_get_selection (slot->content_view);
 	}
 	begin_location_change
-		(window, location, selection,
+		(slot, location, selection,
 		 NAUTILUS_LOCATION_CHANGE_RELOAD, 0, current_pos);
         g_free (current_pos);
 	g_object_unref (location);
 	eel_g_object_list_free (selection);
 }
 
-static void
-remove_all (GtkWidget *widget,
-	    gpointer data)
-{
-	GtkContainer *container;
-	container = GTK_CONTAINER (data);
-
-	gtk_container_remove (container, widget);
-}
-
-static void
-remove_extra_location_widgets (NautilusWindow *window)
-{
-	gtk_container_foreach (GTK_CONTAINER (window->details->extra_location_widgets),
-			       remove_all,
-			       window->details->extra_location_widgets);
-}
-
 void
-nautilus_window_add_extra_location_widget (NautilusWindow *window,
-					   GtkWidget *widget)
+nautilus_window_reload (NautilusWindow *window)
 {
-	gtk_box_pack_start (GTK_BOX (window->details->extra_location_widgets),
-			    widget, TRUE, TRUE, 0);
-}
+	g_assert (NAUTILUS_IS_WINDOW (window));
 
-static void
-update_extra_location_widgets_visibility (NautilusWindow *window)
-{
-	GList *children;
-	
-	children = gtk_container_get_children (GTK_CONTAINER (window->details->extra_location_widgets));
-	
-	if (children != NULL) {
-		gtk_widget_show (window->details->extra_location_widgets);
-	} else {
-		gtk_widget_hide (window->details->extra_location_widgets);
-	}
-	g_list_free (children);
+	nautilus_window_slot_reload (window->details->active_slot);
 }
+

Modified: trunk/src/nautilus-window-manage-views.h
==============================================================================
--- trunk/src/nautilus-window-manage-views.h	(original)
+++ trunk/src/nautilus-window-manage-views.h	Tue Jul  8 21:05:55 2008
@@ -31,29 +31,8 @@
 #include "nautilus-navigation-window.h"
 
 void                    nautilus_window_manage_views_destroy          (NautilusWindow           *window);
-void                    nautilus_window_manage_views_finalize         (NautilusWindow           *window);
-void                    nautilus_window_open_location                 (NautilusWindow           *window,
-                                                                       GFile                    *location,
-                                                                       gboolean                  close_behind);
-void                    nautilus_window_open_location_with_selection  (NautilusWindow           *window,
-                                                                       GFile                    *location,
-                                                                       GList                    *selection,
-                                                                       gboolean                  close_behind);
-void                    nautilus_window_open_location_full            (NautilusWindow           *window,
-                                                                       GFile                    *location,
-                                                                       NautilusWindowOpenMode    mode,
-                                                                       NautilusWindowOpenFlags   flags,
-                                                                       GList                    *new_selection);
-void                    nautilus_window_stop_loading                  (NautilusWindow           *window);
-void                    nautilus_window_set_content_view              (NautilusWindow           *window,
-                                                                       const char               *id);
-gboolean                nautilus_window_content_view_matches_iid      (NautilusWindow           *window,
-                                                                       const char               *iid);
-const char             *nautilus_window_get_content_view_id           (NautilusWindow           *window);
-char                   *nautilus_window_get_view_error_label          (NautilusWindow           *window);
-char                   *nautilus_window_get_view_startup_error_label  (NautilusWindow           *window);
-void                    nautilus_navigation_window_set_sidebar_panels (NautilusNavigationWindow *window,
-                                                                       GList                    *view_identifier_list);
+void                    nautilus_window_manage_views_close_slot       (NautilusWindow           *window,
+								       NautilusWindowSlot       *slot);
 
 
 /* NautilusWindowInfo implementation: */
@@ -64,5 +43,6 @@
                                                NautilusView       *view);
 void nautilus_window_report_load_complete     (NautilusWindow     *window,
                                                NautilusView       *view);
+void nautilus_window_report_location_change   (NautilusWindow     *window);
 
 #endif /* NAUTILUS_WINDOW_MANAGE_VIEWS_H */

Modified: trunk/src/nautilus-window-menus.c
==============================================================================
--- trunk/src/nautilus-window-menus.c	(original)
+++ trunk/src/nautilus-window-menus.c	Tue Jul  8 21:05:55 2008
@@ -42,9 +42,11 @@
 #include <gtk/gtk.h>
 #include <gio/gio.h>
 #include <glib/gi18n.h>
+#include <eel/eel-preferences.h>
 #include <libgnomeui/gnome-help.h>
 #include <libnautilus-extension/nautilus-menu-provider.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
+#include <libnautilus-private/nautilus-global-preferences.h>
 #include <libnautilus-private/nautilus-icon-names.h>
 #include <libnautilus-private/nautilus-ui-utilities.h>
 #include <libnautilus-private/nautilus-module.h>
@@ -108,9 +110,26 @@
 	bookmark_holder_free (callback_data);
 }
 
+static gboolean
+should_open_in_new_tab (void)
+{
+	/* FIXME this is duplicated */
+	GdkEvent *event;
+
+	event = gtk_get_current_event ();
+	if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) {
+		return event->button.button == 2;
+	}
+
+	gdk_event_free (event);
+
+	return FALSE;
+}
+
 static void
 activate_bookmark_in_menu_item (GtkAction *action, gpointer user_data)
 {
+	NautilusWindowSlot *slot;
         BookmarkHolder *holder;
         GFile *location;
 
@@ -120,7 +139,10 @@
 		holder->failed_callback (holder->window, holder->bookmark);
 	} else {
 	        location = nautilus_bookmark_get_location (holder->bookmark);
-	        nautilus_window_go_to (holder->window, location);
+		slot = nautilus_window_get_active_slot (holder->window);
+	        nautilus_window_slot_go_to (slot, 
+					    location, 
+					    should_open_in_new_tab ());
 	        g_object_unref (location);
         }
 }
@@ -185,10 +207,16 @@
 }
 
 static void
-action_close_window_callback (GtkAction *action, 
-			      gpointer user_data)
+action_close_window_slot_callback (GtkAction *action,
+				   gpointer user_data)
 {
-	nautilus_window_close (NAUTILUS_WINDOW (user_data));
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
+
+	window = NAUTILUS_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (window);
+
+	nautilus_window_slot_close (slot);
 }
 
 static void
@@ -196,9 +224,12 @@
 				   gpointer user_data)
 {
 	NautilusWindow *window = NAUTILUS_WINDOW (user_data);
+	NautilusWindowSlot *slot;
 	GtkWidget *dialog;
 	GFile *location;
-	location = nautilus_window_get_location (window);
+
+	slot = nautilus_window_get_active_slot (window);
+	location = nautilus_window_slot_get_location (slot);
 	dialog = nautilus_connect_server_dialog_new (window, location);
 	if (location) {
 		g_object_unref (location);
@@ -236,7 +267,13 @@
 action_stop_callback (GtkAction *action, 
 		      gpointer user_data)
 {
-	nautilus_window_stop_loading (NAUTILUS_WINDOW (user_data));
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
+
+	window = NAUTILUS_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (window);
+
+	nautilus_window_slot_stop_loading (slot);
 }
 
 static void
@@ -251,17 +288,31 @@
 action_home_callback (GtkAction *action, 
 		      gpointer user_data) 
 {
-	nautilus_window_go_home (NAUTILUS_WINDOW (user_data));
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
+
+	window = NAUTILUS_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (window);
+
+	nautilus_window_slot_go_home (slot, 
+				      should_open_in_new_tab ());
 }
 
 static void
 action_go_to_computer_callback (GtkAction *action, 
 				gpointer user_data) 
 {
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	GFile *computer;
+
+	window = NAUTILUS_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (window);
+
 	computer = g_file_new_for_uri (COMPUTER_URI);
-	nautilus_window_go_to (NAUTILUS_WINDOW (user_data),
-			       computer);
+	nautilus_window_slot_go_to (slot,
+				    computer,
+				    should_open_in_new_tab ());
 	g_object_unref (computer);
 }
 
@@ -269,10 +320,17 @@
 action_go_to_network_callback (GtkAction *action, 
 				gpointer user_data) 
 {
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	GFile *network;
+
+	window = NAUTILUS_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (window);
+
 	network = g_file_new_for_uri (NETWORK_URI);
-	nautilus_window_go_to (NAUTILUS_WINDOW (user_data),
-			       network);
+	nautilus_window_slot_go_to (slot,
+				    network,
+				    should_open_in_new_tab ());
 	g_object_unref (network);
 }
 
@@ -280,14 +338,20 @@
 action_go_to_templates_callback (GtkAction *action,
 				 gpointer user_data) 
 {
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	char *path;
 	GFile *location;
 
+	window = NAUTILUS_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (window);
+
 	path = nautilus_get_templates_directory ();
 	location = g_file_new_for_path (path);
 	g_free (path);
-	nautilus_window_go_to (NAUTILUS_WINDOW (user_data),
-			       location);
+	nautilus_window_slot_go_to (slot,
+				    location,
+				    should_open_in_new_tab ());
 	g_object_unref (location);
 }
 
@@ -295,10 +359,17 @@
 action_go_to_trash_callback (GtkAction *action, 
 			     gpointer user_data) 
 {
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	GFile *trash;
+
+	window = NAUTILUS_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (window);
+
 	trash = g_file_new_for_uri ("trash:///");
-	nautilus_window_go_to (NAUTILUS_WINDOW (user_data),
-			       trash);
+	nautilus_window_slot_go_to (slot,
+				    trash,
+				    should_open_in_new_tab ());
 	g_object_unref (trash);
 }
 
@@ -306,10 +377,17 @@
 action_go_to_burn_cd_callback (GtkAction *action,
 			       gpointer user_data) 
 {
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 	GFile *burn;
+
+	window = NAUTILUS_WINDOW (user_data);
+	slot = nautilus_window_get_active_slot (window);
+
 	burn = g_file_new_for_uri (BURN_CD_URI);
-	nautilus_window_go_to (NAUTILUS_WINDOW (user_data),
-			       burn);
+	nautilus_window_slot_go_to (slot,
+				    burn,
+				    should_open_in_new_tab ());
 	g_object_unref (burn);
 	
 }
@@ -343,6 +421,48 @@
 }
 
 static void
+action_show_hidden_files_callback (GtkAction *action, 
+				   gpointer callback_data)
+{
+	NautilusWindow *window;
+	NautilusWindowShowHiddenFilesMode mode;
+
+	window = NAUTILUS_WINDOW (callback_data);
+
+	if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
+		mode = NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_ENABLE;
+	} else {
+		mode = NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DISABLE;
+	}
+
+	nautilus_window_info_set_hidden_files_mode (window, mode);
+}
+
+static void
+show_hidden_files_preference_callback (gpointer callback_data)
+{
+	NautilusWindow *window;
+	GtkAction *action;
+
+	window = NAUTILUS_WINDOW (callback_data);
+
+	if (window->details->show_hidden_files_mode == NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT) {
+		action = gtk_action_group_get_action (window->details->main_action_group, NAUTILUS_ACTION_SHOW_HIDDEN_FILES);
+		g_assert (GTK_IS_ACTION (action));
+
+		/* update button */
+		g_signal_handlers_block_by_func (action, action_show_hidden_files_callback, window);
+		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+					      eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES));
+		g_signal_handlers_unblock_by_func (action, action_show_hidden_files_callback, window);
+
+		/* inform views */
+		nautilus_window_info_set_hidden_files_mode (window, NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT);
+
+	}
+}
+
+static void
 preferences_respond_callback (GtkDialog *dialog,
 			      gint response_id)
 {
@@ -467,7 +587,7 @@
 action_up_callback (GtkAction *action, 
 		     gpointer user_data) 
 {
-	nautilus_window_go_up (NAUTILUS_WINDOW (user_data), FALSE);
+	nautilus_window_go_up (NAUTILUS_WINDOW (user_data), FALSE, should_open_in_new_tab ());
 }
 
 static void
@@ -534,18 +654,89 @@
 			   window->details->help_message_cid);
 }
 
+static GtkWidget *
+get_event_widget (GtkWidget *proxy)
+{
+	GtkWidget *widget;
+
+	/**
+	 * Finding the interesting widget requires internal knowledge of
+	 * the widgets in question. This can't be helped, but by keeping
+	 * the sneaky code in one place, it can easily be updated.
+	 */
+	if (GTK_IS_MENU_ITEM (proxy)) {
+		/* Menu items already forward middle clicks */
+		widget = NULL;
+	} else if (GTK_IS_MENU_TOOL_BUTTON (proxy)) {
+		/**
+		 * The menu tool button's button is the first child
+		 * of the child hbox.
+		 */
+		GtkContainer *container =
+			GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (proxy)));
+		widget = GTK_WIDGET (gtk_container_get_children (container)->data);
+	} else if (GTK_IS_TOOL_BUTTON (proxy)) {
+		/* The tool button's button is the direct child */
+		widget = gtk_bin_get_child (GTK_BIN (proxy));
+	} else if (GTK_IS_BUTTON (proxy)) {
+		widget = proxy;
+	} else {
+		/* Don't touch anything we don't know about */
+		widget = NULL;
+	}
+
+	return widget;
+}
+
+static gboolean
+proxy_button_press_event_cb (GtkButton *button,
+			     GdkEventButton *event,
+			     gpointer user_data)
+{
+	if (event->button == 2) {
+		gtk_button_pressed (button);
+	}
+
+	return FALSE;
+}
+
+static gboolean
+proxy_button_release_event_cb (GtkButton *button,
+			       GdkEventButton *event,
+			       gpointer user_data)
+{
+	if (event->button == 2) {
+		gtk_button_released (button);
+	}
+
+	return FALSE;
+}
+
 static void
 disconnect_proxy_cb (GtkUIManager *manager,
 		     GtkAction *action,
 		     GtkWidget *proxy,
 		     NautilusWindow *window)
 {
+	GtkWidget *widget;
+
 	if (GTK_IS_MENU_ITEM (proxy)) {
 		g_signal_handlers_disconnect_by_func
 			(proxy, G_CALLBACK (menu_item_select_cb), window);
 		g_signal_handlers_disconnect_by_func
 			(proxy, G_CALLBACK (menu_item_deselect_cb), window);
 	}
+
+	widget = get_event_widget (proxy);
+	if (widget) {
+		g_signal_handlers_disconnect_by_func (widget,
+						      G_CALLBACK (proxy_button_press_event_cb),
+						      action);
+		g_signal_handlers_disconnect_by_func (widget,
+						      G_CALLBACK (proxy_button_release_event_cb),
+						      action);
+	}
+
 }
 
 static void
@@ -581,6 +772,15 @@
 		}
 	}
 	
+	widget = get_event_widget (proxy);
+	if (widget) {
+		g_signal_connect (widget, "button-press-event",
+				  G_CALLBACK (proxy_button_press_event_cb),
+				  action);
+		g_signal_connect (widget, "button-release-event",
+				  G_CALLBACK (proxy_button_release_event_cb),
+				  action);
+	}
 }
 
 static const GtkActionEntry main_entries[] = {
@@ -591,7 +791,7 @@
   /* name, stock id */         { "Close", GTK_STOCK_CLOSE,
   /* label, accelerator */       N_("_Close"), "<control>W",
   /* tooltip */                  N_("Close this folder"),
-                                 G_CALLBACK (action_close_window_callback) },
+                                 G_CALLBACK (action_close_window_slot_callback) },
                                { "Backgrounds and Emblems", NULL,
                                  N_("_Backgrounds and Emblems..."),               
                                  NULL, N_("Display patterns, colors, and emblems that can be used to customize appearance"),
@@ -679,6 +879,14 @@
                                  G_CALLBACK (action_go_to_burn_cd_callback) },
 };
 
+static const GtkToggleActionEntry main_toggle_entries[] = {
+  /* name, stock id */         { "Show Hidden Files", NULL,
+  /* label, accelerator */       N_("Show _Hidden Files"), "<control>H",
+  /* tooltip */                  N_("Toggle the display of hidden files in the current window"),
+                                 G_CALLBACK (action_show_hidden_files_callback),
+                                 TRUE },
+};
+
 /**
  * nautilus_window_initialize_menus
  * 
@@ -699,6 +907,9 @@
 	gtk_action_group_add_actions (action_group, 
 				      main_entries, G_N_ELEMENTS (main_entries),
 				      window);
+	gtk_action_group_add_toggle_actions (action_group, 
+					     main_toggle_entries, G_N_ELEMENTS (main_toggle_entries),
+					     window);
 
 	action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_UP);
 	g_object_set (action, "short_label", _("_Up"), NULL);
@@ -706,6 +917,17 @@
 	action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_HOME);
 	g_object_set (action, "short_label", _("_Home"), NULL);
 
+	action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_SHOW_HIDDEN_FILES);
+	g_signal_handlers_block_by_func (action, action_show_hidden_files_callback, window);
+	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+				      eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES));
+	g_signal_handlers_unblock_by_func (action, action_show_hidden_files_callback, window);
+
+
+	eel_preferences_add_callback_while_alive (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
+						  show_hidden_files_preference_callback,
+						  window, G_OBJECT (window));
+
 	window->details->ui_manager = gtk_ui_manager_new ();
 	ui_manager = window->details->ui_manager;
 	gtk_window_add_accel_group (GTK_WINDOW (window),
@@ -744,6 +966,7 @@
 static GList *
 get_extension_menus (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GList *providers;
 	GList *items;
 	GList *l;
@@ -751,6 +974,8 @@
 	providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
 	items = NULL;
 
+	slot = nautilus_window_get_active_slot (window);
+
 	for (l = providers; l != NULL; l = l->next) {
 		NautilusMenuProvider *provider;
 		GList *file_items;
@@ -758,7 +983,7 @@
 		provider = NAUTILUS_MENU_PROVIDER (l->data);
 		file_items = nautilus_menu_provider_get_background_items (provider,
 									  GTK_WIDGET (window),
-									  window->details->viewed_file);
+									  slot->viewed_file);
 		items = g_list_concat (items, file_items);
 	}
 

Modified: trunk/src/nautilus-window-private.h
==============================================================================
--- trunk/src/nautilus-window-private.h	(original)
+++ trunk/src/nautilus-window-private.h	Tue Jul  8 21:05:55 2008
@@ -29,6 +29,7 @@
 #define NAUTILUS_WINDOW_PRIVATE_H
 
 #include "nautilus-window.h"
+#include "nautilus-window-slot.h"
 #include "nautilus-spatial-window.h"
 #include "nautilus-navigation-window.h"
 
@@ -37,23 +38,12 @@
 #include <bonobo/bonobo-ui-toolbar-button-item.h>
 #include <libnautilus-private/nautilus-directory.h>
 
-typedef enum {
-        NAUTILUS_LOCATION_CHANGE_STANDARD,
-        NAUTILUS_LOCATION_CHANGE_BACK,
-        NAUTILUS_LOCATION_CHANGE_FORWARD,
-        NAUTILUS_LOCATION_CHANGE_RELOAD,
-        NAUTILUS_LOCATION_CHANGE_REDIRECT,
-        NAUTILUS_LOCATION_CHANGE_FALLBACK
-} NautilusLocationChangeType;
-
 /* FIXME bugzilla.gnome.org 42575: Migrate more fields into here. */
 struct NautilusWindowDetails
 {
         GtkWidget *table;
         GtkWidget *statusbar;
         GtkWidget *menubar;
-
-        GtkWidget *extra_location_widgets;
         
         GtkUIManager *ui_manager;
         GtkActionGroup *main_action_group; /* owned by ui_manager */
@@ -66,43 +56,26 @@
         GtkActionGroup *bookmarks_action_group;
         guint refresh_bookmarks_menu_idle_id;
         guint bookmarks_merge_id;
-        
-        /* Current location. */
-        GFile *location;
-	char *title;
-	NautilusFile *viewed_file;
-        gboolean viewed_file_seen;
-	gboolean viewed_file_in_trash;
-	gboolean allow_stop;
-
-        /* New location. */
-        NautilusLocationChangeType location_change_type;
-        guint location_change_distance;
-        GFile *pending_location;
-        char *pending_scroll_to;
-        GList *pending_selection;
-        NautilusFile *determine_view_file;
-        GCancellable *mount_cancellable;
-        GError *mount_error;
-        gboolean tried_mount;
-
-        /* View As choices */
-        GtkActionGroup *view_as_action_group; /* owned by ui_manager */
-        GtkRadioAction *view_as_radio_action;
-        GtkRadioAction *extra_viewer_radio_action;
-        guint short_list_merge_id;
-        guint extra_viewer_merge_id;
-        GList *short_list_viewers;
-        char *extra_viewer;
-
-        /* Deferred location change. */
-        GFile *location_to_change_to_at_idle;
-        guint location_change_at_idle_id;
 
-        NautilusWindowShowHiddenFilesMode show_hidden_files_mode;
-        gboolean search_mode;
-
-        GCancellable *find_mount_cancellable;
+	/* available slots, and active slot.
+ 	 * Both of them may never be NULL.
+ 	 */
+	GList *slots;
+	GList *active_slots;
+	NautilusWindowSlot *active_slot;
+
+	NautilusWindowShowHiddenFilesMode show_hidden_files_mode;
+
+	/* View As menu */
+	GList *short_list_viewers;
+	char *extra_viewer;
+
+	/* View As choices */
+	GtkActionGroup *view_as_action_group; /* owned by ui_manager */
+	GtkRadioAction *view_as_radio_action;
+	GtkRadioAction *extra_viewer_radio_action;
+	guint short_list_merge_id;
+	guint extra_viewer_merge_id;
 
 	/* Ensures that we do not react on signals of a
 	 * view that is re-used as new view when its loading
@@ -135,13 +108,16 @@
 	guint refresh_go_menu_idle_id;
         guint go_menu_merge_id;
         
+	GtkActionGroup *tabs_menu_action_group;
+	guint tabs_menu_merge_id;
+
         /* Toolbar */
         GtkWidget *toolbar;
         GtkWidget *location_bar;
 
         guint extensions_toolbar_merge_id;
         GtkActionGroup *extensions_toolbar_action_group;
-        
+
 	/* Throbber */
         gboolean    throbber_active;
         GtkWidget  *throbber;
@@ -187,6 +163,7 @@
                                                 NautilusBookmark *bookmark);
 
 void               nautilus_window_set_status                            (NautilusWindow    *window,
+									  NautilusWindowSlot *slot,
                                                                           const char        *status);
 void               nautilus_window_load_view_as_menus                    (NautilusWindow    *window);
 void               nautilus_window_load_extension_menus                  (NautilusWindow    *window);
@@ -210,23 +187,44 @@
 void               nautilus_window_zoom_to_level                         (NautilusWindow    *window,
                                                                           NautilusZoomLevel  level);
 void               nautilus_window_zoom_to_default                       (NautilusWindow    *window);
-void		   nautilus_window_show_view_as_dialog			 (NautilusWindow    *window);
-void               nautilus_window_set_content_view_widget               (NautilusWindow    *window,
-                                                                          NautilusView       *content_view);
-void               nautilus_window_set_viewed_file                       (NautilusWindow    *window,
-                                                                          NautilusFile      *file);
+
+NautilusWindowSlot *nautilus_window_open_slot                            (NautilusWindow     *window,
+									  NautilusWindowOpenSlotFlags flags);
+void                nautilus_window_close_slot                           (NautilusWindow     *window,
+									  NautilusWindowSlot *slot);
+
+NautilusWindowSlot *nautilus_window_get_slot_for_view                    (NautilusWindow *window,
+									  NautilusView   *view);
+NautilusWindowSlot *nautilus_window_get_slot_for_content_box             (NautilusWindow *window,
+									  GtkWidget *content_box);
+
+GList *              nautilus_window_get_slots                           (NautilusWindow    *window);
+NautilusWindowSlot * nautilus_window_get_active_slot                     (NautilusWindow    *window);
+void                 nautilus_window_set_active_slot                     (NautilusWindow     *window,
+									  NautilusWindowSlot *slot);
+
 void               nautilus_send_history_list_changed                    (void);
-void               nautilus_window_add_current_location_to_history_list  (NautilusWindow    *window);
 void               nautilus_remove_from_history_list_no_notify           (GFile             *location);
+gboolean           nautilus_add_bookmark_to_history_list                 (NautilusBookmark  *bookmark);
 gboolean           nautilus_add_to_history_list_no_notify                (GFile             *location,
 									  const char        *name,
 									  gboolean           has_custom_name,
 									  GIcon            *icon);
 GList *            nautilus_get_history_list                             (void);
 void               nautilus_window_bookmarks_preference_changed_callback (gpointer           user_data);
-void		   nautilus_window_update_icon				 (NautilusWindow    *window);
 void               nautilus_window_constructed                           (NautilusWindow    *window);
 
+
+/* sync window GUI with current slot. Used when changing slots,
+ * and when updating the slot state.
+ */
+void nautilus_window_sync_status           (NautilusWindow *window);
+void nautilus_window_sync_allow_stop       (NautilusWindow *window,
+					    NautilusWindowSlot *slot);
+void nautilus_window_sync_title            (NautilusWindow *window,
+					    NautilusWindowSlot *slot);
+void nautilus_window_sync_location_widgets (NautilusWindow *window);
+
 /* Navigation window menus */
 void               nautilus_navigation_window_initialize_actions                    (NautilusNavigationWindow    *window);
 void               nautilus_navigation_window_initialize_menus                      (NautilusNavigationWindow    *window);
@@ -235,6 +233,9 @@
 void               nautilus_navigation_window_remove_bookmarks_menu_items           (NautilusNavigationWindow    *window);
 void               nautilus_navigation_window_update_show_hide_menu_items           (NautilusNavigationWindow     *window);
 void               nautilus_navigation_window_update_spatial_menu_item              (NautilusNavigationWindow     *window);
+void               nautilus_navigation_window_update_tab_menu_item_visibility       (NautilusNavigationWindow     *window);
+void               nautilus_navigation_window_sync_tab_menu_title                   (NautilusNavigationWindow     *window,
+										     NautilusWindowSlot           *slot);
 void               nautilus_navigation_window_remove_go_menu_callback    (NautilusNavigationWindow    *window);
 void               nautilus_navigation_window_remove_go_menu_items       (NautilusNavigationWindow    *window);
 

Added: trunk/src/nautilus-window-slot.c
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-window-slot.c	Tue Jul  8 21:05:55 2008
@@ -0,0 +1,582 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-window-slot.c: Nautilus window slot
+ 
+   Copyright (C) 2008 Free Software Foundation, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Christian Neumair <cneumair gnome org>
+*/
+#include "nautilus-window-slot.h"
+#include "nautilus-navigation-window-slot.h"
+
+#include "nautilus-desktop-window.h"
+#include "nautilus-window-private.h"
+#include "nautilus-window-manage-views.h"
+#include <libnautilus-private/nautilus-file.h>
+#include <libnautilus-private/nautilus-file-utilities.h>
+#include <libnautilus-private/nautilus-window-slot-info.h>
+#include <eel/eel-gtk-macros.h>
+#include <eel/eel-string.h>
+
+static void nautilus_window_slot_init       (NautilusWindowSlot *slot);
+static void nautilus_window_slot_class_init (NautilusWindowSlotClass *class);
+static void nautilus_window_slot_dispose    (GObject *object);
+
+static void nautilus_window_slot_info_iface_init (NautilusWindowSlotInfoIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (NautilusWindowSlot,
+			 nautilus_window_slot,
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (NAUTILUS_TYPE_WINDOW_SLOT_INFO,
+						nautilus_window_slot_info_iface_init))
+#define parent_class nautilus_window_slot_parent_class
+
+static void
+query_editor_changed_callback (NautilusSearchBar *bar,
+			       NautilusQuery *query,
+			       gboolean reload,
+			       NautilusWindowSlot *slot)
+{
+	NautilusDirectory *directory;
+
+	directory = nautilus_directory_get_for_file (slot->viewed_file);
+	g_assert (NAUTILUS_IS_SEARCH_DIRECTORY (directory));
+
+	nautilus_search_directory_set_query (NAUTILUS_SEARCH_DIRECTORY (directory),
+					     query);
+	if (reload) {
+		nautilus_window_slot_reload (slot);
+	}
+
+	nautilus_directory_unref (directory);
+}
+
+static void
+real_update_query_editor (NautilusWindowSlot *slot)
+{
+	GtkWidget *query_editor;
+	NautilusQuery *query;
+	NautilusDirectory *directory;
+	NautilusSearchDirectory *search_directory;
+
+	directory = nautilus_directory_get (slot->location);
+
+	if (NAUTILUS_IS_SEARCH_DIRECTORY (directory)) {
+		search_directory = NAUTILUS_SEARCH_DIRECTORY (directory);
+
+		query_editor = nautilus_query_editor_new (nautilus_search_directory_is_saved_search (search_directory),
+							  nautilus_search_directory_is_indexed (search_directory));
+
+		slot->query_editor = NAUTILUS_QUERY_EDITOR (query_editor);
+
+		nautilus_window_slot_add_extra_location_widget (slot, query_editor);
+		gtk_widget_show (query_editor);
+		g_signal_connect_object (query_editor, "changed",
+					 G_CALLBACK (query_editor_changed_callback), slot, 0);
+		
+		query = nautilus_search_directory_get_query (search_directory);
+		if (query != NULL) {
+			nautilus_query_editor_set_query (NAUTILUS_QUERY_EDITOR (query_editor),
+							 query);
+			g_object_unref (query);
+		} else {
+			nautilus_query_editor_set_default_query (NAUTILUS_QUERY_EDITOR (query_editor));
+		}
+	} 
+
+	nautilus_directory_unref (directory);
+}
+
+
+static void
+real_active (NautilusWindowSlot *slot)
+{
+	NautilusWindow *window;
+
+	window = slot->window;
+
+	/* sync window to new slot */
+	nautilus_window_sync_status (window);
+	nautilus_window_sync_allow_stop (window, slot);
+	nautilus_window_sync_title (window, slot);
+	nautilus_window_sync_location_widgets (window);
+	nautilus_window_sync_search_widgets (window);
+
+	if (slot->viewed_file != NULL) {
+		nautilus_window_load_view_as_menus (window);
+		nautilus_window_load_extension_menus (window);
+	}
+}
+
+static void
+nautilus_window_slot_active (NautilusWindowSlot *slot)
+{
+	NautilusWindow *window;
+
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	window = NAUTILUS_WINDOW (slot->window);
+	g_assert (g_list_find (window->details->slots, slot) != NULL);
+	g_assert (slot == window->details->active_slot);
+
+	EEL_CALL_METHOD (NAUTILUS_WINDOW_SLOT_CLASS, slot,
+			 active, (slot));
+}
+
+static void
+real_inactive (NautilusWindowSlot *slot)
+{
+	NautilusWindow *window;
+
+	window = NAUTILUS_WINDOW (slot->window);
+	g_assert (slot == window->details->active_slot);
+}
+
+static void
+nautilus_window_slot_inactive (NautilusWindowSlot *slot)
+{
+	NautilusWindow *window;
+
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	window = NAUTILUS_WINDOW (slot->window);
+	g_assert (g_list_find (window->details->slots, slot) != NULL);
+	g_assert (slot == window->details->active_slot);
+
+	EEL_CALL_METHOD (NAUTILUS_WINDOW_SLOT_CLASS, slot,
+			 inactive, (slot));
+}
+
+
+static void
+nautilus_window_slot_init (NautilusWindowSlot *slot)
+{
+	GtkWidget *content_box, *eventbox, *extras_vbox;
+
+	content_box = gtk_vbox_new (FALSE, 0);
+	slot->content_box = content_box;
+	gtk_widget_show (content_box);
+
+	eventbox = gtk_event_box_new ();
+	slot->extra_location_event_box = eventbox;
+	gtk_widget_set_name (eventbox, "nautilus-extra-view-widget");
+	gtk_box_pack_start (GTK_BOX (content_box), eventbox, FALSE, FALSE, 0);
+	
+	extras_vbox = gtk_vbox_new (FALSE, 6);
+	gtk_container_set_border_width (GTK_CONTAINER (extras_vbox), 6);
+	slot->extra_location_widgets = extras_vbox;
+	gtk_container_add (GTK_CONTAINER (eventbox), extras_vbox);
+	gtk_widget_show (extras_vbox);
+
+	slot->view_box = gtk_vbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (content_box), slot->view_box, TRUE, TRUE, 0);
+	gtk_widget_show (slot->view_box);
+
+	slot->title = g_strdup (_("Loading..."));
+}
+
+static void
+nautilus_window_slot_class_init (NautilusWindowSlotClass *class)
+{
+	class->active = real_active;
+	class->inactive = real_inactive;
+	class->update_query_editor = real_update_query_editor; 
+
+	G_OBJECT_CLASS (class)->dispose = nautilus_window_slot_dispose;
+}
+
+static int
+nautilus_window_slot_get_selection_count (NautilusWindowSlot *slot)
+{
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	if (slot->content_view != NULL) {
+		return nautilus_view_get_selection_count (slot->content_view);
+	}
+	return 0;
+}
+
+GFile *
+nautilus_window_slot_get_location (NautilusWindowSlot *slot)
+{
+	g_assert (slot != NULL);
+	g_assert (NAUTILUS_IS_WINDOW (slot->window));
+
+	if (slot->location != NULL) {
+		return g_object_ref (slot->location);
+	}
+	return NULL;
+}
+
+char *
+nautilus_window_slot_get_location_uri (NautilusWindowSlotInfo *slot)
+{
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	if (slot->location) {
+		return g_file_get_uri (slot->location);
+	}
+	return NULL;
+}
+
+char *
+nautilus_window_slot_get_title (NautilusWindowSlot *slot)
+{
+	char *title;
+
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	title = NULL;
+	if (slot->new_content_view != NULL) {
+		title = nautilus_view_get_title (slot->new_content_view);
+	} else if (slot->content_view != NULL) {
+		title = nautilus_view_get_title (slot->content_view);
+	}
+
+	if (title == NULL) {
+		title = nautilus_compute_title_for_location (slot->location);
+	}
+
+	return title;
+}
+
+static NautilusWindow *
+nautilus_window_slot_get_window (NautilusWindowSlot *slot)
+{
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+	return slot->window;
+}
+
+/* nautilus_window_slot_set_title:
+ *
+ * Sets slot->title, and if it changed
+ * synchronizes the actual GtkWindow title which
+ * might look a bit different (e.g. with "file browser:" added)
+ */
+static void
+nautilus_window_slot_set_title (NautilusWindowSlot *slot,
+				const char *title)
+{
+	NautilusWindow *window;
+	gboolean changed;
+
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	window = NAUTILUS_WINDOW (slot->window);
+
+	changed = FALSE;
+
+	if (eel_strcmp (title, slot->title) != 0) {
+		changed = TRUE;
+
+		g_free (slot->title);
+		slot->title = g_strdup (title);
+	}
+
+	if (eel_strlen (slot->title) > 0 && slot->current_location_bookmark &&
+	    nautilus_bookmark_set_name (slot->current_location_bookmark,
+					slot->title)) {
+		changed = TRUE;
+
+		/* Name of item in history list changed, tell listeners. */
+		nautilus_send_history_list_changed ();
+	}
+
+	if (changed) {
+		nautilus_window_sync_title (window, slot);
+	}
+}
+
+
+/* nautilus_window_slot_update_title:
+ * 
+ * Re-calculate the slot title.
+ * Called when the location or view has changed.
+ * @slot: The NautilusWindowSlot in question.
+ * 
+ */
+void
+nautilus_window_slot_update_title (NautilusWindowSlot *slot)
+{
+	char *title;
+
+	title = nautilus_window_slot_get_title (slot);
+	nautilus_window_slot_set_title (slot, title);
+	g_free (title);
+}
+
+/* nautilus_window_slot_update_icon:
+ * 
+ * Re-calculate the slot icon
+ * Called when the location or view or icon set has changed.
+ * @slot: The NautilusWindowSlot in question.
+ */
+void
+nautilus_window_slot_update_icon (NautilusWindowSlot *slot)
+{
+	NautilusWindow *window;
+	NautilusIconInfo *info;
+	const char *icon_name;
+	GdkPixbuf *pixbuf;
+
+	window = slot->window;
+
+	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+
+	info = EEL_CALL_METHOD_WITH_RETURN_VALUE (NAUTILUS_WINDOW_CLASS, window,
+						 get_icon, (window, slot));
+
+	icon_name = NULL;
+	if (info) {
+		icon_name = nautilus_icon_info_get_used_name (info);
+		if (icon_name != NULL) {
+			gtk_window_set_icon_name (GTK_WINDOW (window), icon_name);
+		} else {
+			pixbuf = nautilus_icon_info_get_pixbuf_nodefault (info);
+			
+			if (pixbuf) {
+				gtk_window_set_icon (GTK_WINDOW (window), pixbuf);
+				g_object_unref (pixbuf);
+			} 
+		}
+		
+		g_object_unref (info);
+	}
+}
+
+void
+nautilus_window_slot_set_content_view_widget (NautilusWindowSlot *slot,
+					      NautilusView *new_view)
+{
+	NautilusWindow *window;
+	GtkWidget *widget;
+	gboolean inform_window;
+
+	window = slot->window;
+	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+
+	inform_window = slot == window->details->active_slot;
+
+	if (slot->content_view != NULL) {
+		/* disconnect old view */
+		if (inform_window) {
+			nautilus_window_disconnect_content_view (window, slot->content_view);
+		}
+
+		widget = nautilus_view_get_widget (slot->content_view);
+		gtk_widget_destroy (widget);
+		g_object_unref (slot->content_view);
+		slot->content_view = NULL;
+	}
+
+	if (new_view != NULL) {
+		widget = nautilus_view_get_widget (new_view);
+		gtk_container_add (GTK_CONTAINER (slot->view_box),
+						  GTK_WIDGET (new_view));
+
+		gtk_widget_show (widget);
+
+		slot->content_view = new_view;
+		g_object_ref (slot->content_view);
+
+		/* connect new view */
+		if (inform_window) {
+			nautilus_window_connect_content_view (window, new_view);
+		}
+	}
+}
+
+void
+nautilus_window_slot_set_allow_stop (NautilusWindowSlot *slot,
+				     gboolean allow)
+{
+	NautilusWindow *window;
+
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	slot->allow_stop = allow;
+
+	window = NAUTILUS_WINDOW (slot->window);
+	nautilus_window_sync_allow_stop (window, slot);
+}
+
+void
+nautilus_window_slot_set_status (NautilusWindowSlot *slot,
+				 const char *status)
+{
+	NautilusWindow *window;
+
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+
+	g_free (slot->status_text);
+	slot->status_text = g_strdup (status);
+
+	window = NAUTILUS_WINDOW (slot->window);
+	if (slot == window->details->active_slot) {
+		nautilus_window_sync_status (window);
+	}
+}
+
+/* nautilus_window_slot_update_query_editor:
+ * 
+ * Update the query editor.
+ * Called when the location has changed.
+ *
+ * @slot: The NautilusWindowSlot in question.
+ */
+void
+nautilus_window_slot_update_query_editor (NautilusWindowSlot *slot)
+{
+	if (slot->query_editor != NULL) {
+		gtk_widget_destroy (GTK_WIDGET (slot->query_editor));
+		slot->query_editor = NULL;
+	}
+
+        EEL_CALL_METHOD (NAUTILUS_WINDOW_SLOT_CLASS, slot,
+                         update_query_editor, (slot));
+}
+
+static void
+remove_all (GtkWidget *widget,
+	    gpointer data)
+{
+	GtkContainer *container;
+	container = GTK_CONTAINER (data);
+
+	gtk_container_remove (container, widget);
+}
+
+void
+nautilus_window_slot_remove_extra_location_widgets (NautilusWindowSlot *slot)
+{
+	gtk_container_foreach (GTK_CONTAINER (slot->extra_location_widgets),
+			       remove_all,
+			       slot->extra_location_widgets);
+	gtk_widget_hide (slot->extra_location_event_box);
+}
+
+void
+nautilus_window_slot_add_extra_location_widget (NautilusWindowSlot *slot,
+						GtkWidget *widget)
+{
+	gtk_box_pack_start (GTK_BOX (slot->extra_location_widgets),
+			    widget, TRUE, TRUE, 0);
+	gtk_widget_show (slot->extra_location_event_box);
+}
+
+void
+nautilus_window_slot_add_current_location_to_history_list (NautilusWindowSlot *slot)
+{
+
+	if ((slot->window == NULL || !NAUTILUS_IS_DESKTOP_WINDOW (slot->window)) &&
+	    nautilus_add_bookmark_to_history_list (slot->current_location_bookmark)) {
+		nautilus_send_history_list_changed ();
+	}
+}
+
+/* returns either the pending or the actual current location - used by side panes. */
+static char *
+real_slot_info_get_current_location (NautilusWindowSlotInfo *info)
+{
+	NautilusWindowSlot *slot;
+
+	slot = NAUTILUS_WINDOW_SLOT (info);
+
+	if (slot->pending_location != NULL) {
+		return g_file_get_uri (slot->pending_location);
+	}
+
+	if (slot->location != NULL) {
+		return g_file_get_uri (slot->location);
+	}
+
+	g_assert_not_reached ();
+	return NULL;
+}
+
+static void
+nautilus_window_slot_dispose (GObject *object)
+{
+	NautilusWindowSlot *slot;
+	GtkWidget *widget;
+
+	slot = NAUTILUS_WINDOW_SLOT (object);
+
+	nautilus_window_slot_set_viewed_file (slot, NULL);
+	/* TODO? why do we unref here? the file is NULL.
+	 * It was already here before the slot move, though */
+	nautilus_file_unref (slot->viewed_file);
+
+	if (slot->location) {
+		/* TODO? why do we ref here, instead of unreffing?
+		 * It was already here before the slot migration, though */
+		g_object_ref (slot->location);
+	}
+
+	eel_g_list_free_deep (slot->pending_selection);
+	slot->pending_selection = NULL;
+
+	if (slot->current_location_bookmark != NULL) {
+		g_object_unref (slot->current_location_bookmark);
+		slot->current_location_bookmark = NULL;
+	}
+	if (slot->last_location_bookmark != NULL) {
+		g_object_unref (slot->last_location_bookmark);
+		slot->last_location_bookmark = NULL;
+	}
+
+	if (slot->find_mount_cancellable != NULL) {
+		g_cancellable_cancel (slot->find_mount_cancellable);
+		slot->find_mount_cancellable = NULL;
+	}
+
+	if (slot->content_view) {
+		widget = nautilus_view_get_widget (slot->content_view);
+		gtk_widget_destroy (widget);
+		g_object_unref (slot->content_view);
+		slot->content_view = NULL;
+	}
+
+	if (slot->new_content_view) {
+		widget = nautilus_view_get_widget (slot->new_content_view);
+		gtk_widget_destroy (widget);
+		g_object_unref (slot->new_content_view);
+		slot->new_content_view = NULL;
+	}
+
+	slot->window = NULL;
+
+	g_free (slot->title);
+	slot->title = NULL;
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+nautilus_window_slot_info_iface_init (NautilusWindowSlotInfoIface *iface)
+{
+	iface->active = nautilus_window_slot_active;
+	iface->inactive = nautilus_window_slot_inactive;
+	iface->get_window = nautilus_window_slot_get_window;
+	iface->get_selection_count = nautilus_window_slot_get_selection_count;
+	iface->get_current_location = real_slot_info_get_current_location;
+	iface->set_status = nautilus_window_slot_set_status;
+	iface->get_title = nautilus_window_slot_get_title;
+	iface->open_location = nautilus_window_slot_open_location_full;
+}
+

Added: trunk/src/nautilus-window-slot.h
==============================================================================
--- (empty file)
+++ trunk/src/nautilus-window-slot.h	Tue Jul  8 21:05:55 2008
@@ -0,0 +1,326 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-window-slot.h: Nautilus window slot
+ 
+   Copyright (C) 2008 Free Software Foundation, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Christian Neumair <cneumair gnome org>
+*/
+
+#ifndef NAUTILUS_WINDOW_SLOT_H
+#define NAUTILUS_WINDOW_SLOT_H
+
+#include "nautilus-window.h"
+#include "nautilus-query-editor.h"
+
+#define NAUTILUS_TYPE_WINDOW_SLOT	 (nautilus_window_slot_get_type())
+#define NAUTILUS_WINDOW_SLOT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_TYPE_WINDOW_SLOT, NautilusWindowSlotClass))
+#define NAUTILUS_WINDOW_SLOT(obj)	 (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_WINDOW_SLOT, NautilusWindowSlot))
+#define NAUTILUS_IS_WINDOW_SLOT(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_WINDOW_SLOT))
+#define NAUTILUS_IS_WINDOW_SLOT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_WINDOW_SLOT))
+#define NAUTILUS_WINDOW_SLOT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_WINDOW_SLOT, NautilusWindowSlotClass))
+
+typedef enum {
+	NAUTILUS_LOCATION_CHANGE_STANDARD,
+	NAUTILUS_LOCATION_CHANGE_BACK,
+	NAUTILUS_LOCATION_CHANGE_FORWARD,
+	NAUTILUS_LOCATION_CHANGE_RELOAD,
+	NAUTILUS_LOCATION_CHANGE_REDIRECT,
+	NAUTILUS_LOCATION_CHANGE_FALLBACK
+} NautilusLocationChangeType;
+
+struct NautilusWindowSlotClass {
+	GObjectClass parent_class;
+
+	/* wrapped NautilusWindowInfo signals, for overloading */
+	void (* active)   (NautilusWindowSlot *slot);
+	void (* inactive) (NautilusWindowSlot *slot);
+
+	void (* update_query_editor) (NautilusWindowSlot *slot);
+};
+
+/* Each NautilusWindowSlot corresponds to
+ * a location in the window for displaying
+ * a NautilusView.
+ *
+ * For navigation windows, this would be a
+ * tab, while spatial windows only have one slot.
+ */
+struct NautilusWindowSlot {
+	GObject parent;
+
+	NautilusWindow *window;
+
+	/* content_box contains
+ 	 *  1) an event box containing extra_location_widgets
+ 	 *  2) the view box for the content view
+ 	 */
+	GtkWidget *content_box;
+	GtkWidget *extra_location_event_box;
+	GtkWidget *extra_location_widgets;
+	GtkWidget *view_box;
+
+	NautilusView *content_view;
+	NautilusView *new_content_view;
+
+	/* Information about bookmarks */
+	NautilusBookmark *current_location_bookmark;
+	NautilusBookmark *last_location_bookmark;
+
+	/* Current location. */
+	GFile *location;
+	char *title;
+	char *status_text;
+
+	NautilusFile *viewed_file;
+	gboolean viewed_file_seen;
+	gboolean viewed_file_in_trash;
+
+	gboolean allow_stop;
+
+	NautilusQueryEditor *query_editor;
+
+	/* New location. */
+	NautilusLocationChangeType location_change_type;
+	guint location_change_distance;
+	GFile *pending_location;
+	char *pending_scroll_to;
+	GList *pending_selection;
+	NautilusFile *determine_view_file;
+	GCancellable *mount_cancellable;
+	GError *mount_error;
+	gboolean tried_mount;
+
+	GCancellable *find_mount_cancellable;
+};
+
+GType   nautilus_window_slot_get_type (void);
+
+char *  nautilus_window_slot_get_title			   (NautilusWindowSlot *slot);
+void    nautilus_window_slot_update_title		   (NautilusWindowSlot *slot);
+void    nautilus_window_slot_update_icon		   (NautilusWindowSlot *slot);
+void    nautilus_window_slot_update_query_editor	   (NautilusWindowSlot *slot);
+
+GFile * nautilus_window_slot_get_location		   (NautilusWindowSlot *slot);
+char *  nautilus_window_slot_get_location_uri		   (NautilusWindowSlot *slot);
+
+void    nautilus_window_slot_close			   (NautilusWindowSlot *slot);
+void    nautilus_window_slot_reload			   (NautilusWindowSlot *slot);
+
+void			nautilus_window_slot_open_location	      (NautilusWindowSlot	*slot,
+								       GFile			*location,
+								       gboolean			 close_behind);
+void			nautilus_window_slot_open_location_with_selection (NautilusWindowSlot	    *slot,
+									   GFile		    *location,
+									   GList		    *selection,
+									   gboolean		     close_behind);
+void			nautilus_window_slot_open_location_full       (NautilusWindowSlot	*slot,
+								       GFile			*location,
+								       NautilusWindowOpenMode	 mode,
+								       NautilusWindowOpenFlags	 flags,
+								       GList			*new_selection);
+void			nautilus_window_slot_stop_loading	      (NautilusWindowSlot	*slot);
+
+void			nautilus_window_slot_set_content_view	      (NautilusWindowSlot	*slot,
+								       const char		*id);
+const char	       *nautilus_window_slot_get_content_view_id      (NautilusWindowSlot	*slot);
+gboolean		nautilus_window_slot_content_view_matches_iid (NautilusWindowSlot	*slot,
+								       const char		*iid);
+
+#define nautilus_window_slot_go_to(slot,location, new_tab) \
+	nautilus_window_slot_open_location_full(slot, location, NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, \
+						(new_tab ? NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB : 0), \
+						NULL)
+
+#define nautilus_window_slot_go_to_with_selection(slot,location,new_selection) \
+	nautilus_window_slot_open_location_with_selection(slot, location, new_selection, FALSE)
+
+void    nautilus_window_slot_go_home			   (NautilusWindowSlot *slot,
+							    gboolean            new_tab);
+void    nautilus_window_slot_go_up			   (NautilusWindowSlot *slot,
+							    gboolean           close_behind);
+
+void    nautilus_window_slot_set_content_view_widget	   (NautilusWindowSlot *slot,
+							    NautilusView       *content_view);
+void    nautilus_window_slot_set_viewed_file		   (NautilusWindowSlot *slot,
+							    NautilusFile      *file);
+void    nautilus_window_slot_set_allow_stop		   (NautilusWindowSlot *slot,
+							    gboolean	    allow_stop);
+void    nautilus_window_slot_set_status			   (NautilusWindowSlot *slot,
+							    const char	 *status);
+
+void    nautilus_window_slot_add_extra_location_widget     (NautilusWindowSlot *slot,
+							    GtkWidget       *widget);
+void    nautilus_window_slot_remove_extra_location_widgets (NautilusWindowSlot *slot);
+
+void    nautilus_window_slot_add_current_location_to_history_list (NautilusWindowSlot *slot);
+
+#endif /* NAUTILUS_WINDOW_SLOT_H */
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+   nautilus-window-slot.h: Nautilus window slot
+ 
+   Copyright (C) 2008 Free Software Foundation, Inc.
+  
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+  
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+  
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+  
+   Author: Christian Neumair <cneumair gnome org>
+*/
+
+#ifndef NAUTILUS_WINDOW_SLOT_H
+#define NAUTILUS_WINDOW_SLOT_H
+
+#include "nautilus-window.h"
+#include "nautilus-query-editor.h"
+
+#define NAUTILUS_TYPE_WINDOW_SLOT	 (nautilus_window_slot_get_type())
+#define NAUTILUS_WINDOW_SLOT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_TYPE_WINDOW_SLOT, NautilusWindowSlotClass))
+#define NAUTILUS_WINDOW_SLOT(obj)	 (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_WINDOW_SLOT, NautilusWindowSlot))
+#define NAUTILUS_IS_WINDOW_SLOT(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_WINDOW_SLOT))
+#define NAUTILUS_IS_WINDOW_SLOT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_WINDOW_SLOT))
+#define NAUTILUS_WINDOW_SLOT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_WINDOW_SLOT, NautilusWindowSlotClass))
+
+typedef enum {
+	NAUTILUS_LOCATION_CHANGE_STANDARD,
+	NAUTILUS_LOCATION_CHANGE_BACK,
+	NAUTILUS_LOCATION_CHANGE_FORWARD,
+	NAUTILUS_LOCATION_CHANGE_RELOAD,
+	NAUTILUS_LOCATION_CHANGE_REDIRECT,
+	NAUTILUS_LOCATION_CHANGE_FALLBACK
+} NautilusLocationChangeType;
+
+struct NautilusWindowSlotClass {
+	GObjectClass parent_class;
+
+	/* wrapped NautilusWindowInfo signals, for overloading */
+	void (* active)   (NautilusWindowSlot *slot);
+	void (* inactive) (NautilusWindowSlot *slot);
+
+	void (* update_query_editor) (NautilusWindowSlot *slot);
+};
+
+/* Each NautilusWindowSlot corresponds to
+ * a location in the window for displaying
+ * a NautilusView.
+ *
+ * For navigation windows, this would be a
+ * tab, while spatial windows only have one slot.
+ */
+struct NautilusWindowSlot {
+	GObject parent;
+
+	NautilusWindow *window;
+
+	/* content_box contains
+ 	 *  1) an event box containing extra_location_widgets
+ 	 *  2) the view box for the content view
+ 	 */
+	GtkWidget *content_box;
+	GtkWidget *extra_location_event_box;
+	GtkWidget *extra_location_widgets;
+	GtkWidget *view_box;
+
+	NautilusView *content_view;
+	NautilusView *new_content_view;
+
+	/* Information about bookmarks */
+	NautilusBookmark *current_location_bookmark;
+	NautilusBookmark *last_location_bookmark;
+
+	/* Current location. */
+	GFile *location;
+	char *title;
+	char *status_text;
+
+	NautilusFile *viewed_file;
+	gboolean viewed_file_seen;
+	gboolean viewed_file_in_trash;
+
+	gboolean allow_stop;
+
+	NautilusQueryEditor *query_editor;
+
+	/* New location. */
+	NautilusLocationChangeType location_change_type;
+	guint location_change_distance;
+	GFile *pending_location;
+	char *pending_scroll_to;
+	GList *pending_selection;
+	NautilusFile *determine_view_file;
+	GCancellable *mount_cancellable;
+	GError *mount_error;
+	gboolean tried_mount;
+
+	GCancellable *find_mount_cancellable;
+};
+
+GType   nautilus_window_slot_get_type (void);
+
+char *  nautilus_window_slot_get_title			   (NautilusWindowSlot *slot);
+void    nautilus_window_slot_update_title		   (NautilusWindowSlot *slot);
+void    nautilus_window_slot_update_icon		   (NautilusWindowSlot *slot);
+void    nautilus_window_slot_update_query_editor	   (NautilusWindowSlot *slot);
+
+GFile * nautilus_window_slot_get_location		   (NautilusWindowSlot *slot);
+char *  nautilus_window_slot_get_location_uri		   (NautilusWindowSlot *slot);
+
+void    nautilus_window_slot_close			   (NautilusWindowSlot *slot);
+void    nautilus_window_slot_reload			   (NautilusWindowSlot *slot);
+
+#define nautilus_window_slot_go_to(slot,location, new_tab) \
+	nautilus_window_slot_open_location_full(slot, location, NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, \
+						(new_tab ? NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB : 0), \
+						NULL)
+
+#define nautilus_window_slot_go_to_with_selection(slot,location,new_selection) \
+	nautilus_window_slot_open_location_with_selection(slot, location, new_selection, FALSE)
+
+void    nautilus_window_slot_go_home			   (NautilusWindowSlot *slot,
+							    gboolean            new_tab);
+void    nautilus_window_slot_go_up			   (NautilusWindowSlot *slot,
+							    gboolean           close_behind);
+
+void    nautilus_window_slot_set_content_view_widget	   (NautilusWindowSlot *slot,
+							    NautilusView       *content_view);
+void    nautilus_window_slot_set_viewed_file		   (NautilusWindowSlot *slot,
+							    NautilusFile      *file);
+void    nautilus_window_slot_set_allow_stop		   (NautilusWindowSlot *slot,
+							    gboolean	    allow_stop);
+void    nautilus_window_slot_set_status			   (NautilusWindowSlot *slot,
+							    const char	 *status);
+
+void    nautilus_window_slot_add_extra_location_widget     (NautilusWindowSlot *slot,
+							    GtkWidget       *widget);
+void    nautilus_window_slot_remove_extra_location_widgets (NautilusWindowSlot *slot);
+
+void    nautilus_window_slot_add_current_location_to_history_list (NautilusWindowSlot *slot);
+
+#endif /* NAUTILUS_WINDOW_SLOT_H */

Modified: trunk/src/nautilus-window-toolbars.c
==============================================================================
--- trunk/src/nautilus-window-toolbars.c	(original)
+++ trunk/src/nautilus-window-toolbars.c	Tue Jul  8 21:05:55 2008
@@ -136,6 +136,7 @@
 static GList *
 get_extension_toolbar_items (NautilusNavigationWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GList *items;
 	GList *providers;
 	GList *l;
@@ -143,6 +144,8 @@
 	providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
 	items = NULL;
 
+	slot = NAUTILUS_WINDOW (window)->details->active_slot;
+
 	for (l = providers; l != NULL; l = l->next) {
 		NautilusMenuProvider *provider;
 		GList *file_items;
@@ -151,7 +154,7 @@
 		file_items = nautilus_menu_provider_get_toolbar_items 
 			(provider, 
 			 GTK_WIDGET (window),
-			 NAUTILUS_WINDOW (window)->details->viewed_file);
+			 slot->viewed_file);
 		items = g_list_concat (items, file_items);		
 	}
 

Modified: trunk/src/nautilus-window.c
==============================================================================
--- trunk/src/nautilus-window.c	(original)
+++ trunk/src/nautilus-window.c	Tue Jul  8 21:05:55 2008
@@ -37,6 +37,8 @@
 #include "nautilus-main.h"
 #include "nautilus-window-manage-views.h"
 #include "nautilus-window-bookmarks.h"
+#include "nautilus-window-slot.h"
+#include "nautilus-navigation-window-slot.h"
 #include "nautilus-zoom-control.h"
 #include "nautilus-search-bar.h"
 #include <eel/eel-debug.h>
@@ -105,7 +107,7 @@
 	char *id;
 } ActivateViewData;
 
-static void cancel_view_as_callback         (NautilusWindow          *window);
+static void cancel_view_as_callback         (NautilusWindowSlot      *slot);
 static void nautilus_window_info_iface_init (NautilusWindowInfoIface *iface);
 static void action_view_as_callback         (GtkAction               *action,
 					     ActivateViewData        *data);
@@ -188,8 +190,6 @@
 
 	/* Keep the main event loop alive as long as the window exists */
 	nautilus_main_event_loop_register (GTK_OBJECT (window));
-
-	nautilus_window_allow_stop (window, FALSE);
 }
 
 /* Unconditionally synchronize the GtkUIManager of WINDOW. */
@@ -201,8 +201,9 @@
 	gtk_ui_manager_ensure_update (window->details->ui_manager);
 }
 
-void
-nautilus_window_set_status (NautilusWindow *window, const char *text)
+static void
+nautilus_window_push_status (NautilusWindow *window,
+			     const char *text)
 {
 	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
 
@@ -215,50 +216,73 @@
 }
 
 void
+nautilus_window_sync_status (NautilusWindow *window)
+{
+	NautilusWindowSlot *slot;
+
+	slot = window->details->active_slot;
+	nautilus_window_push_status (window, slot->status_text);
+}
+
+void
 nautilus_window_go_to (NautilusWindow *window, GFile *location)
 {
 	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
 
-	nautilus_window_open_location (window, location, FALSE);
+	nautilus_window_slot_go_to (window->details->active_slot, location, FALSE);
 }
 
-
 void
 nautilus_window_go_to_with_selection (NautilusWindow *window, GFile *location, GList *new_selection)
 {
 	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
 
-	nautilus_window_open_location_with_selection (window, location, new_selection, FALSE);
+	nautilus_window_slot_go_to_with_selection (window->details->active_slot, location, new_selection);
 }
 
 static gboolean
 nautilus_window_go_up_signal (NautilusWindow *window, gboolean close_behind)
 {
-	nautilus_window_go_up (window, close_behind);
+	nautilus_window_go_up (window, close_behind, FALSE);
 	return TRUE;
 }
 
 void
-nautilus_window_go_up (NautilusWindow *window, gboolean close_behind)
+nautilus_window_go_up (NautilusWindow *window, gboolean close_behind, gboolean new_tab)
 {
+	NautilusWindowSlot *slot;
 	GFile *parent;
 	GList *selection;
+	NautilusWindowOpenFlags flags;
 
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	slot = window->details->active_slot;
 
-	if (window->details->location == NULL) {
+	if (slot->location == NULL) {
 		return;
 	}
 	
-	parent = g_file_get_parent (window->details->location);
+	parent = g_file_get_parent (slot->location);
 
 	if (parent == NULL) {
 		return;
 	}
 	
-	selection = g_list_prepend (NULL, g_object_ref (window->details->location));
+	selection = g_list_prepend (NULL, g_object_ref (slot->location));
 	
-	nautilus_window_open_location_with_selection (window, parent, selection, close_behind);
+	flags = 0;
+	if (close_behind) {
+		flags |= NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND;
+	}
+	if (new_tab) {
+		flags |= NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB;
+	}
+
+	nautilus_window_slot_open_location_full (slot, parent, 
+						 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
+						 flags,
+						 selection);
 	
 	g_object_unref (parent);
 	
@@ -293,9 +317,12 @@
 static void
 update_cursor (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GdkCursor *cursor;
 
-	if (window->details->allow_stop) {
+	slot = window->details->active_slot;
+
+	if (slot->allow_stop) {
 		cursor = gdk_cursor_new (GDK_WATCH);
 		gdk_window_set_cursor (GTK_WIDGET (window)->window, cursor);
 		gdk_cursor_unref (cursor);
@@ -305,26 +332,31 @@
 }
 
 void
-nautilus_window_allow_stop (NautilusWindow *window, gboolean allow)
+nautilus_window_sync_allow_stop (NautilusWindow *window,
+				 NautilusWindowSlot *slot)
 {
 	GtkAction *action;
-	
-        g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+	gboolean allow_stop;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
 
 	action = gtk_action_group_get_action (window->details->main_action_group,
 					      NAUTILUS_ACTION_STOP);
-	gtk_action_set_sensitive (action, allow);
+	allow_stop = gtk_action_get_sensitive (action);
 
-	if (window->details->allow_stop != allow) {
-		window->details->allow_stop = allow;
+	if (slot != window->details->active_slot ||
+	    allow_stop != slot->allow_stop) {
+		if (slot == window->details->active_slot) {
+			gtk_action_set_sensitive (action, slot->allow_stop);
+		}
 
 		if (GTK_WIDGET_REALIZED (GTK_WIDGET (window))) {
 			update_cursor (window);
 		}
+
+		EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
+				 sync_allow_stop, (window, slot));
 	}
-	
-	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
-			 set_throbber_active, (window, allow));
 }
 
 void
@@ -342,13 +374,9 @@
 void
 nautilus_window_go_home (NautilusWindow *window)
 {
-	GFile *home;
-
 	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
 
-	home = g_file_new_for_path (g_get_home_dir ());
-	nautilus_window_open_location (window, home, FALSE);
-	g_object_unref (home);
+	nautilus_window_slot_go_home (window->details->active_slot, FALSE);
 }
 
 void
@@ -361,49 +389,40 @@
                          prompt_for_location, (window, initial));
 }
 
-char *
+static char *
 nautilus_window_get_location_uri (NautilusWindow *window)
 {
-	g_return_val_if_fail (NAUTILUS_IS_WINDOW (window), NULL);
+	NautilusWindowSlot *slot;
 
-	if (window->details->location) {
-		return g_file_get_uri (window->details->location);
-	}
-	return NULL;
-}
+	g_assert (NAUTILUS_IS_WINDOW (window));
 
-GFile *
-nautilus_window_get_location (NautilusWindow *window)
-{
-	g_return_val_if_fail (NAUTILUS_IS_WINDOW (window), NULL);
+	slot = window->details->active_slot;
 
-	if (window->details->location != NULL) {
-		return g_object_ref (window->details->location);
+	if (slot->location) {
+		return g_file_get_uri (slot->location);
 	}
 	return NULL;
 }
 
 void
-nautilus_window_set_search_mode (NautilusWindow *window,
-				 gboolean search_mode,
-				 NautilusSearchDirectory *search_directory)
+nautilus_window_sync_search_widgets (NautilusWindow *window)
 {
 	g_assert (NAUTILUS_IS_WINDOW (window));
 
-	window->details->search_mode = search_mode;
-
 	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
-			 set_search_mode, (window, search_mode, search_directory));
+			 sync_search_widgets, (window));
 }
 
-
 void
 nautilus_window_zoom_in (NautilusWindow *window)
 {
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+	NautilusWindowSlot *slot;
+
+	g_assert (window != NULL);
 
-	if (window->content_view != NULL) {
-		nautilus_view_bump_zoom_level (window->content_view, 1);
+	slot = window->details->active_slot;
+	if (slot->content_view != NULL) {
+		nautilus_view_bump_zoom_level (slot->content_view, 1);
 	}
 }
 
@@ -411,28 +430,39 @@
 nautilus_window_zoom_to_level (NautilusWindow *window,
 			       NautilusZoomLevel level)
 {
-	if (window->content_view != NULL) {
-		nautilus_view_zoom_to_level (window->content_view, level);
+	NautilusWindowSlot *slot;
+
+	g_assert (window != NULL);
+
+	slot = window->details->active_slot;
+	if (slot->content_view != NULL) {
+		nautilus_view_zoom_to_level (slot->content_view, level);
 	}
 }
 
 void
 nautilus_window_zoom_out (NautilusWindow *window)
 {
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+	NautilusWindowSlot *slot;
+
+	g_assert (window != NULL);
 
-	if (window->content_view != NULL) {
-		nautilus_view_bump_zoom_level (window->content_view, -1);
+	slot = window->details->active_slot;
+	if (slot->content_view != NULL) {
+		nautilus_view_bump_zoom_level (slot->content_view, -1);
 	}
 }
 
 void
 nautilus_window_zoom_to_default (NautilusWindow *window)
 {
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+	NautilusWindowSlot *slot;
+
+	g_assert (window != NULL);
 
-	if (window->content_view != NULL) {
-		nautilus_view_restore_default_zoom_level (window->content_view);
+	slot = window->details->active_slot;
+	if (slot->content_view != NULL) {
+		nautilus_view_restore_default_zoom_level (slot->content_view);
 	}
 }
 
@@ -564,25 +594,22 @@
 nautilus_window_destroy (GtkObject *object)
 {
 	NautilusWindow *window;
-	GtkWidget *widget;
+	NautilusWindowSlot *slot;
+	GList *l, *slots;
 
 	window = NAUTILUS_WINDOW (object);
 
-	cancel_view_as_callback (window);
-	
-	nautilus_window_manage_views_destroy (window);
+	nautilus_window_set_active_slot (window, NULL);
 
-	if (window->content_view) {
-		g_object_unref (window->content_view);
-		window->content_view = NULL;
+	/* close all slots */
+	slots = g_list_copy (window->details->slots);
+	for (l = slots; l != NULL; l = l->next) {
+		slot = NAUTILUS_WINDOW_SLOT (l->data);
+		nautilus_window_close_slot (window, slot);
 	}
+	g_list_free (slots);
 
-	if (window->new_content_view) {
-		widget = nautilus_view_get_widget (window->new_content_view);
-		gtk_widget_destroy (widget);
-		g_object_unref (window->new_content_view);
-		window->new_content_view = NULL;
-	}
+	nautilus_window_manage_views_destroy (window);
 
 	GTK_OBJECT_CLASS (nautilus_window_parent_class)->destroy (object);
 }
@@ -591,44 +618,18 @@
 nautilus_window_finalize (GObject *object)
 {
 	NautilusWindow *window;
-	
+
 	window = NAUTILUS_WINDOW (object);
 
 	nautilus_window_remove_bookmarks_menu_callback (window);
-	
-	nautilus_window_manage_views_finalize (window);
-
-	nautilus_window_set_viewed_file (window, NULL);
-
-	nautilus_file_unref (window->details->viewed_file);
 
 	free_stored_viewers (window);
 
-	if (window->details->location) {
-		g_object_ref (window->details->location);
-	}
-	eel_g_list_free_deep (window->details->pending_selection);
-
-	if (window->current_location_bookmark != NULL) {
-		g_object_unref (window->current_location_bookmark);
-	}
-	if (window->last_location_bookmark != NULL) {
-		g_object_unref (window->last_location_bookmark);
-	}
+	/* nautilus_window_close() should have run */
+	g_assert (window->details->slots == NULL);
 
 	g_object_unref (window->details->ui_manager);
 
-	if (window->details->location_change_at_idle_id != 0) {
-		g_source_remove (window->details->location_change_at_idle_id);
-	}
-
-	g_free (window->details->title);
-
-	if (window->details->find_mount_cancellable != NULL) {
-		g_cancellable_cancel (window->details->find_mount_cancellable);
-		window->details->find_mount_cancellable = NULL;
-	}
-
 	G_OBJECT_CLASS (nautilus_window_parent_class)->finalize (object);
 }
 
@@ -639,6 +640,7 @@
 {
 	GObject *object;
 	NautilusWindow *window;
+	NautilusWindowSlot *slot;
 
 	object = (* G_OBJECT_CLASS (nautilus_window_parent_class)->constructor) (type,
 										 n_construct_properties,
@@ -646,6 +648,9 @@
 
 	window = NAUTILUS_WINDOW (object);
 
+	slot = nautilus_window_open_slot (window, 0);
+	nautilus_window_set_active_slot (window, slot);
+
 	nautilus_window_initialize_menus_constructed (window);
 
 	return object;
@@ -654,19 +659,28 @@
 void
 nautilus_window_show_window (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
+	GList *l;
+
 	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
 
 	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
 			 show_window, (window));
 
-	nautilus_window_update_title (window);
-	nautilus_window_update_icon (window);
+	for (l = window->details->slots; l != NULL; l = l->next) {
+		slot = l->data;
+
+		nautilus_window_slot_update_title (slot);
+		nautilus_window_slot_update_icon (slot);
+	}
 
 	gtk_widget_show (GTK_WIDGET (window));
 
-	if (window->details->viewed_file) {
+	slot = window->details->active_slot;
+
+	if (slot->viewed_file) {
 		if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
-			nautilus_file_set_has_open_window (window->details->viewed_file, TRUE);
+			nautilus_file_set_has_open_window (slot->viewed_file, TRUE);
 		}
 	}
 }
@@ -682,6 +696,153 @@
 	gtk_widget_destroy (GTK_WIDGET (window));
 }
 
+NautilusWindowSlot *
+nautilus_window_open_slot (NautilusWindow *window,
+			   NautilusWindowOpenSlotFlags flags)
+{
+	NautilusWindowSlot *slot;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	slot = EEL_CALL_METHOD_WITH_RETURN_VALUE (NAUTILUS_WINDOW_CLASS, window,
+						  open_slot, (window, flags));
+
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+	g_assert (window == slot->window);
+
+	window->details->slots = g_list_append (window->details->slots, slot);
+
+	return slot;
+}
+
+static void
+real_close_slot (NautilusWindow *window,
+		 NautilusWindowSlot *slot)
+{
+	nautilus_window_manage_views_close_slot (window, slot);
+	cancel_view_as_callback (slot);
+	g_object_unref (slot);
+}
+
+void
+nautilus_window_close_slot (NautilusWindow *window,
+			    NautilusWindowSlot *slot)
+{
+	g_assert (NAUTILUS_IS_WINDOW (window));
+	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
+	g_assert (window == slot->window);
+	g_assert (g_list_find (window->details->slots, slot) != NULL);
+
+	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
+			 close_slot, (window, slot));
+
+	window->details->slots = g_list_remove (window->details->slots, slot);
+}
+
+void
+nautilus_window_set_active_slot (NautilusWindow *window,
+				 NautilusWindowSlot *new_slot)
+{
+	NautilusWindowSlot *old_slot;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	if (new_slot != NULL) {
+		g_assert (NAUTILUS_IS_WINDOW_SLOT (new_slot));
+		g_assert (window == new_slot->window);
+		g_assert (g_list_find (window->details->slots, new_slot) != NULL);
+	}
+
+	old_slot = window->details->active_slot;
+
+	if (old_slot == new_slot) {
+		return;
+	}
+
+	if (old_slot != NULL) {
+		/* inform window */
+		if (old_slot->content_view != NULL) {
+			nautilus_window_disconnect_content_view (window, old_slot->content_view);
+		}
+
+		/* inform slot & view */
+		g_signal_emit_by_name (old_slot, "inactive");
+	}
+
+	window->details->active_slot = new_slot;
+
+
+	if (new_slot != NULL) {
+		window->details->active_slots = g_list_remove (window->details->active_slots, new_slot);
+		window->details->active_slots = g_list_prepend (window->details->active_slots, new_slot);
+
+		/* inform sidebar panels */
+		nautilus_window_report_location_change (window);
+		/* TODO decide whether "selection-changed" should be emitted */
+
+		if (new_slot->content_view != NULL) {
+			/* inform window */
+			nautilus_window_connect_content_view (window, new_slot->content_view);
+		}
+
+		/* inform slot & view */
+		g_signal_emit_by_name (new_slot, "active");
+	}
+}
+
+static inline NautilusWindowSlot *
+get_last_active_slot (NautilusWindow *window)
+{
+	if (window->details->active_slots != NULL) {
+		return NAUTILUS_WINDOW_SLOT (window->details->active_slots->data);
+	}
+
+	return NULL;
+}
+
+static inline NautilusWindowSlot *
+get_first_inactive_slot (NautilusWindow *window)
+{
+	GList *l;
+	NautilusWindowSlot *slot;
+
+	for (l = window->details->slots; l != NULL; l = l->next) {
+		slot = NAUTILUS_WINDOW_SLOT (l->data);
+		if (slot != window->details->active_slot) {
+			return slot;
+		}
+	}
+
+	return NULL;
+}
+
+void
+nautilus_window_slot_close (NautilusWindowSlot *slot)
+{
+	NautilusWindow *window;
+	NautilusWindowSlot *next_slot;
+
+	window = slot->window;
+	if (window != NULL) {
+		window->details->active_slots = g_list_remove (window->details->active_slots, slot);
+
+		if (window->details->active_slot == slot) {
+			next_slot = get_last_active_slot (window);
+			if (next_slot == NULL) {
+				next_slot = get_first_inactive_slot (window);
+			}
+
+			nautilus_window_set_active_slot (window, next_slot);
+		}
+
+		nautilus_window_close_slot (window, slot);
+
+		if (g_list_length (window->details->slots) == 0) {
+			nautilus_window_close (window);
+		}
+	}
+}
+
 static void
 nautilus_window_size_request (GtkWidget		*widget,
 			      GtkRequisition	*requisition)
@@ -784,9 +945,15 @@
 action_view_as_callback (GtkAction *action,
 			 ActivateViewData *data)
 {
+	NautilusWindow *window;
+	NautilusWindowSlot *slot;
+
+	window = data->window;
+
 	if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
-		nautilus_window_set_content_view (data->window, 
-						  data->id);
+		slot = window->details->active_slot;
+		nautilus_window_slot_set_content_view (slot,
+						       data->id);
 	}
 }
 
@@ -914,9 +1081,12 @@
 static void
 replace_extra_viewer_in_view_as_menus (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	const char *id;
 
-	id = nautilus_window_get_content_view_id (window);
+	slot = window->details->active_slot;
+
+	id = nautilus_window_slot_get_content_view_id (slot);
 	update_extra_viewer_in_view_as_menus (window, id);
 }
 
@@ -932,6 +1102,7 @@
 static void
 nautilus_window_synch_view_as_menus (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	int index;
 	char action_name[32];
 	GList *node;
@@ -939,13 +1110,15 @@
 
 	g_assert (NAUTILUS_IS_WINDOW (window));
 
-	if (window->content_view == NULL) {
+	slot = window->details->active_slot;
+
+	if (slot->content_view == NULL) {
 		return;
 	}
 	for (node = window->details->short_list_viewers, index = 1;
 	     node != NULL;
 	     node = node->next, ++index) {
-		if (nautilus_window_content_view_matches_iid (window, (char *)node->data)) {
+		if (nautilus_window_slot_content_view_matches_iid (slot, (char *)node->data)) {
 			break;
 		}
 	}
@@ -979,13 +1152,16 @@
 static void
 refresh_stored_viewers (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GList *viewers;
 	char *uri, *mimetype;
 
-	uri = nautilus_file_get_uri (window->details->viewed_file);
-	mimetype = nautilus_file_get_mime_type (window->details->viewed_file);
+	slot = window->details->active_slot;
+
+	uri = nautilus_file_get_uri (slot->viewed_file);
+	mimetype = nautilus_file_get_mime_type (slot->viewed_file);
 	viewers = nautilus_view_factory_get_views_for_uri (uri,
-							   nautilus_file_get_file_type (window->details->viewed_file),
+							   nautilus_file_get_file_type (slot->viewed_file),
 							   mimetype);
 	g_free (uri);
 	g_free (mimetype);
@@ -997,9 +1173,12 @@
 static void
 real_load_view_as_menu (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	GList *node;
 	int index;
 	guint merge_id;
+
+	slot = window->details->active_slot;
 	
 	if (window->details->short_list_merge_id != 0) {
 		gtk_ui_manager_remove_ui (window->details->ui_manager,
@@ -1018,8 +1197,6 @@
 		window->details->view_as_action_group = NULL;
 	}
 
-	g_free (window->details->extra_viewer);
-	window->details->extra_viewer = NULL;
 	
 	refresh_stored_viewers (window);
 
@@ -1054,35 +1231,43 @@
 			    gpointer callback_data)
 {
 	NautilusWindow *window;
-	
-	window = NAUTILUS_WINDOW (callback_data);
-	
-	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
-                         load_view_as_menu, (window));
+	NautilusWindowSlot *slot;
+
+	slot = callback_data;
+	window = NAUTILUS_WINDOW (slot->window);
+
+	if (slot == window->details->active_slot) {
+		/* slot may have changed in the meantime */
+		EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
+				 load_view_as_menu, (window));
+	}
 }
 
 static void
-cancel_view_as_callback (NautilusWindow *window)
+cancel_view_as_callback (NautilusWindowSlot *slot)
 {
-	nautilus_file_cancel_call_when_ready (window->details->viewed_file, 
+	nautilus_file_cancel_call_when_ready (slot->viewed_file, 
 					      load_view_as_menus_callback,
-					      window);
+					      slot);
 }
 
 void
 nautilus_window_load_view_as_menus (NautilusWindow *window)
 {
+	NautilusWindowSlot *slot;
 	NautilusFileAttributes attributes;
 
         g_return_if_fail (NAUTILUS_IS_WINDOW (window));
 
 	attributes = nautilus_mime_actions_get_required_file_attributes ();
 
-	cancel_view_as_callback (window);
-	nautilus_file_call_when_ready (window->details->viewed_file,
+	slot = window->details->active_slot;
+
+	cancel_view_as_callback (slot);
+	nautilus_file_call_when_ready (slot->viewed_file,
 				       attributes, 
 				       load_view_as_menus_callback,
-				       window);
+				       slot);
 }
 
 void
@@ -1100,187 +1285,83 @@
 static char *
 real_get_title (NautilusWindow *window)
 {
-	char *title;
-
-	title = NULL;
-	
-	if (window->new_content_view != NULL) {
-                title = nautilus_view_get_title (window->new_content_view);
-        } else if (window->content_view != NULL) {
-                title = nautilus_view_get_title (window->content_view);
-        }
-        
-	if (title == NULL) {
-                title = nautilus_compute_title_for_location (window->details->location);
-        }
+	g_assert (NAUTILUS_IS_WINDOW (window));
 
-	return title;
+	return nautilus_window_slot_get_title (window->details->active_slot);
 }
 
-static char *
-nautilus_window_get_cached_title (NautilusWindow *window)
-{
-	return g_strdup (window->details->title);
-}
-
-static char *
-nautilus_window_get_title (NautilusWindow *window)
-{
-	return EEL_CALL_METHOD_WITH_RETURN_VALUE (NAUTILUS_WINDOW_CLASS, window,
-						  get_title, (window));
-}
-
-static gboolean
-real_set_title (NautilusWindow *window,
-		const char *title)
+static void
+real_sync_title (NautilusWindow *window,
+		 NautilusWindowSlot *slot)
 {
-	gboolean changed;
 	char *copy;
 
-	changed = FALSE;
-
-	if (eel_strcmp (title, window->details->title) != 0) {
-		changed = TRUE;
-
-		g_free (window->details->title);
-		window->details->title = g_strdup (title);
-	}
-
-        if (eel_strlen (window->details->title) > 0 && window->current_location_bookmark &&
-            nautilus_bookmark_set_name (window->current_location_bookmark, window->details->title)) {
-		changed = TRUE;
-
-                /* Name of item in history list changed, tell listeners. */
-                nautilus_send_history_list_changed ();
-        }
-
-	if (changed) {
-		copy = g_strdup (window->details->title);
+	if (slot == window->details->active_slot) {
+		copy = g_strdup (slot->title);
 		g_signal_emit_by_name (window, "title_changed",
-				       copy);
+				       slot->title);
 		g_free (copy);
 	}
-
-	return changed;
-}
-
-/* Sets window->details->title, and the actual GtkWindow title which
- * might look a bit different (e.g. with "file browser:" added) */
-static void
-nautilus_window_set_title (NautilusWindow *window, 
-			   const char *title)
-{
-	g_assert (NAUTILUS_IS_WINDOW (window));
-
-	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
-                         set_title, (window, title));
-
 }
 
-/* update_title:
- * 
- * Re-calculate the window title.
- * Called when the location or view has changed.
- * @window: The NautilusWindow in question.
- * 
- */
 void
-nautilus_window_update_title (NautilusWindow *window)
+nautilus_window_sync_title (NautilusWindow *window,
+			    NautilusWindowSlot *slot)
 {
-	char *title;
-
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
-	
-	title = nautilus_window_get_title (window);
-	nautilus_window_set_title (window, title);
-	
-	g_free (title);
+	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
+			 sync_title, (window, slot));
 }
 
-/* nautilus_window_update_icon:
- * 
- * Re-calculate the window icon
- * Called when the location or view or icon set has changed.
- * @window: The NautilusWindow in question.
- * 
- */
-void
-nautilus_window_update_icon (NautilusWindow *window)
+static void
+real_connect_content_view (NautilusWindow *window,
+			   NautilusView *view)
 {
-	NautilusIconInfo *info;
-	const char *icon_name;
-	GdkPixbuf *pixbuf;
-
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+	NautilusWindowSlot *slot;
 
-	info = EEL_CALL_METHOD_WITH_RETURN_VALUE (NAUTILUS_WINDOW_CLASS, window,
-						 get_icon, (window));
+	slot = window->details->active_slot;
 
-	icon_name = NULL;
-	if (info) {
-		icon_name = nautilus_icon_info_get_used_name (info);
-		if (icon_name != NULL) {
-			gtk_window_set_icon_name (GTK_WINDOW (window), icon_name);
-		} else {
-			pixbuf = nautilus_icon_info_get_pixbuf_nodefault (info);
-			
-			if (pixbuf) {
-				gtk_window_set_icon (GTK_WINDOW (window), pixbuf);
-				g_object_unref (pixbuf);
-			} 
-		}
-		
-		g_object_unref (info);
+      /* Update displayed view in menu. Only do this if we're not switching
+       * locations though, because if we are switching locations we'll
+       * install a whole new set of views in the menu later (the current
+       * views in the menu are for the old location).
+       */
+	if (slot->pending_location == NULL) {
+		nautilus_window_load_view_as_menus (window);
 	}
-}
 
+	nautilus_view_grab_focus (view);
+}
 
 static void
-real_set_content_view_widget (NautilusWindow *window,
-			      NautilusView *new_view)
+real_disconnect_content_view (NautilusWindow *window,
+			      NautilusView *view)
 {
-	GtkWidget *widget;
-	
 	g_assert (NAUTILUS_IS_WINDOW (window));
-	g_assert (new_view == NULL || NAUTILUS_IS_VIEW (new_view));
-	
-	if (new_view == window->content_view) {
-		return;
-	}
-	
-	if (window->content_view != NULL) {
-		widget = nautilus_view_get_widget (window->content_view);
-		gtk_widget_destroy (widget);
-		g_object_unref (window->content_view);
-		window->content_view = NULL;
-	}
+	g_assert (NAUTILUS_IS_VIEW (view));
 
-	if (new_view != NULL) {
-		widget = nautilus_view_get_widget (new_view);
-		gtk_widget_show (widget);
-	}
+	/* nothing to do... */
+}
 
-	window->content_view = new_view;
-	g_object_ref (window->content_view);
+void
+nautilus_window_connect_content_view (NautilusWindow *window,
+				      NautilusView *view)
+{
+	g_assert (NAUTILUS_IS_WINDOW (window));
+	g_assert (NAUTILUS_IS_VIEW (view));
 
-        /* Update displayed view in menu. Only do this if we're not switching
-         * locations though, because if we are switching locations we'll
-         * install a whole new set of views in the menu later (the current
-         * views in the menu are for the old location).
-         */
-	if (window->details->pending_location == NULL) {
-		nautilus_window_synch_view_as_menus (window);
-	}
+	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
+			 connect_content_view, (window, view));
 }
 
 void
-nautilus_window_set_content_view_widget (NautilusWindow *window,
-					 NautilusView *frame)
+nautilus_window_disconnect_content_view (NautilusWindow *window,
+					 NautilusView *view)
 {
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
-	
+	g_assert (NAUTILUS_IS_WINDOW (window));
+	g_assert (NAUTILUS_IS_VIEW (view));
+
 	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
-                         set_content_view_widget, (window, frame));
+			 disconnect_content_view, (window, view));
 }
 
 /**
@@ -1311,37 +1392,40 @@
 }
 
 void
-nautilus_window_set_viewed_file (NautilusWindow *window,
-				 NautilusFile *file)
+nautilus_window_slot_set_viewed_file (NautilusWindowSlot *slot,
+				      NautilusFile *file)
 {
+	NautilusWindow *window;
 	NautilusFileAttributes attributes;
 
-	if (window->details->viewed_file == file) {
+	window = slot->window;
+
+	if (slot->viewed_file == file) {
 		return;
 	}
 
 	nautilus_file_ref (file);
 
-	cancel_view_as_callback (window);
+	cancel_view_as_callback (slot);
 
-	if (window->details->viewed_file != NULL) {
+	if (slot->viewed_file != NULL) {
 		if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
-			nautilus_file_set_has_open_window (window->details->viewed_file,
+			nautilus_file_set_has_open_window (slot->viewed_file,
 							   FALSE);
 		}
-		nautilus_file_monitor_remove (window->details->viewed_file,
-					      window);
+		nautilus_file_monitor_remove (slot->viewed_file,
+					      slot);
 	}
 
 	if (file != NULL) {
 		attributes =
 			NAUTILUS_FILE_ATTRIBUTE_INFO |
 			NAUTILUS_FILE_ATTRIBUTE_LINK_INFO;
-		nautilus_file_monitor_add (file, window, attributes);
+		nautilus_file_monitor_add (file, slot, attributes);
 	}
 
-	nautilus_file_unref (window->details->viewed_file);
-	window->details->viewed_file = file;
+	nautilus_file_unref (slot->viewed_file);
+	slot->viewed_file = file;
 }
 
 void
@@ -1383,8 +1467,8 @@
 	}
 }
 
-static gboolean
-add_to_history_list (NautilusBookmark *bookmark)
+gboolean
+nautilus_add_bookmark_to_history_list (NautilusBookmark *bookmark)
 {
 	/* Note that the history is shared amongst all windows so
 	 * this is not a NautilusNavigationWindow function. Perhaps it belongs
@@ -1446,35 +1530,54 @@
 	gboolean ret;
 
 	bookmark = nautilus_bookmark_new_with_icon (location, name, has_custom_name, icon);
-	ret = add_to_history_list (bookmark);
+	ret = nautilus_add_bookmark_to_history_list (bookmark);
 	g_object_unref (bookmark);
 
 	return ret;
 }
 
-static void
-real_add_current_location_to_history_list (NautilusWindow *window)
-{
-        g_assert (NAUTILUS_IS_WINDOW (window));
-                
-	if (add_to_history_list (window->current_location_bookmark)) {
-		nautilus_send_history_list_changed ();
+NautilusWindowSlot *
+nautilus_window_get_slot_for_view (NautilusWindow *window,
+				   NautilusView *view)
+{
+	NautilusWindowSlot *slot;
+	GList *l;
+
+	for (l = window->details->slots; l != NULL; l = l->next) {
+		slot = l->data;
+		if (slot->content_view == view ||
+		    slot->new_content_view == view) {
+			return slot;
+		}
 	}
+
+	return NULL;
 }
 
-void
-nautilus_window_add_current_location_to_history_list (NautilusWindow *window)
+NautilusWindowSlot *
+nautilus_window_get_slot_for_content_box (NautilusWindow *window,
+					  GtkWidget *content_box)
 {
-	g_return_if_fail (NAUTILUS_IS_WINDOW (window));
+	NautilusWindowSlot *slot;
+	GList *l;
 
-	EEL_CALL_METHOD (NAUTILUS_WINDOW_CLASS, window,
-                         add_current_location_to_history_list, (window));
+	for (l = window->details->slots; l != NULL; l = l->next) {
+		slot = NAUTILUS_WINDOW_SLOT (l->data);
+
+		if (slot->content_box == content_box) {
+			return slot;
+		}
+	}
+
+	return NULL;
 }
 
 void
 nautilus_forget_history (void) 
 {
-	GList *window_node;
+	NautilusWindowSlot *slot;
+	NautilusNavigationWindowSlot *navigation_slot;
+	GList *window_node, *l;
 
 	/* Clear out each window's back & forward lists. Also, remove 
 	 * each window's current location bookmark from history list 
@@ -1488,15 +1591,26 @@
 			NautilusNavigationWindow *window;
 			
 			window = NAUTILUS_NAVIGATION_WINDOW (window_node->data);
-			
-			nautilus_navigation_window_clear_back_list (window);
-			nautilus_navigation_window_clear_forward_list (window);
-			
+
+			for (l = NAUTILUS_WINDOW (window_node->data)->details->slots;
+			     l != NULL; l = l->next) {
+				navigation_slot = l->data;
+
+				nautilus_navigation_window_slot_clear_back_list (navigation_slot);
+				nautilus_navigation_window_slot_clear_forward_list (navigation_slot);
+			}
+
 			nautilus_navigation_window_allow_back (window, FALSE);
 			nautilus_navigation_window_allow_forward (window, FALSE);
 		}
+
+		for (l = NAUTILUS_WINDOW (window_node->data)->details->slots;
+		     l != NULL; l = l->next) {
+			slot = l->data;
+			history_list = g_list_remove (history_list,
+						      slot->current_location_bookmark);
+		}
 			
-		history_list = g_list_remove (history_list, NAUTILUS_WINDOW (window_node->data)->current_location_bookmark);
 	}
 
 	/* Clobber history list. */
@@ -1507,9 +1621,14 @@
 	     window_node != NULL;
 	     window_node = window_node->next) {
 		NautilusWindow *window;
-		
+		NautilusWindowSlot *slot;
+		GList *l;
+
 		window = NAUTILUS_WINDOW (window_node->data);
-		nautilus_window_add_current_location_to_history_list (NAUTILUS_WINDOW (window));
+		for (l = window->details->slots; l != NULL; l = l->next) {
+			slot = NAUTILUS_WINDOW_SLOT (l->data);
+			nautilus_window_slot_add_current_location_to_history_list (slot);
+		}
 	}
 }
 
@@ -1537,23 +1656,36 @@
 static int
 nautilus_window_get_selection_count (NautilusWindow *window)
 {
-	if (window->content_view != NULL) {
-		return nautilus_view_get_selection_count (window->content_view);
+	NautilusWindowSlot *slot;
+ 
+	g_assert (NAUTILUS_IS_WINDOW (window));
+ 
+	slot = window->details->active_slot;
+ 
+	if (slot->content_view != NULL) {
+		return nautilus_view_get_selection_count (slot->content_view);
 	}
+
 	return 0;
 }
 
 static GList *
 nautilus_window_get_selection (NautilusWindow *window)
 {
-	if (window->content_view != NULL) {
-		return nautilus_view_get_selection (window->content_view);
+	NautilusWindowSlot *slot;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	slot = window->details->active_slot;
+
+	if (slot->content_view != NULL) {
+		return nautilus_view_get_selection (slot->content_view);
 	}
 	return NULL;
 }
 
 static NautilusWindowShowHiddenFilesMode
-nautilus_window_get_hidden_files_mode (NautilusWindow *window)
+nautilus_window_get_hidden_files_mode (NautilusWindowInfo *window)
 {
 	return window->details->show_hidden_files_mode;
 }
@@ -1564,16 +1696,43 @@
 {
 	window->details->show_hidden_files_mode = mode;
 
-	g_signal_emit_by_name (window, "hidden_files_mode_changed",
-			       mode);
+	g_signal_emit_by_name (window, "hidden_files_mode_changed");
 }
 
 static NautilusBookmarkList *
-nautilus_window_get_bookmark_list (NautilusWindow *window)
+nautilus_window_get_bookmark_list (NautilusWindowInfo *window)
 {
   return nautilus_get_bookmark_list ();
 }
 
+static char *
+nautilus_window_get_cached_title (NautilusWindow *window)
+{
+	NautilusWindowSlot *slot;
+
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	slot = window->details->active_slot;
+
+	return g_strdup (slot->title);
+}
+
+NautilusWindowSlot *
+nautilus_window_get_active_slot (NautilusWindow *window)
+{
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	return window->details->active_slot;
+}
+
+GList *
+nautilus_window_get_slots (NautilusWindow *window)
+{
+	g_assert (NAUTILUS_IS_WINDOW (window));
+
+	return g_list_copy (window->details->slots);
+}
+
 static void
 nautilus_window_info_iface_init (NautilusWindowInfoIface *iface)
 {
@@ -1581,10 +1740,9 @@
 	iface->report_load_complete = nautilus_window_report_load_complete;
 	iface->report_selection_changed = nautilus_window_report_selection_changed;
 	iface->report_view_failed = nautilus_window_report_view_failed;
-	iface->open_location = nautilus_window_open_location_full;
 	iface->show_window = nautilus_window_show_window;
 	iface->close_window = nautilus_window_close;
-	iface->set_status = nautilus_window_set_status;
+	iface->push_status = nautilus_window_push_status;
 	iface->get_window_type = nautilus_window_get_window_type;
 	iface->get_title = nautilus_window_get_cached_title;
 	iface->get_history = nautilus_window_get_history;
@@ -1595,6 +1753,7 @@
 	iface->get_selection = nautilus_window_get_selection;
 	iface->get_hidden_files_mode = nautilus_window_get_hidden_files_mode;
 	iface->set_hidden_files_mode = nautilus_window_set_hidden_files_mode;
+	iface->get_active_slot = nautilus_window_get_active_slot;
 }
 
 static void
@@ -1611,12 +1770,13 @@
 	GTK_WIDGET_CLASS (class)->size_request = nautilus_window_size_request;
 	GTK_WIDGET_CLASS (class)->realize = nautilus_window_realize;
 	GTK_WIDGET_CLASS (class)->key_press_event = nautilus_window_key_press_event;
-	class->add_current_location_to_history_list = real_add_current_location_to_history_list;
 	class->get_title = real_get_title;
-	class->set_title = real_set_title;
-	class->set_content_view_widget = real_set_content_view_widget;
+	class->sync_title = real_sync_title;
+	class->connect_content_view = real_connect_content_view;
+	class->disconnect_content_view = real_disconnect_content_view;
 	class->load_view_as_menu = real_load_view_as_menu;
 	class->set_allow_up = real_set_allow_up;
+	class->close_slot = real_close_slot;
 
 	g_object_class_install_property (G_OBJECT_CLASS (class),
 					 ARG_APP,

Modified: trunk/src/nautilus-window.h
==============================================================================
--- trunk/src/nautilus-window.h	(original)
+++ trunk/src/nautilus-window.h	Tue Jul  8 21:05:55 2008
@@ -50,6 +50,16 @@
 typedef struct NautilusWindow NautilusWindow;
 #endif
 
+#ifndef NAUTILUS_WINDOW_SLOT_DEFINED
+#define NAUTILUS_WINDOW_SLOT_DEFINED
+typedef struct NautilusWindowSlot NautilusWindowSlot;
+#endif
+
+typedef struct NautilusWindowSlotClass NautilusWindowSlotClass;
+typedef enum NautilusWindowOpenSlotFlags NautilusWindowOpenSlotFlags;
+
+GType          nautilus_window_slot_get_type (void);
+
 typedef struct {
         GtkWindowClass parent_spot;
 
@@ -58,30 +68,40 @@
 
 	/* Function pointers for overriding, without corresponding signals */
 
-	/* add_current_location_to_history_list is a function pointer that
-	 * subclasses may override if they wish to add something other than
-	 * NautilusWindow's idea of the "current location" to the history
-	 * list, or nothing at all.
-	 */
-        void   (* add_current_location_to_history_list) (NautilusWindow *window);
-
         char * (* get_title) (NautilusWindow *window);
-        gboolean (* set_title) (NautilusWindow *window, const char *title);
-        NautilusIconInfo * (* get_icon) (NautilusWindow *window);
+        void   (* sync_title) (NautilusWindow *window,
+			       NautilusWindowSlot *slot);
+        NautilusIconInfo * (* get_icon) (NautilusWindow *window,
+					 NautilusWindowSlot *slot);
 
         void   (* load_view_as_menu) (NautilusWindow *window);
-        void   (* set_content_view_widget) (NautilusWindow *window, 
+
+	/* these are called
+ 	 *   A) when switching the view within the active slot
+ 	 *   B) when switching the active slot
+ 	 */
+        void   (* connect_content_view) (NautilusWindow *window, 
+                                         NautilusView *new_view);
+        void   (* disconnect_content_view) (NautilusWindow *window, 
                                             NautilusView *new_view);
-        void   (* set_throbber_active) (NautilusWindow *window,
-                                        gboolean active);
+
+        void   (* sync_allow_stop) (NautilusWindow *window,
+				    NautilusWindowSlot *slot);
 	void   (* set_allow_up) (NautilusWindow *window, gboolean allow);
 	void   (* reload)              (NautilusWindow *window);
         void   (* prompt_for_location) (NautilusWindow *window, const char *initial);
-        void   (* set_search_mode) (NautilusWindow *window, gboolean search_enabled, NautilusSearchDirectory *search_directory);
+        void   (* sync_search_widgets) (NautilusWindow *window);
         void   (* get_default_size) (NautilusWindow *window, guint *default_width, guint *default_height);
         void   (* show_window)  (NautilusWindow *window);
         void   (* close) (NautilusWindow *window);
 
+        NautilusWindowSlot * (* open_slot) (NautilusWindow *window,
+					    NautilusWindowOpenSlotFlags flags);
+        void                 (* close_slot) (NautilusWindow *window,
+					     NautilusWindowSlot *slot);
+        void                 (* set_active_slot) (NautilusWindow *window,
+						  NautilusWindowSlot *slot);
+
         /* Signals used only for keybindings */
         gboolean (* go_up) (NautilusWindow *window, gboolean close);
 } NautilusWindowClass;
@@ -92,6 +112,11 @@
         NAUTILUS_WINDOW_SHOULD_SHOW
 } NautilusWindowShowState;
 
+enum NautilusWindowOpenSlotFlags {
+	NAUTILUS_WINDOW_OPEN_SLOT_NONE = 0,
+	NAUTILUS_WINDOW_OPEN_SLOT_APPEND = 1
+};
+
 typedef struct NautilusWindowDetails NautilusWindowDetails;
 
 struct NautilusWindow {
@@ -101,40 +126,30 @@
         
         /** CORBA-related elements **/
         NautilusApplication *application;
-        
-        /** State information **/
-        
-        /* Information about current location/selection */        
-        NautilusBookmark *current_location_bookmark;
-        NautilusBookmark *last_location_bookmark;
-
-        /* Current views stuff */
-        NautilusView *content_view;
-        
-        /* Pending changes */
-        NautilusView *new_content_view;
 };
 
 GType            nautilus_window_get_type             (void);
 void             nautilus_window_show_window          (NautilusWindow    *window);
 void             nautilus_window_close                (NautilusWindow    *window);
-char *           nautilus_window_get_location_uri     (NautilusWindow    *window);
-GFile *          nautilus_window_get_location         (NautilusWindow    *window);
+
+void             nautilus_window_connect_content_view (NautilusWindow    *window,
+						       NautilusView      *view);
+void             nautilus_window_disconnect_content_view (NautilusWindow    *window,
+							  NautilusView      *view);
+
 void             nautilus_window_go_to                (NautilusWindow    *window,
-                                                       GFile            *location);
+                                                       GFile             *location);
 void             nautilus_window_go_to_with_selection (NautilusWindow    *window,
                                                        GFile             *location,
                                                        GList             *new_selection);
 void             nautilus_window_go_home              (NautilusWindow    *window);
 void             nautilus_window_go_up                (NautilusWindow    *window,
-                                                       gboolean           close_behind);
+                                                       gboolean           close_behind,
+						       gboolean           new_tab);
 void             nautilus_window_prompt_for_location  (NautilusWindow    *window,
                                                        const char        *initial);
-void		 nautilus_window_set_search_mode      (NautilusWindow    *window,
-                                                       gboolean           search_mode,
-                                                       NautilusSearchDirectory *search_directory);
+void		 nautilus_window_sync_search_widgets  (NautilusWindow    *window);
 void             nautilus_window_launch_cd_burner     (NautilusWindow    *window);
-void             nautilus_window_update_title         (NautilusWindow    *window);
 void             nautilus_window_display_error        (NautilusWindow    *window,
                                                        const char        *error_msg);
 void		 nautilus_window_reload		      (NautilusWindow	 *window);
@@ -148,8 +163,6 @@
 void             nautilus_window_allow_burn_cd        (NautilusWindow    *window,
                                                        gboolean           allow);
 GtkUIManager *   nautilus_window_get_ui_manager       (NautilusWindow    *window);
-void             nautilus_window_add_extra_location_widget (NautilusWindow  *window,
-                                                            GtkWidget       *widget);
 gboolean         nautilus_window_has_menubar_and_statusbar (NautilusWindow *window);
 
 #endif



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