1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6 * Copyright (C) 1999, 2000 Red Hat, Inc.
7 * Copyright (C) 1999, 2000, 2001 Eazel, Inc.
9 * Nautilus is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public
11 * License as published by the Free Software Foundation; either
12 * 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 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Authors: Elliot Lee <sopwith@redhat.com>
24 * John Sullivan <sullivan@eazel.com>
25 * Darin Adler <darin@bentspoon.com>
29 #include "nautilus-window-manage-views.h"
31 #include "nautilus-actions.h"
32 #include "nautilus-application.h"
33 #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 #include "nautilus-trash-bar.h"
39 #include "nautilus-x-content-bar.h"
40 #include "nautilus-zoom-control.h"
41 #include <eel/eel-accessibility.h>
42 #include <eel/eel-debug.h>
43 #include <eel/eel-gdk-extensions.h>
44 #include <eel/eel-glib-extensions.h>
45 #include <eel/eel-gtk-extensions.h>
46 #include <eel/eel-stock-dialogs.h>
47 #include <eel/eel-string.h>
48 #include <eel/eel-mount-operation.h>
49 #include <gtk/gtkmain.h>
50 #include <gtk/gtksignal.h>
52 #include <glib/gi18n.h>
53 #include <libgnomeui/gnome-icon-theme.h>
54 #include <libnautilus-extension/nautilus-location-widget-provider.h>
55 #include <libnautilus-private/nautilus-debug-log.h>
56 #include <libnautilus-private/nautilus-file-attributes.h>
57 #include <libnautilus-private/nautilus-file-utilities.h>
58 #include <libnautilus-private/nautilus-file.h>
59 #include <libnautilus-private/nautilus-global-preferences.h>
60 #include <libnautilus-private/nautilus-metadata.h>
61 #include <libnautilus-private/nautilus-mime-actions.h>
62 #include <libnautilus-private/nautilus-module.h>
63 #include <libnautilus-private/nautilus-monitor.h>
64 #include <libnautilus-private/nautilus-search-directory.h>
65 #include <libnautilus-private/nautilus-view-factory.h>
66 #include <libnautilus-private/nautilus-window-info.h>
67 #include <libnautilus-private/nautilus-autorun.h>
69 /* FIXME bugzilla.gnome.org 41243:
70 * We should use inheritance instead of these special cases
71 * for the desktop window.
73 #include "nautilus-desktop-window.h"
75 /* This number controls a maximum character count for a URL that is
76 * displayed as part of a dialog. It's fairly arbitrary -- big enough
77 * to allow most "normal" URIs to display in full, but small enough to
78 * prevent the dialog from getting insanely wide.
80 #define MAX_URI_IN_DIALOG_LENGTH 60
82 static void connect_view (NautilusWindow
*window
,
84 static void disconnect_view (NautilusWindow
*window
,
86 static void begin_location_change (NautilusWindow
*window
,
89 NautilusLocationChangeType type
,
91 const char *scroll_pos
);
92 static void free_location_change (NautilusWindow
*window
);
93 static void end_location_change (NautilusWindow
*window
);
94 static void cancel_location_change (NautilusWindow
*window
);
95 static void got_file_info_for_view_selection_callback (NautilusFile
*file
,
96 gpointer callback_data
);
97 static void create_content_view (NautilusWindow
*window
,
99 static void display_view_selection_failure (NautilusWindow
*window
,
103 static void load_new_location (NautilusWindow
*window
,
106 gboolean tell_current_content_view
,
107 gboolean tell_new_content_view
);
108 static void location_has_really_changed (NautilusWindow
*window
);
109 static void update_for_new_location (NautilusWindow
*window
);
110 static void zoom_parameters_changed_callback (NautilusView
*view
,
111 NautilusWindow
*window
);
112 static void update_extra_location_widgets_visibility (NautilusWindow
*window
);
113 static void remove_extra_location_widgets (NautilusWindow
*window
);
116 nautilus_window_report_selection_changed (NautilusWindowInfo
*window
)
118 g_signal_emit_by_name (window
, "selection_changed");
121 /* set_displayed_location:
124 set_displayed_location (NautilusWindow
*window
, GFile
*location
)
126 GFile
*bookmark_location
;
130 if (window
->current_location_bookmark
== NULL
|| location
== NULL
) {
133 bookmark_location
= nautilus_bookmark_get_location (window
->current_location_bookmark
);
134 recreate
= !g_file_equal (bookmark_location
, location
);
135 g_object_unref (bookmark_location
);
139 /* We've changed locations, must recreate bookmark for current location. */
140 if (window
->last_location_bookmark
!= NULL
) {
141 g_object_unref (window
->last_location_bookmark
);
143 window
->last_location_bookmark
= window
->current_location_bookmark
;
144 name
= g_file_get_uri (location
);
145 window
->current_location_bookmark
= (location
== NULL
) ? NULL
146 : nautilus_bookmark_new (location
, name
);
149 nautilus_window_update_title (window
);
150 nautilus_window_update_icon (window
);
154 check_bookmark_location_matches (NautilusBookmark
*bookmark
, GFile
*location
)
156 GFile
*bookmark_location
;
157 char *bookmark_uri
, *uri
;
159 bookmark_location
= nautilus_bookmark_get_location (bookmark
);
160 if (!g_file_equal (location
, bookmark_location
)) {
161 bookmark_uri
= g_file_get_uri (bookmark_location
);
162 uri
= g_file_get_uri (location
);
163 g_warning ("bookmark uri is %s, but expected %s", bookmark_uri
, uri
);
165 g_free (bookmark_uri
);
167 g_object_unref (bookmark_location
);
170 /* Debugging function used to verify that the last_location_bookmark
171 * is in the state we expect when we're about to use it to update the
172 * Back or Forward list.
175 check_last_bookmark_location_matches_window (NautilusWindow
*window
)
177 check_bookmark_location_matches (window
->last_location_bookmark
,
178 window
->details
->location
);
182 handle_go_back (NautilusNavigationWindow
*window
, GFile
*location
)
186 NautilusBookmark
*bookmark
;
188 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window
));
190 /* Going back. Move items from the back list to the forward list. */
191 g_assert (g_list_length (window
->back_list
) > NAUTILUS_WINDOW (window
)->details
->location_change_distance
);
192 check_bookmark_location_matches (NAUTILUS_BOOKMARK (g_list_nth_data (window
->back_list
,
193 NAUTILUS_WINDOW (window
)->details
->location_change_distance
)),
195 g_assert (NAUTILUS_WINDOW (window
)->details
->location
!= NULL
);
197 /* Move current location to Forward list */
199 check_last_bookmark_location_matches_window (NAUTILUS_WINDOW (window
));
201 /* Use the first bookmark in the history list rather than creating a new one. */
202 window
->forward_list
= g_list_prepend (window
->forward_list
,
203 NAUTILUS_WINDOW (window
)->last_location_bookmark
);
204 g_object_ref (window
->forward_list
->data
);
206 /* Move extra links from Back to Forward list */
207 for (i
= 0; i
< NAUTILUS_WINDOW (window
)->details
->location_change_distance
; ++i
) {
208 bookmark
= NAUTILUS_BOOKMARK (window
->back_list
->data
);
209 window
->back_list
= g_list_remove (window
->back_list
, bookmark
);
210 window
->forward_list
= g_list_prepend (window
->forward_list
, bookmark
);
213 /* One bookmark falls out of back/forward lists and becomes viewed location */
214 link
= window
->back_list
;
215 window
->back_list
= g_list_remove_link (window
->back_list
, link
);
216 g_object_unref (link
->data
);
217 g_list_free_1 (link
);
221 handle_go_forward (NautilusNavigationWindow
*window
, GFile
*location
)
225 NautilusBookmark
*bookmark
;
227 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window
));
229 /* Going forward. Move items from the forward list to the back list. */
230 g_assert (g_list_length (window
->forward_list
) > NAUTILUS_WINDOW (window
)->details
->location_change_distance
);
231 check_bookmark_location_matches (NAUTILUS_BOOKMARK (g_list_nth_data (window
->forward_list
,
232 NAUTILUS_WINDOW (window
)->details
->location_change_distance
)),
234 g_assert (NAUTILUS_WINDOW (window
)->details
->location
!= NULL
);
236 /* Move current location to Back list */
238 check_last_bookmark_location_matches_window (NAUTILUS_WINDOW (window
));
240 /* Use the first bookmark in the history list rather than creating a new one. */
241 window
->back_list
= g_list_prepend (window
->back_list
,
242 NAUTILUS_WINDOW (window
)->last_location_bookmark
);
243 g_object_ref (window
->back_list
->data
);
245 /* Move extra links from Forward to Back list */
246 for (i
= 0; i
< NAUTILUS_WINDOW (window
)->details
->location_change_distance
; ++i
) {
247 bookmark
= NAUTILUS_BOOKMARK (window
->forward_list
->data
);
248 window
->forward_list
= g_list_remove (window
->forward_list
, bookmark
);
249 window
->back_list
= g_list_prepend (window
->back_list
, bookmark
);
252 /* One bookmark falls out of back/forward lists and becomes viewed location */
253 link
= window
->forward_list
;
254 window
->forward_list
= g_list_remove_link (window
->forward_list
, link
);
255 g_object_unref (link
->data
);
256 g_list_free_1 (link
);
260 handle_go_elsewhere (NautilusWindow
*window
, GFile
*location
)
263 if (NAUTILUS_IS_NAVIGATION_WINDOW (window
)) {
264 /* Clobber the entire forward list, and move displayed location to back list */
265 nautilus_navigation_window_clear_forward_list (NAUTILUS_NAVIGATION_WINDOW (window
));
267 if (window
->details
->location
!= NULL
) {
268 /* If we're returning to the same uri somehow, don't put this uri on back list.
269 * This also avoids a problem where set_displayed_location
270 * didn't update last_location_bookmark since the uri didn't change.
272 if (!g_file_equal (window
->details
->location
, location
)) {
273 /* Store bookmark for current location in back list, unless there is no current location */
274 check_last_bookmark_location_matches_window (window
);
275 /* Use the first bookmark in the history list rather than creating a new one. */
276 NAUTILUS_NAVIGATION_WINDOW (window
)->back_list
= g_list_prepend (NAUTILUS_NAVIGATION_WINDOW (window
)->back_list
,
277 window
->last_location_bookmark
);
278 g_object_ref (NAUTILUS_NAVIGATION_WINDOW (window
)->back_list
->data
);
286 update_up_button (NautilusWindow
*window
)
292 if (window
->details
->location
!= NULL
) {
293 parent
= g_file_get_parent (window
->details
->location
);
294 allowed
= parent
!= NULL
;
295 if (parent
!= NULL
) {
296 g_object_unref (parent
);
300 nautilus_window_allow_up (window
, allowed
);
304 viewed_file_changed_callback (NautilusFile
*file
,
305 NautilusWindow
*window
)
308 gboolean is_in_trash
, was_in_trash
;
311 g_assert (NAUTILUS_IS_FILE (file
));
312 g_assert (NAUTILUS_IS_WINDOW (window
));
313 g_assert (window
->details
->viewed_file
== file
);
315 if (!nautilus_file_is_not_yet_confirmed (file
)) {
316 window
->details
->viewed_file_seen
= TRUE
;
319 was_in_trash
= window
->details
->viewed_file_in_trash
;
321 window
->details
->viewed_file_in_trash
= is_in_trash
= nautilus_file_is_in_trash (file
);
323 /* Close window if the file it's viewing has been deleted or moved to trash. */
324 if (nautilus_file_is_gone (file
) || (is_in_trash
&& !was_in_trash
)) {
325 /* Don't close the window in the case where the
326 * file was never seen in the first place.
328 if (window
->details
->viewed_file_seen
) {
329 /* Detecting a file is gone may happen in the
330 * middle of a pending location change, we
331 * need to cancel it before closing the window
334 /* FIXME: It makes no sense that this call is
335 * needed. When the window is destroyed, it
336 * calls nautilus_window_manage_views_destroy,
337 * which calls free_location_change, which
338 * should be sufficient. Also, if this was
339 * really needed, wouldn't it be needed for
340 * all other nautilus_window_close callers?
342 end_location_change (window
);
344 if (NAUTILUS_IS_NAVIGATION_WINDOW (window
)) {
345 /* auto-show existing parent. */
346 GFile
*go_to_file
, *parent
, *location
;
349 location
= nautilus_file_get_location (file
);
350 parent
= g_file_get_parent (location
);
351 g_object_unref (location
);
353 go_to_file
= nautilus_find_existing_uri_in_hierarchy (parent
);
354 g_object_unref (parent
);
357 if (go_to_file
!= NULL
) {
358 /* the path bar URI will be set to go_to_uri immediately
359 * in begin_location_change, but we don't want the
360 * inexistant children to show up anymore */
361 nautilus_path_bar_clear_buttons (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window
)->path_bar
));
362 nautilus_window_go_to (NAUTILUS_WINDOW (window
), go_to_file
);
363 g_object_unref (go_to_file
);
365 nautilus_window_go_home (NAUTILUS_WINDOW (window
));
368 nautilus_window_close (window
);
372 new_location
= nautilus_file_get_location (file
);
374 /* If the file was renamed, update location and/or
376 if (!g_file_equal (new_location
,
377 window
->details
->location
)) {
378 g_object_unref (window
->details
->location
);
379 window
->details
->location
= new_location
;
381 /* Check if we can go up. */
382 update_up_button (window
);
384 uri
= g_file_get_uri (window
->details
->location
);
385 if (NAUTILUS_IS_NAVIGATION_WINDOW (window
)) {
386 /* Change the location bar and path bar to match the current location. */
387 nautilus_navigation_bar_set_location
388 (NAUTILUS_NAVIGATION_BAR (NAUTILUS_NAVIGATION_WINDOW (window
)->navigation_bar
),
390 nautilus_path_bar_set_path (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window
)->path_bar
),
391 window
->details
->location
);
393 if (NAUTILUS_IS_SPATIAL_WINDOW (window
)) {
394 /* Change the location button to match the current location. */
395 nautilus_spatial_window_set_location_button
396 (NAUTILUS_SPATIAL_WINDOW (window
),
397 window
->details
->location
);
403 g_object_unref (new_location
);
406 nautilus_window_update_title (window
);
407 nautilus_window_update_icon (window
);
412 update_history (NautilusWindow
*window
,
413 NautilusLocationChangeType type
,
417 case NAUTILUS_LOCATION_CHANGE_STANDARD
:
418 case NAUTILUS_LOCATION_CHANGE_FALLBACK
:
419 nautilus_window_add_current_location_to_history_list (window
);
420 handle_go_elsewhere (window
, new_location
);
422 case NAUTILUS_LOCATION_CHANGE_RELOAD
:
423 /* for reload there is no work to do */
425 case NAUTILUS_LOCATION_CHANGE_BACK
:
426 nautilus_window_add_current_location_to_history_list (window
);
427 handle_go_back (NAUTILUS_NAVIGATION_WINDOW (window
),
430 case NAUTILUS_LOCATION_CHANGE_FORWARD
:
431 nautilus_window_add_current_location_to_history_list (window
);
432 handle_go_forward (NAUTILUS_NAVIGATION_WINDOW (window
),
435 case NAUTILUS_LOCATION_CHANGE_REDIRECT
:
436 /* for the redirect case, the caller can do the updating */
439 g_return_if_fail (FALSE
);
443 cancel_viewed_file_changed_callback (NautilusWindow
*window
)
447 file
= window
->details
->viewed_file
;
449 g_signal_handlers_disconnect_by_func (G_OBJECT (file
),
450 G_CALLBACK (viewed_file_changed_callback
),
452 nautilus_file_monitor_remove (file
, &window
->details
->viewed_file
);
457 new_window_show_callback (GtkWidget
*widget
,
460 NautilusWindow
*window
;
462 window
= NAUTILUS_WINDOW (user_data
);
464 nautilus_window_close (window
);
466 g_signal_handlers_disconnect_by_func (widget
,
467 G_CALLBACK (new_window_show_callback
),
473 nautilus_window_open_location_full (NautilusWindow
*window
,
475 NautilusWindowOpenMode mode
,
476 NautilusWindowOpenFlags flags
,
477 GList
*new_selection
)
479 NautilusWindow
*target_window
;
480 gboolean do_load_location
= TRUE
;
482 char *old_uri
, *new_uri
;
484 target_window
= NULL
;
486 old_uri
= nautilus_window_get_location_uri (window
);
487 if (old_uri
== NULL
) {
488 old_uri
= g_strdup ("(none)");
490 new_uri
= g_file_get_uri (location
);
491 nautilus_debug_log (FALSE
, NAUTILUS_DEBUG_LOG_DOMAIN_USER
,
492 "window %p open location: old=\"%s\", new=\"%s\"",
500 old_location
= nautilus_window_get_location (window
);
502 case NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE
:
503 if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER
)) {
504 target_window
= window
;
505 if (NAUTILUS_IS_SPATIAL_WINDOW (window
)) {
506 if (!NAUTILUS_SPATIAL_WINDOW (window
)->affect_spatial_window_on_next_location_change
) {
507 target_window
= nautilus_application_create_navigation_window
508 (window
->application
,
510 gtk_window_get_screen (GTK_WINDOW (window
)));
512 NAUTILUS_SPATIAL_WINDOW (window
)->affect_spatial_window_on_next_location_change
= FALSE
;
514 } else if ((flags
& NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW
) != 0) {
515 target_window
= nautilus_application_create_navigation_window
516 (window
->application
,
518 gtk_window_get_screen (GTK_WINDOW (window
)));
520 } else if (NAUTILUS_IS_SPATIAL_WINDOW (window
)) {
521 if (!NAUTILUS_SPATIAL_WINDOW (window
)->affect_spatial_window_on_next_location_change
) {
522 target_window
= nautilus_application_present_spatial_window_with_selection (
528 gtk_window_get_screen (GTK_WINDOW (window
)));
529 do_load_location
= FALSE
;
531 NAUTILUS_SPATIAL_WINDOW (window
)->affect_spatial_window_on_next_location_change
= FALSE
;
532 target_window
= window
;
534 } else if (flags
& NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW
) {
535 target_window
= nautilus_application_create_navigation_window
536 (window
->application
,
538 gtk_window_get_screen (GTK_WINDOW (window
)));
540 target_window
= window
;
543 case NAUTILUS_WINDOW_OPEN_IN_SPATIAL
:
544 target_window
= nautilus_application_present_spatial_window (
549 gtk_window_get_screen (GTK_WINDOW (window
)));
551 case NAUTILUS_WINDOW_OPEN_IN_NAVIGATION
:
552 target_window
= nautilus_application_create_navigation_window
553 (window
->application
,
555 gtk_window_get_screen (GTK_WINDOW (window
)));
558 g_warning ("Unknown open location mode");
559 g_object_unref (old_location
);
563 g_assert (target_window
!= NULL
);
565 if ((flags
& NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND
) != 0) {
566 if (NAUTILUS_IS_SPATIAL_WINDOW (window
) && !NAUTILUS_IS_DESKTOP_WINDOW (window
)) {
567 if (GTK_WIDGET_VISIBLE (target_window
)) {
568 nautilus_window_close (window
);
570 g_signal_connect_object (target_window
,
572 G_CALLBACK (new_window_show_callback
),
579 if ((!do_load_location
) ||
580 (target_window
== window
&&
581 old_location
&& g_file_equal (old_location
, location
))) {
582 g_object_unref (old_location
);
587 g_object_unref (old_location
);
590 begin_location_change (target_window
, location
, new_selection
,
591 NAUTILUS_LOCATION_CHANGE_STANDARD
, 0, NULL
);
595 nautilus_window_open_location (NautilusWindow
*window
,
597 gboolean close_behind
)
599 NautilusWindowOpenFlags flags
;
603 flags
= NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND
;
606 nautilus_window_open_location_full (window
, location
,
607 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE
,
612 nautilus_window_open_location_with_selection (NautilusWindow
*window
,
615 gboolean close_behind
)
617 NautilusWindowOpenFlags flags
;
621 flags
= NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND
;
623 nautilus_window_open_location_full (window
, location
,
624 NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE
,
629 nautilus_window_get_view_error_label (NautilusWindow
*window
)
631 const NautilusViewInfo
*info
;
633 info
= nautilus_view_factory_lookup (nautilus_window_get_content_view_id (window
));
635 return g_strdup (info
->error_label
);
639 nautilus_window_get_view_startup_error_label (NautilusWindow
*window
)
641 const NautilusViewInfo
*info
;
643 info
= nautilus_view_factory_lookup (nautilus_window_get_content_view_id (window
));
645 return g_strdup (info
->startup_error_label
);
649 report_current_content_view_failure_to_user (NautilusWindow
*window
,
654 message
= nautilus_window_get_view_startup_error_label (window
);
655 eel_show_error_dialog (message
,
656 _("You can choose another view or go to a different location."),
657 GTK_WINDOW (window
));
662 report_nascent_content_view_failure_to_user (NautilusWindow
*window
,
667 message
= nautilus_window_get_view_error_label (window
);
668 eel_show_error_dialog (message
,
669 _("The location cannot be displayed with this viewer."),
670 GTK_WINDOW (window
));
676 nautilus_window_get_content_view_id (NautilusWindow
*window
)
678 if (window
->content_view
== NULL
) {
681 return nautilus_view_get_view_id (window
->content_view
);
685 nautilus_window_content_view_matches_iid (NautilusWindow
*window
,
688 if (window
->content_view
== NULL
) {
691 return eel_strcmp (nautilus_view_get_view_id (window
->content_view
),
697 * begin_location_change
699 * Change a window's location.
700 * @window: The NautilusWindow whose location should be changed.
701 * @location: A url specifying the location to load
702 * @new_selection: The initial selection to present after loading the location
703 * @type: Which type of location change is this? Standard, back, forward, or reload?
704 * @distance: If type is back or forward, the index into the back or forward chain. If
705 * type is standard or reload, this is ignored, and must be 0.
706 * @scroll_pos: The file to scroll to when the location is loaded.
708 * This is the core function for changing the location of a window. Every change to the
709 * location begins here.
712 begin_location_change (NautilusWindow
*window
,
714 GList
*new_selection
,
715 NautilusLocationChangeType type
,
717 const char *scroll_pos
)
719 NautilusDirectory
*directory
;
721 gboolean force_reload
;
724 g_assert (NAUTILUS_IS_WINDOW (window
));
725 g_assert (location
!= NULL
);
726 g_assert (type
== NAUTILUS_LOCATION_CHANGE_BACK
727 || type
== NAUTILUS_LOCATION_CHANGE_FORWARD
730 g_object_ref (window
);
732 end_location_change (window
);
734 nautilus_window_allow_stop (window
, TRUE
);
735 nautilus_window_set_status (window
, " ");
737 g_assert (window
->details
->pending_location
== NULL
);
738 g_assert (window
->details
->pending_selection
== NULL
);
740 window
->details
->pending_location
= g_object_ref (location
);
741 window
->details
->location_change_type
= type
;
742 window
->details
->location_change_distance
= distance
;
743 window
->details
->tried_mount
= FALSE
;
744 window
->details
->pending_selection
= eel_g_object_list_copy (new_selection
);
747 window
->details
->pending_scroll_to
= g_strdup (scroll_pos
);
749 directory
= nautilus_directory_get (location
);
751 /* The code to force a reload is here because if we do it
752 * after determining an initial view (in the components), then
753 * we end up fetching things twice.
755 if (type
== NAUTILUS_LOCATION_CHANGE_RELOAD
) {
757 } else if (!nautilus_monitor_active ()) {
760 force_reload
= !nautilus_directory_is_local (directory
);
764 nautilus_directory_force_reload (directory
);
765 file
= nautilus_directory_get_corresponding_file (directory
);
766 nautilus_file_invalidate_all_attributes (file
);
767 nautilus_file_unref (file
);
770 nautilus_directory_unref (directory
);
772 /* Set current_bookmark scroll pos */
773 if (window
->current_location_bookmark
!= NULL
&&
774 window
->content_view
!= NULL
) {
775 current_pos
= nautilus_view_get_first_visible_file (window
->content_view
);
776 nautilus_bookmark_set_scroll_pos (window
->current_location_bookmark
, current_pos
);
777 g_free (current_pos
);
780 /* Get the info needed for view selection */
782 window
->details
->determine_view_file
= nautilus_file_get (location
);
784 g_assert (window
->details
->determine_view_file
!= NULL
);
786 /* if the currently viewed file is marked gone while loading the new location,
787 * this ensures that the window isn't destroyed */
788 cancel_viewed_file_changed_callback (window
);
790 nautilus_file_call_when_ready (window
->details
->determine_view_file
,
791 NAUTILUS_FILE_ATTRIBUTE_INFO
|
792 NAUTILUS_FILE_ATTRIBUTE_MOUNT
|
793 NAUTILUS_FILE_ATTRIBUTE_METADATA
,
794 got_file_info_for_view_selection_callback
,
797 g_object_unref (window
);
801 setup_new_window (NautilusWindow
*window
, NautilusFile
*file
)
803 char *show_hidden_file_setting
;
804 char *geometry_string
;
806 gboolean maximized
, sticky
, above
;
808 if (NAUTILUS_IS_SPATIAL_WINDOW (window
) && !NAUTILUS_IS_DESKTOP_WINDOW (window
)) {
809 /* load show hidden state */
810 show_hidden_file_setting
= nautilus_file_get_metadata
811 (file
, NAUTILUS_METADATA_KEY_WINDOW_SHOW_HIDDEN_FILES
,
813 if (show_hidden_file_setting
!= NULL
) {
814 if (strcmp (show_hidden_file_setting
, "1") == 0) {
815 NAUTILUS_WINDOW (window
)->details
->show_hidden_files_mode
= NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_ENABLE
;
817 NAUTILUS_WINDOW (window
)->details
->show_hidden_files_mode
= NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DISABLE
;
820 NAUTILUS_WINDOW (window
)->details
->show_hidden_files_mode
= NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT
;
822 g_free (show_hidden_file_setting
);
824 /* load the saved window geometry */
825 maximized
= nautilus_file_get_boolean_metadata
826 (file
, NAUTILUS_METADATA_KEY_WINDOW_MAXIMIZED
, FALSE
);
828 gtk_window_maximize (GTK_WINDOW (window
));
830 gtk_window_unmaximize (GTK_WINDOW (window
));
833 sticky
= nautilus_file_get_boolean_metadata
834 (file
, NAUTILUS_METADATA_KEY_WINDOW_STICKY
, FALSE
);
836 gtk_window_stick (GTK_WINDOW (window
));
838 gtk_window_unstick (GTK_WINDOW (window
));
841 above
= nautilus_file_get_boolean_metadata
842 (file
, NAUTILUS_METADATA_KEY_WINDOW_KEEP_ABOVE
, FALSE
);
844 gtk_window_set_keep_above (GTK_WINDOW (window
), TRUE
);
846 gtk_window_set_keep_above (GTK_WINDOW (window
), FALSE
);
849 geometry_string
= nautilus_file_get_metadata
850 (file
, NAUTILUS_METADATA_KEY_WINDOW_GEOMETRY
, NULL
);
851 if (geometry_string
!= NULL
) {
852 eel_gtk_window_set_initial_geometry_from_string
853 (GTK_WINDOW (window
),
855 NAUTILUS_SPATIAL_WINDOW_MIN_WIDTH
,
856 NAUTILUS_SPATIAL_WINDOW_MIN_HEIGHT
,
859 g_free (geometry_string
);
861 if (window
->details
->pending_selection
== NULL
) {
862 /* If there is no pending selection, then load the saved scroll position. */
863 scroll_string
= nautilus_file_get_metadata
864 (file
, NAUTILUS_METADATA_KEY_WINDOW_SCROLL_POSITION
,
867 /* If there is a pending selection, we want to scroll to an item in
868 * the pending selection list. */
869 scroll_string
= g_file_get_uri (window
->details
->pending_selection
->data
);
872 /* scroll_string might be NULL if there was no saved scroll position. */
873 if (scroll_string
!= NULL
) {
874 window
->details
->pending_scroll_to
= scroll_string
;
880 GCancellable
*cancellable
;
881 NautilusWindow
*window
;
882 } MountNotMountedData
;
885 mount_not_mounted_callback (GObject
*source_object
,
889 MountNotMountedData
*data
;
890 NautilusWindow
*window
;
892 GCancellable
*cancellable
;
895 window
= data
->window
;
896 cancellable
= data
->cancellable
;
899 if (g_cancellable_is_cancelled (cancellable
)) {
900 /* Cancelled, don't call back */
901 g_object_unref (cancellable
);
905 window
->details
->mount_cancellable
= NULL
;
907 window
->details
->determine_view_file
= nautilus_file_get (window
->details
->pending_location
);
910 if (!g_file_mount_enclosing_volume_finish (G_FILE (source_object
), res
, &error
)) {
911 window
->details
->mount_error
= error
;
912 got_file_info_for_view_selection_callback (window
->details
->determine_view_file
, window
);
913 window
->details
->mount_error
= NULL
;
914 g_error_free (error
);
916 nautilus_file_invalidate_all_attributes (window
->details
->determine_view_file
);
917 nautilus_file_call_when_ready (window
->details
->determine_view_file
,
918 NAUTILUS_FILE_ATTRIBUTE_INFO
|
919 NAUTILUS_FILE_ATTRIBUTE_METADATA
,
920 got_file_info_for_view_selection_callback
,
924 g_object_unref (cancellable
);
928 got_file_info_for_view_selection_callback (NautilusFile
*file
,
929 gpointer callback_data
)
934 NautilusWindow
*window
;
935 NautilusFile
*viewed_file
;
937 GMountOperation
*mount_op
;
938 MountNotMountedData
*data
;
940 window
= callback_data
;
942 g_assert (window
->details
->determine_view_file
== file
);
943 window
->details
->determine_view_file
= NULL
;
945 if (window
->details
->mount_error
) {
946 error
= window
->details
->mount_error
;
948 error
= nautilus_file_get_file_info_error (file
);
951 if (error
&& error
->domain
== G_IO_ERROR
&& error
->code
== G_IO_ERROR_NOT_MOUNTED
&&
952 !window
->details
->tried_mount
) {
953 window
->details
->tried_mount
= TRUE
;
955 mount_op
= eel_mount_operation_new (GTK_WINDOW (window
));
956 location
= nautilus_file_get_location (file
);
957 data
= g_new0 (MountNotMountedData
, 1);
958 data
->cancellable
= g_cancellable_new ();
959 data
->window
= window
;
960 window
->details
->mount_cancellable
= data
->cancellable
;
961 g_file_mount_enclosing_volume (location
, 0, mount_op
, window
->details
->mount_cancellable
,
962 mount_not_mounted_callback
, data
);
963 g_object_unref (location
);
964 g_object_unref (mount_op
);
966 nautilus_file_unref (file
);
971 location
= window
->details
->pending_location
;
976 (error
->domain
== G_IO_ERROR
&& error
->code
== G_IO_ERROR_NOT_SUPPORTED
)) {
977 /* We got the information we need, now pick what view to use: */
979 mimetype
= nautilus_file_get_mime_type (file
);
981 /* If fallback, don't use view from metadata */
982 if (window
->details
->location_change_type
!= NAUTILUS_LOCATION_CHANGE_FALLBACK
) {
983 /* Look in metadata for view */
984 view_id
= nautilus_file_get_metadata
985 (file
, NAUTILUS_METADATA_KEY_DEFAULT_COMPONENT
, NULL
);
986 if (view_id
!= NULL
&&
987 !nautilus_view_factory_view_supports_uri (view_id
,
989 nautilus_file_get_file_type (file
),
996 /* Otherwise, use default */
997 if (view_id
== NULL
) {
998 view_id
= nautilus_global_preferences_get_default_folder_viewer_preference_as_iid ();
1000 if (view_id
!= NULL
&&
1001 !nautilus_view_factory_view_supports_uri (view_id
,
1003 nautilus_file_get_file_type (file
),
1013 if (view_id
!= NULL
) {
1014 if (!GTK_WIDGET_VISIBLE (window
)) {
1015 /* We now have the metadata to set up the window position, etc */
1016 setup_new_window (window
, file
);
1018 create_content_view (window
, view_id
);
1021 display_view_selection_failure (window
, file
,
1024 if (!GTK_WIDGET_VISIBLE (GTK_WIDGET (window
))) {
1025 /* Destroy never-had-a-chance-to-be-seen window. This case
1026 * happens when a new window cannot display its initial URI.
1028 /* if this is the only window, we don't want to quit, so we redirect it to home */
1029 if (nautilus_application_get_n_windows () <= 1) {
1030 g_assert (nautilus_application_get_n_windows () == 1);
1032 /* Make sure we re-use this window */
1033 if (NAUTILUS_IS_SPATIAL_WINDOW (window
)) {
1034 NAUTILUS_SPATIAL_WINDOW (window
)->affect_spatial_window_on_next_location_change
= TRUE
;
1036 /* the user could have typed in a home directory that doesn't exist,
1037 in which case going home would cause an infinite loop, so we
1038 better test for that */
1040 if (!nautilus_is_root_directory (location
)) {
1041 if (!nautilus_is_home_directory (location
)) {
1042 nautilus_window_go_home (NAUTILUS_WINDOW (window
));
1046 root
= g_file_new_for_path ("/");
1047 /* the last fallback is to go to a known place that can't be deleted! */
1048 nautilus_window_go_to (NAUTILUS_WINDOW (window
), root
);
1049 g_object_unref (root
);
1052 gtk_object_destroy (GTK_OBJECT (window
));
1055 /* Since this is a window, destroying it will also unref it. */
1056 gtk_object_destroy (GTK_OBJECT (window
));
1059 /* Clean up state of already-showing window */
1060 end_location_change (window
);
1062 /* We disconnected this, so we need to re-connect it */
1063 viewed_file
= nautilus_file_get (window
->details
->location
);
1064 nautilus_window_set_viewed_file (window
, viewed_file
);
1065 nautilus_file_monitor_add (viewed_file
, &window
->details
->viewed_file
, 0);
1066 g_signal_connect_object (viewed_file
, "changed",
1067 G_CALLBACK (viewed_file_changed_callback
), window
, 0);
1068 nautilus_file_unref (viewed_file
);
1070 /* Leave the location bar showing the bad location that the user
1071 * typed (or maybe achieved by dragging or something). Many times
1072 * the mistake will just be an easily-correctable typo. The user
1073 * can choose "Refresh" to get the original URI back in the location bar.
1078 nautilus_file_unref (file
);
1081 /* Load a view into the window, either reusing the old one or creating
1082 * a new one. This happens when you want to load a new location, or just
1083 * switch to a different view.
1084 * If pending_location is set we're loading a new location and
1085 * pending_location/selection will be used. If not, we're just switching
1086 * view, and the current location will be used.
1089 create_content_view (NautilusWindow
*window
,
1090 const char *view_id
)
1096 /* FIXME bugzilla.gnome.org 41243:
1097 * We should use inheritance instead of these special cases
1098 * for the desktop window.
1100 if (NAUTILUS_IS_DESKTOP_WINDOW (window
)) {
1101 /* We force the desktop to use a desktop_icon_view. It's simpler
1102 * to fix it here than trying to make it pick the right view in
1105 view_id
= NAUTILUS_DESKTOP_ICON_VIEW_IID
;
1108 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1109 NAUTILUS_ACTION_ZOOM_IN
);
1110 gtk_action_set_sensitive (action
, FALSE
);
1111 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1112 NAUTILUS_ACTION_ZOOM_OUT
);
1113 gtk_action_set_sensitive (action
, FALSE
);
1114 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1115 NAUTILUS_ACTION_ZOOM_NORMAL
);
1116 gtk_action_set_sensitive (action
, FALSE
);
1118 if (window
->content_view
!= NULL
&&
1119 eel_strcmp (nautilus_view_get_view_id (window
->content_view
),
1121 /* reuse existing content view */
1122 view
= window
->content_view
;
1123 window
->new_content_view
= view
;
1124 g_object_ref (view
);
1126 /* create a new content view */
1127 view
= nautilus_view_factory_create (view_id
,
1128 NAUTILUS_WINDOW_INFO (window
));
1130 eel_accessibility_set_name (view
, _("Content View"));
1131 eel_accessibility_set_description (view
, _("View of the current folder"));
1133 connect_view (window
, view
);
1135 window
->new_content_view
= view
;
1138 /* Actually load the pending location and selection: */
1140 if (window
->details
->pending_location
!= NULL
) {
1141 load_new_location (window
,
1142 window
->details
->pending_location
,
1143 window
->details
->pending_selection
,
1147 eel_g_object_list_free (window
->details
->pending_selection
);
1148 window
->details
->pending_selection
= NULL
;
1149 } else if (window
->details
->location
!= NULL
) {
1150 selection
= nautilus_view_get_selection (window
->content_view
);
1151 load_new_location (window
,
1152 window
->details
->location
,
1156 eel_g_object_list_free (selection
);
1158 /* Something is busted, there was no location to load.
1159 Just load the homedir. */
1160 nautilus_window_go_home (NAUTILUS_WINDOW (window
));
1166 load_new_location (NautilusWindow
*window
,
1169 gboolean tell_current_content_view
,
1170 gboolean tell_new_content_view
)
1172 GList
*selection_copy
;
1176 g_assert (NAUTILUS_IS_WINDOW (window
));
1177 g_assert (location
!= NULL
);
1179 selection_copy
= eel_g_object_list_copy (selection
);
1183 /* Note, these may recurse into report_load_underway */
1184 if (window
->content_view
!= NULL
&& tell_current_content_view
) {
1185 view
= window
->content_view
;
1186 uri
= g_file_get_uri (location
);
1187 nautilus_view_load_location (window
->content_view
, uri
);
1191 if (window
->new_content_view
!= NULL
&& tell_new_content_view
&&
1192 (!tell_current_content_view
||
1193 window
->new_content_view
!= window
->content_view
) ) {
1194 view
= window
->new_content_view
;
1195 uri
= g_file_get_uri (location
);
1196 nautilus_view_load_location (window
->new_content_view
, uri
);
1200 /* window->new_content_view might have changed here if
1201 report_load_underway was called from load_location */
1202 nautilus_view_set_selection (view
, selection_copy
);
1205 eel_g_object_list_free (selection_copy
);
1208 /* A view started to load the location its viewing, either due to
1209 * a load_location request, or some internal reason. Expect
1210 * a matching load_compete later
1213 nautilus_window_report_load_underway (NautilusWindow
*window
,
1216 g_assert (NAUTILUS_IS_WINDOW (window
));
1218 if (view
== window
->new_content_view
) {
1219 location_has_really_changed (window
);
1220 } else if (view
== window
->content_view
) {
1221 nautilus_window_allow_stop (window
, TRUE
);
1223 g_warning ("Got load_underway report from unknown view");
1227 /* This is called when we have decided we can actually change to the new view/location situation. */
1229 location_has_really_changed (NautilusWindow
*window
)
1232 GFile
*location_copy
;
1235 location_copy
= NULL
;
1237 if (window
->new_content_view
!= NULL
) {
1238 widget
= nautilus_view_get_widget (window
->new_content_view
);
1239 /* Switch to the new content view. */
1240 if (widget
->parent
== NULL
) {
1241 disconnect_view (window
, window
->content_view
);
1242 nautilus_window_set_content_view_widget (window
, window
->new_content_view
);
1244 g_object_unref (window
->new_content_view
);
1245 window
->new_content_view
= NULL
;
1248 if (window
->details
->pending_location
!= NULL
) {
1249 location_copy
= g_object_ref (window
->details
->pending_location
);
1250 /* Tell the window we are finished. */
1251 update_for_new_location (window
);
1254 free_location_change (window
);
1256 if (location_copy
!= NULL
) {
1257 uri
= g_file_get_uri (location_copy
);
1258 g_signal_emit_by_name (window
, "loading_uri", uri
);
1260 g_object_unref (location_copy
);
1265 add_extension_extra_widgets (NautilusWindow
*window
, GFile
*location
)
1267 GList
*providers
, *l
;
1271 providers
= nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_LOCATION_WIDGET_PROVIDER
);
1273 uri
= g_file_get_uri (location
);
1274 for (l
= providers
; l
!= NULL
; l
= l
->next
) {
1275 NautilusLocationWidgetProvider
*provider
;
1277 provider
= NAUTILUS_LOCATION_WIDGET_PROVIDER (l
->data
);
1278 widget
= nautilus_location_widget_provider_get_widget (provider
, uri
, GTK_WIDGET (window
));
1279 if (widget
!= NULL
) {
1280 nautilus_window_add_extra_location_widget (window
, widget
);
1285 nautilus_module_extension_list_free (providers
);
1289 nautilus_window_show_x_content_bar (NautilusWindow
*window
, GMount
*mount
, const char **x_content_types
)
1293 g_assert (NAUTILUS_IS_WINDOW (window
));
1295 for (n
= 0; x_content_types
[n
] != NULL
; n
++) {
1296 GAppInfo
*default_app
;
1298 /* skip blank media; the burn:/// location will provide it's own cluebar */
1299 if (g_str_has_prefix (x_content_types
[n
], "x-content/blank-")) {
1303 /* only show the cluebar if a default app is available */
1304 default_app
= g_app_info_get_default_for_type (x_content_types
[n
], FALSE
);
1305 if (default_app
!= NULL
) {
1307 bar
= nautilus_x_content_bar_new (mount
, x_content_types
[n
]);
1308 gtk_widget_show (bar
);
1309 nautilus_window_add_extra_location_widget (window
, bar
);
1310 g_object_unref (default_app
);
1316 nautilus_window_show_trash_bar (NautilusWindow
*window
)
1320 g_assert (NAUTILUS_IS_WINDOW (window
));
1322 bar
= nautilus_trash_bar_new ();
1323 gtk_widget_show (bar
);
1325 nautilus_window_add_extra_location_widget (window
, bar
);
1329 NautilusWindow
*window
;
1330 GCancellable
*cancellable
;
1335 found_content_type_cb (const char **x_content_types
, FindMountData
*data
)
1337 NautilusWindow
*window
;
1339 if (g_cancellable_is_cancelled (data
->cancellable
)) {
1343 window
= data
->window
;
1345 if (x_content_types
!= NULL
&& x_content_types
[0] != NULL
) {
1346 nautilus_window_show_x_content_bar (window
, data
->mount
, x_content_types
);
1347 update_extra_location_widgets_visibility (window
);
1350 window
->details
->find_mount_cancellable
= NULL
;
1353 g_object_unref (data
->mount
);
1354 g_object_unref (data
->cancellable
);
1359 found_mount_cb (GObject
*source_object
,
1363 FindMountData
*data
= user_data
;
1365 NautilusWindow
*window
;
1367 if (g_cancellable_is_cancelled (data
->cancellable
)) {
1371 window
= data
->window
;
1373 mount
= g_file_find_enclosing_mount_finish (G_FILE (source_object
),
1376 if (mount
!= NULL
) {
1377 data
->mount
= mount
;
1378 nautilus_autorun_get_x_content_types_for_mount_async (mount
,
1379 (NautilusAutorunGetContent
)found_content_type_cb
,
1385 window
->details
->find_mount_cancellable
= NULL
;
1388 g_object_unref (data
->cancellable
);
1392 /* Handle the changes for the NautilusWindow itself. */
1394 update_for_new_location (NautilusWindow
*window
)
1396 GFile
*new_location
;
1398 NautilusDirectory
*directory
;
1399 gboolean location_really_changed
;
1401 FindMountData
*data
;
1403 new_location
= window
->details
->pending_location
;
1404 window
->details
->pending_location
= NULL
;
1406 set_displayed_location (window
, new_location
);
1408 update_history (window
, window
->details
->location_change_type
, new_location
);
1410 location_really_changed
=
1411 window
->details
->location
== NULL
||
1412 !g_file_equal (window
->details
->location
, new_location
);
1414 /* Set the new location. */
1415 if (window
->details
->location
) {
1416 g_object_unref (window
->details
->location
);
1418 window
->details
->location
= new_location
;
1420 /* Create a NautilusFile for this location, so we can catch it
1423 cancel_viewed_file_changed_callback (window
);
1424 file
= nautilus_file_get (window
->details
->location
);
1425 nautilus_window_set_viewed_file (window
, file
);
1426 window
->details
->viewed_file_seen
= !nautilus_file_is_not_yet_confirmed (file
);
1427 window
->details
->viewed_file_in_trash
= nautilus_file_is_in_trash (file
);
1428 nautilus_file_monitor_add (file
, &window
->details
->viewed_file
, 0);
1429 g_signal_connect_object (file
, "changed",
1430 G_CALLBACK (viewed_file_changed_callback
), window
, 0);
1431 nautilus_file_unref (file
);
1433 /* Check if we can go up. */
1434 update_up_button (window
);
1436 /* Set up the initial zoom levels */
1437 zoom_parameters_changed_callback (window
->content_view
,
1440 /* Set up the content view menu for this new location. */
1441 nautilus_window_load_view_as_menus (window
);
1443 /* Load menus from nautilus extensions for this location */
1444 nautilus_window_load_extension_menus (window
);
1446 if (location_really_changed
) {
1447 remove_extra_location_widgets (window
);
1449 directory
= nautilus_directory_get (window
->details
->location
);
1450 if (NAUTILUS_IS_SEARCH_DIRECTORY (directory
)) {
1451 nautilus_window_set_search_mode (window
, TRUE
, NAUTILUS_SEARCH_DIRECTORY (directory
));
1453 nautilus_window_set_search_mode (window
, FALSE
, NULL
);
1456 if (nautilus_directory_is_in_trash (directory
)) {
1457 nautilus_window_show_trash_bar (window
);
1460 /* need the mount to determine if we should put up the x-content cluebar */
1461 if (window
->details
->find_mount_cancellable
!= NULL
) {
1462 g_cancellable_cancel (window
->details
->find_mount_cancellable
);
1463 window
->details
->find_mount_cancellable
= NULL
;
1466 data
= g_new (FindMountData
, 1);
1467 data
->window
= window
;
1468 data
->cancellable
= g_cancellable_new ();
1471 window
->details
->find_mount_cancellable
= data
->cancellable
;
1472 g_file_find_enclosing_mount_async (window
->details
->location
,
1478 nautilus_directory_unref (directory
);
1480 add_extension_extra_widgets (window
, window
->details
->location
);
1482 update_extra_location_widgets_visibility (window
);
1485 #if !NEW_UI_COMPLETE
1486 if (NAUTILUS_IS_NAVIGATION_WINDOW (window
)) {
1487 /* Check if the back and forward buttons need enabling or disabling. */
1488 nautilus_navigation_window_allow_back (NAUTILUS_NAVIGATION_WINDOW (window
), NAUTILUS_NAVIGATION_WINDOW (window
)->back_list
!= NULL
);
1489 nautilus_navigation_window_allow_forward (NAUTILUS_NAVIGATION_WINDOW (window
), NAUTILUS_NAVIGATION_WINDOW (window
)->forward_list
!= NULL
);
1491 /* Change the location bar and path bar to match the current location. */
1492 uri
= g_file_get_uri (window
->details
->location
);
1493 nautilus_navigation_bar_set_location (NAUTILUS_NAVIGATION_BAR (NAUTILUS_NAVIGATION_WINDOW (window
)->navigation_bar
),
1496 nautilus_path_bar_set_path (NAUTILUS_PATH_BAR (NAUTILUS_NAVIGATION_WINDOW (window
)->path_bar
),
1497 window
->details
->location
);
1498 nautilus_navigation_window_load_extension_toolbar_items (NAUTILUS_NAVIGATION_WINDOW (window
));
1501 if (NAUTILUS_IS_SPATIAL_WINDOW (window
)) {
1502 /* Change the location button to match the current location. */
1503 nautilus_spatial_window_set_location_button (NAUTILUS_SPATIAL_WINDOW (window
),
1504 window
->details
->location
);
1509 /* A location load previously announced by load_underway
1510 * has been finished */
1512 nautilus_window_report_load_complete (NautilusWindow
*window
,
1515 g_assert (NAUTILUS_IS_WINDOW (window
));
1517 /* Only handle this if we're expecting it.
1518 * Don't handle it if its from an old view we've switched from */
1519 if (view
== window
->content_view
) {
1520 if (window
->details
->pending_scroll_to
!= NULL
) {
1521 nautilus_view_scroll_to_file (window
->content_view
,
1522 window
->details
->pending_scroll_to
);
1524 end_location_change (window
);
1529 end_location_change (NautilusWindow
*window
)
1533 uri
= nautilus_window_get_location_uri (window
);
1535 nautilus_debug_log (FALSE
, NAUTILUS_DEBUG_LOG_DOMAIN_USER
,
1536 "finished loading window %p: %s", window
, uri
);
1540 nautilus_window_allow_stop (window
, FALSE
);
1542 /* Now we can free pending_scroll_to, since the load_complete
1543 * callback already has been emitted.
1545 g_free (window
->details
->pending_scroll_to
);
1546 window
->details
->pending_scroll_to
= NULL
;
1548 free_location_change (window
);
1552 free_location_change (NautilusWindow
*window
)
1554 if (window
->details
->pending_location
) {
1555 g_object_unref (window
->details
->pending_location
);
1557 window
->details
->pending_location
= NULL
;
1559 eel_g_object_list_free (window
->details
->pending_selection
);
1560 window
->details
->pending_selection
= NULL
;
1562 /* Don't free pending_scroll_to, since thats needed until
1563 * the load_complete callback.
1566 if (window
->details
->mount_cancellable
!= NULL
) {
1567 g_cancellable_cancel (window
->details
->mount_cancellable
);
1568 window
->details
->mount_cancellable
= NULL
;
1571 if (window
->details
->determine_view_file
!= NULL
) {
1572 nautilus_file_cancel_call_when_ready
1573 (window
->details
->determine_view_file
,
1574 got_file_info_for_view_selection_callback
, window
);
1575 window
->details
->determine_view_file
= NULL
;
1578 if (window
->new_content_view
!= NULL
) {
1579 disconnect_view (window
, window
->new_content_view
);
1580 g_object_unref (window
->new_content_view
);
1581 window
->new_content_view
= NULL
;
1586 cancel_location_change (NautilusWindow
*window
)
1590 if (window
->details
->pending_location
!= NULL
1591 && window
->details
->location
!= NULL
1592 && window
->content_view
!= NULL
) {
1594 /* No need to tell the new view - either it is the
1595 * same as the old view, in which case it will already
1596 * be told, or it is the very pending change we wish
1599 selection
= nautilus_view_get_selection (window
->content_view
);
1600 load_new_location (window
,
1601 window
->details
->location
,
1605 eel_g_object_list_free (selection
);
1608 end_location_change (window
);
1612 nautilus_window_report_view_failed (NautilusWindow
*window
,
1615 gboolean do_close_window
;
1616 GFile
*fallback_load_location
;
1617 g_warning ("A view failed. The UI will handle this with a dialog but this should be debugged.");
1620 do_close_window
= FALSE
;
1621 fallback_load_location
= NULL
;
1623 if (view
== window
->content_view
) {
1624 disconnect_view (window
, window
->content_view
);
1625 nautilus_window_set_content_view_widget (window
, NULL
);
1627 report_current_content_view_failure_to_user (window
, view
);
1629 /* Only report error on first try */
1630 if (window
->details
->location_change_type
!= NAUTILUS_LOCATION_CHANGE_FALLBACK
) {
1631 report_nascent_content_view_failure_to_user (window
, view
);
1633 fallback_load_location
= g_object_ref (window
->details
->pending_location
);
1635 if (!GTK_WIDGET_VISIBLE (window
)) {
1636 do_close_window
= TRUE
;
1641 cancel_location_change (window
);
1643 if (fallback_load_location
!= NULL
) {
1644 /* We loose the pending selection change here, but who cares... */
1645 begin_location_change (window
, fallback_load_location
, NULL
,
1646 NAUTILUS_LOCATION_CHANGE_FALLBACK
, 0, NULL
);
1647 g_object_unref (fallback_load_location
);
1650 if (do_close_window
) {
1651 gtk_widget_destroy (GTK_WIDGET (window
));
1656 display_view_selection_failure (NautilusWindow
*window
, NautilusFile
*file
,
1657 GFile
*location
, GError
*error
)
1659 char *full_uri_for_display
;
1660 char *uri_for_display
;
1661 char *error_message
;
1662 char *detail_message
;
1663 char *scheme_string
;
1666 /* Some sort of failure occurred. How 'bout we tell the user? */
1667 full_uri_for_display
= g_file_get_parse_name (location
);
1668 /* Truncate the URI so it doesn't get insanely wide. Note that even
1669 * though the dialog uses wrapped text, if the URI doesn't contain
1670 * white space then the text-wrapping code is too stupid to wrap it.
1672 uri_for_display
= eel_str_middle_truncate
1673 (full_uri_for_display
, MAX_URI_IN_DIALOG_LENGTH
);
1674 g_free (full_uri_for_display
);
1676 error_message
= NULL
;
1677 detail_message
= NULL
;
1678 if (error
== NULL
) {
1679 if (nautilus_file_is_directory (file
)) {
1680 error_message
= g_strdup_printf
1681 (_("Could not display \"%s\"."),
1683 detail_message
= g_strdup
1684 (_("Nautilus has no installed viewer capable of displaying the folder."));
1686 error_message
= g_strdup_printf
1687 (_("Could not display \"%s\"."),
1689 detail_message
= g_strdup
1690 (_("The location is not a folder."));
1692 } else if (error
->domain
== G_IO_ERROR
) {
1693 switch (error
->code
) {
1694 case G_IO_ERROR_NOT_FOUND
:
1695 error_message
= g_strdup_printf
1696 (_("Could not find \"%s\"."),
1698 detail_message
= g_strdup
1699 (_("Please check the spelling and try again."));
1701 case G_IO_ERROR_NOT_SUPPORTED
:
1702 scheme_string
= g_file_get_uri_scheme (location
);
1704 error_message
= g_strdup_printf (_("Could not display \"%s\"."),
1706 if (scheme_string
!= NULL
) {
1707 detail_message
= g_strdup_printf (_("Nautilus cannot handle \"%s\" locations."),
1710 detail_message
= g_strdup (_("Nautilus cannot handle this kind of locations."));
1712 g_free (scheme_string
);
1714 case G_IO_ERROR_NOT_MOUNTED
:
1715 error_message
= g_strdup_printf (_("Could not display \"%s\"."),
1717 detail_message
= g_strdup (_("Unable to mount the location."));
1720 case G_IO_ERROR_PERMISSION_DENIED
:
1721 error_message
= g_strdup_printf (_("Could not display \"%s\"."),
1723 detail_message
= g_strdup (_("Access was denied."));
1726 case G_IO_ERROR_HOST_NOT_FOUND
:
1727 /* This case can be hit for user-typed strings like "foo" due to
1728 * the code that guesses web addresses when there's no initial "/".
1729 * But this case is also hit for legitimate web addresses when
1730 * the proxy is set up wrong.
1732 error_message
= g_strdup_printf (_("Could not display \"%s\", because the host could not be found."),
1734 detail_message
= g_strdup (_("Check that the spelling is correct and that your proxy settings are correct."));
1736 case G_IO_ERROR_CANCELLED
:
1737 g_free (uri_for_display
);
1745 if (error_message
== NULL
) {
1746 error_message
= g_strdup_printf (_("Could not display \"%s\"."),
1748 detail_message
= g_strdup_printf (_("Error: %s\nPlease select another viewer and try again."), error
->message
);
1751 dialog
= eel_show_error_dialog (error_message
, detail_message
, NULL
);
1753 g_free (uri_for_display
);
1754 g_free (error_message
);
1755 g_free (detail_message
);
1760 nautilus_window_stop_loading (NautilusWindow
*window
)
1762 nautilus_view_stop_loading (window
->content_view
);
1764 if (window
->new_content_view
!= NULL
) {
1765 nautilus_view_stop_loading (window
->new_content_view
);
1768 cancel_location_change (window
);
1772 nautilus_window_set_content_view (NautilusWindow
*window
,
1778 g_return_if_fail (NAUTILUS_IS_WINDOW (window
));
1779 g_return_if_fail (window
->details
->location
!= NULL
);
1780 g_return_if_fail (id
!= NULL
);
1782 location
= nautilus_window_get_location_uri (window
);
1783 nautilus_debug_log (FALSE
, NAUTILUS_DEBUG_LOG_DOMAIN_USER
,
1784 "change view of window %p: \"%s\" to \"%s\"",
1785 window
, location
, id
);
1788 if (nautilus_window_content_view_matches_iid (window
, id
)) {
1792 end_location_change (window
);
1794 file
= nautilus_file_get (window
->details
->location
);
1795 nautilus_file_set_metadata
1796 (file
, NAUTILUS_METADATA_KEY_DEFAULT_COMPONENT
, NULL
, id
);
1797 nautilus_file_unref (file
);
1799 nautilus_window_allow_stop (window
, TRUE
);
1801 if (nautilus_view_get_selection_count (window
->content_view
) == 0) {
1802 /* If there is no selection, queue a scroll to the same icon that
1803 * is currently visible */
1804 window
->details
->pending_scroll_to
= nautilus_view_get_first_visible_file (window
->content_view
);
1806 window
->details
->location_change_type
= NAUTILUS_LOCATION_CHANGE_RELOAD
;
1808 create_content_view (window
, id
);
1812 zoom_level_changed_callback (NautilusView
*view
,
1813 NautilusWindow
*window
)
1816 gboolean supports_zooming
;
1818 g_assert (NAUTILUS_IS_WINDOW (window
));
1820 /* This is called each time the component successfully completed
1821 * a zooming operation.
1824 supports_zooming
= nautilus_view_supports_zooming (view
);
1826 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1827 NAUTILUS_ACTION_ZOOM_IN
);
1828 gtk_action_set_visible (action
, supports_zooming
);
1829 gtk_action_set_sensitive (action
,
1830 nautilus_view_can_zoom_in (view
));
1832 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1833 NAUTILUS_ACTION_ZOOM_OUT
);
1834 gtk_action_set_visible (action
, supports_zooming
);
1835 gtk_action_set_sensitive (action
,
1836 nautilus_view_can_zoom_out (view
));
1838 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1839 NAUTILUS_ACTION_ZOOM_NORMAL
);
1840 gtk_action_set_visible (action
, supports_zooming
);
1841 gtk_action_set_sensitive (action
, supports_zooming
);
1845 zoom_parameters_changed_callback (NautilusView
*view
,
1846 NautilusWindow
*window
)
1851 g_assert (NAUTILUS_IS_WINDOW (window
));
1853 /* The initial zoom level of a component is allowed to be 0.0 if
1854 * there is no file loaded yet. In this case we need to set the
1855 * commands insensitive but display the zoom control nevertheless
1856 * (the component is just temporarily unable to zoom, but the
1857 * zoom control will "do the right thing" here).
1859 zoom_level
= nautilus_view_get_zoom_level (view
);
1860 if (zoom_level
== 0.0) {
1861 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1862 NAUTILUS_ACTION_ZOOM_IN
);
1863 gtk_action_set_sensitive (action
, FALSE
);
1864 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1865 NAUTILUS_ACTION_ZOOM_OUT
);
1866 gtk_action_set_sensitive (action
, FALSE
);
1867 action
= gtk_action_group_get_action (window
->details
->main_action_group
,
1868 NAUTILUS_ACTION_ZOOM_NORMAL
);
1869 gtk_action_set_sensitive (action
, FALSE
);
1871 /* Don't attempt to set 0.0 as zoom level. */
1875 /* "zoom_parameters_changed" always implies "zoom_level_changed",
1876 * but you won't get both signals, so we need to pass it down.
1878 zoom_level_changed_callback (view
, window
);
1882 title_changed_callback (NautilusView
*view
,
1883 NautilusWindow
*window
)
1885 g_assert (NAUTILUS_IS_WINDOW (window
));
1887 nautilus_window_update_title (window
);
1888 nautilus_window_update_icon (window
);
1892 connect_view (NautilusWindow
*window
,
1895 g_signal_connect (view
, "title_changed",
1896 G_CALLBACK (title_changed_callback
), window
);
1897 g_signal_connect (view
, "zoom_level_changed",
1898 G_CALLBACK (zoom_level_changed_callback
), window
);
1899 g_signal_connect (view
, "zoom_parameters_changed",
1900 G_CALLBACK (zoom_parameters_changed_callback
), window
);
1904 disconnect_view (NautilusWindow
*window
,
1911 g_signal_handlers_disconnect_by_func (view
, title_changed_callback
, window
);
1912 g_signal_handlers_disconnect_by_func (view
, zoom_level_changed_callback
, window
);
1913 g_signal_handlers_disconnect_by_func (view
, zoom_parameters_changed_callback
, window
);
1917 nautilus_window_manage_views_destroy (NautilusWindow
*window
)
1919 /* Disconnect view signals here so they don't trigger when
1920 * views are destroyed.
1923 if (window
->content_view
!= NULL
) {
1924 disconnect_view (window
, window
->content_view
);
1926 if (window
->new_content_view
!= NULL
) {
1927 disconnect_view (window
, window
->new_content_view
);
1932 nautilus_window_manage_views_finalize (NautilusWindow
*window
)
1934 free_location_change (window
);
1935 cancel_viewed_file_changed_callback (window
);
1939 nautilus_navigation_window_back_or_forward (NautilusNavigationWindow
*window
,
1940 gboolean back
, guint distance
)
1946 NautilusBookmark
*bookmark
;
1948 list
= back
? window
->back_list
: window
->forward_list
;
1950 len
= (guint
) g_list_length (list
);
1952 /* If we can't move in the direction at all, just return. */
1956 /* If the distance to move is off the end of the list, go to the end
1958 if (distance
>= len
)
1961 bookmark
= g_list_nth_data (list
, distance
);
1962 location
= nautilus_bookmark_get_location (bookmark
);
1963 scroll_pos
= nautilus_bookmark_get_scroll_pos (bookmark
);
1964 begin_location_change
1965 (NAUTILUS_WINDOW (window
),
1967 back
? NAUTILUS_LOCATION_CHANGE_BACK
: NAUTILUS_LOCATION_CHANGE_FORWARD
,
1971 g_object_unref (location
);
1972 g_free (scroll_pos
);
1975 /* reload the contents of the window */
1977 nautilus_window_reload (NautilusWindow
*window
)
1983 g_return_if_fail (NAUTILUS_IS_WINDOW (window
));
1985 if (window
->details
->location
== NULL
) {
1989 /* window->details->location can be free'd during the processing
1990 * of begin_location_change, so make a copy
1992 location
= g_object_ref (window
->details
->location
);
1995 if (window
->content_view
!= NULL
) {
1996 current_pos
= nautilus_view_get_first_visible_file (window
->content_view
);
1997 selection
= nautilus_view_get_selection (window
->content_view
);
1999 begin_location_change
2000 (window
, location
, selection
,
2001 NAUTILUS_LOCATION_CHANGE_RELOAD
, 0, current_pos
);
2002 g_free (current_pos
);
2003 g_object_unref (location
);
2004 eel_g_object_list_free (selection
);
2008 remove_all (GtkWidget
*widget
,
2011 GtkContainer
*container
;
2012 container
= GTK_CONTAINER (data
);
2014 gtk_container_remove (container
, widget
);
2018 remove_extra_location_widgets (NautilusWindow
*window
)
2020 gtk_container_foreach (GTK_CONTAINER (window
->details
->extra_location_widgets
),
2022 window
->details
->extra_location_widgets
);
2026 nautilus_window_add_extra_location_widget (NautilusWindow
*window
,
2029 gtk_box_pack_start (GTK_BOX (window
->details
->extra_location_widgets
),
2030 widget
, TRUE
, TRUE
, 0);
2034 update_extra_location_widgets_visibility (NautilusWindow
*window
)
2038 children
= gtk_container_get_children (GTK_CONTAINER (window
->details
->extra_location_widgets
));
2040 if (children
!= NULL
) {
2041 gtk_widget_show (window
->details
->extra_location_widgets
);
2043 gtk_widget_hide (window
->details
->extra_location_widgets
);
2045 g_list_free (children
);