/* * Copyright (C) 2001, 2002 Ricardo Fernández Pascual * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include "ephy-embed-popup-control.h" #include "ephy-nautilus-view.h" #include "ephy-embed.h" #include "ephy-embed-utils.h" #include "find-dialog.h" #include "print-dialog.h" #include "ephy-prefs.h" #include "ephy-zoom.h" #include "eel-gconf-extensions.h" #include "ephy-debug.h" static void gnv_embed_location_cb (EphyEmbed *embed, EphyNautilusView *view); static void gnv_embed_title_cb (EphyEmbed *embed, EphyNautilusView *view); static void gnv_embed_new_window_cb (EphyEmbed *embed, EphyEmbed **new_embed, EmbedChromeMask chromemask, EphyNautilusView *view); static void gnv_embed_link_message_cb (EphyEmbed *embed, const char *message, EphyNautilusView *view); static gint gnv_embed_dom_mouse_click_cb (EphyEmbed *embed, EphyEmbedEvent *event, EphyNautilusView *view); static void gnv_embed_context_menu_cb (EphyEmbed *embed, EphyEmbedEvent *event, EphyNautilusView *view); static void gnv_embed_zoom_change_cb (EphyNautilusView *embed, float new_zoom, EphyNautilusView *view); static void gnv_load_location_cb (EphyNautilusView *view, const char *location, gpointer user_data); static void gnv_stop_loading_cb (EphyNautilusView *view, gpointer user_data); static void gnv_bonobo_control_activate_cb (BonoboControl *control, gboolean state, EphyNautilusView *view); /* zoomable */ static void gnv_zoomable_set_zoom_level_cb (BonoboZoomable *zoomable, float level, EphyNautilusView *view); static void gnv_zoomable_zoom_in_cb (BonoboZoomable *zoomable, EphyNautilusView *view); static void gnv_zoomable_zoom_out_cb (BonoboZoomable *zoomable, EphyNautilusView *view); static void gnv_zoomable_zoom_to_fit_cb (BonoboZoomable *zoomable, EphyNautilusView *view); static void gnv_zoomable_zoom_to_default_cb (BonoboZoomable *zoomable, EphyNautilusView *view); /* commands */ static void gnv_cmd_set_encoding (BonoboUIComponent *uic, EphyNautilusView *view, const char* verbname); static void gnv_cmd_file_print (BonoboUIComponent *uic, EphyNautilusView *view, const char* verbname); static void gnv_cmd_edit_find (BonoboUIComponent *uic, EphyNautilusView *view, const char* verbname); /* popups */ static EphyNautilusView *gnv_view_from_popup (EphyEmbedPopup *popup); static void gnv_popup_cmd_new_window (BonoboUIComponent *uic, EphyEmbedPopup *popup, const char* verbname); static void gnv_popup_cmd_image_in_new_window (BonoboUIComponent *uic, EphyEmbedPopup *popup, const char* verbname); static void gnv_popup_cmd_frame_in_new_window (BonoboUIComponent *uic, EphyEmbedPopup *popup, const char* verbname); struct EphyNautilusViewPrivate { EphyEmbed *embed; char *title; char *location; int load_percent; /* BonoboPropertyBag *property_bag; */ EphyEmbedPopupControl *popup; BonoboUIComponent *popup_ui; BonoboControl *control; BonoboUIComponent *ui; BonoboZoomable *zoomable; EphyDialog *find_dialog; }; static BonoboUIVerb ephy_popup_verbs [] = { BONOBO_UI_VERB ("EPOpenInNewWindow", (BonoboUIVerbFn) gnv_popup_cmd_new_window), BONOBO_UI_VERB ("EPOpenImageInNewWindow", (BonoboUIVerbFn) gnv_popup_cmd_image_in_new_window), BONOBO_UI_VERB ("DPOpenFrameInNewWindow", (BonoboUIVerbFn) gnv_popup_cmd_frame_in_new_window), BONOBO_UI_VERB_END }; BonoboUIVerb ephy_verbs [] = { BONOBO_UI_VERB ("FilePrint", (BonoboUIVerbFn) gnv_cmd_file_print), BONOBO_UI_VERB ("EditFind", (BonoboUIVerbFn) gnv_cmd_edit_find), BONOBO_UI_VERB_END }; #define ENCODING_MENU_PATH "/menu/View/Encoding" BONOBO_CLASS_BOILERPLATE (EphyNautilusView, ephy_nautilus_view, NautilusView, NAUTILUS_TYPE_VIEW) static void ephy_nautilus_view_instance_init (EphyNautilusView *view) { GtkWidget *w; EphyNautilusViewPrivate *p = g_new0 (EphyNautilusViewPrivate, 1); EphyEmbedSingle *single; float *levels; gchar **names; guint i; single = ephy_embed_shell_get_embed_single (EPHY_EMBED_SHELL (ephy_shell)); view->priv = p; view->priv->embed = ephy_embed_new (G_OBJECT (single)); g_object_ref (G_OBJECT (ephy_shell)); g_signal_connect (view->priv->embed, "ge_link_message", GTK_SIGNAL_FUNC (gnv_embed_link_message_cb), view); g_signal_connect (view->priv->embed, "ge_location", GTK_SIGNAL_FUNC (gnv_embed_location_cb), view); g_signal_connect (view->priv->embed, "ge_title", GTK_SIGNAL_FUNC (gnv_embed_title_cb), view); /* g_signal_connect (view->priv->embed, "ge_js_status", GTK_SIGNAL_FUNC (gnv_embed_js_status_cb), view); g_signal_connect (view->priv->embed, "ge_progress", GTK_SIGNAL_FUNC (gnv_embed_progress_cb), view); g_signal_connect (view->priv->embed, "ge_net_state", GTK_SIGNAL_FUNC (gnv_embed_net_state_cb), view); */ g_signal_connect (view->priv->embed, "ge_new_window", GTK_SIGNAL_FUNC (gnv_embed_new_window_cb), view); /* g_signal_connect (view->priv->embed, "ge_visibility", GTK_SIGNAL_FUNC (gnv_embed_visibility_cb), view); g_signal_connect (view->priv->embed, "ge_destroy_brsr", GTK_SIGNAL_FUNC (gnv_embed_destroy_brsr_cb), view); g_signal_connect (view->priv->embed, "ge_open_uri", GTK_SIGNAL_FUNC (gnv_embed_open_uri_cb), view); g_signal_connect (view->priv->embed, "ge_size_to", GTK_SIGNAL_FUNC (gnv_embed_size_to_cb), view); g_signal_connect (view->priv->embed, "ge_dom_mouse_click", GTK_SIGNAL_FUNC (gnv_embed_dom_mouse_click_cb), view); */ g_signal_connect (view->priv->embed, "ge_dom_mouse_click", GTK_SIGNAL_FUNC (gnv_embed_dom_mouse_click_cb), view); g_signal_connect (view->priv->embed, "ge_context_menu", GTK_SIGNAL_FUNC (gnv_embed_context_menu_cb), view); /* g_signal_connect (view->priv->embed, "ge_security_change", GTK_SIGNAL_FUNC (gnv_embed_security_change_cb), view); */ g_signal_connect (view->priv->embed, "ge_zoom_change", GTK_SIGNAL_FUNC (gnv_embed_zoom_change_cb), view); w = GTK_WIDGET (view->priv->embed); gtk_widget_show (w); nautilus_view_construct (NAUTILUS_VIEW (view), w); g_signal_connect (G_OBJECT (view), "load_location", G_CALLBACK (gnv_load_location_cb), NULL); g_signal_connect (G_OBJECT (view), "stop_loading", G_CALLBACK (gnv_stop_loading_cb), NULL); g_signal_connect (G_OBJECT (nautilus_view_get_bonobo_control (NAUTILUS_VIEW (view))), "activate", G_CALLBACK (gnv_bonobo_control_activate_cb), view); view->priv->zoomable = bonobo_zoomable_new (); bonobo_object_add_interface (BONOBO_OBJECT (view), BONOBO_OBJECT (view->priv->zoomable)); /* get zoom levels */ levels = g_new0 (float, n_zoom_levels); names = g_new0 (gchar *, n_zoom_levels); for (i = 0; i < n_zoom_levels; i++) { levels[i] = zoom_levels[i].level; names[i] = zoom_levels[i].name; } bonobo_zoomable_set_parameters_full (view->priv->zoomable, 1.0, levels [0], levels [n_zoom_levels-1], FALSE, FALSE, TRUE, levels, (const gchar **) names, n_zoom_levels); g_free (levels); g_free (names); bonobo_object_add_interface (BONOBO_OBJECT (view), BONOBO_OBJECT (view->priv->zoomable)); g_signal_connect (view->priv->zoomable, "set_zoom_level", G_CALLBACK (gnv_zoomable_set_zoom_level_cb), view); g_signal_connect (view->priv->zoomable, "zoom_in", G_CALLBACK (gnv_zoomable_zoom_in_cb), view); g_signal_connect (view->priv->zoomable, "zoom_out", G_CALLBACK (gnv_zoomable_zoom_out_cb), view); g_signal_connect (view->priv->zoomable, "zoom_to_fit", G_CALLBACK (gnv_zoomable_zoom_to_fit_cb), view); g_signal_connect (view->priv->zoomable, "zoom_to_default", G_CALLBACK (gnv_zoomable_zoom_to_default_cb), view); p->control = nautilus_view_get_bonobo_control (NAUTILUS_VIEW (view)); p->popup_ui = bonobo_control_get_popup_ui_component (p->control); g_assert (BONOBO_IS_UI_COMPONENT (p->popup_ui)); bonobo_ui_util_set_ui (p->popup_ui, SHARE_DIR, "nautilus-epiphany-view.xml", "EphyNautilusView", NULL); p->popup = ephy_embed_popup_control_new (p->control); ephy_embed_popup_connect_verbs (EPHY_EMBED_POPUP (p->popup), p->popup_ui); g_object_set_data (G_OBJECT (p->popup), "NautilisView", view); bonobo_ui_component_add_verb_list_with_data (p->popup_ui, ephy_popup_verbs, p->popup); } /** * Returns a new EphyNautilusView as a BonoboObject **/ BonoboObject * ephy_nautilus_view_new_component (EphyShell *gs) { EphyNautilusView *view; view = EPHY_NAUTILUS_VIEW (g_object_new (EPHY_TYPE_NAUTILUS_VIEW, NULL)); return BONOBO_OBJECT (view); } static void ephy_nautilus_view_finalize (GObject *object) { EphyNautilusView *view = EPHY_NAUTILUS_VIEW (object); EphyNautilusViewPrivate *p = view->priv; if (p->find_dialog) { g_object_unref (p->find_dialog); } g_object_unref (p->popup); g_free (p->title); g_free (p->location); g_free (p); GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); g_object_unref (G_OBJECT (ephy_shell)); } static void ephy_nautilus_view_class_init (EphyNautilusViewClass *class) { G_OBJECT_CLASS (class)->finalize = ephy_nautilus_view_finalize; } static gint gnv_embed_dom_mouse_click_cb (EphyEmbed *embed, EphyEmbedEvent *event, EphyNautilusView *view) { EphyEmbedEventType type; EmbedEventContext context; ephy_embed_event_get_event_type (event, &type); ephy_embed_event_get_context (event, &context); if (type == EPHY_EMBED_EVENT_MOUSE_BUTTON2 && (context & EMBED_CONTEXT_LINK)) { const GValue *value; const gchar *url; ephy_embed_event_get_property (event, "link", &value); url = g_value_get_string (value); g_return_val_if_fail (url, FALSE); nautilus_view_open_location_force_new_window (NAUTILUS_VIEW (view), url, NULL); } return FALSE; } static void gnv_embed_context_menu_cb (EphyEmbed *embed, EphyEmbedEvent *event, EphyNautilusView *view) { EphyNautilusViewPrivate *p = view->priv; EmbedEventContext context; ephy_embed_event_get_context (event, &context); ephy_embed_popup_set_event (EPHY_EMBED_POPUP (p->popup), event); ephy_embed_popup_show (EPHY_EMBED_POPUP (p->popup), embed); } static void gnv_embed_link_message_cb (EphyEmbed *embed, const char *message, EphyNautilusView *view) { g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); g_return_if_fail (message != NULL); nautilus_view_report_status (NAUTILUS_VIEW (view), message); } static void gnv_embed_location_cb (EphyEmbed *embed, EphyNautilusView *view) { EphyNautilusViewPrivate *p; const gchar *prefixes_to_ignore[] = { "about:", "javascript:", NULL }; int i = 0; gchar *new_uri; g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); p = view->priv; g_return_if_fail (view->priv->embed == embed); ephy_embed_get_location (embed, TRUE, &new_uri); g_return_if_fail (new_uri != NULL); /* don't inform nautilus about uris that it can't understand */ while (prefixes_to_ignore[i] != NULL) { if (!strncmp (prefixes_to_ignore[i], new_uri, strlen (prefixes_to_ignore[i]))) { g_free (new_uri); return; } ++i; } nautilus_view_report_location_change (NAUTILUS_VIEW (view), new_uri, NULL, new_uri); /* TODO, FIXME nautilus_view_report_redirect (view, p->location, new_uri, NULL, new_uri); */ g_free (p->location); p->location = new_uri; } static void gnv_embed_title_cb (EphyEmbed *embed, EphyNautilusView *view) { EphyNautilusViewPrivate *p; g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); p = view->priv; g_return_if_fail (view->priv->embed == embed); g_free (p->title); ephy_embed_get_title (embed, &p->title); nautilus_view_set_title (NAUTILUS_VIEW (view), p->title); } static void gnv_load_location_cb (EphyNautilusView *view, const char *location, gpointer user_data) { g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); g_return_if_fail (location != NULL); nautilus_view_report_load_underway (NAUTILUS_VIEW (view)); ephy_embed_load_url (view->priv->embed, location); } static void gnv_stop_loading_cb (EphyNautilusView *view, gpointer user_data) { } static void gnv_embed_new_window_cb (EphyEmbed *embed, EphyEmbed **new_embed, EmbedChromeMask chromemask, EphyNautilusView *view) { EphyTab *new_tab; EphyWindow *window; window = ephy_window_new (); if (!(chromemask & EMBED_CHROME_OPENASCHROME)) { ephy_window_set_chrome (window, chromemask | EMBED_CHROME_OPENASPOPUP); } new_tab = ephy_tab_new (); ephy_window_add_tab (window, new_tab, EPHY_NOTEBOOK_INSERT_LAST, FALSE); *new_embed = ephy_tab_get_embed (new_tab); } static void gnv_bonobo_control_activate_cb (BonoboControl *control, gboolean state, EphyNautilusView *view) { if (state) { EphyNautilusViewPrivate *p = view->priv; p->ui = nautilus_view_set_up_ui (NAUTILUS_VIEW (view), SHARE_DIR, "nautilus-epiphany-view.xml", "EphyNautilusView"); g_return_if_fail (BONOBO_IS_UI_COMPONENT (p->ui)); ephy_embed_utils_build_encodings_submenu (p->ui, ENCODING_MENU_PATH, (BonoboUIVerbFn) gnv_cmd_set_encoding, view); bonobo_ui_component_add_verb_list_with_data (p->ui, ephy_verbs, view); } } static EphyNautilusView * gnv_view_from_popup (EphyEmbedPopup *popup) { return g_object_get_data (G_OBJECT (popup), "NautilisView"); } static void gnv_popup_cmd_new_window (BonoboUIComponent *uic, EphyEmbedPopup *popup, const char* verbname) { EphyEmbedEvent *info; EphyNautilusView *view; const GValue *value; view = gnv_view_from_popup (popup); info = ephy_embed_popup_get_event (popup); ephy_embed_event_get_property (info, "link", &value); nautilus_view_open_location_force_new_window (NAUTILUS_VIEW (view), g_value_get_string (value), NULL); } static void gnv_popup_cmd_image_in_new_window (BonoboUIComponent *uic, EphyEmbedPopup *popup, const char* verbname) { EphyEmbedEvent *info; EphyNautilusView *view; const GValue *value; view = gnv_view_from_popup (popup); info = ephy_embed_popup_get_event (popup); ephy_embed_event_get_property (info, "image", &value); nautilus_view_open_location_force_new_window (NAUTILUS_VIEW (view), g_value_get_string (value), NULL); } static void gnv_popup_cmd_frame_in_new_window (BonoboUIComponent *uic, EphyEmbedPopup *popup, const char* verbname) { EphyEmbedEvent *info; EphyNautilusView *view; gchar *location; view = gnv_view_from_popup (popup); info = ephy_embed_popup_get_event (popup); ephy_embed_get_location (view->priv->embed, FALSE, &location); nautilus_view_open_location_force_new_window (NAUTILUS_VIEW (view), location, NULL); g_free (location); } void gnv_cmd_set_encoding (BonoboUIComponent *uic, EphyNautilusView *view, const char* verbname) { const char *encoding; g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); if (strncmp (verbname, "Encoding", 8) == 0) { encoding = verbname + 8; LOG ("Set encoding %s", encoding) ephy_embed_set_encoding (view->priv->embed, encoding); } } static void gnv_cmd_file_print (BonoboUIComponent *uic, EphyNautilusView *view, const char* verbname) { EphyDialog *dialog; EphyNautilusViewPrivate *p = view->priv; dialog = print_dialog_new (p->embed, NULL); //g_signal_connect (G_OBJECT(dialog), // "preview", // G_CALLBACK (print_dialog_preview_cb), // window); ephy_dialog_set_modal (dialog, TRUE); ephy_dialog_show (dialog); } static void gnv_cmd_edit_find (BonoboUIComponent *uic, EphyNautilusView *view, const char* verbname) { EphyNautilusViewPrivate *p = view->priv; if (!p->find_dialog) { p->find_dialog = find_dialog_new (p->embed); } ephy_dialog_show (p->find_dialog); } /* zoomable */ static void gnv_zoomable_set_zoom_level_cb (BonoboZoomable *zoomable, float level, EphyNautilusView *view) { g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); ephy_embed_zoom_set (view->priv->embed, ephy_zoom_get_nearest_zoom_level (level), TRUE); } static void gnv_zoomable_zoom_in_cb (BonoboZoomable *zoomable, EphyNautilusView *view) { float zoom, new_zoom; gresult rv; g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); rv = ephy_embed_zoom_get (view->priv->embed, &zoom); if (rv == G_FAILED) return; new_zoom = ephy_zoom_get_changed_zoom_level (zoom, 1); ephy_embed_zoom_set (view->priv->embed, new_zoom, TRUE); } static void gnv_zoomable_zoom_out_cb (BonoboZoomable *zoomable, EphyNautilusView *view) { float zoom, new_zoom; gresult rv; g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); rv = ephy_embed_zoom_get (view->priv->embed, &zoom); if (rv == G_FAILED) return; new_zoom = ephy_zoom_get_changed_zoom_level (zoom, -1); ephy_embed_zoom_set (view->priv->embed, new_zoom, TRUE); } static void gnv_zoomable_zoom_to_fit_cb (BonoboZoomable *zoomable, EphyNautilusView *view) { gnv_zoomable_zoom_to_default_cb (zoomable, view); } static void gnv_zoomable_zoom_to_default_cb (BonoboZoomable *zoomable, EphyNautilusView *view) { g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); ephy_embed_zoom_set (view->priv->embed, 1.0, TRUE); } static void gnv_embed_zoom_change_cb (EphyNautilusView *embed, float new_zoom, EphyNautilusView *view) { g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); bonobo_zoomable_report_zoom_level_changed (view->priv->zoomable, new_zoom, NULL); } #ifdef IM_TOO_LAZY_TO_MOVE_THIS_TO_ANOTHER_FILE /* property bag properties */ enum { ICON_NAME, COMPONENT_INFO }; static void get_bonobo_properties (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer callback_data) { EphyNautilusView *content_view; content_view = (EphyNautilusView*) callback_data; switch (arg_id) { case ICON_NAME: if (!strncmp (content_view->priv->uri, "man:", 4)) { BONOBO_ARG_SET_STRING (arg, "manual"); } else if (!strncmp (content_view->priv->uri, "http:", 5)) { BONOBO_ARG_SET_STRING (arg, "i-web"); } else if (!strncmp (content_view->priv->uri, "https:", 6)) { /* FIXME: put a nice icon for secure sites */ BONOBO_ARG_SET_STRING (arg, "i-web"); } else { BONOBO_ARG_SET_STRING (arg, ""); } break; case COMPONENT_INFO: BONOBO_ARG_SET_STRING (arg, ""); break; default: g_warning ("Unhandled arg %d", arg_id); break; } } /* there are no settable properties, so complain if someone tries to set one */ static void set_bonobo_properties (BonoboPropertyBag *bag, const BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer callback_data) { g_warning ("Bad Property set on view: property ID %d", arg_id); } static void ephy_nautilus_view_initialize (EphyNautilusView *view) { #ifdef NOT_PORTED bonobo_control_set_properties (nautilus_view_get_bonobo_control (view->priv->nautilus_view), view->priv->property_bag); #endif bonobo_property_bag_add (view->priv->property_bag, "icon_name", ICON_NAME, BONOBO_ARG_STRING, NULL, _("name of icon for the mozilla view"), 0); bonobo_property_bag_add (view->priv->property_bag, "summary_info", COMPONENT_INFO, BONOBO_ARG_STRING, NULL, _("mozilla summary info"), 0); } /* free the property bag */ if (view->priv->property_bag != NULL) { bonobo_object_unref (BONOBO_OBJECT (view->priv->property_bag)); view->priv->property_bag = NULL; } } void ephy_nautilus_view_report_load_progress (EphyNautilusView *view, double value) { g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); if (value < 0.0) value = 0.0; if (value > 1.0) value = 1.0; nautilus_view_report_load_progress (view->priv->nautilus_view, value); } /***********************************************************************************/ /** * vfs_open_cb * * Callback for gnome_vfs_async_open. Attempt to read data from handle * and pass to mozilla streaming callback. * **/ static void vfs_open_cb (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data) { EphyNautilusView *view = data; LOG ("+%s GnomeVFSResult: %u", G_GNUC_FUNCTION, (unsigned)result) if (result != GNOME_VFS_OK) { gtk_moz_embed_close_stream (GTK_MOZ_EMBED (view->priv->embed->mozembed)); /* NOTE: the view may go away after a call to report_load_failed */ LOG (">nautilus_view_report_load_failed") nautilus_view_report_load_failed (view->priv->nautilus_view); } else { if (view->priv->vfs_read_buffer == NULL) { view->priv->vfs_read_buffer = g_malloc (VFS_READ_BUFFER_SIZE); } gtk_moz_embed_open_stream (GTK_MOZ_EMBED (view->priv->embed->mozembed), "file:///", "text/html"); gnome_vfs_async_read (handle, view->priv->vfs_read_buffer, VFS_READ_BUFFER_SIZE, vfs_read_cb, view); } LOG ("-%s", G_GNUC_FUNCTION); } /** * vfs_read_cb: * * Read data from buffer and copy into mozilla stream. **/ static void vfs_read_cb (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer buffer, GnomeVFSFileSize bytes_requested, GnomeVFSFileSize bytes_read, gpointer data) { EphyNautilusView *view = data; LOG ("+%s %ld/%ld bytes", G_GNUC_FUNCTION, (long)bytes_requested, (long) bytes_read) if (bytes_read != 0) { gtk_moz_embed_append_data (GTK_MOZ_EMBED (view->priv->embed->mozembed), buffer, bytes_read); } if (bytes_read == 0 || result != GNOME_VFS_OK) { gtk_moz_embed_close_stream (GTK_MOZ_EMBED (view->priv->embed->mozembed)); view->priv->vfs_handle = NULL; g_free (view->priv->vfs_read_buffer); view->priv->vfs_read_buffer = NULL; gnome_vfs_async_close (handle, (GnomeVFSAsyncCloseCallback) gtk_true, NULL); LOG (">nautilus_view_report_load_complete") nautilus_view_report_load_complete (view->priv->nautilus_view); LOG ("=%s load complete", G_GNUC_FUNCTION) } else { gnome_vfs_async_read (handle, view->priv->vfs_read_buffer, VFS_READ_BUFFER_SIZE, vfs_read_cb, view); } LOG ("-%s", G_GNUC_FUNCTION) } /***********************************************************************************/ static void cancel_pending_vfs_operation (EphyNautilusView *view) { if (view->priv->vfs_handle != NULL) { gnome_vfs_async_cancel (view->priv->vfs_handle); gtk_moz_embed_close_stream (GTK_MOZ_EMBED (view->priv->embed->mozembed)); } view->priv->vfs_handle = NULL; g_free (view->priv->vfs_read_buffer); view->priv->vfs_read_buffer = NULL; } /* this takes a "nautilus" uri, not a "mozilla" uri and uses (sometimes) GnomeVFS */ static void navigate_mozilla_to_nautilus_uri (EphyNautilusView *view, const char *uri) { char *old_uri; cancel_pending_vfs_operation (view); if (!GTK_WIDGET_REALIZED (view->priv->embed->mozembed)) { /* Doing certain things to gtkmozembed before * the widget has realized (specifically, opening * content streams) can cause crashes. To avoid * this, we postpone all navigations * until the widget has realized (we believe * premature realization may cause other issues) */ LOG ("=%s: Postponing navigation request to widget realization", G_GNUC_FUNCTION) /* Note that view->priv->uri is still set below */ } else { if (should_mozilla_load_uri_directly (uri)) { /* See if the current URI is the same as what mozilla already * has. If so, issue a reload rather than a load. * We ask mozilla for it's uri rather than using view->priv->uri because, * from time to time, our understanding of mozilla's URI can become inaccurate * (in particular, certain errors may cause embedded mozilla to not change * locations) */ old_uri = view->priv->embed->location; if (old_uri != NULL && uris_identical (uri, old_uri)) { LOG ("=%s uri's identical, telling ephy to reload", G_GNUC_FUNCTION) embed_reload (view->priv->embed, GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE); } else { embed_load_url (view->priv->embed, uri); } } else { LOG ("=%s loading URI via gnome-vfs", G_GNUC_FUNCTION) gnome_vfs_async_open (&(view->priv->vfs_handle), uri, GNOME_VFS_OPEN_READ, GNOME_VFS_PRIORITY_DEFAULT, vfs_open_cb, view); } } g_free (view->priv->uri); view->priv->uri = g_strdup (uri); LOG ("=%s current URI is now '%s'", G_GNUC_FUNCTION, view->priv->uri) } /* * This a list of URI schemes that mozilla should load directly, rather than load through gnome-vfs */ static gboolean should_mozilla_load_uri_directly (const char *uri) { static const char *handled_by_mozilla[] = { "http", "file", "toc", "man", "info", "ghelp", "gnome-help", "https", NULL }; gint i; gint uri_length; if (uri == NULL) return FALSE; uri_length = strlen (uri); for (i = 0; handled_by_mozilla[i] != NULL; i++) { const gchar *current = handled_by_mozilla[i]; gint current_length = strlen (current); if ((uri_length >= current_length) && (!strncasecmp (uri, current, current_length))) return TRUE; } return FALSE; } #endif