nautilus-window-manage-views.c 65.1 KB
Newer Older
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 3 4 5 6

/*
 *  Nautilus
 *
 *  Copyright (C) 1999, 2000 Red Hat, Inc.
7
 *  Copyright (C) 1999, 2000, 2001 Eazel, Inc.
8
 *
9
 *  Nautilus is free software; you can redistribute it and/or
10 11 12 13
 *  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.
 *
14
 *  Nautilus is distributed in the hope that it will be useful,
15 16 17 18 19
 *  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
20
 *  License along with this program; if not, write to the Free
21 22
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
23 24
 *  Authors: Elliot Lee <sopwith@redhat.com>
 *           John Sullivan <sullivan@eazel.com>
25
 *           Darin Adler <darin@bentspoon.com>
26
 */
27 28

#include <config.h>
29
#include "nautilus-window-manage-views.h"
30

31
#include "nautilus-actions.h"
32 33
#include "nautilus-application.h"
#include "nautilus-location-bar.h"
34
#include "nautilus-search-bar.h"
35
#include "nautilus-pathbar.h"
36
#include "nautilus-main.h"
37
#include "nautilus-window-private.h"
38 39
#include "nautilus-window-slot.h"
#include "nautilus-navigation-window-slot.h"
40
#include "nautilus-trash-bar.h"
41
#include "nautilus-x-content-bar.h"
42
#include "nautilus-zoom-control.h"
43
#include "nautilus-navigation-window-pane.h"
44
#include <eel/eel-accessibility.h>
45 46 47 48
#include <eel/eel-debug.h>
#include <eel/eel-gdk-extensions.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-gtk-extensions.h>
49
#include <eel/eel-gtk-macros.h>
50 51
#include <eel/eel-stock-dialogs.h>
#include <eel/eel-string.h>
52
#include <gtk/gtk.h>
53
#include <gdk/gdkx.h>
54
#include <glib/gi18n.h>
55
#include <libnautilus-extension/nautilus-location-widget-provider.h>
56
#include <libnautilus-private/nautilus-debug-log.h>
57 58 59 60 61 62
#include <libnautilus-private/nautilus-file-attributes.h>
#include <libnautilus-private/nautilus-file-utilities.h>
#include <libnautilus-private/nautilus-file.h>
#include <libnautilus-private/nautilus-global-preferences.h>
#include <libnautilus-private/nautilus-metadata.h>
#include <libnautilus-private/nautilus-mime-actions.h>
63
#include <libnautilus-private/nautilus-module.h>
64
#include <libnautilus-private/nautilus-monitor.h>
65
#include <libnautilus-private/nautilus-search-directory.h>
66 67
#include <libnautilus-private/nautilus-view-factory.h>
#include <libnautilus-private/nautilus-window-info.h>
68
#include <libnautilus-private/nautilus-window-slot-info.h>
69
#include <libnautilus-private/nautilus-autorun.h>
70

71
/* FIXME bugzilla.gnome.org 41243: 
72
 * We should use inheritance instead of these special cases
73 74 75 76
 * for the desktop window.
 */
#include "nautilus-desktop-window.h"

77 78 79 80
/* This number controls a maximum character count for a URL that is
 * displayed as part of a dialog. It's fairly arbitrary -- big enough
 * to allow most "normal" URIs to display in full, but small enough to
 * prevent the dialog from getting insanely wide.
81 82 83
 */
#define MAX_URI_IN_DIALOG_LENGTH 60

84
static void begin_location_change                     (NautilusWindowSlot         *slot,
Alexander Larsson's avatar
Alexander Larsson committed
85
						       GFile                      *location,
86 87 88 89
						       GList                      *new_selection,
						       NautilusLocationChangeType  type,
						       guint                       distance,
						       const char                 *scroll_pos);
90 91 92
static void free_location_change                      (NautilusWindowSlot         *slot);
static void end_location_change                       (NautilusWindowSlot         *slot);
static void cancel_location_change                    (NautilusWindowSlot         *slot);
93 94
static void got_file_info_for_view_selection_callback (NautilusFile               *file,
						       gpointer                    callback_data);
95
static void create_content_view                       (NautilusWindowSlot         *slot,
96 97 98
						       const char                 *view_id);
static void display_view_selection_failure            (NautilusWindow             *window,
						       NautilusFile               *file,
Alexander Larsson's avatar
Alexander Larsson committed
99 100
						       GFile                      *location,
						       GError                     *error);
101
static void load_new_location                         (NautilusWindowSlot         *slot,
Alexander Larsson's avatar
Alexander Larsson committed
102
						       GFile                      *location,
103 104 105
						       GList                      *selection,
						       gboolean                    tell_current_content_view,
						       gboolean                    tell_new_content_view);
106 107
static void location_has_really_changed               (NautilusWindowSlot         *slot);
static void update_for_new_location                   (NautilusWindowSlot         *slot);
108

109
void
110
nautilus_window_report_selection_changed (NautilusWindowInfo *window)
111
{
112 113 114 115
	if (window->details->temporarily_ignore_view_signals) {
		return;
	}

116
	g_signal_emit_by_name (window, "selection_changed");
117 118
}

119
/* set_displayed_location:
120 121
 */
static void
122
set_displayed_location (NautilusWindowSlot *slot, GFile *location)
123
{
124
	NautilusWindow *window;
Alexander Larsson's avatar
Alexander Larsson committed
125
        GFile *bookmark_location;
126
        gboolean recreate;
Alexander Larsson's avatar
Alexander Larsson committed
127
	char *name;
128

129
	window = slot->pane->window;
130
        
131
        if (slot->current_location_bookmark == NULL || location == NULL) {
132 133
                recreate = TRUE;
        } else {
134
                bookmark_location = nautilus_bookmark_get_location (slot->current_location_bookmark);
Alexander Larsson's avatar
Alexander Larsson committed
135 136
                recreate = !g_file_equal (bookmark_location, location);
                g_object_unref (bookmark_location);
137
        }
138
        
139
        if (recreate) {
140
                /* We've changed locations, must recreate bookmark for current location. */
141 142
		if (slot->last_location_bookmark != NULL)  {
			g_object_unref (slot->last_location_bookmark);
143
                }
144
		slot->last_location_bookmark = slot->current_location_bookmark;
145
		name = g_file_get_basename (location);
146
		slot->current_location_bookmark = (location == NULL) ? NULL
147
                        : nautilus_bookmark_new (location, name, FALSE, NULL);
Alexander Larsson's avatar
Alexander Larsson committed
148
		g_free (name);
149 150 151
        }
}

152
static void
Alexander Larsson's avatar
Alexander Larsson committed
153
check_bookmark_location_matches (NautilusBookmark *bookmark, GFile *location)
154
{
Alexander Larsson's avatar
Alexander Larsson committed
155 156
        GFile *bookmark_location;
        char *bookmark_uri, *uri;
157

Alexander Larsson's avatar
Alexander Larsson committed
158 159 160 161
	bookmark_location = nautilus_bookmark_get_location (bookmark);
	if (!g_file_equal (location, bookmark_location)) {
		bookmark_uri = g_file_get_uri (bookmark_location);
		uri = g_file_get_uri (location);
162
		g_warning ("bookmark uri is %s, but expected %s", bookmark_uri, uri);
Alexander Larsson's avatar
Alexander Larsson committed
163 164
		g_free (uri);
		g_free (bookmark_uri);
165
	}
Alexander Larsson's avatar
Alexander Larsson committed
166
	g_object_unref (bookmark_location);
167 168
}

169 170 171 172 173
/* Debugging function used to verify that the last_location_bookmark
 * is in the state we expect when we're about to use it to update the
 * Back or Forward list.
 */
static void
174
check_last_bookmark_location_matches_slot (NautilusWindowSlot *slot)
175
{
176 177
	check_bookmark_location_matches (slot->last_location_bookmark,
					 slot->location);
178 179
}

180
static void
181 182
handle_go_back (NautilusNavigationWindowSlot *navigation_slot,
		GFile *location)
183
{
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
	NautilusWindowSlot *slot;
	guint i;
	GList *link;
	NautilusBookmark *bookmark;

	slot = NAUTILUS_WINDOW_SLOT (navigation_slot);

	/* 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 */
199

200
	check_last_bookmark_location_matches_slot (slot);
201

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
	/* 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);
221 222 223
}

static void
224 225
handle_go_forward (NautilusNavigationWindowSlot *navigation_slot,
		   GFile *location)
226
{
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
	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);
263 264
}

265
static void
266
handle_go_elsewhere (NautilusWindowSlot *slot, GFile *location)
267
{
268
#if !NEW_UI_COMPLETE
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
	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);
			}
		}
	}
292
#endif
293 294
}

295 296
void
nautilus_window_update_up_button (NautilusWindow *window)
297
{
298 299 300 301 302 303 304 305 306 307 308 309
	NautilusWindowSlot *slot;
	gboolean allowed;
	GFile *parent;

	slot = window->details->active_pane->active_slot;

	allowed = FALSE;
	if (slot->location != NULL) {
		parent = g_file_get_parent (slot->location);
		allowed = parent != NULL;
		if (parent != NULL) {
			g_object_unref (parent);
Alexander Larsson's avatar
Alexander Larsson committed
310
		}
311
	}
312

313
	nautilus_window_allow_up (window, allowed);
314 315
}

316
static void
317
viewed_file_changed_callback (NautilusFile *file,
318
                              NautilusWindowSlot *slot)
319
{
320
	NautilusWindow *window;
Alexander Larsson's avatar
Alexander Larsson committed
321
        GFile *new_location;
322
	gboolean is_in_trash, was_in_trash;
323

324
	window = slot->pane->window;
325

326
        g_assert (NAUTILUS_IS_FILE (file));
327
	g_assert (NAUTILUS_IS_WINDOW_PANE (slot->pane));
328
	g_assert (NAUTILUS_IS_WINDOW (window));
329 330

	g_assert (file == slot->viewed_file);
331

332
        if (!nautilus_file_is_not_yet_confirmed (file)) {
333
                slot->viewed_file_seen = TRUE;
334 335
        }

336
	was_in_trash = slot->viewed_file_in_trash;
337

338
	slot->viewed_file_in_trash = is_in_trash = nautilus_file_is_in_trash (file);
339 340 341

	/* 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)) {
342 343
                /* Don't close the window in the case where the
                 * file was never seen in the first place.
344
                 */
345
                if (slot->viewed_file_seen) {
346 347 348 349 350 351 352 353 354 355 356 357 358
                        /* Detecting a file is gone may happen in the
                         * middle of a pending location change, we
                         * need to cancel it before closing the window
                         * or things break.
                         */
                        /* FIXME: It makes no sense that this call is
                         * needed. When the window is destroyed, it
                         * calls nautilus_window_manage_views_destroy,
                         * which calls free_location_change, which
                         * should be sufficient. Also, if this was
                         * really needed, wouldn't it be needed for
                         * all other nautilus_window_close callers?
                         */
359
			end_location_change (slot);
360 361

			if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) {
Alexander Larsson's avatar
Alexander Larsson committed
362 363 364 365 366 367 368 369 370 371 372 373 374
				/* auto-show existing parent. */
				GFile *go_to_file, *parent, *location;

				go_to_file = NULL;
				location =  nautilus_file_get_location (file);
				parent = g_file_get_parent (location);
				g_object_unref (location);
				if (parent) {
					go_to_file = nautilus_find_existing_uri_in_hierarchy (parent);
					g_object_unref (parent);
				}
				
				if (go_to_file != NULL) {
375 376 377
					/* 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 */
378
					if (slot == slot->pane->active_slot) {
379 380 381
						/* multiview-TODO also update NautilusWindowSlot
						 * [which as of writing doesn't save/store any path bar state]
						 */
382
						nautilus_path_bar_clear_buttons (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW_PANE (slot->pane)->path_bar));
383 384 385
					}

					nautilus_window_slot_go_to (slot, go_to_file, FALSE);
Alexander Larsson's avatar
Alexander Larsson committed
386
					g_object_unref (go_to_file);
387
				} else {
388
					nautilus_window_slot_go_home (slot, FALSE);
389 390 391 392
				}
			} else {
				nautilus_window_close (window);
			}
393
                }
394
	} else {
Alexander Larsson's avatar
Alexander Larsson committed
395
                new_location = nautilus_file_get_location (file);
396

397
                /* If the file was renamed, update location and/or
Alexander Larsson's avatar
Alexander Larsson committed
398 399
                 * title. */
                if (!g_file_equal (new_location,
400 401 402
				   slot->location)) {
                        g_object_unref (slot->location);
                        slot->location = new_location;
403
			if (slot == slot->pane->active_slot) {
404
				nautilus_window_pane_sync_location_widgets (slot->pane);
405
			}
406
                } else {
407 408
			/* TODO?
 			 *   why do we update title & icon at all in this case? */
Alexander Larsson's avatar
Alexander Larsson committed
409
                        g_object_unref (new_location);
410
                }
411

412 413
                nautilus_window_slot_update_title (slot);
		nautilus_window_slot_update_icon (slot);
414
        }
415 416
}

417
static void
418
update_history (NautilusWindowSlot *slot,
419
                NautilusLocationChangeType type,
Alexander Larsson's avatar
Alexander Larsson committed
420
                GFile *new_location)
421 422 423
{
        switch (type) {
        case NAUTILUS_LOCATION_CHANGE_STANDARD:
424
        case NAUTILUS_LOCATION_CHANGE_FALLBACK:
425 426
                nautilus_window_slot_add_current_location_to_history_list (slot);
                handle_go_elsewhere (slot, new_location);
427 428 429 430 431
                return;
        case NAUTILUS_LOCATION_CHANGE_RELOAD:
                /* for reload there is no work to do */
                return;
        case NAUTILUS_LOCATION_CHANGE_BACK:
432 433
                nautilus_window_slot_add_current_location_to_history_list (slot);
                handle_go_back (NAUTILUS_NAVIGATION_WINDOW_SLOT (slot), new_location);
434 435
                return;
        case NAUTILUS_LOCATION_CHANGE_FORWARD:
436 437
                nautilus_window_slot_add_current_location_to_history_list (slot);
                handle_go_forward (NAUTILUS_NAVIGATION_WINDOW_SLOT (slot), new_location);
438 439 440 441 442 443 444 445
                return;
        case NAUTILUS_LOCATION_CHANGE_REDIRECT:
                /* for the redirect case, the caller can do the updating */
                return;
        }
	g_return_if_fail (FALSE);
}

446
static void
447
cancel_viewed_file_changed_callback (NautilusWindowSlot *slot)
448
{
449
        NautilusFile *file;
450

451
        file = slot->viewed_file;
452 453 454
        if (file != NULL) {
                g_signal_handlers_disconnect_by_func (G_OBJECT (file),
                                                      G_CALLBACK (viewed_file_changed_callback),
455 456
						      slot);
                nautilus_file_monitor_remove (file, &slot->viewed_file);
457
        }
458
}
459

460 461 462 463 464 465 466 467
static void
new_window_show_callback (GtkWidget *widget,
                          gpointer user_data)
{
        NautilusWindow *window;
        
        window = NAUTILUS_WINDOW (user_data);
        
468
        nautilus_window_close (window);
469 470 471 472 473 474 475

        g_signal_handlers_disconnect_by_func (widget, 
                                              G_CALLBACK (new_window_show_callback),
                                              user_data);
}


476
void
477 478 479 480 481
nautilus_window_slot_open_location_full (NautilusWindowSlot *slot,
					 GFile *location,
					 NautilusWindowOpenMode mode,
					 NautilusWindowOpenFlags flags,
					 GList *new_selection)
482
{
483
	NautilusWindow *window;
484
        NautilusWindow *target_window;
485
        NautilusWindowPane *pane;
486 487
        NautilusWindowSlot *target_slot;
	NautilusWindowOpenFlags slot_flags;
488
        gboolean do_load_location = TRUE;
Alexander Larsson's avatar
Alexander Larsson committed
489 490
	GFile *old_location;
	char *old_uri, *new_uri;
491
	int new_slot_position;
492
	GList *l;
493

494
	window = slot->pane->window;
495

496
        target_window = NULL;
497
	target_slot = NULL;
498

499
	old_uri = nautilus_window_slot_get_location_uri (slot);
Alexander Larsson's avatar
Alexander Larsson committed
500 501 502 503
	if (old_uri == NULL) {
		old_uri = g_strdup ("(none)");
	}
	new_uri = g_file_get_uri (location);
504 505 506
	nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER,
			    "window %p open location: old=\"%s\", new=\"%s\"",
			    window,
Alexander Larsson's avatar
Alexander Larsson committed
507 508 509 510 511
			    old_uri,
			    new_uri);
	g_free (old_uri);
	g_free (new_uri);

512 513
	g_assert (!((flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) != 0 &&
		    (flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB) != 0));
514

515 516

	old_location = nautilus_window_slot_get_location (slot);
517
	switch (mode) {
518
        case NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE :
519 520
		if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
			target_window = window;
521
			if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
522 523 524
				if (!NAUTILUS_SPATIAL_WINDOW (window)->affect_spatial_window_on_next_location_change) {
					target_window = nautilus_application_create_navigation_window 
						(window->application,
525
						 NULL,
526 527 528 529
						 gtk_window_get_screen (GTK_WINDOW (window)));
				} else {
					NAUTILUS_SPATIAL_WINDOW (window)->affect_spatial_window_on_next_location_change = FALSE;
				}
530 531 532 533 534
			} else if ((flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) != 0) {
				target_window = nautilus_application_create_navigation_window 
					(window->application,
					 NULL,
					 gtk_window_get_screen (GTK_WINDOW (window)));
535 536
			}
		} else if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
537
                        if (!NAUTILUS_SPATIAL_WINDOW (window)->affect_spatial_window_on_next_location_change) {
538
                                target_window = nautilus_application_present_spatial_window_with_selection (
539
                                        window->application,
540
					window,
541
					NULL,
542
                                        location,
543
					new_selection,
544 545 546 547 548 549
                                        gtk_window_get_screen (GTK_WINDOW (window)));
                                do_load_location = FALSE;
                        } else {
                                NAUTILUS_SPATIAL_WINDOW (window)->affect_spatial_window_on_next_location_change = FALSE;
                                target_window = window;
                        }
550 551 552 553 554 555
		} else if (flags & NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW) {
			target_window = nautilus_application_create_navigation_window 
				(window->application,
				 NULL,
				 gtk_window_get_screen (GTK_WINDOW (window)));
		} else {
556 557 558
                        target_window = window;
                }       
                break;
559
        case NAUTILUS_WINDOW_OPEN_IN_SPATIAL :
560 561
                target_window = nautilus_application_present_spatial_window (
                        window->application,
562
			window,
563
			NULL,
564 565 566
                        location,
                        gtk_window_get_screen (GTK_WINDOW (window)));
                break;
567
        case NAUTILUS_WINDOW_OPEN_IN_NAVIGATION :
568 569
                target_window = nautilus_application_create_navigation_window 
                        (window->application,
570
			 NULL,
571 572 573 574
                         gtk_window_get_screen (GTK_WINDOW (window)));
                break;
        default :
                g_warning ("Unknown open location mode");
Alexander Larsson's avatar
Alexander Larsson committed
575
		g_object_unref (old_location);
576 577 578 579 580
                return;
        }

        g_assert (target_window != NULL);

581 582 583 584 585 586 587 588 589 590 591
	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;
		}

592
		target_slot = nautilus_window_open_slot (window->details->active_pane, slot_flags);
593 594
	}

595
        if ((flags & NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND) != 0) {
596
                if (NAUTILUS_IS_SPATIAL_WINDOW (window) && !NAUTILUS_IS_DESKTOP_WINDOW (window)) {
597
                        if (gtk_widget_get_visible (GTK_WIDGET (target_window))) {
598
                                nautilus_window_close (window);
599 600 601 602 603 604 605
                        } else {
                                g_signal_connect_object (target_window,
                                                         "show",
                                                         G_CALLBACK (new_window_show_callback),
                                                         window,
                                                         G_CONNECT_AFTER);
                        }
606
                }
607 608
        }

609 610 611 612
	if (target_slot == NULL) {
		if (target_window == window) {
			target_slot = slot;
		} else {
613
			target_slot = target_window->details->active_pane->active_slot;
614 615 616
		}
	}

617
        if ((!do_load_location) ||
618
	    (target_window == window && target_slot == slot &&
Alexander Larsson's avatar
Alexander Larsson committed
619
	     old_location && g_file_equal (old_location, location))) {
620 621 622
		if (old_location) {
			g_object_unref (old_location);
		}
623 624
                return;
        }
Alexander Larsson's avatar
Alexander Larsson committed
625 626 627 628
	
	if (old_location) {
		g_object_unref (old_location);
	}
629

630
        begin_location_change (target_slot, location, new_selection,
631
                               NAUTILUS_LOCATION_CHANGE_STANDARD, 0, NULL);
632 633 634 635 636 637 638 639 640 641 642

	/* Additionally, load this in all slots that have no location, this means
	   we load both panes in e.g. a newly opened dual pane window. */
	for (l = target_window->details->panes; l != NULL; l = l->next) {
		pane = l->data;
		slot = pane->active_slot;
		if (slot->location == NULL && slot->pending_location == NULL) {
			begin_location_change (slot, location, new_selection,
					       NAUTILUS_LOCATION_CHANGE_STANDARD, 0, NULL);
		}
	}
643 644
}

645
void
646 647 648
nautilus_window_slot_open_location (NautilusWindowSlot *slot,
				    GFile *location,
				    gboolean close_behind)
649
{
650
	NautilusWindowOpenFlags flags;
651 652 653

	flags = 0;
	if (close_behind) {
654
		flags = NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND;
655 656
	}
	
657 658 659
	nautilus_window_slot_open_location_full (slot, location,
						 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE,
						 flags, NULL);
660 661
}

662
void
663 664 665 666
nautilus_window_slot_open_location_with_selection (NautilusWindowSlot *slot,
						   GFile *location,
						   GList *selection,
						   gboolean close_behind)
667
{
668
	NautilusWindowOpenFlags flags;
669 670 671

	flags = 0;
	if (close_behind) {
672
		flags = NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND;
673
	}
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
	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;
	}

	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
712

713 714
static char *
nautilus_window_slot_get_view_error_label (NautilusWindowSlot *slot)
715
{
716 717
	const NautilusViewInfo *info;

718
	info = nautilus_view_factory_lookup (nautilus_window_slot_get_content_view_id (slot));
719 720 721 722

	return g_strdup (info->error_label);
}

723 724
static char *
nautilus_window_slot_get_view_startup_error_label (NautilusWindowSlot *slot)
725 726 727
{
	const NautilusViewInfo *info;

728
	info = nautilus_view_factory_lookup (nautilus_window_slot_get_content_view_id (slot));
729

730
	return g_strdup (info->startup_error_label);
731 732 733
}

static void
734
report_current_content_view_failure_to_user (NautilusWindowSlot *slot)
735
{
736
	NautilusWindow *window;
737 738
	char *message;

739
	window = slot->pane->window;
740 741 742 743 744

	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));
745
	g_free (message);
746 747 748
}

static void
749 750
report_nascent_content_view_failure_to_user (NautilusWindowSlot *slot,
					     NautilusView *view)
751
{
752
	NautilusWindow *window;
753 754
	char *message;

755
	window = slot->pane->window;
756 757 758 759 760

	/* 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);
761 762 763 764
	eel_show_error_dialog (message,
			       _("The location cannot be displayed with this viewer."),
			       GTK_WINDOW (window));
	g_free (message);
765 766
}

767

768
const char *
769
nautilus_window_slot_get_content_view_id (NautilusWindowSlot *slot)
770
{
771 772 773 774
	if (slot->content_view == NULL) {
		return NULL;
	}
	return nautilus_view_get_view_id (slot->content_view);
775 776
}

777
gboolean
778 779
nautilus_window_slot_content_view_matches_iid (NautilusWindowSlot *slot, 
					       const char *iid)
780
{
781 782 783 784
	if (slot->content_view == NULL) {
		return FALSE;
	}
	return eel_strcmp (nautilus_view_get_view_id (slot->content_view), iid) == 0;
785 786
}

787

788 789 790 791 792 793 794 795 796 797 798 799 800 801 802
/*
 * begin_location_change
 * 
 * Change a window's location.
 * @window: The NautilusWindow whose location should be changed.
 * @location: A url specifying the location to load
 * @new_selection: The initial selection to present after loading the location
 * @type: Which type of location change is this? Standard, back, forward, or reload?
 * @distance: If type is back or forward, the index into the back or forward chain. If
 * type is standard or reload, this is ignored, and must be 0.
 * @scroll_pos: The file to scroll to when the location is loaded.
 *
 * This is the core function for changing the location of a window. Every change to the
 * location begins here.
 */
803
static void
804
begin_location_change (NautilusWindowSlot *slot,
Alexander Larsson's avatar
Alexander Larsson committed
805
                       GFile *location,
806 807 808 809
		       GList *new_selection,
                       NautilusLocationChangeType type,
                       guint distance,
                       const char *scroll_pos)
810
{
811
	NautilusWindow *window;
812 813 814 815
        NautilusDirectory *directory;
        NautilusFile *file;
	gboolean force_reload;
        char *current_pos;
816

817
	g_assert (slot != NULL);
818 819 820 821
        g_assert (location != NULL);
        g_assert (type == NAUTILUS_LOCATION_CHANGE_BACK
                  || type == NAUTILUS_LOCATION_CHANGE_FORWARD
                  || distance == 0);
822

823
	window = slot->pane->window;
824
        g_assert (NAUTILUS_IS_WINDOW (window));
825
        g_object_ref (window);
826

827
	end_location_change (slot);
828

829 830 831 832 833
	nautilus_window_slot_set_allow_stop (slot, TRUE);
	nautilus_window_slot_set_status (slot, " ");

	g_assert (slot->pending_location == NULL);
	g_assert (slot->pending_selection == NULL);
834
	
835 836 837 838 839
	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);
840

841
	slot->pending_scroll_to = g_strdup (scroll_pos);
842 843
        
        directory = nautilus_directory_get (location);
844

845 846 847 848 849 850 851 852 853 854 855
	/* The code to force a reload is here because if we do it
	 * after determining an initial view (in the components), then
	 * we end up fetching things twice.
	 */
	if (type == NAUTILUS_LOCATION_CHANGE_RELOAD) {
		force_reload = TRUE;
	} else if (!nautilus_monitor_active ()) {
		force_reload = TRUE;
	} else {
		force_reload = !nautilus_directory_is_local (directory);
	}
856

857 858 859 860 861 862
	if (force_reload) {
		nautilus_directory_force_reload (directory);
		file = nautilus_directory_get_corresponding_file (directory);
		nautilus_file_invalidate_all_attributes (file);
		nautilus_file_unref (file);
	}
863

864
        nautilus_directory_unref (directory);
865

866
        /* Set current_bookmark scroll pos */
867 868 869 870
        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);
871
                g_free (current_pos);
872 873
        }

874
	/* Get the info needed for view selection */
875
	
876 877
        slot->determine_view_file = nautilus_file_get (location);
	g_assert (slot->determine_view_file != NULL);
878 879 880

	/* if the currently viewed file is marked gone while loading the new location,
	 * this ensures that the window isn't destroyed */
881
        cancel_viewed_file_changed_callback (slot);
882

883
	nautilus_file_call_when_ready (slot->determine_view_file,
Alexander Larsson's avatar
Alexander Larsson committed
884
				       NAUTILUS_FILE_ATTRIBUTE_INFO |
885
				       NAUTILUS_FILE_ATTRIBUTE_MOUNT,
886
                                       got_file_info_for_view_selection_callback,
887
				       slot);
888

889
        g_object_unref (window);
890 891
}

892
static void
893
setup_new_spatial_window (NautilusWindowSlot *slot, NautilusFile *file)
894
{
895
	NautilusWindow *window;
896
	char *show_hidden_file_setting;
897
	char *geometry_string;
898
	char *scroll_string;
899
	gboolean maximized, sticky, above;
900
	GtkAction *action;
901

902
	window = slot->pane->window;
903

904
	if (NAUTILUS_IS_SPATIAL_WINDOW (window) && !NAUTILUS_IS_DESKTOP_WINDOW (window)) {
905 906 907
		/* load show hidden state */
		show_hidden_file_setting = nautilus_file_get_metadata 
			(file, NAUTILUS_METADATA_KEY_WINDOW_SHOW_HIDDEN_FILES,
908
			 NULL);
909 910
		if (show_hidden_file_setting != NULL) {
			if (strcmp (show_hidden_file_setting, "1") == 0) {
911
				window->details->show_hidden_files_mode = NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_ENABLE;
912
			} else {
913
				window->details->show_hidden_files_mode = NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DISABLE;
914
			}
915 916 917 918 919 920 921

			/* Update the UI, since we initialize it to the default */
			action = gtk_action_group_get_action (window->details->main_action_group, NAUTILUS_ACTION_SHOW_HIDDEN_FILES);
			gtk_action_block_activate (action);
			gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
						      window->details->show_hidden_files_mode == NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_ENABLE);
			gtk_action_unblock_activate (action);
922
		} else {
923
			NAUTILUS_WINDOW (window)->details->show_hidden_files_mode = NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT;
924 925
		}
		g_free (show_hidden_file_setting);
926

927
		/* load the saved window geometry */
928 929 930 931 932 933 934 935
		maximized = nautilus_file_get_boolean_metadata
			(file, NAUTILUS_METADATA_KEY_WINDOW_MAXIMIZED, FALSE);
		if (maximized) {
			gtk_window_maximize (GTK_WINDOW (window));
		} else {
			gtk_window_unmaximize (GTK_WINDOW (window));
		}

936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951
		sticky = nautilus_file_get_boolean_metadata
			(file, NAUTILUS_METADATA_KEY_WINDOW_STICKY, FALSE);
		if (sticky) {
			gtk_window_stick (GTK_WINDOW (window));
		} else {
			gtk_window_unstick (GTK_WINDOW (window));
		}

		above = nautilus_file_get_boolean_metadata
			(file, NAUTILUS_METADATA_KEY_WINDOW_KEEP_ABOVE, FALSE);
		if (above) {
			gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
		} else {
			gtk_window_set_keep_above (GTK_WINDOW (window), FALSE);
		}

952
		geometry_string = nautilus_file_get_metadata 
953
			(file, NAUTILUS_METADATA_KEY_WINDOW_GEOMETRY, NULL);
954 955 956 957
                if (geometry_string != NULL) {
                        eel_gtk_window_set_initial_geometry_from_string 
                                (GTK_WINDOW (window), 
                                 geometry_string,
958 959
                                 NAUTILUS_SPATIAL_WINDOW_MIN_WIDTH, 
                                 NAUTILUS_SPATIAL_WINDOW_MIN_HEIGHT,
960
				 FALSE);
961 962
                }
                g_free (geometry_string);
963

964
		if (slot->pending_selection == NULL) {
965 966 967 968 969 970 971
			/* 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,
				 NULL);
		} else {
			/* If there is a pending selection, we want to scroll to an item in
			 * the pending selection list. */
972
			scroll_string = g_file_get_uri (slot->pending_selection->data);
973 974 975
		}

		/* scroll_string might be NULL if there was no saved scroll position. */
976
		if (scroll_string != NULL) {
977
			slot->pending_scroll_to = scroll_string;
978 979
		}
        }
980 981
}

Alexander Larsson's avatar
Alexander Larsson committed
982 983
typedef struct {
	GCancellable *cancellable;
984
	NautilusWindowSlot *slot;
Alexander Larsson's avatar
Alexander Larsson committed
985 986 987 988 989 990 991 992 993
} MountNotMountedData;

static void 
mount_not_mounted_callback (GObject *source_object,
			    GAsyncResult *res,
			    gpointer user_data)
{
	MountNotMountedData *data;
	NautilusWindow *window;
994
	NautilusWindowSlot *slot;
Alexander Larsson's avatar
Alexander Larsson committed
995 996 997 998
	GError *error;
	GCancellable *cancellable;

	data = user_data;
999
	slot = data->slot;
1000
	window = slot->pane->window;
Alexander Larsson's avatar
Alexander Larsson committed
1001 1002 1003 1004 1005 1006 1007 1008 1009
	cancellable = data->cancellable;
	g_free (data);

	if (g_cancellable_is_cancelled (cancellable)) {
		/* Cancelled, don't call back */
		g_object_unref (cancellable);
		return;
	}

1010
	slot->mount_cancellable = NULL;
Alexander Larsson's avatar
Alexander Larsson committed
1011

1012
	slot->determine_view_file = nautilus_file_get (slot->pending_location);
Alexander Larsson's avatar
Alexander Larsson committed
1013 1014
	
	error = NULL;
1015
	if (!g_file_mount_enclosing_volume_finish (G_FILE (source_object), res, &error)) {
1016 1017 1018
		slot->mount_error = error;
		got_file_info_for_view_selection_callback (slot->determine_view_file, slot);
		slot->mount_error = NULL;
Alexander Larsson's avatar
Alexander Larsson committed
1019 1020
		g_error_free (error);
	} else {
1021 1022
		nautilus_file_invalidate_all_attributes (slot->determine_view_file);
		nautilus_file_call_when_ready (slot->determine_view_file,
1023
					       NAUTILUS_FILE_ATTRIBUTE_INFO,
Alexander Larsson's avatar
Alexander Larsson committed
1024
					       got_file_info_for_view_selection_callback,
1025
					       slot);
Alexander Larsson's avatar
Alexander Larsson committed
1026 1027 1028 1029 1030
	}

	g_object_unref (cancellable);
}

1031 1032 1033 1034
static void
got_file_info_for_view_selection_callback (NautilusFile *file,
					   gpointer callback_data)
{
Alexander Larsson's avatar
Alexander Larsson committed
1035
        GError *error;
1036 1037 1038
	char *view_id;
	char *mimetype;
	NautilusWindow *window;
1039
	NautilusWindowSlot *slot;
1040
	NautilusFile *viewed_file;
Alexander Larsson's avatar
Alexander Larsson committed
1041 1042 1043
	GFile *location;
	GMountOperation *mount_op;
	MountNotMountedData *data;
1044

1045 1046 1047 1048
	slot = callback_data;
	g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
	g_assert (slot->determine_view_file == file);

1049
	window = slot->pane->window;
1050 1051 1052 1053 1054 1055
	g_assert (NAUTILUS_IS_WINDOW (window));

	slot->determine_view_file = NULL;

	if (slot->mount_error) {
		error = slot->mount_error;
Alexander Larsson's avatar
Alexander Larsson committed
1056 1057 1058
	} else {
		error = nautilus_file_get_file_info_error (file);
	}
1059

Alexander Larsson's avatar
Alexander Larsson committed
1060
	if (error && error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_MOUNTED &&
1061 1062 1063
	    !slot->tried_mount) {
		slot->tried_mount = TRUE;

1064
		mount_op = gtk_mount_operation_new (GTK_WINDOW (window));
1065
		g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
Alexander Larsson's avatar
Alexander Larsson committed
1066 1067 1068
		location = nautilus_file_get_location (file);
		data = g_new0 (MountNotMountedData, 1);
		data->cancellable = g_cancellable_new ();
1069 1070 1071
		data->slot = slot;
		slot->mount_cancellable = data->cancellable;
		g_file_mount_enclosing_volume (location, 0, mount_op, slot->mount_cancellable,
1072
					       mount_not_mounted_callback, data);
Alexander Larsson's avatar
Alexander Larsson committed
1073 1074
		g_object_unref (location);
		g_object_unref (mount_op);
1075 1076 1077

		nautilus_file_unref (file);

Alexander Larsson's avatar
Alexander Larsson committed
1078 1079 1080
		return;
	}
	
1081
	location = slot->pending_location;
1082
	
1083 1084
	view_id = NULL;
	
Alexander Larsson's avatar
Alexander Larsson committed
1085 1086
        if (error == NULL ||
	    (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_SUPPORTED)) {
1087
		/* We got the information we need, now pick what view to use: */
1088

1089
		mimetype = nautilus_file_get_mime_type (file);
1090

1091
		/* If fallback, don't use view from metadata */
1092
		if (slot->location_change_type != NAUTILUS_LOCATION_CHANGE_FALLBACK) {
1093 1094
			/* Look in metadata for view */
			view_id = nautilus_file_get_metadata 
1095
				(file, NAUTILUS_METADATA_KEY_DEFAULT_VIEW, NULL);
1096 1097 1098 1099 1100 1101 1102 1103 1104
			if (view_id != NULL && 
			    !nautilus_view_factory_view_supports_uri (view_id,
								      location,
								      nautilus_file_get_file_type (file),
								      mimetype)) {
				g_free (view_id);
				view_id = NULL;
			}
		}
1105

1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
		/* Otherwise, use default */
		if (view_id == NULL) {
			view_id = nautilus_global_preferences_get_default_folder_viewer_preference_as_iid ();

			if (view_id != NULL && 
			    !nautilus_view_factory_view_supports_uri (view_id,
								      location,
								      nautilus_file_get_file_type (file),
								      mimetype)) {
				g_free (view_id);
				view_id = NULL;
			}
		}
		
		g_free (mimetype);
	}
1122

1123
	if (view_id != NULL) {
1124
                if (!gtk_widget_get_visible (GTK_WIDGET (window)) && NAUTILUS_IS_SPATIAL_WINDOW (window)) {
1125
			/* We now have the metadata to set up the window position, etc */
1126
			setup_new_spatial_window (slot, file);
1127
		}
1128
		create_content_view (slot, view_id);
1129 1130 1131
		g_free (view_id);
	} else {
		display_view_selection_failure (window, file,
Alexander Larsson's avatar
Alexander Larsson committed
1132
						location, error);
1133

1134
		if (!gtk_widget_get_visible (GTK_WIDGET (window))) {
1135 1136 1137 1138
			/* Destroy never-had-a-chance-to-be-seen window. This case
			 * happens when a new window cannot display its initial URI. 
			 */
			/* if this is the only window, we don't want to quit, so we redirect it to home */
1139 1140 1141
			if (nautilus_application_get_n_windows () <= 1) {
				g_assert (nautilus_application_get_n_windows () == 1);

1142 1143 1144 1145 1146 1147 1148
				/* Make sure we re-use this window */
				if (NAUTILUS_IS_SPATIAL_WINDOW (window)) {
					NAUTILUS_SPATIAL_WINDOW (window)->affect_spatial_window_on_next_location_change = TRUE;
				}
				/* the user could have typed in a home directory that doesn't exist,
				   in which case going home would cause an infinite loop, so we
				   better test for that */
Alexander Larsson's avatar
Alexander Larsson committed
1149 1150 1151

				if (!nautilus_is_root_directory (location)) {
					if (!nautilus_is_home_directory (location)) {	
1152
						nautilus_window_slot_go_home (slot, FALSE);
1153
					} else {
Alexander Larsson's avatar
Alexander Larsson committed
1154 1155 1156
						GFile *root;

						root = g_file_new_for_path ("/");
1157
						/* the last fallback is to go to a known place that can't be deleted! */
1158
						nautilus_window_slot_go_to (slot, location, FALSE);
Alexander Larsson's avatar
Alexander Larsson committed
1159
						g_object_unref (root);
1160 1161 1162 1163 1164 1165 1166 1167
					}
				} else {
					gtk_object_destroy (GTK_OBJECT (window));
				}
			} else {
				/* Since this is a window, destroying it will also unref it. */
				gtk_object_destroy (GTK_OBJECT (window));
			}
1168
		} else {
1169
			/* Clean up state of already-showing window */
1170 1171 1172 1173 1174 1175
			end_location_change (slot);

			/* TODO? shouldn't we call
			 *   cancel_viewed_file_changed_callback (slot);
			 * at this point, or in end_location_change()
			 */
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
			/* We're missing a previous location (if opened location
			 * in a new tab) so close it and return */
			if (slot->location == NULL) {
				nautilus_window_slot_close (slot);
			} else {
				/* We disconnected this, so we need to re-connect it */
				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), slot, 0);
				nautilus_file_unref (viewed_file);
1188
			
1189 1190 1191 1192 1193 1194
				/* Leave the location bar showing the bad location that the user
				 * typed (or maybe achieved by dragging or something). Many times
				 * the mistake will just be an easily-correctable typo. The user
				 * can choose "Refresh" to get the original URI back in the location bar.
				 */
			}
1195
		}
1196 1197 1198 1199
	}
	
	nautilus_file_unref (file);
}
1200

1201 1202 1203 1204 1205 1206 1207 1208
/* Load a view into the window, either reusing the old one or creating
 * a new one. This happens when you want to load a new location, or just
 * switch to a different view.
 * If pending_location is set we're loading a new location and
 * pending_location/selection will be used. If not, we're just switching
 * view, and the current location will be used.
 */
static void
1209
create_content_view (NautilusWindowSlot *slot,
1210 1211
		     const char *view_id)
{
1212
	NautilusWindow *window;
1213 1214
        NautilusView *view;
	GList *selection;
1215

1216
	window = slot->pane->window;
1217

1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
 	/* FIXME bugzilla.gnome.org 41243: 
	 * We should use inheritance instead of these special cases
	 * for the desktop window.
	 */
        if (NAUTILUS_IS_DESKTOP_WINDOW (window)) {
        	/* We force the desktop to use a desktop_icon_view. It's simpler
        	 * to fix it here than trying to make it pick the right view in
        	 * the first place.
        	 */
		view_id = NAUTILUS_DESKTOP_ICON_VIEW_IID;
	} 
1229
        
1230 1231
        if (slot->content_view != NULL &&
	    eel_strcmp (nautilus_view_get_view_id (slot->content_view),
1232 1233
			view_id) == 0) {
                /* reuse existing content view */
1234 1235
                view = slot->content_view;
                slot->new_content_view = view;
1236 1237 1238 1239
        	g_object_ref (view);
        } else {
                /* create a new content view */
		view = nautilus_view_factory_create (view_id,
1240
						     NAUTILUS_WINDOW_SLOT_INFO (slot));
1241

1242 1243
                eel_accessibility_s