/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Nautilus * * Copyright (C) 1999, 2000 Red Hat, Inc. * Copyright (C) 1999, 2000 Eazel, Inc. * * Nautilus is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * Nautilus is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Authors: Elliot Lee * John Sullivan * */ /* nautilus-window.c: Implementation of the main window object */ #include #include "nautilus-window-private.h" #include "nautilus-main.h" #include "nautilus-application.h" #include "nautilus-bookmarks-window.h" #include "nautilus-sidebar.h" #include "nautilus-signaller.h" #include "nautilus-switchable-navigation-bar.h" #include "nautilus-throbber.h" #include "nautilus-window-manage-views.h" #include "nautilus-zoom-control.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* FIXME bugzilla.eazel.com 1243: * We should use inheritance instead of these special cases * for the desktop window. */ #include "nautilus-desktop-window.h" /* Milliseconds */ #define STATUS_BAR_CLEAR_TIMEOUT 5000 /* GNOME Dock Items */ #define URI_ENTRY_DOCK_ITEM "uri_entry" /* default web search uri - FIXME bugzilla.eazel.com 2465: this will be changed to point to the Eazel service */ #define DEFAULT_SEARCH_WEB_URI "http://www.google.com" enum { ARG_0, ARG_APP_ID, ARG_APP, ARG_CONTENT_VIEW }; /* Other static variables */ static GList *history_list = NULL; static void nautilus_window_initialize_class (NautilusWindowClass *klass); static void nautilus_window_initialize (NautilusWindow *window); static void nautilus_window_destroy (GtkObject *object); static void nautilus_window_set_arg (GtkObject *object, GtkArg *arg, guint arg_id); static void nautilus_window_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); static void nautilus_window_size_request (GtkWidget *widget, GtkRequisition *requisition); static void nautilus_window_realize (GtkWidget *widget); static void nautilus_window_real_set_content_view (NautilusWindow *window, NautilusViewFrame *new_view); static void sidebar_panels_changed_callback (gpointer user_data); static void nautilus_window_show (GtkWidget *widget); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusWindow, nautilus_window, GNOME_TYPE_APP) static void nautilus_window_initialize_class (NautilusWindowClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; parent_class = gtk_type_class(gnome_app_get_type()); object_class = (GtkObjectClass*) klass; object_class->destroy = nautilus_window_destroy; object_class->get_arg = nautilus_window_get_arg; object_class->set_arg = nautilus_window_set_arg; widget_class = (GtkWidgetClass*) klass; widget_class->show = nautilus_window_show; gtk_object_add_arg_type ("NautilusWindow::app_id", GTK_TYPE_STRING, GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT, ARG_APP_ID); gtk_object_add_arg_type ("NautilusWindow::app", GTK_TYPE_OBJECT, GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT, ARG_APP); gtk_object_add_arg_type ("NautilusWindow::content_view", GTK_TYPE_OBJECT, GTK_ARG_READWRITE, ARG_CONTENT_VIEW); widget_class->realize = nautilus_window_realize; widget_class->size_request = nautilus_window_size_request; } static void nautilus_window_initialize (NautilusWindow *window) { window->details = g_new0 (NautilusWindowDetails, 1); gtk_quit_add_destroy (1, GTK_OBJECT (window)); /* Keep track of any sidebar panel changes */ nautilus_preferences_add_callback (NAUTILUS_PREFERENCES_SIDEBAR_PANELS_NAMESPACE, sidebar_panels_changed_callback, window); /* Keep the main event loop alive as long as the window exists */ nautilus_main_event_loop_register (GTK_OBJECT (window)); } static gboolean nautilus_window_clear_status(NautilusWindow *window) { gtk_statusbar_pop(GTK_STATUSBAR(GNOME_APP(window)->statusbar), window->status_bar_context_id); window->status_bar_clear_id = 0; return FALSE; } void nautilus_window_set_status(NautilusWindow *window, const char *txt) { if(window->status_bar_clear_id) g_source_remove(window->status_bar_clear_id); gtk_statusbar_pop(GTK_STATUSBAR(GNOME_APP(window)->statusbar), window->status_bar_context_id); if(txt && *txt) { window->status_bar_clear_id = g_timeout_add(STATUS_BAR_CLEAR_TIMEOUT, (GSourceFunc)nautilus_window_clear_status, window); gtk_statusbar_push(GTK_STATUSBAR(GNOME_APP(window)->statusbar), window->status_bar_context_id, txt); } else window->status_bar_clear_id = 0; } void nautilus_window_goto_uri (NautilusWindow *window, const char *uri) { nautilus_window_open_location (window, uri, NULL); } static void goto_uri_callback (GtkWidget *widget, const char *uri, GtkWidget *window) { nautilus_window_goto_uri (NAUTILUS_WINDOW (window), uri); } static void navigation_bar_mode_changed_callback (GtkWidget *widget, NautilusSwitchableNavigationBarMode mode, GtkWidget *window) { nautilus_window_update_find_menu_item (NAUTILUS_WINDOW (window)); switch (mode) { case NAUTILUS_SWITCHABLE_NAVIGATION_BAR_MODE_LOCATION: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (NAUTILUS_WINDOW (window)->search_local_button), FALSE); break; case NAUTILUS_SWITCHABLE_NAVIGATION_BAR_MODE_SEARCH: gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (NAUTILUS_WINDOW (window)->search_local_button), TRUE); break; default: g_assert_not_reached (); } } void nautilus_window_zoom_in (NautilusWindow *window) { if (window->content_view != NULL) { nautilus_view_frame_zoom_in (window->content_view); } } void nautilus_window_zoom_to_level (NautilusWindow *window, double level) { if (window->content_view != NULL) { nautilus_view_frame_set_zoom_level (window->content_view, level); } } void nautilus_window_zoom_out (NautilusWindow *window) { if (window->content_view != NULL) { nautilus_view_frame_zoom_out (window->content_view); } } void nautilus_window_zoom_to_fit (NautilusWindow *window) { if (window->content_view != NULL) { nautilus_view_frame_zoom_to_fit (window->content_view); } } /* This is our replacement for gnome_app_set_statusbar. * It uses nautilus_any_width_bin to make text changes in the * status bar not affect the width of the window. */ static void install_status_bar (GnomeApp *app, GtkWidget *status_bar) { GtkWidget *bin; g_assert (GNOME_IS_APP (app)); g_assert (GTK_IS_WIDGET (status_bar)); g_assert (app->statusbar == NULL); app->statusbar = status_bar; gtk_widget_show (status_bar); bin = nautilus_any_width_bin_new (); gtk_container_set_border_width (GTK_CONTAINER (bin), 0); gtk_widget_show (bin); gtk_container_add (GTK_CONTAINER (bin), status_bar); gtk_box_pack_start (GTK_BOX (app->vbox), bin, FALSE, FALSE, 0); } static void nautilus_window_constructed (NautilusWindow *window) { GnomeApp *app; GtkWidget *location_bar_box, *status_bar; GtkWidget *view_as_menu_vbox; GnomeDockItemBehavior behavior; int sidebar_width; app = GNOME_APP (window); /* set up location bar */ location_bar_box = gtk_hbox_new (FALSE, GNOME_PAD); gtk_container_set_border_width (GTK_CONTAINER (location_bar_box), GNOME_PAD_SMALL); window->navigation_bar = nautilus_switchable_navigation_bar_new (); gtk_widget_show (GTK_WIDGET (window->navigation_bar)); gtk_signal_connect (GTK_OBJECT (window->navigation_bar), "location_changed", goto_uri_callback, window); gtk_signal_connect (GTK_OBJECT (window->navigation_bar), "mode_changed", navigation_bar_mode_changed_callback, window); gtk_box_pack_start (GTK_BOX (location_bar_box), window->navigation_bar, TRUE, TRUE, GNOME_PAD_SMALL); behavior = GNOME_DOCK_ITEM_BEH_EXCLUSIVE | GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL; if (!gnome_preferences_get_toolbar_detachable ()) { behavior |= GNOME_DOCK_ITEM_BEH_LOCKED; } gnome_app_add_docked (app, location_bar_box, URI_ENTRY_DOCK_ITEM, behavior, GNOME_DOCK_TOP, 2, 0, 0); /* Option menu for content view types; it's empty here, filled in when a uri is set. * Pack it into vbox so it doesn't grow vertically when location bar does. */ view_as_menu_vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); gtk_widget_show (view_as_menu_vbox); gtk_box_pack_end (GTK_BOX (location_bar_box), view_as_menu_vbox, FALSE, FALSE, 0); window->view_as_option_menu = gtk_option_menu_new(); gtk_box_pack_end (GTK_BOX (view_as_menu_vbox), window->view_as_option_menu, TRUE, FALSE, 0); gtk_widget_show (window->view_as_option_menu); /* Allocate the zoom control and place on the right next to the menu. * It gets shown later, if the view-frame contains something zoomable. */ window->zoom_control = nautilus_zoom_control_new (); gtk_signal_connect_object (GTK_OBJECT (window->zoom_control), "zoom_in", nautilus_window_zoom_in, GTK_OBJECT (window)); gtk_signal_connect_object (GTK_OBJECT (window->zoom_control), "zoom_out", nautilus_window_zoom_out, GTK_OBJECT (window)); gtk_signal_connect_object (GTK_OBJECT (window->zoom_control), "zoom_to_level", nautilus_window_zoom_to_level, GTK_OBJECT (window)); gtk_signal_connect_object (GTK_OBJECT (window->zoom_control), "zoom_to_fit", nautilus_window_zoom_to_fit, GTK_OBJECT (window)); gtk_box_pack_end (GTK_BOX (location_bar_box), window->zoom_control, FALSE, FALSE, 0); gtk_widget_show (location_bar_box); /* set up status bar */ status_bar = gtk_statusbar_new (); install_status_bar (app, status_bar); /* insert a little padding so text isn't jammed against frame */ gtk_misc_set_padding (GTK_MISC (GTK_STATUSBAR (status_bar)->label), GNOME_PAD, 0); window->status_bar_context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (status_bar), "IhateGtkStatusbar"); /* FIXME bugzilla.eazel.com 1243: * We should use inheritance instead of these special cases * for the desktop window. */ if (NAUTILUS_IS_DESKTOP_WINDOW (window)) { window->content_hbox = gtk_widget_new (NAUTILUS_TYPE_GENEROUS_BIN, NULL); } else { /* set up window contents and policy */ gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE); /* FIXME bugzilla.eazel.com 1244: Hard-wired size here? */ gtk_window_set_default_size (GTK_WINDOW (window), 650, 400); window->content_hbox = nautilus_horizontal_splitter_new (); /* FIXME bugzilla.eazel.com 1245: No constant for the default? */ /* FIXME bugzilla.eazel.com 1245: Saved in pixels instead of in %? */ /* FIXME bugzilla.eazel.com 1245: No reality check on the value? */ /* FIXME bugzilla.eazel.com 1245: get_enum? why not get_integer? */ sidebar_width = nautilus_preferences_get_enum (NAUTILUS_PREFERENCES_SIDEBAR_WIDTH, 148); e_paned_set_position (E_PANED (window->content_hbox), sidebar_width); } gnome_app_set_contents (app, window->content_hbox); /* set up the index panel */ window->sidebar = nautilus_sidebar_new (); gtk_widget_show (GTK_WIDGET (window->sidebar)); gtk_signal_connect (GTK_OBJECT (window->sidebar), "location_changed", goto_uri_callback, window); /* FIXME bugzilla.eazel.com 1243: * We should use inheritance instead of these special cases * for the desktop window. */ if (!NAUTILUS_IS_DESKTOP_WINDOW (window)) { e_paned_pack1 (E_PANED(window->content_hbox), GTK_WIDGET(window->sidebar), FALSE, FALSE); } /* CORBA and Bonobo setup */ window->ui_handler = bonobo_ui_handler_new (); bonobo_ui_handler_set_app (window->ui_handler, app); bonobo_ui_handler_set_statusbar (window->ui_handler, status_bar); /* Create menus and tool bars */ nautilus_window_initialize_menus (window); nautilus_window_initialize_toolbars (window); /* Set initial sensitivity of some buttons & menu items * now that they're all created. */ nautilus_window_allow_back (window, FALSE); nautilus_window_allow_forward (window, FALSE); nautilus_window_allow_stop (window, FALSE); /* Set up undo manager */ nautilus_undo_manager_attach (window->application->undo_manager, GTK_OBJECT (window)); } static void nautilus_window_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) { GnomeApp *app = (GnomeApp *) object; char *old_app_name; NautilusWindow *window = (NautilusWindow *) object; switch(arg_id) { case ARG_APP_ID: if(!GTK_VALUE_STRING(*arg)) return; old_app_name = app->name; g_free(app->name); app->name = g_strdup(GTK_VALUE_STRING(*arg)); g_assert(app->name); g_free(app->prefix); app->prefix = g_strconcat("/", app->name, "/", NULL); if(!old_app_name) { nautilus_window_constructed(NAUTILUS_WINDOW(object)); } break; case ARG_APP: window->application = NAUTILUS_APPLICATION (GTK_VALUE_OBJECT (*arg)); break; case ARG_CONTENT_VIEW: nautilus_window_real_set_content_view (window, (NautilusViewFrame *) GTK_VALUE_OBJECT(*arg)); break; } } static void nautilus_window_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) { GnomeApp *app = (GnomeApp *) object; switch(arg_id) { case ARG_APP_ID: GTK_VALUE_STRING (*arg) = app->name; break; case ARG_APP: GTK_VALUE_OBJECT (*arg) = GTK_OBJECT (NAUTILUS_WINDOW (object)->application); break; case ARG_CONTENT_VIEW: GTK_VALUE_OBJECT (*arg) = GTK_OBJECT (NAUTILUS_WINDOW (object)->content_view); break; } } static void view_disconnect (gpointer data, gpointer user_data) { g_assert (NAUTILUS_IS_WINDOW (user_data)); g_assert (NAUTILUS_IS_VIEW_FRAME (data)); nautilus_window_disconnect_view (NAUTILUS_WINDOW (user_data), NAUTILUS_VIEW_FRAME (data)); } static void nautilus_window_destroy (GtkObject *object) { NautilusWindow *window; window = NAUTILUS_WINDOW (object); /* Dont keep track of sidebar panel changes no more */ nautilus_preferences_remove_callback (NAUTILUS_PREFERENCES_SIDEBAR_PANELS_NAMESPACE, sidebar_panels_changed_callback, NULL); nautilus_window_remove_bookmarks_menu_callback (window); nautilus_window_remove_bookmarks_menu_items (window); nautilus_window_remove_go_menu_callback (window); nautilus_window_remove_go_menu_items (window); nautilus_window_toolbar_remove_theme_callback (window); /* Disconnect view signals here so they don't trigger when * views are destroyed normally. */ g_list_foreach (window->sidebar_panels, view_disconnect, window); g_list_free (window->sidebar_panels); nautilus_window_disconnect_view (window, window->content_view); nautilus_view_identifier_free (window->content_view_id); g_free (window->location); nautilus_g_list_free_deep (window->selection); nautilus_g_list_free_deep (window->pending_selection); nautilus_window_clear_back_list (window); nautilus_window_clear_forward_list (window); if (window->current_location_bookmark != NULL) { gtk_object_unref (GTK_OBJECT (window->current_location_bookmark)); } if (window->last_location_bookmark != NULL) { gtk_object_unref (GTK_OBJECT (window->last_location_bookmark)); } if (window->status_bar_clear_id != 0) { g_source_remove (window->status_bar_clear_id); } NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (GTK_OBJECT (window))); if (window->ui_handler != NULL) { bonobo_object_unref (BONOBO_OBJECT (window->ui_handler)); } } void nautilus_window_close (NautilusWindow *window) { g_return_if_fail (NAUTILUS_IS_WINDOW (window)); gtk_widget_destroy (GTK_WIDGET (window)); } static void nautilus_window_realize (GtkWidget *widget) { char *filename; GdkPixbuf *pixbuf; GdkPixmap *pixmap; GdkBitmap *mask; /* Create our GdkWindow */ NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, realize, (widget)); /* Set the mini icon */ filename = nautilus_pixmap_file ("nautilus-mini-logo.png"); if (filename != NULL) { pixbuf = gdk_pixbuf_new_from_file(filename); if (pixbuf != NULL) { gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &mask, NAUTILUS_STANDARD_ALPHA_THRESHHOLD); gdk_pixbuf_unref (pixbuf); nautilus_set_mini_icon (widget->window, pixmap, mask); /* FIXME bugzilla.eazel.com 610: It seems we are * leaking the pixmap and mask here, but if we unref * them here, the task bar crashes. */ } g_free (filename); } } static void nautilus_window_size_request (GtkWidget *widget, GtkRequisition *requisition) { guint max_width; guint max_height; g_return_if_fail (NAUTILUS_IS_WINDOW (widget)); g_return_if_fail (requisition != NULL); NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, size_request, (widget, requisition)); /* Limit the requisition to be within 90% of the available screen * real state. * * This way the user will have a fighting chance of getting * control of their window back if for whatever reason one of the * window's descendants decide they want to be 4000 pixels wide. * * Note that the user can still make the window really huge by hand. * * Bugs in components or other widgets that cause such huge geometries * to be requested, should still be fixed. This code is here only to * prevent the extremely frustrating consequence of such bugs. */ max_width = (gdk_screen_width () * 90) / 100; max_height = (gdk_screen_height () * 90) / 100; if (requisition->width > max_width) { requisition->width = max_width; } if (requisition->height > max_height) { requisition->height = max_height; } } /* * Main API */ static void nautilus_window_switch_views (NautilusWindow *window, NautilusViewIdentifier *id) { NautilusDirectory *directory; NautilusViewFrame *view; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (window->location != NULL); g_return_if_fail (id != NULL); directory = nautilus_directory_get (window->location); g_assert (directory != NULL); nautilus_mime_set_default_component_for_uri (window->location, id->iid); nautilus_directory_unref (directory); nautilus_window_allow_stop (window, TRUE); view = nautilus_window_load_content_view (window, id, NULL); nautilus_window_set_state_info (window, (NautilusWindowStateItem) NEW_CONTENT_VIEW_ACTIVATED, view, (NautilusWindowStateItem) 0); } static void view_menu_switch_views_callback (GtkWidget *widget, gpointer data) { NautilusWindow *window; NautilusViewIdentifier *identifier; g_return_if_fail (GTK_IS_MENU_ITEM (widget)); g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); identifier = (NautilusViewIdentifier *) gtk_object_get_data (GTK_OBJECT (widget), "identifier"); nautilus_window_switch_views (window, identifier); } /* Note: The identifier parameter ownership is handed off to the menu item. */ static GtkWidget * create_content_view_menu_item (NautilusWindow *window, NautilusViewIdentifier *identifier) { GtkWidget *menu_item; char *menu_label; menu_label = g_strdup_printf (_("View as %s"), identifier->name); menu_item = gtk_menu_item_new_with_label (menu_label); g_free (menu_label); gtk_signal_connect (GTK_OBJECT (menu_item), "activate", GTK_SIGNAL_FUNC (view_menu_switch_views_callback), NULL); /* Store copy of iid in item; free when item destroyed. */ gtk_object_set_data_full (GTK_OBJECT (menu_item), "identifier", identifier, (GtkDestroyNotify) nautilus_view_identifier_free); /* Store reference to window in item; no need to free this. */ gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); gtk_widget_show (menu_item); return menu_item; } static GtkWidget * new_gtk_separator (void) { GtkWidget *result; result = gtk_menu_item_new (); gtk_widget_show (result); gtk_widget_set_sensitive (result, FALSE); return result; } /* Make a special first item in the "View as" option menu that represents * the current content view. This should only be called if the current * content view isn't already in the "View as" option menu. */ static void replace_special_current_view_in_content_view_menu (NautilusWindow *window) { GtkWidget *menu; GtkWidget *first_menu_item; GtkWidget *new_menu_item; menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (window->view_as_option_menu)); /* Remove menu before changing contents so it is resized properly * when reattached later in this function. */ gtk_widget_ref (menu); gtk_option_menu_remove_menu (GTK_OPTION_MENU (window->view_as_option_menu)); first_menu_item = nautilus_gtk_container_get_first_child (GTK_CONTAINER (menu)); g_assert (first_menu_item != NULL); if (GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (first_menu_item), "current content view"))) { gtk_container_remove (GTK_CONTAINER (menu), first_menu_item); } else { /* Prepend separator. */ gtk_menu_prepend (GTK_MENU (menu), new_gtk_separator ()); } new_menu_item = create_content_view_menu_item (window, nautilus_view_identifier_copy (window->content_view_id)); gtk_object_set_data (GTK_OBJECT (new_menu_item), "current content view", GINT_TO_POINTER (TRUE)); gtk_menu_prepend (GTK_MENU (menu), new_menu_item); gtk_option_menu_set_menu (GTK_OPTION_MENU (window->view_as_option_menu), menu); gtk_widget_unref (menu); } /** * nautilus_window_synch_content_view_menu: * * Set the visible item of the "View as" option menu to * match the current content view. * * @window: The NautilusWindow whose "View as" option menu should be synched. */ void nautilus_window_synch_content_view_menu (NautilusWindow *window) { GList *children, *child; GtkWidget *menu; NautilusViewIdentifier *item_id; int index, matching_index; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (window->view_as_option_menu)); if (menu == NULL) { return; } children = gtk_container_children (GTK_CONTAINER (menu)); matching_index = -1; for (child = children, index = 0; child != NULL; child = child->next, ++index) { item_id = (NautilusViewIdentifier *)(gtk_object_get_data (GTK_OBJECT (child->data), "identifier")); if (item_id != NULL && strcmp (window->content_view->iid, item_id->iid) == 0) { matching_index = index; break; } } if (matching_index == -1) { replace_special_current_view_in_content_view_menu (window); matching_index = 0; } gtk_option_menu_set_history (GTK_OPTION_MENU (window->view_as_option_menu), matching_index); g_list_free (children); } static void chose_component_callback (NautilusViewIdentifier *identifier, gpointer callback_data) { /* Can't assume callback_data is a valid NautilusWindow, because * it might be garbage if the program is exiting when this dialog * is up. */ if (identifier != NULL) { g_return_if_fail (NAUTILUS_IS_WINDOW (callback_data)); nautilus_window_switch_views (NAUTILUS_WINDOW (callback_data), identifier); } /* FIXME bugzilla.eazel.com 1334: * There should be some global way to signal that the * file type associations have changed, so that the places that * display these lists can react. For now, hardwire this case, which * is the most obvious one by far. */ if (NAUTILUS_IS_WINDOW (callback_data)) { nautilus_window_load_content_view_menu (NAUTILUS_WINDOW (callback_data)); } } static void view_menu_choose_view_callback (GtkWidget *widget, gpointer data) { NautilusWindow *window; NautilusFile *file; g_return_if_fail (GTK_IS_MENU_ITEM (widget)); g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); /* Set the option menu back to its previous setting (Don't leave it * on this dialog-producing "View as Other..." setting). If the menu choice * causes a content view change, this will be updated again later, * in nautilus_window_load_content_view_menu. Do this right away so * the user never sees the option menu set to "View as Other...". */ nautilus_window_synch_content_view_menu (window); /* FIXME bugzilla.eazel.com 866: Can't expect to put this * window up instantly. We might need to read the metafile * first. */ file = nautilus_file_get (window->location); g_return_if_fail (NAUTILUS_IS_FILE (file)); nautilus_choose_component_for_file (file, GTK_WINDOW (window), chose_component_callback, window); nautilus_file_unref (file); } static void view_menu_vfs_method_callback (GtkWidget *widget, gpointer data) { NautilusWindow *window; char *new_location; char *method; g_return_if_fail (GTK_IS_MENU_ITEM (widget)); g_return_if_fail (NAUTILUS_IS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window"))); window = NAUTILUS_WINDOW (gtk_object_get_data (GTK_OBJECT (widget), "window")); method = (char *)(gtk_object_get_data (GTK_OBJECT (widget), "method")); g_return_if_fail (method); new_location = g_strdup_printf("%s#%s:/",window->location,method); nautilus_window_goto_uri(window, new_location); g_free(new_location); } void nautilus_window_load_content_view_menu (NautilusWindow *window) { GList *components; char *method; GList *p; GtkWidget *new_menu; GtkWidget *menu_item; char *label; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (GTK_IS_OPTION_MENU (window->view_as_option_menu)); new_menu = gtk_menu_new (); /* Add a menu item for each view in the preferred list for this location. */ components = nautilus_mime_get_short_list_components_for_uri (window->location); for (p = components; p != NULL; p = p->next) { menu_item = create_content_view_menu_item (window, nautilus_view_identifier_new_from_content_view (p->data)); gtk_menu_append (GTK_MENU (new_menu), menu_item); } gnome_vfs_mime_component_list_free (components); /* Add a menu item for each special GNOME-VFS method for this * URI. This is a questionable user interface, since it's a * one way trip if you choose one of these view menu items, but * it's better than nothing. */ method = nautilus_mime_get_short_list_methods_for_uri (window->location); /* FIXME bugzilla.eazel.com 2466: Name of the function is plural, but it returns only * one item. That must be fixed. */ if (method != NULL) { label = g_strdup_printf (_("View as %s..."), method); menu_item = gtk_menu_item_new_with_label (label); g_free (label); gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); gtk_object_set_data_full (GTK_OBJECT (menu_item), "method", g_strdup (method), g_free); gtk_signal_connect (GTK_OBJECT (menu_item), "activate", view_menu_vfs_method_callback, NULL); gtk_widget_show (menu_item); gtk_menu_append (GTK_MENU (new_menu), menu_item); g_free (method); } /* Add separator before "Other" if there are any other viewers in menu. */ if (components != NULL || method != NULL) { gtk_menu_append (GTK_MENU (new_menu), new_gtk_separator ()); } /* Add "View as Other..." extra bonus choice. */ menu_item = gtk_menu_item_new_with_label (_("View as Other...")); gtk_object_set_data (GTK_OBJECT (menu_item), "window", window); gtk_signal_connect (GTK_OBJECT (menu_item), "activate", view_menu_choose_view_callback, NULL); gtk_widget_show (menu_item); gtk_menu_append (GTK_MENU (new_menu), menu_item); /* We create and attach a new menu here because adding/removing * items from existing menu screws up the size of the option menu. */ gtk_option_menu_set_menu (GTK_OPTION_MENU (window->view_as_option_menu), new_menu); nautilus_window_synch_content_view_menu (window); } void nautilus_window_set_content_view (NautilusWindow *window, NautilusViewFrame *content_view) { nautilus_window_real_set_content_view (window, content_view); } void nautilus_window_add_sidebar_panel (NautilusWindow *window, NautilusViewFrame *sidebar_panel) { g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (sidebar_panel)); g_return_if_fail (g_list_find (window->sidebar_panels, sidebar_panel) == NULL); nautilus_sidebar_add_panel (window->sidebar, sidebar_panel); gtk_widget_ref (GTK_WIDGET (sidebar_panel)); window->sidebar_panels = g_list_prepend (window->sidebar_panels, sidebar_panel); } void nautilus_window_remove_sidebar_panel (NautilusWindow *window, NautilusViewFrame *sidebar_panel) { g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (NAUTILUS_IS_VIEW_FRAME (sidebar_panel)); if (g_list_find (window->sidebar_panels, sidebar_panel) == NULL) { return; } nautilus_sidebar_remove_panel (window->sidebar, sidebar_panel); window->sidebar_panels = g_list_remove (window->sidebar_panels, sidebar_panel); gtk_widget_unref (GTK_WIDGET (sidebar_panel)); } void nautilus_window_back_or_forward (NautilusWindow *window, gboolean back, guint distance) { GList *list; char *uri; list = back ? window->back_list : window->forward_list; g_assert (g_list_length (list) > distance); uri = nautilus_bookmark_get_uri (g_list_nth_data (list, distance)); nautilus_window_begin_location_change (window, uri, NULL, back ? NAUTILUS_LOCATION_CHANGE_BACK : NAUTILUS_LOCATION_CHANGE_FORWARD, distance); g_free (uri); } void nautilus_window_go_back (NautilusWindow *window) { nautilus_window_back_or_forward (window, TRUE, 0); } void nautilus_window_go_forward (NautilusWindow *window) { nautilus_window_back_or_forward (window, FALSE, 0); } void nautilus_window_go_up (NautilusWindow *window) { GnomeVFSURI *current_uri; GnomeVFSURI *parent_uri; char *parent_uri_string; if (window->location == NULL) return; current_uri = gnome_vfs_uri_new (window->location); parent_uri = gnome_vfs_uri_get_parent (current_uri); gnome_vfs_uri_unref (current_uri); if (parent_uri == NULL) { g_warning ("Can't go Up from here. The UI should have prevented us from getting this far."); return; } parent_uri_string = gnome_vfs_uri_to_string (parent_uri, GNOME_VFS_URI_HIDE_NONE); gnome_vfs_uri_unref (parent_uri); nautilus_window_goto_uri (window, parent_uri_string); g_free (parent_uri_string); } void nautilus_window_set_search_mode (NautilusWindow *window, gboolean search_mode) { nautilus_switchable_navigation_bar_set_mode (NAUTILUS_SWITCHABLE_NAVIGATION_BAR (window->navigation_bar), search_mode ? NAUTILUS_SWITCHABLE_NAVIGATION_BAR_MODE_SEARCH : NAUTILUS_SWITCHABLE_NAVIGATION_BAR_MODE_LOCATION); } gboolean nautilus_window_get_search_mode (NautilusWindow *window) { return nautilus_switchable_navigation_bar_get_mode (NAUTILUS_SWITCHABLE_NAVIGATION_BAR (window->navigation_bar)) == NAUTILUS_SWITCHABLE_NAVIGATION_BAR_MODE_SEARCH; } void nautilus_window_go_web_search (NautilusWindow *window) { char *search_web_uri; nautilus_window_set_search_mode (window, FALSE); search_web_uri = nautilus_preferences_get (NAUTILUS_PREFERENCES_SEARCH_WEB_URI, DEFAULT_SEARCH_WEB_URI); g_assert (search_web_uri != NULL); nautilus_window_goto_uri (window, search_web_uri); g_free (search_web_uri); } void nautilus_window_go_home (NautilusWindow *window) { char *default_home_uri, *home_uri; nautilus_window_set_search_mode (window, FALSE); default_home_uri = gnome_vfs_get_uri_from_local_path (g_get_home_dir ()); home_uri = nautilus_preferences_get (NAUTILUS_PREFERENCES_HOME_URI, default_home_uri); g_free (default_home_uri); g_assert (home_uri != NULL); nautilus_window_goto_uri (window, home_uri); g_free (home_uri); } void nautilus_window_allow_back (NautilusWindow *window, gboolean allow) { gtk_widget_set_sensitive (window->back_button, allow); bonobo_ui_handler_menu_set_sensitivity (window->ui_handler, NAUTILUS_MENU_PATH_BACK_ITEM, allow); } void nautilus_window_allow_forward (NautilusWindow *window, gboolean allow) { gtk_widget_set_sensitive (window->forward_button, allow); bonobo_ui_handler_menu_set_sensitivity (window->ui_handler, NAUTILUS_MENU_PATH_FORWARD_ITEM, allow); } void nautilus_window_allow_up (NautilusWindow *window, gboolean allow) { gtk_widget_set_sensitive (window->up_button, allow); bonobo_ui_handler_menu_set_sensitivity (window->ui_handler, NAUTILUS_MENU_PATH_UP_ITEM, allow); } void nautilus_window_allow_reload (NautilusWindow *window, gboolean allow) { gtk_widget_set_sensitive (window->reload_button, allow); bonobo_ui_handler_menu_set_sensitivity (window->ui_handler, NAUTILUS_MENU_PATH_RELOAD_ITEM, allow); } void nautilus_window_allow_stop (NautilusWindow *window, gboolean allow) { gtk_widget_set_sensitive (window->stop_button, allow); if (window->throbber == NULL) return; if (allow) { nautilus_throbber_start (NAUTILUS_THROBBER (window->throbber)); } else { nautilus_throbber_stop (NAUTILUS_THROBBER (window->throbber)); } } void nautilus_send_history_list_changed (void) { gtk_signal_emit_by_name (GTK_OBJECT (nautilus_signaller_get_current ()), "history_list_changed"); } static void free_history_list (void) { nautilus_gtk_object_list_free (history_list); history_list = NULL; } void nautilus_add_to_history_list (NautilusBookmark *bookmark) { /* Note that the history is shared amongst all windows so * this is not a NautilusWindow function. Perhaps it belongs * in its own file. */ static gboolean free_history_list_is_set_up; GList *found_link; g_return_if_fail (NAUTILUS_IS_BOOKMARK (bookmark)); if (!free_history_list_is_set_up) { g_atexit (free_history_list); free_history_list_is_set_up = TRUE; } gtk_object_ref (GTK_OBJECT (bookmark)); /* Compare only the uris here. Comparing the names also is not necessary * and can cause problems due to the asynchronous nature of when the title * of the window is set. */ found_link = g_list_find_custom (history_list, bookmark, nautilus_bookmark_compare_uris); /* Remove any older entry for this same item. There can be at most 1. */ if (found_link != NULL) { gtk_object_unref (found_link->data); history_list = g_list_remove_link (history_list, found_link); } /* New item goes first. */ history_list = g_list_prepend (history_list, bookmark); /* Tell world that history list has changed. At least all the * NautilusWindows (not just this one) are listening. */ nautilus_send_history_list_changed (); } void nautilus_window_clear_forward_list (NautilusWindow *window) { nautilus_gtk_object_list_free (window->forward_list); window->forward_list = NULL; } void nautilus_window_clear_back_list (NautilusWindow *window) { nautilus_gtk_object_list_free (window->back_list); window->back_list = NULL; } void nautilus_forget_history (void) { GSList *window_node; NautilusWindow *window; /* Clear out each window's back & forward lists. Also, remove * each window's current location bookmark from history list * so it doesn't get clobbered. */ for (window_node = nautilus_application_windows (); window_node != NULL; window_node = window_node->next) { window = NAUTILUS_WINDOW (window_node->data); nautilus_window_clear_back_list (window); nautilus_window_clear_forward_list (window); nautilus_window_allow_back (window, FALSE); nautilus_window_allow_forward (window, FALSE); history_list = g_list_remove (history_list, window->current_location_bookmark); } /* Clobber history list. */ free_history_list (); /* Re-add each window's current location to history list. */ for (window_node = nautilus_application_windows (); window_node != NULL; window_node = window_node->next) { window = NAUTILUS_WINDOW (window_node->data); nautilus_add_to_history_list (window->current_location_bookmark); } } GList * nautilus_get_history_list (void) { return history_list; } static void nautilus_window_open_location_callback (NautilusViewFrame *view, const char *location, NautilusWindow *window) { nautilus_window_open_location (window, location, view); } static void nautilus_window_open_location_in_new_window_callback (NautilusViewFrame *view, const char *location, NautilusWindow *window) { nautilus_window_open_location_in_new_window (window, location, view); } static void nautilus_window_open_in_new_window_and_select_callback (NautilusViewFrame *view, const char *location, GList *selection, NautilusWindow *window) { nautilus_window_open_in_new_window_and_select (window, location, selection, view); } static void nautilus_window_report_location_change_callback (NautilusViewFrame *view, const char *location, NautilusWindow *window) { nautilus_window_report_location_change (window, location, view); } static void nautilus_window_report_selection_change_callback (NautilusViewFrame *view, GList *selection, NautilusWindow *window) { nautilus_window_report_selection_change (window, selection, view); } static void nautilus_window_report_status_callback (NautilusViewFrame *view, const char *status, NautilusWindow *window) { nautilus_window_report_status (window, status, view); } static void nautilus_window_report_load_underway_callback (NautilusViewFrame *view, NautilusWindow *window) { nautilus_window_report_load_underway (window, view); } static void nautilus_window_report_load_progress_callback (NautilusViewFrame *view, double fraction_done, NautilusWindow *window) { nautilus_window_report_load_progress (window, fraction_done, view); } static void nautilus_window_report_load_complete_callback (NautilusViewFrame *view, NautilusWindow *window) { nautilus_window_report_load_complete (window, view); } static void nautilus_window_report_load_failed_callback (NautilusViewFrame *view, NautilusWindow *window) { nautilus_window_report_load_failed (window, view); } static void nautilus_window_title_changed_callback (NautilusViewFrame *view, NautilusWindow *window) { nautilus_window_title_changed (window, view); } static void nautilus_window_zoom_level_changed_callback (NautilusViewFrame *view, double zoom_level, NautilusWindow *window) { nautilus_zoom_control_set_zoom_level (NAUTILUS_ZOOM_CONTROL (window->zoom_control), zoom_level); /* We rely on the initial zoom_level_change signal to inform us that the * view-frame is showing a new zoomable. */ if (!GTK_WIDGET_VISIBLE (window->zoom_control)) { nautilus_zoom_control_set_min_zoom_level (NAUTILUS_ZOOM_CONTROL (window->zoom_control), nautilus_view_frame_get_min_zoom_level (view)); nautilus_zoom_control_set_max_zoom_level (NAUTILUS_ZOOM_CONTROL (window->zoom_control), nautilus_view_frame_get_max_zoom_level (view)); nautilus_zoom_control_set_preferred_zoom_levels (NAUTILUS_ZOOM_CONTROL (window->zoom_control), nautilus_view_frame_get_preferred_zoom_levels (view)); gtk_widget_show (window->zoom_control); } bonobo_ui_handler_menu_set_sensitivity (window->ui_handler, NAUTILUS_MENU_PATH_ZOOM_IN_ITEM, zoom_level < nautilus_view_frame_get_max_zoom_level (view)); bonobo_ui_handler_menu_set_sensitivity (window->ui_handler, NAUTILUS_MENU_PATH_ZOOM_OUT_ITEM, zoom_level > nautilus_view_frame_get_min_zoom_level (view)); bonobo_ui_handler_menu_set_sensitivity (window->ui_handler, NAUTILUS_MENU_PATH_ZOOM_NORMAL_ITEM, TRUE); } static Nautilus_HistoryList * nautilus_window_get_history_list_callback (NautilusViewFrame *view, NautilusWindow *window) { Nautilus_HistoryList *list; NautilusBookmark *bookmark; int length, i; GList *p; char *name, *location; /* Get total number of history items */ length = g_list_length (history_list); list = Nautilus_HistoryList__alloc (); list->_length = length; list->_maximum = length; list->_buffer = CORBA_sequence_Nautilus_HistoryItem_allocbuf (length); CORBA_sequence_set_release (list, CORBA_TRUE); /* Iterate through list and copy item data */ for (i = 0, p = history_list; i < length; i++, p = p->next) { bookmark = p->data; name = nautilus_bookmark_get_name (bookmark); location = nautilus_bookmark_get_uri (bookmark); list->_buffer[i].title = CORBA_string_dup (name); list->_buffer[i].location = CORBA_string_dup (location); g_free (name); g_free (location); } return list; } void nautilus_window_connect_view (NautilusWindow *window, NautilusViewFrame *view) { GtkObject *view_object; view_object = GTK_OBJECT (view); #define CONNECT(signal) gtk_signal_connect (view_object, #signal, GTK_SIGNAL_FUNC (nautilus_window_##signal##_callback), window) CONNECT (open_location); CONNECT (open_location_in_new_window); CONNECT (open_in_new_window_and_select); CONNECT (report_location_change); CONNECT (report_selection_change); CONNECT (report_status); CONNECT (report_load_underway); CONNECT (report_load_progress); CONNECT (report_load_complete); CONNECT (report_load_failed); CONNECT (title_changed); CONNECT (zoom_level_changed); CONNECT (get_history_list); #undef CONNECT /* Can't use connect_object_while_alive here, because * elsewhere disconnect_by_function is used to disconnect the * switched-out content view's signal, and disconnect_by_function * doesn't completely clean up after connect_object_while_alive, * leading to assertion failures later on. */ gtk_signal_connect_object (view_object, "destroy", nautilus_window_view_failed, GTK_OBJECT (window)); gtk_signal_connect_object (view_object, "client_gone", nautilus_window_view_failed, GTK_OBJECT (window)); } void nautilus_window_disconnect_view (NautilusWindow *window, NautilusViewFrame *view) { g_assert (NAUTILUS_IS_WINDOW (window)); if (view == NULL) { return; } g_assert (NAUTILUS_IS_VIEW_FRAME (view)); gtk_signal_disconnect_by_func (GTK_OBJECT(view), nautilus_window_view_failed, window); } void nautilus_window_display_error(NautilusWindow *window, const char *error_msg) { GtkWidget *dialog; dialog = gnome_message_box_new (error_msg, GNOME_MESSAGE_BOX_ERROR, _("Close"), NULL); gnome_dialog_set_close (GNOME_DIALOG(dialog), TRUE); gnome_dialog_set_default (GNOME_DIALOG(dialog), 0); gtk_widget_show (dialog); } static void nautilus_window_real_set_content_view (NautilusWindow *window, NautilusViewFrame *new_view) { g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (new_view == NULL || NAUTILUS_IS_VIEW_FRAME (new_view)); if (new_view == window->content_view) { return; } if (window->content_view != NULL) { gtk_container_remove (GTK_CONTAINER (window->content_hbox), GTK_WIDGET (window->content_view)); } /* Here's an explicit check for a problem that happens all too often. */ if (bonobo_ui_handler_menu_path_exists (window->ui_handler, "/File/Open")) { g_warning ("There's a lingering Open menu item. This usually means a new Bonobo bug."); } if (new_view != NULL) { gtk_widget_show (GTK_WIDGET (new_view)); nautilus_view_frame_activate (new_view); /* FIXME bugzilla.eazel.com 1243: * We should use inheritance instead of these special cases * for the desktop window. */ if (!E_IS_PANED (window->content_hbox)) { gtk_container_add (GTK_CONTAINER (window->content_hbox), GTK_WIDGET (new_view)); } else { e_paned_pack2 (E_PANED (window->content_hbox), GTK_WIDGET (new_view), TRUE, FALSE); } } window->content_view = new_view; } /* reload the contents of the window */ void nautilus_window_reload (NautilusWindow *window) { nautilus_window_begin_location_change (window, window->location, NULL, NAUTILUS_LOCATION_CHANGE_RELOAD, 0); } /** * window_find_sidebar_panel_by_identifier: * @window: A NautilusWindow * @identifier: The NautilusViewIdentifier to look for * * Search the list of sidebar panels in the given window for one that * matches the given view identifier. * * Returns a referenced object, not a floating one. bonobo_object_unref * it when done playing with it. */ static NautilusViewFrame * window_find_sidebar_panel_by_identifier (NautilusWindow *window, NautilusViewIdentifier *identifier) { GList *iterator; g_assert (window != NULL); g_assert (NAUTILUS_IS_WINDOW (window)); g_assert (identifier != NULL); for (iterator = window->sidebar_panels; iterator != NULL; iterator = iterator->next) { NautilusViewFrame *sidebar_panel; g_assert (iterator->data != NULL); g_assert (NAUTILUS_IS_VIEW_FRAME (iterator->data)); sidebar_panel = NAUTILUS_VIEW_FRAME (iterator->data); if (strcmp (sidebar_panel->iid, identifier->iid) == 0) { gtk_widget_ref (GTK_WIDGET (sidebar_panel)); return sidebar_panel; } } return NULL; } /** * window_update_sidebar_panels_from_preferences: * @window: A NautilusWindow * * Update the current list of sidebar panels from preferences. * * Disabled panels are removed if they are already in the list. * * Enabled panels are added if they are not already in the list. * */ static void window_update_sidebar_panels_from_preferences (NautilusWindow *window) { GList *enabled_view_identifier_list = NULL; GList *disabled_view_identifier_list = NULL; GList *iterator = NULL; g_assert (window != NULL); g_assert (NAUTILUS_IS_WINDOW (window)); /* Obtain list of disabled view identifiers */ disabled_view_identifier_list = nautilus_global_preferences_get_disabled_sidebar_panel_view_identifiers (); /* Remove disabled panels from the window as needed */ for (iterator = disabled_view_identifier_list; iterator != NULL; iterator = iterator->next) { NautilusViewIdentifier *identifier; NautilusViewFrame *sidebar_panel; g_assert (iterator->data != NULL); identifier = (NautilusViewIdentifier *) iterator->data; sidebar_panel = window_find_sidebar_panel_by_identifier (window, identifier); if (sidebar_panel != NULL) { nautilus_window_disconnect_view (window, sidebar_panel); nautilus_window_remove_sidebar_panel (window, sidebar_panel); } } if (disabled_view_identifier_list) { nautilus_view_identifier_list_free (disabled_view_identifier_list); } /* Obtain list of enabled view identifiers */ enabled_view_identifier_list = nautilus_global_preferences_get_enabled_sidebar_panel_view_identifiers (); /* Add enabled panels from the window as needed */ for (iterator = enabled_view_identifier_list; iterator != NULL; iterator = iterator->next) { NautilusViewIdentifier *identifier; NautilusViewFrame *sidebar_panel; g_assert (iterator->data != NULL); identifier = (NautilusViewIdentifier *) iterator->data; sidebar_panel = window_find_sidebar_panel_by_identifier (window, identifier); if (sidebar_panel == NULL) { gboolean load_result; sidebar_panel = nautilus_view_frame_new (window->ui_handler, window->application->undo_manager); nautilus_window_connect_view (window, sidebar_panel); load_result = nautilus_view_frame_load_client (sidebar_panel, identifier->iid); /* Make sure the load_client succeeded */ if (load_result) { nautilus_view_frame_set_label (sidebar_panel, identifier->name); nautilus_window_add_sidebar_panel (window, sidebar_panel); } else { g_warning ("sidebar_panels_changed_callback: Failed to load_client for '%s' meta view.", identifier->iid); gtk_widget_unref (GTK_WIDGET (sidebar_panel)); sidebar_panel = NULL; } } else { gtk_widget_unref (GTK_WIDGET (sidebar_panel)); } } nautilus_view_identifier_list_free (enabled_view_identifier_list); } /** * sidebar_panels_changed_callback: * @user_data: Callback data * * Called when enabled/disabled preferences change for any * sidebar panel. */ static void sidebar_panels_changed_callback (gpointer user_data) { window_update_sidebar_panels_from_preferences (NAUTILUS_WINDOW (user_data)); } static void show_dock_item (NautilusWindow *window, const char *dock_item_name) { GnomeApp *app; GnomeDockItem *dock_item; app = GNOME_APP (window); dock_item = gnome_app_get_dock_item_by_name (app, dock_item_name); if (dock_item != NULL) { gtk_widget_show (GTK_WIDGET (dock_item)); gtk_widget_queue_resize (GTK_WIDGET (dock_item)->parent); } nautilus_window_update_show_hide_menu_items (window); } static void hide_dock_item (NautilusWindow *window, const char *dock_item_name) { GnomeApp *app; GnomeDockItem *dock_item; app = GNOME_APP (window); dock_item = gnome_app_get_dock_item_by_name (app, dock_item_name); if (dock_item != NULL) { gtk_widget_hide (GTK_WIDGET (dock_item)); gtk_widget_queue_resize (GTK_WIDGET (dock_item)->parent); } nautilus_window_update_show_hide_menu_items (window); } static gboolean dock_item_showing (NautilusWindow *window, const char *dock_item_name) { GnomeApp *app; GnomeDockItem *dock_item; app = GNOME_APP (window); dock_item = gnome_app_get_dock_item_by_name (app, dock_item_name); return dock_item != NULL && GTK_WIDGET_VISIBLE (dock_item); } void nautilus_window_hide_location_bar (NautilusWindow *window) { hide_dock_item (window, URI_ENTRY_DOCK_ITEM); } void nautilus_window_show_location_bar (NautilusWindow *window) { show_dock_item (window, URI_ENTRY_DOCK_ITEM); } gboolean nautilus_window_location_bar_showing (NautilusWindow *window) { return dock_item_showing (window, URI_ENTRY_DOCK_ITEM); } void nautilus_window_hide_tool_bar (NautilusWindow *window) { hide_dock_item (window, GNOME_APP_TOOLBAR_NAME); } void nautilus_window_show_tool_bar (NautilusWindow *window) { show_dock_item (window, GNOME_APP_TOOLBAR_NAME); } gboolean nautilus_window_tool_bar_showing (NautilusWindow *window) { return dock_item_showing (window, GNOME_APP_TOOLBAR_NAME); } void nautilus_window_hide_sidebar (NautilusWindow *window) { gtk_widget_hide (GTK_WIDGET (window->sidebar)); if (window->content_hbox != NULL && !NAUTILUS_IS_DESKTOP_WINDOW (window)) { e_paned_set_position (E_PANED (window->content_hbox), 0); } nautilus_window_update_show_hide_menu_items (window); } void nautilus_window_show_sidebar (NautilusWindow *window) { GtkWidget *widget; widget = GTK_WIDGET (window->sidebar); gtk_widget_show (widget); if (window->content_hbox != NULL && !NAUTILUS_IS_DESKTOP_WINDOW (window)) { e_paned_set_position (E_PANED (window->content_hbox), widget->allocation.width); } nautilus_window_update_show_hide_menu_items (window); } gboolean nautilus_window_sidebar_showing (NautilusWindow *window) { return GTK_WIDGET_VISIBLE (window->sidebar); } void nautilus_window_hide_status_bar (NautilusWindow *window) { GnomeApp *app; app = GNOME_APP (window); if (app->statusbar != NULL) { gtk_widget_hide (GTK_WIDGET (app->statusbar)->parent); } nautilus_window_update_show_hide_menu_items (window); } void nautilus_window_show_status_bar (NautilusWindow *window) { GnomeApp *app; app = GNOME_APP (window); if (app->statusbar != NULL) { gtk_widget_show (GTK_WIDGET (app->statusbar)->parent); } nautilus_window_update_show_hide_menu_items (window); } gboolean nautilus_window_status_bar_showing (NautilusWindow *window) { GnomeApp *app; app = GNOME_APP (window); return (app->statusbar != NULL && GTK_WIDGET_VISIBLE (GTK_WIDGET (app->statusbar)->parent)); } /** * nautilus_window_get_base_page_index: * @window: Window to get index from * * Returns the index of the base page in the history list. * Base page is not the currently displayed page, but the page * that acts as the base from which the back and forward commands * navigate from. */ gint nautilus_window_get_base_page_index (NautilusWindow *window) { gint forward_count; forward_count = g_list_length (window->forward_list); /* If forward is empty, the base it at the top of the list */ if (forward_count == 0) { return 0; } /* The forward count indicate the relative postion of the base page * in the history list */ return forward_count; } /** * nautilus_window_show: * @widget: GtkWidget * * Call parent and then show/hide window items * base on user prefs. */ static void nautilus_window_show (GtkWidget *widget) { NautilusWindow *window; window = NAUTILUS_WINDOW (widget); NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, show, (widget)); /* Initially show or hide views based on preferences; once the window is displayed * these can be controlled on a per-window basis from View menu items. */ if (nautilus_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_TOOL_BAR, TRUE)) { nautilus_window_show_tool_bar (window); } else { nautilus_window_hide_tool_bar (window); } if (nautilus_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_LOCATION_BAR, TRUE)) { nautilus_window_show_location_bar (window); } else { nautilus_window_hide_location_bar (window); } if (nautilus_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_STATUS_BAR, TRUE)) { nautilus_window_show_status_bar (window); } else { nautilus_window_hide_status_bar (window); } if (nautilus_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_SIDEBAR, TRUE)) { nautilus_window_show_sidebar (window); } else { nautilus_window_hide_sidebar (window); } }