Index: libnautilus-private/nautilus-file-utilities.c =================================================================== RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-utilities.c,v retrieving revision 1.114 diff -u -p -r1.114 nautilus-file-utilities.c --- libnautilus-private/nautilus-file-utilities.c 12 Dec 2003 17:55:45 -0000 1.114 +++ libnautilus-private/nautilus-file-utilities.c 7 Jan 2004 18:00:51 -0000 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -356,6 +357,25 @@ nautilus_unique_temporary_file_name (voi return file_name; } +const char * +nautilus_get_vfs_method_display_name (char *method) +{ + if (g_ascii_strcasecmp (method, "computer") == 0 ) { + return _("Computer"); + } else if (g_ascii_strcasecmp (method, "network") == 0 ) { + return _("Network"); + } else if (g_ascii_strcasecmp (method, "fonts") == 0 ) { + return _("Fonts"); + } else if (g_ascii_strcasecmp (method, "themes") == 0 ) { + return _("Themes"); + } else if (g_ascii_strcasecmp (method, "burn") == 0 ) { + return _("CD Creator"); + } else if (g_ascii_strcasecmp (method, "smb") == 0 ) { + return _("Windows Network"); + } + return NULL; +} + #if !defined (NAUTILUS_OMIT_SELF_CHECK) void Index: libnautilus-private/nautilus-file-utilities.h =================================================================== RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-utilities.h,v retrieving revision 1.51 diff -u -p -r1.51 nautilus-file-utilities.h --- libnautilus-private/nautilus-file-utilities.h 12 Dec 2003 17:55:45 -0000 1.51 +++ libnautilus-private/nautilus-file-utilities.h 7 Jan 2004 18:00:51 -0000 @@ -69,4 +69,6 @@ char * nautilus_unique_temporary_file_ char * nautilus_find_file_in_gnome_path (char *file); GList * nautilus_find_all_files_in_gnome_path (char *file); +const char *nautilus_get_vfs_method_display_name (char *method); + #endif /* NAUTILUS_FILE_UTILITIES_H */ Index: src/nautilus-shell-ui.xml =================================================================== RCS file: /cvs/gnome/nautilus/src/nautilus-shell-ui.xml,v retrieving revision 1.109 diff -u -p -r1.109 nautilus-shell-ui.xml --- src/nautilus-shell-ui.xml 30 Sep 2003 20:37:20 -0000 1.109 +++ src/nautilus-shell-ui.xml 7 Jan 2004 18:00:51 -0000 @@ -214,6 +214,7 @@ + Index: src/nautilus-spatial-window.c =================================================================== RCS file: /cvs/gnome/nautilus/src/nautilus-spatial-window.c,v retrieving revision 1.422 diff -u -p -r1.422 nautilus-spatial-window.c --- src/nautilus-spatial-window.c 3 Jan 2004 18:34:42 -0000 1.422 +++ src/nautilus-spatial-window.c 7 Jan 2004 18:00:51 -0000 @@ -34,6 +34,7 @@ #include "nautilus-application.h" #include "nautilus-desktop-window.h" #include "nautilus-bookmarks-window.h" +#include "nautilus-file-utilities.h" #include "nautilus-location-dialog.h" #include "nautilus-main.h" #include "nautilus-signaller.h" @@ -89,6 +90,10 @@ struct _NautilusSpatialWindowDetails { guint save_geometry_timeout_id; GtkWidget *content_box; + GtkWidget *location_button; + GtkWidget *location_statusbar; + + GnomeVFSURI *location; }; GNOME_CLASS_BOILERPLATE (NautilusSpatialWindow, nautilus_spatial_window, @@ -189,6 +194,10 @@ nautilus_spatial_window_finalize (GObjec window = NAUTILUS_SPATIAL_WINDOW (object); + if (window->details->location != NULL) { + gnome_vfs_uri_unref (window->details->location); + } + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -282,6 +291,7 @@ static void real_merge_menus (NautilusWindow *nautilus_window) { NautilusSpatialWindow *window; + BonoboControl *control; BonoboUIVerb verbs [] = { BONOBO_UI_VERB ("Close Parent Folders", file_menu_close_parent_windows_callback), BONOBO_UI_VERB ("UpCloseCurrent", go_up_close_current_window_callback), @@ -300,6 +310,12 @@ real_merge_menus (NautilusWindow *nautil bonobo_ui_component_add_verb_list_with_data (nautilus_window->details->shell_ui, verbs, window); + + control = bonobo_control_new (window->details->location_statusbar); + bonobo_ui_component_object_set (nautilus_window->details->shell_ui, + "/status/StatusButton", + BONOBO_OBJREF (control), + NULL); } static void @@ -332,8 +348,158 @@ real_get_default_size(NautilusWindow *wi } static void +location_menu_item_activated_callback (GtkWidget *menu_item, + NautilusSpatialWindow *window) +{ + GnomeVFSURI *uri; + char *location; + + uri = g_object_get_data (G_OBJECT (menu_item), "uri"); + location = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + nautilus_window_go_to (NAUTILUS_WINDOW (window), location); + g_free (location); + +} + +static void +menu_deactivate_callback (GtkWidget *menu, + gpointer data) +{ + GMainLoop *loop; + + loop = data; + + if (g_main_loop_is_running (loop)) { + g_main_loop_quit (loop); + } +} + +static void +menu_popup_pos (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data) +{ + GtkWidget *widget; + GtkRequisition menu_requisition, button_requisition; + + widget = user_data; + + gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition); + gtk_widget_size_request (widget, &button_requisition); + + gdk_window_get_origin (widget->window, x, y); + + *y -= menu_requisition.height - button_requisition.height; + + *push_in = TRUE; +} + +static char * +get_uri_name (GnomeVFSURI *uri) +{ + char *name, *short_name; + const char *method; + + if (!gnome_vfs_uri_has_parent (uri) && + g_ascii_strcasecmp (uri->method_string, "file") != 0) { + method = nautilus_get_vfs_method_display_name (uri->method_string); + if (method == NULL) { + method = uri->method_string; + } + + short_name = gnome_vfs_uri_extract_short_name (uri); + if (short_name == NULL || + strcmp (short_name, GNOME_VFS_URI_PATH_STR) == 0) { + return g_strdup (method); + } + name = g_strdup_printf ("%s: %s", method, short_name); + g_free (short_name); + } else { + name = gnome_vfs_uri_extract_short_name (uri); + } + return name; +} + +static void +location_button_clicked_callback (GtkWidget *widget, NautilusSpatialWindow *window) +{ + GtkWidget *popup, *menu_item; + GnomeVFSURI *uri; + char *name; + GMainLoop *loop; + + g_return_if_fail (window->details->location != NULL); + + popup = gtk_menu_new (); + + uri = gnome_vfs_uri_ref (window->details->location); + while (uri != NULL) { + name = get_uri_name (uri); + menu_item = gtk_image_menu_item_new_with_label (name); + g_free (name); + gtk_widget_show (menu_item); + g_signal_connect (menu_item, "activate", + G_CALLBACK (location_menu_item_activated_callback), + window); + g_object_set_data_full (G_OBJECT (menu_item), "uri", uri, (GDestroyNotify)gnome_vfs_uri_unref); + + gtk_menu_shell_prepend (GTK_MENU_SHELL (popup), menu_item); + + uri = gnome_vfs_uri_get_parent (uri); + } + gtk_menu_set_screen (GTK_MENU (popup), gtk_widget_get_screen (widget)); + + loop = g_main_loop_new (NULL, FALSE); + + g_signal_connect (popup, "deactivate", + G_CALLBACK (menu_deactivate_callback), + loop); + + gtk_grab_add (popup); + gtk_menu_popup (GTK_MENU (popup), NULL, NULL, menu_popup_pos, widget, 1, GDK_CURRENT_TIME); + g_main_loop_run (loop); + gtk_grab_remove (popup); + g_main_loop_unref (loop); + gtk_object_sink (GTK_OBJECT (popup)); +} + +void +nautilus_spatial_window_set_location_button (NautilusSpatialWindow *window, + const char *location) +{ + GnomeVFSURI *uri; + char *name; + + uri = NULL; + if (location != NULL) { + uri = gnome_vfs_uri_new (location); + } + if (uri != NULL) { + name = get_uri_name (uri); + gtk_button_set_label (GTK_BUTTON (window->details->location_button), + name); + g_free (name); + gtk_widget_set_sensitive (window->details->location_button, TRUE); + } else { + gtk_button_set_label (GTK_BUTTON (window->details->location_button), + ""); + gtk_widget_set_sensitive (window->details->location_button, FALSE); + } + + if (window->details->location != NULL) { + gnome_vfs_uri_unref (window->details->location); + } + window->details->location = uri; +} + +static void nautilus_spatial_window_instance_init (NautilusSpatialWindow *window) { + GtkShadowType shadow_type; + GtkWidget *frame; + window->details = g_new0 (NautilusSpatialWindowDetails, 1); window->affect_spatial_window_on_next_location_change = TRUE; @@ -342,6 +508,35 @@ nautilus_spatial_window_instance_init (N gtk_widget_show (window->details->content_box); bonobo_window_set_contents (BONOBO_WINDOW (window), window->details->content_box); + + window->details->location_statusbar = gtk_statusbar_new (); + gtk_widget_show (window->details->location_statusbar); + gtk_widget_hide (GTK_STATUSBAR (window->details->location_statusbar)->frame); + gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (window->details->location_statusbar), + FALSE); + + window->details->location_button = gtk_button_new_with_label (""); + gtk_button_set_relief (GTK_BUTTON (window->details->location_button), + GTK_RELIEF_NONE); + + gtk_widget_show (window->details->location_button); + + frame = gtk_frame_new (NULL); + gtk_widget_style_get (GTK_WIDGET (window->details->location_statusbar), + "shadow_type", &shadow_type, NULL); + gtk_frame_set_shadow_type (GTK_FRAME (frame), shadow_type); + gtk_box_pack_start (GTK_BOX (window->details->location_statusbar), + frame, TRUE, TRUE, 0); + gtk_widget_show (frame); + + gtk_container_add (GTK_CONTAINER (frame), + window->details->location_button); + + gtk_widget_set_sensitive (window->details->location_button, FALSE); + g_signal_connect (window->details->location_button, + "clicked", + G_CALLBACK (location_button_clicked_callback), window); + gtk_widget_show (window->details->location_statusbar); } static void Index: src/nautilus-spatial-window.h =================================================================== RCS file: /cvs/gnome/nautilus/src/nautilus-spatial-window.h,v retrieving revision 1.109 diff -u -p -r1.109 nautilus-spatial-window.h --- src/nautilus-spatial-window.h 30 Sep 2003 20:37:31 -0000 1.109 +++ src/nautilus-spatial-window.h 7 Jan 2004 18:00:51 -0000 @@ -60,6 +60,8 @@ GType nautilus_spatial_window GtkWidget *nautilus_spatial_window_get (const char *uri); void nautilus_spatial_window_save_geometry (NautilusSpatialWindow *window); void nautilus_spatial_window_save_scroll_position (NautilusSpatialWindow *window); +void nautilus_spatial_window_set_location_button (NautilusSpatialWindow *window, + const char *location); #endif Index: src/nautilus-window-manage-views.c =================================================================== RCS file: /cvs/gnome/nautilus/src/nautilus-window-manage-views.c,v retrieving revision 1.329 diff -u -p -r1.329 nautilus-window-manage-views.c --- src/nautilus-window-manage-views.c 18 Dec 2003 18:38:24 -0000 1.329 +++ src/nautilus-window-manage-views.c 7 Jan 2004 18:00:52 -0000 @@ -446,7 +446,7 @@ viewed_file_changed_callback (NautilusFi window->details->location)) { g_free (window->details->location); window->details->location = new_location; - + /* Check if we can go up. */ update_up_button (window); #if !NEW_UI_COMPLETE @@ -456,6 +456,12 @@ viewed_file_changed_callback (NautilusFi (NAUTILUS_NAVIGATION_BAR (NAUTILUS_NAVIGATION_WINDOW (window)->navigation_bar), window->details->location); } + if (NAUTILUS_IS_SPATIAL_WINDOW (window)) { + /* Change the location button to match the current location. */ + nautilus_spatial_window_set_location_button + (NAUTILUS_SPATIAL_WINDOW (window), + window->details->location); + } #endif } else { @@ -570,6 +576,13 @@ update_for_new_location (NautilusWindow window->details->location, window->details->title); } + + if (NAUTILUS_IS_SPATIAL_WINDOW (window)) { + /* Change the location button to match the current location. */ + nautilus_spatial_window_set_location_button + (NAUTILUS_SPATIAL_WINDOW (window), + window->details->location); + } #endif } Index: src/nautilus-window.c =================================================================== RCS file: /cvs/gnome/nautilus/src/nautilus-window.c,v retrieving revision 1.425 diff -u -p -r1.425 nautilus-window.c --- src/nautilus-window.c 3 Jan 2004 18:34:43 -0000 1.425 +++ src/nautilus-window.c 7 Jan 2004 18:00:52 -0000 @@ -32,6 +32,7 @@ #include "nautilus-application.h" #include "nautilus-bookmarks-window.h" +#include "nautilus-file-utilities.h" #include "nautilus-information-panel.h" #include "nautilus-main.h" #include "nautilus-signaller.h" @@ -1160,28 +1161,42 @@ nautilus_window_display_error (NautilusW gtk_widget_show (dialog); } +static gboolean +is_method_root (char *uri) +{ + while (*uri != 0) { + if (*uri == ':') { + break; + } + if (!g_ascii_isalpha (*uri)) { + return FALSE; + } + uri++; + } + return (strcmp (uri, "://") == 0 || + strcmp (uri, ":///") == 0); +} + static char * compute_default_title (const char *text_uri) { NautilusFile *file; char *title; char *canonical_uri; + char *colon; canonical_uri = eel_make_uri_canonical (text_uri); + title = NULL; if (canonical_uri == NULL) { title = g_strdup (""); - } else if (strcmp (canonical_uri, "computer:///") == 0 ) { - title = g_strdup (_("Computer")); - } else if (strcmp (canonical_uri, "network:///") == 0 ) { - title = g_strdup (_("Network")); - } else if (strcmp (canonical_uri, "fonts:///") == 0 ) { - title = g_strdup (_("Fonts")); - } else if (strcmp (canonical_uri, "themes:///") == 0 ) { - title = g_strdup (_("Themes")); - } else if (strcmp (canonical_uri, "burn:///") == 0 ) { - title = g_strdup (_("CD Creator")); - } else { + } else if (is_method_root (canonical_uri)) { + colon = strchr (canonical_uri, ':'); + g_assert (colon != NULL); + *colon = 0; + title = g_strdup (nautilus_get_vfs_method_display_name (canonical_uri)); + } + if (title == NULL) { file = nautilus_file_get (text_uri); title = nautilus_file_get_display_name (file); nautilus_file_unref (file);