diff options
author | Elliot Lee <sopwith@src.gnome.org> | 2000-01-05 23:21:06 +0000 |
---|---|---|
committer | Elliot Lee <sopwith@src.gnome.org> | 2000-01-05 23:21:06 +0000 |
commit | 6018bcea245c2e4a9c50055fe6207435850549ff (patch) | |
tree | 2de36703f80e7a24435e69d4194eb56f62b55454 | |
parent | cdf570ee034dc1349846eeb5f78775a23ea2eb47 (diff) | |
download | nautilus-6018bcea245c2e4a9c50055fe6207435850549ff.tar.gz |
Add support for the location change state machine and related
* src/ntl-types.h, src/ntl-uri-map.[ch], src/ntl-window-msgs.c, src/ntl-window.[ch]:
Add support for the location change state machine and related notifications,
to allow much better error handling.
* src/ntl-view.[ch]: Catch client failures, also allow for active sensing of client death.
* src/file-manager/fm-directory-view.c: Send progress notifications.
* components/html/ntl-web-browser.c: Send progress
notifications. Try to fix crashes caused by ending an error stream
twice.
30 files changed, 1050 insertions, 570 deletions
diff --git a/ChangeLog-20000414 b/ChangeLog-20000414 index 9872de03b..6155f7ef6 100644 --- a/ChangeLog-20000414 +++ b/ChangeLog-20000414 @@ -1,3 +1,14 @@ +2000-01-05 Elliot Lee <sopwith@redhat.com> + + * src/ntl-types.h, src/ntl-uri-map.[ch], src/ntl-window-msgs.c, src/ntl-window.[ch]: + Add support for the location change state machine and related notifications, + to allow much better error handling. + * src/ntl-view.[ch]: Catch client failures, also allow for active sensing of client death. + * src/file-manager/fm-directory-view.c: Send progress notifications. + * components/html/ntl-web-browser.c: Send progress + notifications. Try to fix crashes caused by ending an error stream + twice. + 2000-01-05 John Sullivan <sullivan@eazel.com> * src/nautilus-bookmarks-window.c: (create_bookmarks_window): @@ -13,3 +13,7 @@ Components . Help index, contents, search . Bookmarks . Web search + +Misc +---- +Search for "XXX" or "TODO" in the source. diff --git a/components/html/ntl-web-browser.c b/components/html/ntl-web-browser.c index ba1edbc4b..388648aec 100644 --- a/components/html/ntl-web-browser.c +++ b/components/html/ntl-web-browser.c @@ -152,13 +152,15 @@ canonicalize_url (const char *in_url, const char *base_url) static void browser_url_load_done(GtkWidget *htmlw, BrowserInfo *bi) { - Nautilus_StatusRequestInfo sri; + Nautilus_ProgressRequestInfo pri; gtk_html_calc_scrollbars(GTK_HTML(bi->htmlw)); - memset(&sri, 0, sizeof(sri)); - sri.status_string = _("Load done."); - nautilus_view_client_request_status_change(bi->vc, &sri); + memset(&pri, 0, sizeof(pri)); + + pri.type = Nautilus_PROGRESS_DONE_OK; + pri.amount = 100.0; + nautilus_view_client_request_progress_change(bi->vc, &pri); } struct _HTStream { @@ -307,7 +309,8 @@ browser_url_requested(GtkWidget *htmlw, const char *url, GtkHTMLStreamHandle han if(HTLoad(request, NO) == NO) { HTRequest_delete(request); - gtk_html_end(GTK_HTML(bi->htmlw), handle, GTK_HTML_STREAM_ERROR); + /* I think deleting the request will end the stream, too */ + /* gtk_html_end(GTK_HTML(bi->htmlw), handle, GTK_HTML_STREAM_ERROR); */ } g_free(real_url); @@ -332,6 +335,11 @@ browser_set_base_target(GtkWidget *htmlw, const char *base_target_url, BrowserIn static void browser_goto_url_real(GtkWidget *htmlw, const char *url, BrowserInfo *bi) { + Nautilus_ProgressRequestInfo pri; + + pri.type = Nautilus_PROGRESS_UNDERWAY; + pri.amount = 0.0; + HTNet_killAll(); g_free(bi->base_url); g_free(bi->base_target_url); @@ -349,6 +357,7 @@ browser_goto_url_real(GtkWidget *htmlw, const char *url, BrowserInfo *bi) gtk_html_begin(GTK_HTML(bi->htmlw), url); gtk_html_parse(GTK_HTML(bi->htmlw)); + nautilus_view_client_request_progress_change(bi->vc, &pri); } static void diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index 2d2146cc2..6d81ab764 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -620,6 +620,7 @@ stop_load (FMDirectoryView *view, gboolean error) view->entries_to_display = 0; view->directory_list = NULL; + memset(&pri, 0, sizeof(pri)); pri.amount = 100.0; pri.type = error ? Nautilus_PROGRESS_DONE_ERROR : Nautilus_PROGRESS_DONE_OK; @@ -903,6 +904,7 @@ fm_directory_view_load_uri (FMDirectoryView *view, GNOME_VFS_DIRECTORY_SORT_NONE }; /* FIXME */ GnomeVFSResult result; + Nautilus_ProgressRequestInfo pri; g_return_if_fail (view != NULL); g_return_if_fail (FM_IS_DIRECTORY_VIEW (view)); @@ -919,6 +921,11 @@ fm_directory_view_load_uri (FMDirectoryView *view, gnome_vfs_uri_unref (view->uri); view->uri = gnome_vfs_uri_new (uri); + memset(&pri, 0, sizeof(pri)); + pri.type = Nautilus_PROGRESS_UNDERWAY; + pri.amount = 0; + nautilus_view_client_request_progress_change(NAUTILUS_VIEW_CLIENT(view), &pri); + result = gnome_vfs_async_load_directory_uri (&view->vfs_async_handle, /* handle */ view->uri, /* uri */ @@ -937,11 +944,6 @@ fm_directory_view_load_uri (FMDirectoryView *view, view); /* callback_data */ g_return_if_fail(result == GNOME_VFS_OK); - /* - if (result != GNOME_VFS_OK) - gtk_signal_emit (GTK_OBJECT (view), signals[OPEN_FAILED], - result); - */ } void diff --git a/src/nautilus-applicable-views.c b/src/nautilus-applicable-views.c index a41005da7..fc0f6557a 100644 --- a/src/nautilus-applicable-views.c +++ b/src/nautilus-applicable-views.c @@ -192,15 +192,20 @@ nautilus_navinfo_map(NautilusNavigationInfo *navinfo) navinfo->navinfo.actual_uri = g_strdup(navinfo->navinfo.requested_uri); } -NautilusNavigationInfo * -nautilus_navinfo_new(NautilusNavigationInfo *navinfo, - Nautilus_NavigationRequestInfo *nri, +guint +nautilus_navinfo_new(Nautilus_NavigationRequestInfo *nri, Nautilus_NavigationInfo *old_navinfo, - NautilusView *requesting_view) + NautilusView *requesting_view, + NautilusNavigationInfoFunc notify_when_ready, + gpointer notify_data) { const char *meta_keys[] = {"icon-filename", NULL}; + NautilusNavigationInfo *navinfo; + + navinfo = g_new0(NautilusNavigationInfo, 1); - memset(navinfo, 0, sizeof(*navinfo)); + navinfo->notify_ready = notify_when_ready; + navinfo->data = notify_data; if(old_navinfo) { @@ -229,8 +234,8 @@ nautilus_navinfo_new(NautilusNavigationInfo *navinfo, if(res != GNOME_VFS_OK) { gnome_vfs_file_info_destroy(vfs_fileinfo); - nautilus_navinfo_free(navinfo); - return NULL; + nautilus_navinfo_free(navinfo); navinfo = NULL; + goto out; } navinfo->navinfo.content_type = g_strdup(gnome_vfs_file_info_get_mime_type(vfs_fileinfo)); @@ -278,22 +283,35 @@ nautilus_navinfo_new(NautilusNavigationInfo *navinfo, } else { - g_warning("Unhandled content type %s", navinfo->navinfo.content_type); + /* Error - couldn't handle */ + nautilus_navinfo_free(navinfo); navinfo = NULL; + goto out; } } navinfo->meta_iids = g_slist_append(navinfo->meta_iids, g_strdup("ntl_history_view")); navinfo->meta_iids = g_slist_append(navinfo->meta_iids, g_strdup("ntl_websearch_view")); - return navinfo; + out: + if(notify_when_ready) + { + navinfo->notify_tag = 0; + notify_when_ready(navinfo, notify_data); + } + + return 0; } void nautilus_navinfo_free(NautilusNavigationInfo *navinfo) { + if(navinfo->notify_tag) + /* XXX remove_notification */ ; + g_slist_foreach(navinfo->meta_iids, (GFunc)g_free, NULL); g_slist_free(navinfo->meta_iids); g_free(navinfo->navinfo.requested_uri); g_free(navinfo->navinfo.actual_uri); g_free(navinfo->navinfo.content_type); + g_free(navinfo); } diff --git a/src/nautilus-applicable-views.h b/src/nautilus-applicable-views.h index 26584af1f..52202cf7e 100644 --- a/src/nautilus-applicable-views.h +++ b/src/nautilus-applicable-views.h @@ -31,10 +31,11 @@ #include "ntl-view.h" void nautilus_navinfo_init(void); -NautilusNavigationInfo *nautilus_navinfo_new(NautilusNavigationInfo *navinfo, - Nautilus_NavigationRequestInfo *nri, - Nautilus_NavigationInfo *old_navinfo, - NautilusView *requesting_view); +guint nautilus_navinfo_new(Nautilus_NavigationRequestInfo *nri, + Nautilus_NavigationInfo *old_navinfo, + NautilusView *requesting_view, + NautilusNavigationInfoFunc notify_when_ready, + gpointer notify_data); void nautilus_navinfo_free(NautilusNavigationInfo *navinfo); #endif diff --git a/src/nautilus-navigation-window.c b/src/nautilus-navigation-window.c index 424b2098c..40a1098c0 100644 --- a/src/nautilus-navigation-window.c +++ b/src/nautilus-navigation-window.c @@ -121,15 +121,6 @@ static void nautilus_window_goto_uri_cb (GtkWidget *widget, GtkWidget *window); static void nautilus_window_about_cb (GtkWidget *widget, NautilusWindow *window); -static void nautilus_window_connect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view_exchanged (NautilusView *view, - NautilusWindow *window); - - - #undef CONTENTS_AS_HBOX @@ -574,15 +565,11 @@ nautilus_window_set_arg (GtkObject *object, #endif } - nautilus_window_disconnect_view(window, window->content_view); - gtk_widget_unref(GTK_WIDGET(window->content_view)); } if (new_cv) { - nautilus_window_connect_view(window, NAUTILUS_VIEW(new_cv)); - #ifdef CONTENTS_AS_HBOX gtk_box_pack_end(GTK_BOX(window->content_hbox), new_cv, TRUE, TRUE, GNOME_PAD); #else @@ -617,12 +604,6 @@ static void nautilus_window_destroy (NautilusWindow *window) { NautilusWindowClass *klass = NAUTILUS_WINDOW_CLASS(GTK_OBJECT(window)->klass); - if (window->content_view != NULL) { - nautilus_window_disconnect_view(window, window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc)nautilus_window_disconnect_view_exchanged, window); - g_slist_free(window->meta_views); CORBA_free(window->ni); CORBA_free(window->si); @@ -774,8 +755,6 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - nautilus_window_connect_view(window, meta_view); - desc = nautilus_meta_view_get_label(NAUTILUS_META_VIEW(meta_view)); if(!desc) { @@ -793,21 +772,25 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) } void -nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +nautilus_window_remove_meta_view_real(NautilusWindow *window, NautilusView *meta_view) { gint pagenum; - g_return_if_fail(g_slist_find(window->meta_views, meta_view)); - - window->meta_views = g_slist_remove(window->meta_views, meta_view); - pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(window->meta_notebook), GTK_WIDGET(meta_view)); g_return_if_fail(pagenum >= 0); gtk_notebook_remove_page(GTK_NOTEBOOK(window->meta_notebook), pagenum); +} + +void +nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +{ + g_return_if_fail(g_slist_find(window->meta_views, meta_view)); + + window->meta_views = g_slist_remove(window->meta_views, meta_view); - nautilus_window_disconnect_view(window, meta_view); + nautilus_window_remove_meta_view_real(window, meta_view); } /* FIXME: Factor toolbar stuff out into ntl-window-toolbar.c */ @@ -884,20 +867,9 @@ nautilus_window_home (GtkWidget *btn, NautilusWindow *window) } static void -nv_stop_location_change_adapter(NautilusView *view, gpointer dummy) -{ - nautilus_view_stop_location_change (view); -} - -static void nautilus_window_stop (GtkWidget *btn, NautilusWindow *window) { - if (window->content_view != NULL) { - nautilus_view_stop_location_change (window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc) nv_stop_location_change_adapter, NULL); - + nautilus_window_end_location_change(window); } static void @@ -987,52 +959,43 @@ nautilus_window_request_progress_change_cb (NautilusView *view, nautilus_window_request_progress_change(window, info, view); } - - - -static void +void nautilus_window_connect_view(NautilusWindow *window, NautilusView *view) { - gtk_signal_connect(GTK_OBJECT(view), + GtkObject *viewo; + + viewo = GTK_OBJECT(view); + gtk_signal_connect(viewo, "request_location_change", nautilus_window_request_location_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_selection_change", nautilus_window_request_selection_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_status_change", nautilus_window_request_status_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_progress_change", nautilus_window_request_progress_change_cb, window); + gtk_signal_connect(viewo, + "destroy", + nautilus_window_view_destroyed, + window); } - -static void -nautilus_window_disconnect_view(NautilusWindow *window, NautilusView *view) +void +nautilus_window_display_error(NautilusWindow *window, const char *error_msg) { - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_location_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_selection_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_status_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_progress_change_cb, - window); -} + GtkWidget *dialog; -static void -nautilus_window_disconnect_view_exchanged(NautilusView *view, NautilusWindow *window) -{ - nautilus_window_disconnect_view(window, view); -} + 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); +} diff --git a/src/nautilus-navigation-window.h b/src/nautilus-navigation-window.h index 59996249c..b21cf6604 100644 --- a/src/nautilus-navigation-window.h +++ b/src/nautilus-navigation-window.h @@ -47,6 +47,8 @@ typedef struct { guint window_signals[0]; } NautilusWindowClass; +typedef struct _NautilusWindowLoadInfo NautilusWindowLoadInfo; + struct _NautilusWindow { GnomeApp parent_object; @@ -70,6 +72,8 @@ struct _NautilusWindow { /* Information about current location/selection */ Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; + + NautilusWindowLoadInfo *load_info; }; GtkType nautilus_window_get_type(void); @@ -78,6 +82,8 @@ void nautilus_window_set_content_view(NautilusWindow *window, NautilusView *cont void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_goto_uri(NautilusWindow *window, const char *uri); +void nautilus_window_display_error(NautilusWindow *window, const char *error_msg); + const char *nautilus_window_get_requested_uri(NautilusWindow *window); GnomeUIHandler *nautilus_window_get_uih(NautilusWindow *window); diff --git a/src/nautilus-object-window.c b/src/nautilus-object-window.c index 424b2098c..40a1098c0 100644 --- a/src/nautilus-object-window.c +++ b/src/nautilus-object-window.c @@ -121,15 +121,6 @@ static void nautilus_window_goto_uri_cb (GtkWidget *widget, GtkWidget *window); static void nautilus_window_about_cb (GtkWidget *widget, NautilusWindow *window); -static void nautilus_window_connect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view_exchanged (NautilusView *view, - NautilusWindow *window); - - - #undef CONTENTS_AS_HBOX @@ -574,15 +565,11 @@ nautilus_window_set_arg (GtkObject *object, #endif } - nautilus_window_disconnect_view(window, window->content_view); - gtk_widget_unref(GTK_WIDGET(window->content_view)); } if (new_cv) { - nautilus_window_connect_view(window, NAUTILUS_VIEW(new_cv)); - #ifdef CONTENTS_AS_HBOX gtk_box_pack_end(GTK_BOX(window->content_hbox), new_cv, TRUE, TRUE, GNOME_PAD); #else @@ -617,12 +604,6 @@ static void nautilus_window_destroy (NautilusWindow *window) { NautilusWindowClass *klass = NAUTILUS_WINDOW_CLASS(GTK_OBJECT(window)->klass); - if (window->content_view != NULL) { - nautilus_window_disconnect_view(window, window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc)nautilus_window_disconnect_view_exchanged, window); - g_slist_free(window->meta_views); CORBA_free(window->ni); CORBA_free(window->si); @@ -774,8 +755,6 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - nautilus_window_connect_view(window, meta_view); - desc = nautilus_meta_view_get_label(NAUTILUS_META_VIEW(meta_view)); if(!desc) { @@ -793,21 +772,25 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) } void -nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +nautilus_window_remove_meta_view_real(NautilusWindow *window, NautilusView *meta_view) { gint pagenum; - g_return_if_fail(g_slist_find(window->meta_views, meta_view)); - - window->meta_views = g_slist_remove(window->meta_views, meta_view); - pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(window->meta_notebook), GTK_WIDGET(meta_view)); g_return_if_fail(pagenum >= 0); gtk_notebook_remove_page(GTK_NOTEBOOK(window->meta_notebook), pagenum); +} + +void +nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +{ + g_return_if_fail(g_slist_find(window->meta_views, meta_view)); + + window->meta_views = g_slist_remove(window->meta_views, meta_view); - nautilus_window_disconnect_view(window, meta_view); + nautilus_window_remove_meta_view_real(window, meta_view); } /* FIXME: Factor toolbar stuff out into ntl-window-toolbar.c */ @@ -884,20 +867,9 @@ nautilus_window_home (GtkWidget *btn, NautilusWindow *window) } static void -nv_stop_location_change_adapter(NautilusView *view, gpointer dummy) -{ - nautilus_view_stop_location_change (view); -} - -static void nautilus_window_stop (GtkWidget *btn, NautilusWindow *window) { - if (window->content_view != NULL) { - nautilus_view_stop_location_change (window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc) nv_stop_location_change_adapter, NULL); - + nautilus_window_end_location_change(window); } static void @@ -987,52 +959,43 @@ nautilus_window_request_progress_change_cb (NautilusView *view, nautilus_window_request_progress_change(window, info, view); } - - - -static void +void nautilus_window_connect_view(NautilusWindow *window, NautilusView *view) { - gtk_signal_connect(GTK_OBJECT(view), + GtkObject *viewo; + + viewo = GTK_OBJECT(view); + gtk_signal_connect(viewo, "request_location_change", nautilus_window_request_location_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_selection_change", nautilus_window_request_selection_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_status_change", nautilus_window_request_status_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_progress_change", nautilus_window_request_progress_change_cb, window); + gtk_signal_connect(viewo, + "destroy", + nautilus_window_view_destroyed, + window); } - -static void -nautilus_window_disconnect_view(NautilusWindow *window, NautilusView *view) +void +nautilus_window_display_error(NautilusWindow *window, const char *error_msg) { - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_location_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_selection_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_status_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_progress_change_cb, - window); -} + GtkWidget *dialog; -static void -nautilus_window_disconnect_view_exchanged(NautilusView *view, NautilusWindow *window) -{ - nautilus_window_disconnect_view(window, view); -} + 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); +} diff --git a/src/nautilus-object-window.h b/src/nautilus-object-window.h index 59996249c..b21cf6604 100644 --- a/src/nautilus-object-window.h +++ b/src/nautilus-object-window.h @@ -47,6 +47,8 @@ typedef struct { guint window_signals[0]; } NautilusWindowClass; +typedef struct _NautilusWindowLoadInfo NautilusWindowLoadInfo; + struct _NautilusWindow { GnomeApp parent_object; @@ -70,6 +72,8 @@ struct _NautilusWindow { /* Information about current location/selection */ Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; + + NautilusWindowLoadInfo *load_info; }; GtkType nautilus_window_get_type(void); @@ -78,6 +82,8 @@ void nautilus_window_set_content_view(NautilusWindow *window, NautilusView *cont void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_goto_uri(NautilusWindow *window, const char *uri); +void nautilus_window_display_error(NautilusWindow *window, const char *error_msg); + const char *nautilus_window_get_requested_uri(NautilusWindow *window); GnomeUIHandler *nautilus_window_get_uih(NautilusWindow *window); diff --git a/src/nautilus-spatial-window.c b/src/nautilus-spatial-window.c index 424b2098c..40a1098c0 100644 --- a/src/nautilus-spatial-window.c +++ b/src/nautilus-spatial-window.c @@ -121,15 +121,6 @@ static void nautilus_window_goto_uri_cb (GtkWidget *widget, GtkWidget *window); static void nautilus_window_about_cb (GtkWidget *widget, NautilusWindow *window); -static void nautilus_window_connect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view_exchanged (NautilusView *view, - NautilusWindow *window); - - - #undef CONTENTS_AS_HBOX @@ -574,15 +565,11 @@ nautilus_window_set_arg (GtkObject *object, #endif } - nautilus_window_disconnect_view(window, window->content_view); - gtk_widget_unref(GTK_WIDGET(window->content_view)); } if (new_cv) { - nautilus_window_connect_view(window, NAUTILUS_VIEW(new_cv)); - #ifdef CONTENTS_AS_HBOX gtk_box_pack_end(GTK_BOX(window->content_hbox), new_cv, TRUE, TRUE, GNOME_PAD); #else @@ -617,12 +604,6 @@ static void nautilus_window_destroy (NautilusWindow *window) { NautilusWindowClass *klass = NAUTILUS_WINDOW_CLASS(GTK_OBJECT(window)->klass); - if (window->content_view != NULL) { - nautilus_window_disconnect_view(window, window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc)nautilus_window_disconnect_view_exchanged, window); - g_slist_free(window->meta_views); CORBA_free(window->ni); CORBA_free(window->si); @@ -774,8 +755,6 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - nautilus_window_connect_view(window, meta_view); - desc = nautilus_meta_view_get_label(NAUTILUS_META_VIEW(meta_view)); if(!desc) { @@ -793,21 +772,25 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) } void -nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +nautilus_window_remove_meta_view_real(NautilusWindow *window, NautilusView *meta_view) { gint pagenum; - g_return_if_fail(g_slist_find(window->meta_views, meta_view)); - - window->meta_views = g_slist_remove(window->meta_views, meta_view); - pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(window->meta_notebook), GTK_WIDGET(meta_view)); g_return_if_fail(pagenum >= 0); gtk_notebook_remove_page(GTK_NOTEBOOK(window->meta_notebook), pagenum); +} + +void +nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +{ + g_return_if_fail(g_slist_find(window->meta_views, meta_view)); + + window->meta_views = g_slist_remove(window->meta_views, meta_view); - nautilus_window_disconnect_view(window, meta_view); + nautilus_window_remove_meta_view_real(window, meta_view); } /* FIXME: Factor toolbar stuff out into ntl-window-toolbar.c */ @@ -884,20 +867,9 @@ nautilus_window_home (GtkWidget *btn, NautilusWindow *window) } static void -nv_stop_location_change_adapter(NautilusView *view, gpointer dummy) -{ - nautilus_view_stop_location_change (view); -} - -static void nautilus_window_stop (GtkWidget *btn, NautilusWindow *window) { - if (window->content_view != NULL) { - nautilus_view_stop_location_change (window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc) nv_stop_location_change_adapter, NULL); - + nautilus_window_end_location_change(window); } static void @@ -987,52 +959,43 @@ nautilus_window_request_progress_change_cb (NautilusView *view, nautilus_window_request_progress_change(window, info, view); } - - - -static void +void nautilus_window_connect_view(NautilusWindow *window, NautilusView *view) { - gtk_signal_connect(GTK_OBJECT(view), + GtkObject *viewo; + + viewo = GTK_OBJECT(view); + gtk_signal_connect(viewo, "request_location_change", nautilus_window_request_location_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_selection_change", nautilus_window_request_selection_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_status_change", nautilus_window_request_status_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_progress_change", nautilus_window_request_progress_change_cb, window); + gtk_signal_connect(viewo, + "destroy", + nautilus_window_view_destroyed, + window); } - -static void -nautilus_window_disconnect_view(NautilusWindow *window, NautilusView *view) +void +nautilus_window_display_error(NautilusWindow *window, const char *error_msg) { - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_location_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_selection_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_status_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_progress_change_cb, - window); -} + GtkWidget *dialog; -static void -nautilus_window_disconnect_view_exchanged(NautilusView *view, NautilusWindow *window) -{ - nautilus_window_disconnect_view(window, view); -} + 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); +} diff --git a/src/nautilus-spatial-window.h b/src/nautilus-spatial-window.h index 59996249c..b21cf6604 100644 --- a/src/nautilus-spatial-window.h +++ b/src/nautilus-spatial-window.h @@ -47,6 +47,8 @@ typedef struct { guint window_signals[0]; } NautilusWindowClass; +typedef struct _NautilusWindowLoadInfo NautilusWindowLoadInfo; + struct _NautilusWindow { GnomeApp parent_object; @@ -70,6 +72,8 @@ struct _NautilusWindow { /* Information about current location/selection */ Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; + + NautilusWindowLoadInfo *load_info; }; GtkType nautilus_window_get_type(void); @@ -78,6 +82,8 @@ void nautilus_window_set_content_view(NautilusWindow *window, NautilusView *cont void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_goto_uri(NautilusWindow *window, const char *uri); +void nautilus_window_display_error(NautilusWindow *window, const char *error_msg); + const char *nautilus_window_get_requested_uri(NautilusWindow *window); GnomeUIHandler *nautilus_window_get_uih(NautilusWindow *window); diff --git a/src/nautilus-view-frame-nautilus-view.c b/src/nautilus-view-frame-nautilus-view.c index abb30a995..eb9e939a4 100644 --- a/src/nautilus-view-frame-nautilus-view.c +++ b/src/nautilus-view-frame-nautilus-view.c @@ -61,6 +61,8 @@ nv_show_properties(NautilusView *view, CORBA_Environment *ev) NautilusViewInfo *nvi = view->component_data; Nautilus_View_show_properties(nvi->view_client, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -69,6 +71,8 @@ nv_save_state(NautilusView *view, const char *config_path, CORBA_Environment *ev NautilusViewInfo *nvi = view->component_data; Nautilus_View_save_state(nvi->view_client, config_path, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -77,6 +81,8 @@ nv_load_state(NautilusView *view, const char *config_path, CORBA_Environment *ev NautilusViewInfo *nvi = view->component_data; Nautilus_View_load_state(nvi->view_client, config_path, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -85,6 +91,8 @@ nv_notify_location_change(NautilusView *view, Nautilus_NavigationInfo *nav_ctx, NautilusViewInfo *nvi = view->component_data; Nautilus_View_notify_location_change(nvi->view_client, nav_ctx, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -93,6 +101,8 @@ nv_notify_selection_change(NautilusView *view, Nautilus_SelectionInfo *nav_ctx, NautilusViewInfo *nvi = view->component_data; Nautilus_View_notify_selection_change(nvi->view_client, nav_ctx, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -101,9 +111,10 @@ nv_stop_location_change(NautilusView *view, CORBA_Environment *ev) NautilusViewInfo *nvi = view->component_data; Nautilus_View_stop_location_change(nvi->view_client, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } - static char * nv_get_label(NautilusView *view, CORBA_Environment *ev) { diff --git a/src/nautilus-view-frame.c b/src/nautilus-view-frame.c index 9f030f73e..b3af28154 100644 --- a/src/nautilus-view-frame.c +++ b/src/nautilus-view-frame.c @@ -240,8 +240,12 @@ static void nautilus_view_destroy(GtkObject *view) { NautilusViewClass *klass = NAUTILUS_VIEW_CLASS(view->klass); + NautilusView *nview = NAUTILUS_VIEW(view); - nautilus_view_destroy_client(NAUTILUS_VIEW(view)); + if(nview->timer_id) + g_source_remove(nview->timer_id); + + nautilus_view_destroy_client(nview); if(GTK_OBJECT_CLASS(klass->parent_class)->destroy) GTK_OBJECT_CLASS(klass->parent_class)->destroy(view); @@ -309,6 +313,19 @@ extern NautilusViewComponentType nautilus_view_component_type; /* ntl-view-nauti extern NautilusViewComponentType bonobo_subdoc_component_type; /* ntl-view-bonobo-subdoc.c */ extern NautilusViewComponentType bonobo_control_component_type; /* ntl-view-bonobo-control.c */ +static gboolean +nautilus_view_handle_client_destroy(GtkWidget *widget, NautilusView *view) +{ + gtk_object_destroy(GTK_OBJECT(view)); + return TRUE; +} + +static void +nautilus_view_handle_client_destroy_2(GtkObject *object, CORBA_Object cobject, CORBA_Environment *ev, NautilusView *view) +{ + gtk_object_destroy(GTK_OBJECT(view)); +} + gboolean /* returns TRUE if successful */ nautilus_view_load_client(NautilusView *view, const char *iid) { @@ -363,8 +380,17 @@ nautilus_view_load_client(NautilusView *view, const char *iid) view->iid = g_strdup(iid); - gtk_widget_show(view->client_widget); + gtk_signal_connect_while_alive(GTK_OBJECT(view->client_object), "destroy", + GTK_SIGNAL_FUNC(nautilus_view_handle_client_destroy), view, + GTK_OBJECT(view)); + gtk_signal_connect_while_alive(GTK_OBJECT(view->client_object), "object_gone", + GTK_SIGNAL_FUNC(nautilus_view_handle_client_destroy_2), view, + GTK_OBJECT(view)); + gtk_signal_connect_while_alive(GTK_OBJECT(view->client_object), "system_exception", + GTK_SIGNAL_FUNC(nautilus_view_handle_client_destroy_2), view, + GTK_OBJECT(view)); gtk_container_add(GTK_CONTAINER(view), view->client_widget); + gtk_widget_show(view->client_widget); CORBA_exception_free(&ev); return TRUE; @@ -525,3 +551,38 @@ nautilus_view_request_progress_change(NautilusView *view, gtk_signal_emit(GTK_OBJECT(view), nautilus_view_signals[REQUEST_PROGRESS_CHANGE], loc); } +static gboolean +check_object(NautilusView *view) +{ + CORBA_Environment ev; + gboolean retval = TRUE; + CORBA_exception_init(&ev); + + if(CORBA_Object_non_existent(gnome_object_corba_objref(GNOME_OBJECT(view->client_object)), &ev)) + { + view->timer_id = 0; + gtk_object_destroy(GTK_OBJECT(view)); + retval = FALSE; + } + + CORBA_exception_free(&ev); + return retval; +} + +void +nautilus_view_set_active_errors(NautilusView *view, gboolean enabled) +{ + if(enabled) + { + if(!view->timer_id) + view->timer_id = g_timeout_add(1000, (GSourceFunc)check_object, view); + } + else + { + if(view->timer_id) + { + g_source_remove(view->timer_id); + view->timer_id = 0; + } + } +} diff --git a/src/nautilus-view-frame.h b/src/nautilus-view-frame.h index b8530f13a..a59a95c15 100644 --- a/src/nautilus-view-frame.h +++ b/src/nautilus-view-frame.h @@ -91,6 +91,8 @@ struct _NautilusView NautilusViewComponentType *component_class; gpointer component_data; + + guint timer_id; }; GtkType nautilus_view_get_type (void); @@ -113,8 +115,7 @@ void nautilus_view_save_state (NautilusView *view, const char *config_path); void nautilus_view_show_properties (NautilusView *view); void nautilus_view_stop_location_change (NautilusView *view); - - +void nautilus_view_set_active_errors (NautilusView *view, gboolean enabled); /* This is a "protected" operation */ void nautilus_view_construct_arg_set(NautilusView *view); diff --git a/src/nautilus-window-manage-views.c b/src/nautilus-window-manage-views.c index ad72a0f44..b2870928a 100644 --- a/src/nautilus-window-manage-views.c +++ b/src/nautilus-window-manage-views.c @@ -2,25 +2,37 @@ #include "ntl-window-private.h" #include "explorer-location-bar.h" +struct _NautilusWindowLoadInfo { + enum { + GETTING_URI_INFO, + WAITING_FOR_VIEWS, + PROCESSING, + DONE + } state; + + union { + struct { + guint cancel_tag; + } getting_uri_info; + } u; + + /* Valid in the WAITING_FOR_VIEWS or PROCESSING states */ + NautilusNavigationInfo *ni; + + GSList *new_meta_views; + NautilusView *new_content_view; + + gboolean got_content_progress; + + gboolean is_back; +}; + static void nautilus_window_notify_selection_change(NautilusWindow *window, NautilusView *view, Nautilus_SelectionInfo *loc, NautilusView *requesting_view); static void -Nautilus_NavigationInfo__copy(Nautilus_NavigationInfo *dest_ni, Nautilus_NavigationInfo *src_ni) -{ - dest_ni->requested_uri = CORBA_string_dup(src_ni->requested_uri); - dest_ni->actual_uri = CORBA_string_dup(src_ni->actual_uri); - dest_ni->content_type = CORBA_string_dup(src_ni->content_type); - dest_ni->referring_uri = CORBA_string_dup(src_ni->referring_uri); - dest_ni->actual_referring_uri = CORBA_string_dup(src_ni->actual_referring_uri); - dest_ni->referring_content_type = CORBA_string_dup(src_ni->referring_content_type); - dest_ni->content_view = CORBA_OBJECT_NIL; - dest_ni->self_originated = CORBA_FALSE; -} - -static void Nautilus_SelectionInfo__copy(Nautilus_SelectionInfo *dest_si, Nautilus_SelectionInfo *src_si) { int i, n; @@ -75,22 +87,55 @@ nautilus_window_request_location_change(NautilusWindow *window, nautilus_window_change_location(window, loc, requesting_view, FALSE); } +static void +nautilus_window_notify_selection_change(NautilusWindow *window, + NautilusView *view, + Nautilus_SelectionInfo *loc, + NautilusView *requesting_view) +{ + loc->self_originated = (view == requesting_view); + + nautilus_view_notify_selection_change(view, loc); +} + void nautilus_window_request_progress_change(NautilusWindow *window, Nautilus_ProgressRequestInfo *loc, NautilusView *requesting_view) { - if(requesting_view != window->content_view) - return; /* Only pay attention to progress information from the main view, for now */ - - if (loc->type == Nautilus_PROGRESS_DONE_OK || loc->type == Nautilus_PROGRESS_DONE_ERROR) { - nautilus_window_allow_stop(window, FALSE); - } - g_message("Progress is %f", loc->amount); + if (window->load_info) + { + if(requesting_view != window->load_info->new_content_view) + return; /* Only pay attention to progress information from the main view, for now */ + + /* We have gotten something from the content view, which means it is safe to do the "switchover" to the new page */ + window->load_info->got_content_progress = TRUE; + nautilus_window_end_location_change(window); + nautilus_window_allow_stop (window, !(loc->type == Nautilus_PROGRESS_DONE_OK + || loc->type == Nautilus_PROGRESS_DONE_ERROR)); + + g_message("Progress is %f", loc->amount); + } +} + +/* The bulk of this file - location changing */ + +static void +Nautilus_NavigationInfo__copy(Nautilus_NavigationInfo *dest_ni, Nautilus_NavigationInfo *src_ni) +{ + dest_ni->requested_uri = CORBA_string_dup(src_ni->requested_uri); + dest_ni->actual_uri = CORBA_string_dup(src_ni->actual_uri); + dest_ni->content_type = CORBA_string_dup(src_ni->content_type); + dest_ni->referring_uri = CORBA_string_dup(src_ni->referring_uri); + dest_ni->actual_referring_uri = CORBA_string_dup(src_ni->actual_referring_uri); + dest_ni->referring_content_type = CORBA_string_dup(src_ni->referring_content_type); + dest_ni->content_view = CORBA_OBJECT_NIL; + dest_ni->self_originated = CORBA_FALSE; } +/* Handle the changes for the NautilusWindow itself. */ static void -nautilus_window_change_location_internal(NautilusWindow *window, NautilusNavigationInfo *loci, gboolean is_back) +nautilus_window_change_location_internal(NautilusWindow *window, Nautilus_NavigationInfo *loci, gboolean is_back) { GnomeVFSURI *new_uri; @@ -102,7 +147,7 @@ nautilus_window_change_location_internal(NautilusWindow *window, NautilusNavigat /* Going back. Remove one item from the prev list and add the current item to the next list. */ g_assert(window->uris_prev); - g_assert(!strcmp((const gchar*)window->uris_prev->data, loci->navinfo.requested_uri)); + g_assert(!strcmp((const gchar*)window->uris_prev->data, loci->requested_uri)); g_assert(window->ni); window->uris_next = g_slist_prepend(window->uris_next, g_strdup(window->ni->requested_uri)); @@ -115,7 +160,7 @@ nautilus_window_change_location_internal(NautilusWindow *window, NautilusNavigat * Otherwise, clobber the entire next list. */ - if (window->uris_next && !strcmp(loci->navinfo.requested_uri, (const gchar*)window->uris_next->data)) + if (window->uris_next && !strcmp(loci->requested_uri, (const gchar*)window->uris_next->data)) { g_free(window->uris_next->data); window->uris_next = g_slist_remove_link(window->uris_next, window->uris_next); @@ -132,41 +177,76 @@ nautilus_window_change_location_internal(NautilusWindow *window, NautilusNavigat nautilus_window_allow_back(window, window->uris_prev?TRUE:FALSE); nautilus_window_allow_forward(window, window->uris_next?TRUE:FALSE); - new_uri = gnome_vfs_uri_new (loci->navinfo.requested_uri); + new_uri = gnome_vfs_uri_new (loci->requested_uri); nautilus_window_allow_up(window, gnome_vfs_uri_has_parent(new_uri)); gnome_vfs_uri_destroy(new_uri); - CORBA_free(window->ni); - window->ni = Nautilus_NavigationInfo__alloc(); - Nautilus_NavigationInfo__copy(window->ni, &loci->navinfo); + if(window->ni != loci) + { + Nautilus_NavigationInfo *newni; - CORBA_free(window->si); - window->si = NULL; + newni = Nautilus_NavigationInfo__alloc(); + Nautilus_NavigationInfo__copy(newni, loci); + CORBA_free(window->ni); + window->ni = newni; + + CORBA_free(window->si); + window->si = NULL; + } explorer_location_bar_set_uri_string(EXPLORER_LOCATION_BAR(window->ent_uri), - loci->navinfo.requested_uri); + loci->requested_uri); } static void nautilus_window_update_view(NautilusWindow *window, NautilusView *view, - NautilusNavigationInfo *loci, - NautilusView *requesting_view) + Nautilus_NavigationInfo *loci, + NautilusView *requesting_view, + NautilusView *content_view) { g_return_if_fail(view); - loci->navinfo.self_originated = (view == requesting_view); + loci->self_originated = (view == requesting_view); - nautilus_view_notify_location_change(NAUTILUS_VIEW(view), &(loci->navinfo)); + nautilus_view_notify_location_change(NAUTILUS_VIEW(view), loci); if(window->si) { - window->si->content_view = nautilus_view_get_client_objref(NAUTILUS_VIEW(window->content_view)); + window->si->content_view = nautilus_view_get_client_objref(content_view); nautilus_window_notify_selection_change(window, view, window->si, NULL); } } +void +nautilus_window_view_destroyed(NautilusView *view, NautilusWindow *window) +{ + if(NAUTILUS_IS_CONTENT_VIEW(view)) + { + if(window->load_info) + { + if(view == window->load_info->new_content_view) + { + nautilus_window_display_error + (window, + _("A software component, needed to display the requested page, has turned fatalistic.")); + nautilus_window_end_location_change(window); + } + } + + if(view == window->content_view) + window->content_view = NULL; + } + else if(NAUTILUS_IS_META_VIEW(view)) + { + if(window->load_info) + window->load_info->new_meta_views = g_slist_remove(window->load_info->new_meta_views, view); + + nautilus_window_remove_meta_view(window, view); + } +} + static void nautilus_window_load_content_view(NautilusWindow *window, const char *iid, @@ -189,29 +269,27 @@ nautilus_window_load_content_view(NautilusWindow *window, new_view = NAUTILUS_VIEW(gtk_widget_new(nautilus_content_view_get_type(), "main_window", window, NULL)); - nautilus_window_set_content_view(window, new_view); + nautilus_window_connect_view(window, new_view); + if(!nautilus_view_load_client(new_view, iid)) { gtk_widget_destroy(GTK_WIDGET(new_view)); + new_view = NULL; } - } + else + new_view = window->content_view; - if(window->content_view && NAUTILUS_IS_VIEW(window->content_view)) + if(new_view && NAUTILUS_IS_VIEW(new_view)) { - loci->navinfo.content_view = nautilus_view_get_client_objref(window->content_view); + gtk_object_ref(GTK_OBJECT(new_view)); - nautilus_window_allow_stop(window, TRUE); - nautilus_window_update_view(window, window->content_view, loci, *requesting_view); - } - else - { - /* NautilusView *dummy_view; */ + loci->navinfo.content_view = nautilus_view_get_client_objref(new_view); + window->load_info->new_content_view = new_view; + + nautilus_view_set_active_errors(new_view, TRUE); - /* FIXME - should be another view type - Commenting because set_content_view() would break */ - /* dummy_view = (NautilusView *)gtk_label_new(_("The component needed to display this file was not found.")); */ - /* nautilus_window_set_content_view(window, dummy_view); */ - nautilus_window_set_content_view(window, NULL); + nautilus_window_update_view(window, new_view, &(loci->navinfo), *requesting_view, window->load_info->new_content_view); } } @@ -234,18 +312,108 @@ nautilus_window_load_meta_view(NautilusWindow *window, if(!curview) { meta_view = NAUTILUS_VIEW(gtk_widget_new(nautilus_meta_view_get_type(), "main_window", window, NULL)); + nautilus_window_connect_view(window, meta_view); if(!nautilus_view_load_client(meta_view, iid)) { gtk_widget_destroy(GTK_WIDGET(meta_view)); meta_view = NULL; } - - if(meta_view) - nautilus_window_add_meta_view(window, meta_view); } if(meta_view) - nautilus_window_update_view(window, meta_view, loci, requesting_view); + { + gtk_object_ref(GTK_OBJECT(meta_view)); + + nautilus_view_set_active_errors(meta_view, TRUE); + + window->load_info->new_meta_views = g_slist_prepend(window->load_info->new_meta_views, meta_view); + + nautilus_window_update_view(window, meta_view, &(loci->navinfo), requesting_view, window->load_info->new_content_view); + } +} + +void +nautilus_window_end_location_change(NautilusWindow *window) +{ + GSList *cur, *discard_views; + + if (!window->load_info) + { + if(window->content_view) + nautilus_view_stop_location_change (window->content_view); + + g_slist_foreach(window->meta_views, (GFunc) nautilus_view_stop_location_change, NULL); + + nautilus_window_allow_stop(window, FALSE); + + return; + } + + switch (window->load_info->state) + { + case DONE: /* The normal case - the page has finished loading successfully */ + /* Do lots of shuffling to make sure we don't remove views that were already there, but add new views */ + for(cur = window->load_info->new_meta_views; cur; cur = cur->next) + { + if(!GTK_WIDGET(cur->data)->parent) + nautilus_window_add_meta_view(window, cur->data); + gtk_object_unref(cur->data); + /* nautilus_view_set_active_errors(cur->data, FALSE); */ + } + for(cur = window->meta_views; cur; cur = cur->next) + if(!g_slist_find(window->load_info->new_meta_views, cur->data)) + discard_views = g_slist_prepend(discard_views, cur->data); + + for(cur = discard_views; cur; cur = cur->next) + nautilus_window_remove_meta_view(window, cur->data); + g_slist_free(discard_views); + + if(!GTK_WIDGET(window->load_info->new_content_view)->parent) + nautilus_window_set_content_view(window, window->load_info->new_content_view); + gtk_object_unref(GTK_OBJECT(window->load_info->new_content_view)); + /* nautilus_view_set_active_errors(window->load_info->new_content_view, FALSE); */ + + nautilus_window_change_location_internal(window, &window->load_info->ni->navinfo, window->load_info->is_back); + break; + + /* all of the following are error cases - we try to recover as best we can */ + case WAITING_FOR_VIEWS: + for(cur = window->load_info->new_meta_views; cur; cur = cur->next) + { + gtk_widget_unref(cur->data); + /* nautilus_view_set_active_errors(cur->data, FALSE); */ + } + if(window->load_info->new_content_view) + { + gtk_widget_unref(GTK_WIDGET(window->load_info->new_content_view)); + /* nautilus_view_set_active_errors(window->load_info->new_content_view, FALSE); */ + } + + /* Tell previously-notified views to go back to the old page */ + for(cur = window->meta_views; cur; cur = cur->next) + { + if(g_slist_find(window->load_info->new_meta_views, cur->data)) + nautilus_window_update_view(window, cur->data, window->ni, NULL, window->content_view); + } + if(window->load_info->new_content_view == window->content_view) + nautilus_window_update_view(window, window->content_view, window->ni, NULL, window->content_view); + explorer_location_bar_set_uri_string(EXPLORER_LOCATION_BAR(window->ent_uri), + window->ni->requested_uri); + + case GETTING_URI_INFO: + default: + break; + + case PROCESSING: + return; /* We don't want to do anything in the processing state - someone else is already busy manipulating things */ + } + + nautilus_navinfo_free(window->load_info->ni); + + g_slist_free(window->load_info->new_meta_views); + g_free(window->load_info); window->load_info = NULL; + + nautilus_window_allow_stop(window, FALSE); } /* This is the most complicated routine in Nautilus. Steps include: @@ -254,38 +422,52 @@ nautilus_window_load_meta_view(NautilusWindow *window, 3. Update the history, UI, and internal state for the proposed change. 4. Load/notify content view. 5. Load/notify meta views. - */ -void -nautilus_window_change_location(NautilusWindow *window, - Nautilus_NavigationRequestInfo *loc, - NautilusView *requesting_view, - gboolean is_back) + +/* Step 2 */ +static void +nautilus_window_change_location_2(NautilusNavigationInfo *ni, gpointer data) { - NautilusNavigationInfo loci_spot, *loci; GSList *cur, *discard_views; - /* Step 1 */ - loci = nautilus_navinfo_new(&loci_spot, loc, window->ni, requesting_view); + NautilusWindow *window = data; + + window->load_info->state = PROCESSING; + window->load_info->ni = ni; - /* Step 2 */ - if(!loci) + if(!ni) { - char cbuf[1024]; - g_snprintf(cbuf, sizeof(cbuf), _("Cannot load %s"), loc->requested_uri); - nautilus_window_set_status(window, cbuf); + nautilus_window_display_error + (window, + _("The chosen hyperlink is invalid, or points to an inaccessable page.")); + + nautilus_window_end_location_change(window); + return; } - /* Step 3 */ - nautilus_window_change_location_internal(window, loci, is_back); + if(!ni->content_iid) + { + nautilus_window_display_error + (window, + _("There is not any known method of displaying the selected page.")); - /* Step 4 */ + nautilus_window_end_location_change(window); - if(loci->content_iid) - nautilus_window_load_content_view(window, loci->content_iid, loci, &requesting_view); - else - nautilus_window_set_content_view(window, NULL); + return; + } + + nautilus_window_load_content_view(window, ni->content_iid, ni, (NautilusView **)&ni->requesting_view); + if(!window->load_info->new_content_view) + { + nautilus_window_display_error + (window, + _("The software needed to display this page could not be loaded.")); + + nautilus_window_end_location_change(window); + + return; + } /* Step 5 */ @@ -295,39 +477,55 @@ nautilus_window_change_location(NautilusWindow *window, { NautilusView *view = cur->data; - if(!g_slist_find_custom(loci->meta_iids, view->iid, (GCompareFunc)strcmp)) + if(!g_slist_find_custom(ni->meta_iids, view->iid, (GCompareFunc)g_str_equal)) { - if(view == requesting_view) - requesting_view = NULL; + if(cur->data == ni->requesting_view) + ni->requesting_view = NULL; discard_views = g_slist_prepend(discard_views, view); } } - for(cur = loci->meta_iids; cur; cur = cur->next) - nautilus_window_load_meta_view(window, cur->data, loci, requesting_view); + for(cur = ni->meta_iids; cur; cur = cur->next) + nautilus_window_load_meta_view(window, cur->data, ni, ni->requesting_view); for(cur = discard_views; cur; cur = cur->next) nautilus_window_remove_meta_view(window, cur->data); g_slist_free(discard_views); - nautilus_navinfo_free(loci); -} - -static void -nautilus_window_notify_selection_change(NautilusWindow *window, - NautilusView *view, - Nautilus_SelectionInfo *loc, - NautilusView *requesting_view) -{ - loc->self_originated = (view == requesting_view); - - nautilus_view_notify_selection_change(view, loc); + if(window->load_info->got_content_progress) + { + window->load_info->state = DONE; + nautilus_window_end_location_change(window); + } + else + window->load_info->state = WAITING_FOR_VIEWS; } +/* Step 1 */ +void +nautilus_window_change_location(NautilusWindow *window, + Nautilus_NavigationRequestInfo *loc, + NautilusView *requesting_view, + gboolean is_back) +{ + guint cancel_tag; + nautilus_window_end_location_change(window); /* End any previous location change that was pending. */ + while(gdk_events_pending()) + gtk_main_iteration(); + nautilus_window_allow_stop(window, TRUE); + /* Init load_info */ + window->load_info = g_new0(NautilusWindowLoadInfo, 1); + window->load_info->state = GETTING_URI_INFO; + window->load_info->is_back = is_back; + cancel_tag = + nautilus_navinfo_new(loc, window->ni, requesting_view, nautilus_window_change_location_2, window); + if(window->load_info) + window->load_info->u.getting_uri_info.cancel_tag = cancel_tag; +} diff --git a/src/nautilus-window-private.h b/src/nautilus-window-private.h index f371101bb..381af8034 100644 --- a/src/nautilus-window-private.h +++ b/src/nautilus-window-private.h @@ -23,5 +23,10 @@ void nautilus_window_change_location(NautilusWindow *window, Nautilus_NavigationRequestInfo *loc, NautilusView *requesting_view, gboolean is_back); +void nautilus_window_remove_meta_view_real(NautilusWindow *window, NautilusView *meta_view); +void nautilus_window_end_location_change(NautilusWindow *window); +void nautilus_window_connect_view (NautilusWindow *window, + NautilusView *view); +void nautilus_window_view_destroyed(NautilusView *view, NautilusWindow *window); #endif diff --git a/src/nautilus-window.c b/src/nautilus-window.c index 424b2098c..40a1098c0 100644 --- a/src/nautilus-window.c +++ b/src/nautilus-window.c @@ -121,15 +121,6 @@ static void nautilus_window_goto_uri_cb (GtkWidget *widget, GtkWidget *window); static void nautilus_window_about_cb (GtkWidget *widget, NautilusWindow *window); -static void nautilus_window_connect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view_exchanged (NautilusView *view, - NautilusWindow *window); - - - #undef CONTENTS_AS_HBOX @@ -574,15 +565,11 @@ nautilus_window_set_arg (GtkObject *object, #endif } - nautilus_window_disconnect_view(window, window->content_view); - gtk_widget_unref(GTK_WIDGET(window->content_view)); } if (new_cv) { - nautilus_window_connect_view(window, NAUTILUS_VIEW(new_cv)); - #ifdef CONTENTS_AS_HBOX gtk_box_pack_end(GTK_BOX(window->content_hbox), new_cv, TRUE, TRUE, GNOME_PAD); #else @@ -617,12 +604,6 @@ static void nautilus_window_destroy (NautilusWindow *window) { NautilusWindowClass *klass = NAUTILUS_WINDOW_CLASS(GTK_OBJECT(window)->klass); - if (window->content_view != NULL) { - nautilus_window_disconnect_view(window, window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc)nautilus_window_disconnect_view_exchanged, window); - g_slist_free(window->meta_views); CORBA_free(window->ni); CORBA_free(window->si); @@ -774,8 +755,6 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - nautilus_window_connect_view(window, meta_view); - desc = nautilus_meta_view_get_label(NAUTILUS_META_VIEW(meta_view)); if(!desc) { @@ -793,21 +772,25 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) } void -nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +nautilus_window_remove_meta_view_real(NautilusWindow *window, NautilusView *meta_view) { gint pagenum; - g_return_if_fail(g_slist_find(window->meta_views, meta_view)); - - window->meta_views = g_slist_remove(window->meta_views, meta_view); - pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(window->meta_notebook), GTK_WIDGET(meta_view)); g_return_if_fail(pagenum >= 0); gtk_notebook_remove_page(GTK_NOTEBOOK(window->meta_notebook), pagenum); +} + +void +nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +{ + g_return_if_fail(g_slist_find(window->meta_views, meta_view)); + + window->meta_views = g_slist_remove(window->meta_views, meta_view); - nautilus_window_disconnect_view(window, meta_view); + nautilus_window_remove_meta_view_real(window, meta_view); } /* FIXME: Factor toolbar stuff out into ntl-window-toolbar.c */ @@ -884,20 +867,9 @@ nautilus_window_home (GtkWidget *btn, NautilusWindow *window) } static void -nv_stop_location_change_adapter(NautilusView *view, gpointer dummy) -{ - nautilus_view_stop_location_change (view); -} - -static void nautilus_window_stop (GtkWidget *btn, NautilusWindow *window) { - if (window->content_view != NULL) { - nautilus_view_stop_location_change (window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc) nv_stop_location_change_adapter, NULL); - + nautilus_window_end_location_change(window); } static void @@ -987,52 +959,43 @@ nautilus_window_request_progress_change_cb (NautilusView *view, nautilus_window_request_progress_change(window, info, view); } - - - -static void +void nautilus_window_connect_view(NautilusWindow *window, NautilusView *view) { - gtk_signal_connect(GTK_OBJECT(view), + GtkObject *viewo; + + viewo = GTK_OBJECT(view); + gtk_signal_connect(viewo, "request_location_change", nautilus_window_request_location_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_selection_change", nautilus_window_request_selection_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_status_change", nautilus_window_request_status_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_progress_change", nautilus_window_request_progress_change_cb, window); + gtk_signal_connect(viewo, + "destroy", + nautilus_window_view_destroyed, + window); } - -static void -nautilus_window_disconnect_view(NautilusWindow *window, NautilusView *view) +void +nautilus_window_display_error(NautilusWindow *window, const char *error_msg) { - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_location_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_selection_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_status_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_progress_change_cb, - window); -} + GtkWidget *dialog; -static void -nautilus_window_disconnect_view_exchanged(NautilusView *view, NautilusWindow *window) -{ - nautilus_window_disconnect_view(window, view); -} + 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); +} diff --git a/src/nautilus-window.h b/src/nautilus-window.h index 59996249c..b21cf6604 100644 --- a/src/nautilus-window.h +++ b/src/nautilus-window.h @@ -47,6 +47,8 @@ typedef struct { guint window_signals[0]; } NautilusWindowClass; +typedef struct _NautilusWindowLoadInfo NautilusWindowLoadInfo; + struct _NautilusWindow { GnomeApp parent_object; @@ -70,6 +72,8 @@ struct _NautilusWindow { /* Information about current location/selection */ Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; + + NautilusWindowLoadInfo *load_info; }; GtkType nautilus_window_get_type(void); @@ -78,6 +82,8 @@ void nautilus_window_set_content_view(NautilusWindow *window, NautilusView *cont void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_goto_uri(NautilusWindow *window, const char *uri); +void nautilus_window_display_error(NautilusWindow *window, const char *error_msg); + const char *nautilus_window_get_requested_uri(NautilusWindow *window); GnomeUIHandler *nautilus_window_get_uih(NautilusWindow *window); diff --git a/src/ntl-meta-view.c b/src/ntl-meta-view.c index f04ed6316..05f571faf 100644 --- a/src/ntl-meta-view.c +++ b/src/ntl-meta-view.c @@ -46,6 +46,7 @@ static POA_Nautilus_MetaViewFrame__vepv impl_Nautilus_MetaViewFrame_vepv = static void nautilus_meta_view_class_init (NautilusMetaViewClass *klass); static void nautilus_meta_view_init (NautilusMetaView *view); +static void nautilus_meta_view_destroy (GtkObject *object); GtkType nautilus_meta_view_get_type(void) @@ -79,6 +80,7 @@ nautilus_meta_view_class_init (NautilusMetaViewClass *klass) NautilusViewClass *view_class; object_class = (GtkObjectClass*) klass; + object_class->destroy = nautilus_meta_view_destroy; widget_class = (GtkWidgetClass*) klass; view_class = (NautilusViewClass*) klass; klass->parent_class = gtk_type_class (gtk_type_parent (object_class->type)); @@ -92,6 +94,15 @@ nautilus_meta_view_init (NautilusMetaView *view) { } +static void +nautilus_meta_view_destroy (GtkObject *object) +{ + GtkObjectClass *klass = object->klass; + + if(klass->destroy) + klass->destroy(object); +} + const char * nautilus_meta_view_get_label(NautilusMetaView *nview) { diff --git a/src/ntl-types.h b/src/ntl-types.h index 6f448a137..501362a82 100644 --- a/src/ntl-types.h +++ b/src/ntl-types.h @@ -33,13 +33,21 @@ typedef char *NautilusLocationReference; -typedef struct { +typedef struct _NautilusNavigationInfo NautilusNavigationInfo; + +typedef void (*NautilusNavigationInfoFunc)(NautilusNavigationInfo *navinfo, gpointer data); + +struct _NautilusNavigationInfo { Nautilus_NavigationInfo navinfo; gpointer requesting_view; const char *content_iid; GSList *meta_iids; -} NautilusNavigationInfo; + + guint notify_tag; + NautilusNavigationInfoFunc notify_ready; + gpointer data; +}; #endif diff --git a/src/ntl-uri-map.c b/src/ntl-uri-map.c index a41005da7..fc0f6557a 100644 --- a/src/ntl-uri-map.c +++ b/src/ntl-uri-map.c @@ -192,15 +192,20 @@ nautilus_navinfo_map(NautilusNavigationInfo *navinfo) navinfo->navinfo.actual_uri = g_strdup(navinfo->navinfo.requested_uri); } -NautilusNavigationInfo * -nautilus_navinfo_new(NautilusNavigationInfo *navinfo, - Nautilus_NavigationRequestInfo *nri, +guint +nautilus_navinfo_new(Nautilus_NavigationRequestInfo *nri, Nautilus_NavigationInfo *old_navinfo, - NautilusView *requesting_view) + NautilusView *requesting_view, + NautilusNavigationInfoFunc notify_when_ready, + gpointer notify_data) { const char *meta_keys[] = {"icon-filename", NULL}; + NautilusNavigationInfo *navinfo; + + navinfo = g_new0(NautilusNavigationInfo, 1); - memset(navinfo, 0, sizeof(*navinfo)); + navinfo->notify_ready = notify_when_ready; + navinfo->data = notify_data; if(old_navinfo) { @@ -229,8 +234,8 @@ nautilus_navinfo_new(NautilusNavigationInfo *navinfo, if(res != GNOME_VFS_OK) { gnome_vfs_file_info_destroy(vfs_fileinfo); - nautilus_navinfo_free(navinfo); - return NULL; + nautilus_navinfo_free(navinfo); navinfo = NULL; + goto out; } navinfo->navinfo.content_type = g_strdup(gnome_vfs_file_info_get_mime_type(vfs_fileinfo)); @@ -278,22 +283,35 @@ nautilus_navinfo_new(NautilusNavigationInfo *navinfo, } else { - g_warning("Unhandled content type %s", navinfo->navinfo.content_type); + /* Error - couldn't handle */ + nautilus_navinfo_free(navinfo); navinfo = NULL; + goto out; } } navinfo->meta_iids = g_slist_append(navinfo->meta_iids, g_strdup("ntl_history_view")); navinfo->meta_iids = g_slist_append(navinfo->meta_iids, g_strdup("ntl_websearch_view")); - return navinfo; + out: + if(notify_when_ready) + { + navinfo->notify_tag = 0; + notify_when_ready(navinfo, notify_data); + } + + return 0; } void nautilus_navinfo_free(NautilusNavigationInfo *navinfo) { + if(navinfo->notify_tag) + /* XXX remove_notification */ ; + g_slist_foreach(navinfo->meta_iids, (GFunc)g_free, NULL); g_slist_free(navinfo->meta_iids); g_free(navinfo->navinfo.requested_uri); g_free(navinfo->navinfo.actual_uri); g_free(navinfo->navinfo.content_type); + g_free(navinfo); } diff --git a/src/ntl-uri-map.h b/src/ntl-uri-map.h index 26584af1f..52202cf7e 100644 --- a/src/ntl-uri-map.h +++ b/src/ntl-uri-map.h @@ -31,10 +31,11 @@ #include "ntl-view.h" void nautilus_navinfo_init(void); -NautilusNavigationInfo *nautilus_navinfo_new(NautilusNavigationInfo *navinfo, - Nautilus_NavigationRequestInfo *nri, - Nautilus_NavigationInfo *old_navinfo, - NautilusView *requesting_view); +guint nautilus_navinfo_new(Nautilus_NavigationRequestInfo *nri, + Nautilus_NavigationInfo *old_navinfo, + NautilusView *requesting_view, + NautilusNavigationInfoFunc notify_when_ready, + gpointer notify_data); void nautilus_navinfo_free(NautilusNavigationInfo *navinfo); #endif diff --git a/src/ntl-view-nautilus.c b/src/ntl-view-nautilus.c index abb30a995..eb9e939a4 100644 --- a/src/ntl-view-nautilus.c +++ b/src/ntl-view-nautilus.c @@ -61,6 +61,8 @@ nv_show_properties(NautilusView *view, CORBA_Environment *ev) NautilusViewInfo *nvi = view->component_data; Nautilus_View_show_properties(nvi->view_client, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -69,6 +71,8 @@ nv_save_state(NautilusView *view, const char *config_path, CORBA_Environment *ev NautilusViewInfo *nvi = view->component_data; Nautilus_View_save_state(nvi->view_client, config_path, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -77,6 +81,8 @@ nv_load_state(NautilusView *view, const char *config_path, CORBA_Environment *ev NautilusViewInfo *nvi = view->component_data; Nautilus_View_load_state(nvi->view_client, config_path, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -85,6 +91,8 @@ nv_notify_location_change(NautilusView *view, Nautilus_NavigationInfo *nav_ctx, NautilusViewInfo *nvi = view->component_data; Nautilus_View_notify_location_change(nvi->view_client, nav_ctx, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -93,6 +101,8 @@ nv_notify_selection_change(NautilusView *view, Nautilus_SelectionInfo *nav_ctx, NautilusViewInfo *nvi = view->component_data; Nautilus_View_notify_selection_change(nvi->view_client, nav_ctx, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } static void @@ -101,9 +111,10 @@ nv_stop_location_change(NautilusView *view, CORBA_Environment *ev) NautilusViewInfo *nvi = view->component_data; Nautilus_View_stop_location_change(nvi->view_client, ev); + if(ev->_major != CORBA_NO_EXCEPTION) + gtk_object_destroy(GTK_OBJECT(view)); } - static char * nv_get_label(NautilusView *view, CORBA_Environment *ev) { diff --git a/src/ntl-view.c b/src/ntl-view.c index 9f030f73e..b3af28154 100644 --- a/src/ntl-view.c +++ b/src/ntl-view.c @@ -240,8 +240,12 @@ static void nautilus_view_destroy(GtkObject *view) { NautilusViewClass *klass = NAUTILUS_VIEW_CLASS(view->klass); + NautilusView *nview = NAUTILUS_VIEW(view); - nautilus_view_destroy_client(NAUTILUS_VIEW(view)); + if(nview->timer_id) + g_source_remove(nview->timer_id); + + nautilus_view_destroy_client(nview); if(GTK_OBJECT_CLASS(klass->parent_class)->destroy) GTK_OBJECT_CLASS(klass->parent_class)->destroy(view); @@ -309,6 +313,19 @@ extern NautilusViewComponentType nautilus_view_component_type; /* ntl-view-nauti extern NautilusViewComponentType bonobo_subdoc_component_type; /* ntl-view-bonobo-subdoc.c */ extern NautilusViewComponentType bonobo_control_component_type; /* ntl-view-bonobo-control.c */ +static gboolean +nautilus_view_handle_client_destroy(GtkWidget *widget, NautilusView *view) +{ + gtk_object_destroy(GTK_OBJECT(view)); + return TRUE; +} + +static void +nautilus_view_handle_client_destroy_2(GtkObject *object, CORBA_Object cobject, CORBA_Environment *ev, NautilusView *view) +{ + gtk_object_destroy(GTK_OBJECT(view)); +} + gboolean /* returns TRUE if successful */ nautilus_view_load_client(NautilusView *view, const char *iid) { @@ -363,8 +380,17 @@ nautilus_view_load_client(NautilusView *view, const char *iid) view->iid = g_strdup(iid); - gtk_widget_show(view->client_widget); + gtk_signal_connect_while_alive(GTK_OBJECT(view->client_object), "destroy", + GTK_SIGNAL_FUNC(nautilus_view_handle_client_destroy), view, + GTK_OBJECT(view)); + gtk_signal_connect_while_alive(GTK_OBJECT(view->client_object), "object_gone", + GTK_SIGNAL_FUNC(nautilus_view_handle_client_destroy_2), view, + GTK_OBJECT(view)); + gtk_signal_connect_while_alive(GTK_OBJECT(view->client_object), "system_exception", + GTK_SIGNAL_FUNC(nautilus_view_handle_client_destroy_2), view, + GTK_OBJECT(view)); gtk_container_add(GTK_CONTAINER(view), view->client_widget); + gtk_widget_show(view->client_widget); CORBA_exception_free(&ev); return TRUE; @@ -525,3 +551,38 @@ nautilus_view_request_progress_change(NautilusView *view, gtk_signal_emit(GTK_OBJECT(view), nautilus_view_signals[REQUEST_PROGRESS_CHANGE], loc); } +static gboolean +check_object(NautilusView *view) +{ + CORBA_Environment ev; + gboolean retval = TRUE; + CORBA_exception_init(&ev); + + if(CORBA_Object_non_existent(gnome_object_corba_objref(GNOME_OBJECT(view->client_object)), &ev)) + { + view->timer_id = 0; + gtk_object_destroy(GTK_OBJECT(view)); + retval = FALSE; + } + + CORBA_exception_free(&ev); + return retval; +} + +void +nautilus_view_set_active_errors(NautilusView *view, gboolean enabled) +{ + if(enabled) + { + if(!view->timer_id) + view->timer_id = g_timeout_add(1000, (GSourceFunc)check_object, view); + } + else + { + if(view->timer_id) + { + g_source_remove(view->timer_id); + view->timer_id = 0; + } + } +} diff --git a/src/ntl-view.h b/src/ntl-view.h index b8530f13a..a59a95c15 100644 --- a/src/ntl-view.h +++ b/src/ntl-view.h @@ -91,6 +91,8 @@ struct _NautilusView NautilusViewComponentType *component_class; gpointer component_data; + + guint timer_id; }; GtkType nautilus_view_get_type (void); @@ -113,8 +115,7 @@ void nautilus_view_save_state (NautilusView *view, const char *config_path); void nautilus_view_show_properties (NautilusView *view); void nautilus_view_stop_location_change (NautilusView *view); - - +void nautilus_view_set_active_errors (NautilusView *view, gboolean enabled); /* This is a "protected" operation */ void nautilus_view_construct_arg_set(NautilusView *view); diff --git a/src/ntl-window-msgs.c b/src/ntl-window-msgs.c index ad72a0f44..b2870928a 100644 --- a/src/ntl-window-msgs.c +++ b/src/ntl-window-msgs.c @@ -2,25 +2,37 @@ #include "ntl-window-private.h" #include "explorer-location-bar.h" +struct _NautilusWindowLoadInfo { + enum { + GETTING_URI_INFO, + WAITING_FOR_VIEWS, + PROCESSING, + DONE + } state; + + union { + struct { + guint cancel_tag; + } getting_uri_info; + } u; + + /* Valid in the WAITING_FOR_VIEWS or PROCESSING states */ + NautilusNavigationInfo *ni; + + GSList *new_meta_views; + NautilusView *new_content_view; + + gboolean got_content_progress; + + gboolean is_back; +}; + static void nautilus_window_notify_selection_change(NautilusWindow *window, NautilusView *view, Nautilus_SelectionInfo *loc, NautilusView *requesting_view); static void -Nautilus_NavigationInfo__copy(Nautilus_NavigationInfo *dest_ni, Nautilus_NavigationInfo *src_ni) -{ - dest_ni->requested_uri = CORBA_string_dup(src_ni->requested_uri); - dest_ni->actual_uri = CORBA_string_dup(src_ni->actual_uri); - dest_ni->content_type = CORBA_string_dup(src_ni->content_type); - dest_ni->referring_uri = CORBA_string_dup(src_ni->referring_uri); - dest_ni->actual_referring_uri = CORBA_string_dup(src_ni->actual_referring_uri); - dest_ni->referring_content_type = CORBA_string_dup(src_ni->referring_content_type); - dest_ni->content_view = CORBA_OBJECT_NIL; - dest_ni->self_originated = CORBA_FALSE; -} - -static void Nautilus_SelectionInfo__copy(Nautilus_SelectionInfo *dest_si, Nautilus_SelectionInfo *src_si) { int i, n; @@ -75,22 +87,55 @@ nautilus_window_request_location_change(NautilusWindow *window, nautilus_window_change_location(window, loc, requesting_view, FALSE); } +static void +nautilus_window_notify_selection_change(NautilusWindow *window, + NautilusView *view, + Nautilus_SelectionInfo *loc, + NautilusView *requesting_view) +{ + loc->self_originated = (view == requesting_view); + + nautilus_view_notify_selection_change(view, loc); +} + void nautilus_window_request_progress_change(NautilusWindow *window, Nautilus_ProgressRequestInfo *loc, NautilusView *requesting_view) { - if(requesting_view != window->content_view) - return; /* Only pay attention to progress information from the main view, for now */ - - if (loc->type == Nautilus_PROGRESS_DONE_OK || loc->type == Nautilus_PROGRESS_DONE_ERROR) { - nautilus_window_allow_stop(window, FALSE); - } - g_message("Progress is %f", loc->amount); + if (window->load_info) + { + if(requesting_view != window->load_info->new_content_view) + return; /* Only pay attention to progress information from the main view, for now */ + + /* We have gotten something from the content view, which means it is safe to do the "switchover" to the new page */ + window->load_info->got_content_progress = TRUE; + nautilus_window_end_location_change(window); + nautilus_window_allow_stop (window, !(loc->type == Nautilus_PROGRESS_DONE_OK + || loc->type == Nautilus_PROGRESS_DONE_ERROR)); + + g_message("Progress is %f", loc->amount); + } +} + +/* The bulk of this file - location changing */ + +static void +Nautilus_NavigationInfo__copy(Nautilus_NavigationInfo *dest_ni, Nautilus_NavigationInfo *src_ni) +{ + dest_ni->requested_uri = CORBA_string_dup(src_ni->requested_uri); + dest_ni->actual_uri = CORBA_string_dup(src_ni->actual_uri); + dest_ni->content_type = CORBA_string_dup(src_ni->content_type); + dest_ni->referring_uri = CORBA_string_dup(src_ni->referring_uri); + dest_ni->actual_referring_uri = CORBA_string_dup(src_ni->actual_referring_uri); + dest_ni->referring_content_type = CORBA_string_dup(src_ni->referring_content_type); + dest_ni->content_view = CORBA_OBJECT_NIL; + dest_ni->self_originated = CORBA_FALSE; } +/* Handle the changes for the NautilusWindow itself. */ static void -nautilus_window_change_location_internal(NautilusWindow *window, NautilusNavigationInfo *loci, gboolean is_back) +nautilus_window_change_location_internal(NautilusWindow *window, Nautilus_NavigationInfo *loci, gboolean is_back) { GnomeVFSURI *new_uri; @@ -102,7 +147,7 @@ nautilus_window_change_location_internal(NautilusWindow *window, NautilusNavigat /* Going back. Remove one item from the prev list and add the current item to the next list. */ g_assert(window->uris_prev); - g_assert(!strcmp((const gchar*)window->uris_prev->data, loci->navinfo.requested_uri)); + g_assert(!strcmp((const gchar*)window->uris_prev->data, loci->requested_uri)); g_assert(window->ni); window->uris_next = g_slist_prepend(window->uris_next, g_strdup(window->ni->requested_uri)); @@ -115,7 +160,7 @@ nautilus_window_change_location_internal(NautilusWindow *window, NautilusNavigat * Otherwise, clobber the entire next list. */ - if (window->uris_next && !strcmp(loci->navinfo.requested_uri, (const gchar*)window->uris_next->data)) + if (window->uris_next && !strcmp(loci->requested_uri, (const gchar*)window->uris_next->data)) { g_free(window->uris_next->data); window->uris_next = g_slist_remove_link(window->uris_next, window->uris_next); @@ -132,41 +177,76 @@ nautilus_window_change_location_internal(NautilusWindow *window, NautilusNavigat nautilus_window_allow_back(window, window->uris_prev?TRUE:FALSE); nautilus_window_allow_forward(window, window->uris_next?TRUE:FALSE); - new_uri = gnome_vfs_uri_new (loci->navinfo.requested_uri); + new_uri = gnome_vfs_uri_new (loci->requested_uri); nautilus_window_allow_up(window, gnome_vfs_uri_has_parent(new_uri)); gnome_vfs_uri_destroy(new_uri); - CORBA_free(window->ni); - window->ni = Nautilus_NavigationInfo__alloc(); - Nautilus_NavigationInfo__copy(window->ni, &loci->navinfo); + if(window->ni != loci) + { + Nautilus_NavigationInfo *newni; - CORBA_free(window->si); - window->si = NULL; + newni = Nautilus_NavigationInfo__alloc(); + Nautilus_NavigationInfo__copy(newni, loci); + CORBA_free(window->ni); + window->ni = newni; + + CORBA_free(window->si); + window->si = NULL; + } explorer_location_bar_set_uri_string(EXPLORER_LOCATION_BAR(window->ent_uri), - loci->navinfo.requested_uri); + loci->requested_uri); } static void nautilus_window_update_view(NautilusWindow *window, NautilusView *view, - NautilusNavigationInfo *loci, - NautilusView *requesting_view) + Nautilus_NavigationInfo *loci, + NautilusView *requesting_view, + NautilusView *content_view) { g_return_if_fail(view); - loci->navinfo.self_originated = (view == requesting_view); + loci->self_originated = (view == requesting_view); - nautilus_view_notify_location_change(NAUTILUS_VIEW(view), &(loci->navinfo)); + nautilus_view_notify_location_change(NAUTILUS_VIEW(view), loci); if(window->si) { - window->si->content_view = nautilus_view_get_client_objref(NAUTILUS_VIEW(window->content_view)); + window->si->content_view = nautilus_view_get_client_objref(content_view); nautilus_window_notify_selection_change(window, view, window->si, NULL); } } +void +nautilus_window_view_destroyed(NautilusView *view, NautilusWindow *window) +{ + if(NAUTILUS_IS_CONTENT_VIEW(view)) + { + if(window->load_info) + { + if(view == window->load_info->new_content_view) + { + nautilus_window_display_error + (window, + _("A software component, needed to display the requested page, has turned fatalistic.")); + nautilus_window_end_location_change(window); + } + } + + if(view == window->content_view) + window->content_view = NULL; + } + else if(NAUTILUS_IS_META_VIEW(view)) + { + if(window->load_info) + window->load_info->new_meta_views = g_slist_remove(window->load_info->new_meta_views, view); + + nautilus_window_remove_meta_view(window, view); + } +} + static void nautilus_window_load_content_view(NautilusWindow *window, const char *iid, @@ -189,29 +269,27 @@ nautilus_window_load_content_view(NautilusWindow *window, new_view = NAUTILUS_VIEW(gtk_widget_new(nautilus_content_view_get_type(), "main_window", window, NULL)); - nautilus_window_set_content_view(window, new_view); + nautilus_window_connect_view(window, new_view); + if(!nautilus_view_load_client(new_view, iid)) { gtk_widget_destroy(GTK_WIDGET(new_view)); + new_view = NULL; } - } + else + new_view = window->content_view; - if(window->content_view && NAUTILUS_IS_VIEW(window->content_view)) + if(new_view && NAUTILUS_IS_VIEW(new_view)) { - loci->navinfo.content_view = nautilus_view_get_client_objref(window->content_view); + gtk_object_ref(GTK_OBJECT(new_view)); - nautilus_window_allow_stop(window, TRUE); - nautilus_window_update_view(window, window->content_view, loci, *requesting_view); - } - else - { - /* NautilusView *dummy_view; */ + loci->navinfo.content_view = nautilus_view_get_client_objref(new_view); + window->load_info->new_content_view = new_view; + + nautilus_view_set_active_errors(new_view, TRUE); - /* FIXME - should be another view type - Commenting because set_content_view() would break */ - /* dummy_view = (NautilusView *)gtk_label_new(_("The component needed to display this file was not found.")); */ - /* nautilus_window_set_content_view(window, dummy_view); */ - nautilus_window_set_content_view(window, NULL); + nautilus_window_update_view(window, new_view, &(loci->navinfo), *requesting_view, window->load_info->new_content_view); } } @@ -234,18 +312,108 @@ nautilus_window_load_meta_view(NautilusWindow *window, if(!curview) { meta_view = NAUTILUS_VIEW(gtk_widget_new(nautilus_meta_view_get_type(), "main_window", window, NULL)); + nautilus_window_connect_view(window, meta_view); if(!nautilus_view_load_client(meta_view, iid)) { gtk_widget_destroy(GTK_WIDGET(meta_view)); meta_view = NULL; } - - if(meta_view) - nautilus_window_add_meta_view(window, meta_view); } if(meta_view) - nautilus_window_update_view(window, meta_view, loci, requesting_view); + { + gtk_object_ref(GTK_OBJECT(meta_view)); + + nautilus_view_set_active_errors(meta_view, TRUE); + + window->load_info->new_meta_views = g_slist_prepend(window->load_info->new_meta_views, meta_view); + + nautilus_window_update_view(window, meta_view, &(loci->navinfo), requesting_view, window->load_info->new_content_view); + } +} + +void +nautilus_window_end_location_change(NautilusWindow *window) +{ + GSList *cur, *discard_views; + + if (!window->load_info) + { + if(window->content_view) + nautilus_view_stop_location_change (window->content_view); + + g_slist_foreach(window->meta_views, (GFunc) nautilus_view_stop_location_change, NULL); + + nautilus_window_allow_stop(window, FALSE); + + return; + } + + switch (window->load_info->state) + { + case DONE: /* The normal case - the page has finished loading successfully */ + /* Do lots of shuffling to make sure we don't remove views that were already there, but add new views */ + for(cur = window->load_info->new_meta_views; cur; cur = cur->next) + { + if(!GTK_WIDGET(cur->data)->parent) + nautilus_window_add_meta_view(window, cur->data); + gtk_object_unref(cur->data); + /* nautilus_view_set_active_errors(cur->data, FALSE); */ + } + for(cur = window->meta_views; cur; cur = cur->next) + if(!g_slist_find(window->load_info->new_meta_views, cur->data)) + discard_views = g_slist_prepend(discard_views, cur->data); + + for(cur = discard_views; cur; cur = cur->next) + nautilus_window_remove_meta_view(window, cur->data); + g_slist_free(discard_views); + + if(!GTK_WIDGET(window->load_info->new_content_view)->parent) + nautilus_window_set_content_view(window, window->load_info->new_content_view); + gtk_object_unref(GTK_OBJECT(window->load_info->new_content_view)); + /* nautilus_view_set_active_errors(window->load_info->new_content_view, FALSE); */ + + nautilus_window_change_location_internal(window, &window->load_info->ni->navinfo, window->load_info->is_back); + break; + + /* all of the following are error cases - we try to recover as best we can */ + case WAITING_FOR_VIEWS: + for(cur = window->load_info->new_meta_views; cur; cur = cur->next) + { + gtk_widget_unref(cur->data); + /* nautilus_view_set_active_errors(cur->data, FALSE); */ + } + if(window->load_info->new_content_view) + { + gtk_widget_unref(GTK_WIDGET(window->load_info->new_content_view)); + /* nautilus_view_set_active_errors(window->load_info->new_content_view, FALSE); */ + } + + /* Tell previously-notified views to go back to the old page */ + for(cur = window->meta_views; cur; cur = cur->next) + { + if(g_slist_find(window->load_info->new_meta_views, cur->data)) + nautilus_window_update_view(window, cur->data, window->ni, NULL, window->content_view); + } + if(window->load_info->new_content_view == window->content_view) + nautilus_window_update_view(window, window->content_view, window->ni, NULL, window->content_view); + explorer_location_bar_set_uri_string(EXPLORER_LOCATION_BAR(window->ent_uri), + window->ni->requested_uri); + + case GETTING_URI_INFO: + default: + break; + + case PROCESSING: + return; /* We don't want to do anything in the processing state - someone else is already busy manipulating things */ + } + + nautilus_navinfo_free(window->load_info->ni); + + g_slist_free(window->load_info->new_meta_views); + g_free(window->load_info); window->load_info = NULL; + + nautilus_window_allow_stop(window, FALSE); } /* This is the most complicated routine in Nautilus. Steps include: @@ -254,38 +422,52 @@ nautilus_window_load_meta_view(NautilusWindow *window, 3. Update the history, UI, and internal state for the proposed change. 4. Load/notify content view. 5. Load/notify meta views. - */ -void -nautilus_window_change_location(NautilusWindow *window, - Nautilus_NavigationRequestInfo *loc, - NautilusView *requesting_view, - gboolean is_back) + +/* Step 2 */ +static void +nautilus_window_change_location_2(NautilusNavigationInfo *ni, gpointer data) { - NautilusNavigationInfo loci_spot, *loci; GSList *cur, *discard_views; - /* Step 1 */ - loci = nautilus_navinfo_new(&loci_spot, loc, window->ni, requesting_view); + NautilusWindow *window = data; + + window->load_info->state = PROCESSING; + window->load_info->ni = ni; - /* Step 2 */ - if(!loci) + if(!ni) { - char cbuf[1024]; - g_snprintf(cbuf, sizeof(cbuf), _("Cannot load %s"), loc->requested_uri); - nautilus_window_set_status(window, cbuf); + nautilus_window_display_error + (window, + _("The chosen hyperlink is invalid, or points to an inaccessable page.")); + + nautilus_window_end_location_change(window); + return; } - /* Step 3 */ - nautilus_window_change_location_internal(window, loci, is_back); + if(!ni->content_iid) + { + nautilus_window_display_error + (window, + _("There is not any known method of displaying the selected page.")); - /* Step 4 */ + nautilus_window_end_location_change(window); - if(loci->content_iid) - nautilus_window_load_content_view(window, loci->content_iid, loci, &requesting_view); - else - nautilus_window_set_content_view(window, NULL); + return; + } + + nautilus_window_load_content_view(window, ni->content_iid, ni, (NautilusView **)&ni->requesting_view); + if(!window->load_info->new_content_view) + { + nautilus_window_display_error + (window, + _("The software needed to display this page could not be loaded.")); + + nautilus_window_end_location_change(window); + + return; + } /* Step 5 */ @@ -295,39 +477,55 @@ nautilus_window_change_location(NautilusWindow *window, { NautilusView *view = cur->data; - if(!g_slist_find_custom(loci->meta_iids, view->iid, (GCompareFunc)strcmp)) + if(!g_slist_find_custom(ni->meta_iids, view->iid, (GCompareFunc)g_str_equal)) { - if(view == requesting_view) - requesting_view = NULL; + if(cur->data == ni->requesting_view) + ni->requesting_view = NULL; discard_views = g_slist_prepend(discard_views, view); } } - for(cur = loci->meta_iids; cur; cur = cur->next) - nautilus_window_load_meta_view(window, cur->data, loci, requesting_view); + for(cur = ni->meta_iids; cur; cur = cur->next) + nautilus_window_load_meta_view(window, cur->data, ni, ni->requesting_view); for(cur = discard_views; cur; cur = cur->next) nautilus_window_remove_meta_view(window, cur->data); g_slist_free(discard_views); - nautilus_navinfo_free(loci); -} - -static void -nautilus_window_notify_selection_change(NautilusWindow *window, - NautilusView *view, - Nautilus_SelectionInfo *loc, - NautilusView *requesting_view) -{ - loc->self_originated = (view == requesting_view); - - nautilus_view_notify_selection_change(view, loc); + if(window->load_info->got_content_progress) + { + window->load_info->state = DONE; + nautilus_window_end_location_change(window); + } + else + window->load_info->state = WAITING_FOR_VIEWS; } +/* Step 1 */ +void +nautilus_window_change_location(NautilusWindow *window, + Nautilus_NavigationRequestInfo *loc, + NautilusView *requesting_view, + gboolean is_back) +{ + guint cancel_tag; + nautilus_window_end_location_change(window); /* End any previous location change that was pending. */ + while(gdk_events_pending()) + gtk_main_iteration(); + nautilus_window_allow_stop(window, TRUE); + /* Init load_info */ + window->load_info = g_new0(NautilusWindowLoadInfo, 1); + window->load_info->state = GETTING_URI_INFO; + window->load_info->is_back = is_back; + cancel_tag = + nautilus_navinfo_new(loc, window->ni, requesting_view, nautilus_window_change_location_2, window); + if(window->load_info) + window->load_info->u.getting_uri_info.cancel_tag = cancel_tag; +} diff --git a/src/ntl-window-private.h b/src/ntl-window-private.h index f371101bb..381af8034 100644 --- a/src/ntl-window-private.h +++ b/src/ntl-window-private.h @@ -23,5 +23,10 @@ void nautilus_window_change_location(NautilusWindow *window, Nautilus_NavigationRequestInfo *loc, NautilusView *requesting_view, gboolean is_back); +void nautilus_window_remove_meta_view_real(NautilusWindow *window, NautilusView *meta_view); +void nautilus_window_end_location_change(NautilusWindow *window); +void nautilus_window_connect_view (NautilusWindow *window, + NautilusView *view); +void nautilus_window_view_destroyed(NautilusView *view, NautilusWindow *window); #endif diff --git a/src/ntl-window.c b/src/ntl-window.c index 424b2098c..40a1098c0 100644 --- a/src/ntl-window.c +++ b/src/ntl-window.c @@ -121,15 +121,6 @@ static void nautilus_window_goto_uri_cb (GtkWidget *widget, GtkWidget *window); static void nautilus_window_about_cb (GtkWidget *widget, NautilusWindow *window); -static void nautilus_window_connect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view (NautilusWindow *window, - NautilusView *view); -static void nautilus_window_disconnect_view_exchanged (NautilusView *view, - NautilusWindow *window); - - - #undef CONTENTS_AS_HBOX @@ -574,15 +565,11 @@ nautilus_window_set_arg (GtkObject *object, #endif } - nautilus_window_disconnect_view(window, window->content_view); - gtk_widget_unref(GTK_WIDGET(window->content_view)); } if (new_cv) { - nautilus_window_connect_view(window, NAUTILUS_VIEW(new_cv)); - #ifdef CONTENTS_AS_HBOX gtk_box_pack_end(GTK_BOX(window->content_hbox), new_cv, TRUE, TRUE, GNOME_PAD); #else @@ -617,12 +604,6 @@ static void nautilus_window_destroy (NautilusWindow *window) { NautilusWindowClass *klass = NAUTILUS_WINDOW_CLASS(GTK_OBJECT(window)->klass); - if (window->content_view != NULL) { - nautilus_window_disconnect_view(window, window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc)nautilus_window_disconnect_view_exchanged, window); - g_slist_free(window->meta_views); CORBA_free(window->ni); CORBA_free(window->si); @@ -774,8 +755,6 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - nautilus_window_connect_view(window, meta_view); - desc = nautilus_meta_view_get_label(NAUTILUS_META_VIEW(meta_view)); if(!desc) { @@ -793,21 +772,25 @@ nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) } void -nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +nautilus_window_remove_meta_view_real(NautilusWindow *window, NautilusView *meta_view) { gint pagenum; - g_return_if_fail(g_slist_find(window->meta_views, meta_view)); - - window->meta_views = g_slist_remove(window->meta_views, meta_view); - pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(window->meta_notebook), GTK_WIDGET(meta_view)); g_return_if_fail(pagenum >= 0); gtk_notebook_remove_page(GTK_NOTEBOOK(window->meta_notebook), pagenum); +} + +void +nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view) +{ + g_return_if_fail(g_slist_find(window->meta_views, meta_view)); + + window->meta_views = g_slist_remove(window->meta_views, meta_view); - nautilus_window_disconnect_view(window, meta_view); + nautilus_window_remove_meta_view_real(window, meta_view); } /* FIXME: Factor toolbar stuff out into ntl-window-toolbar.c */ @@ -884,20 +867,9 @@ nautilus_window_home (GtkWidget *btn, NautilusWindow *window) } static void -nv_stop_location_change_adapter(NautilusView *view, gpointer dummy) -{ - nautilus_view_stop_location_change (view); -} - -static void nautilus_window_stop (GtkWidget *btn, NautilusWindow *window) { - if (window->content_view != NULL) { - nautilus_view_stop_location_change (window->content_view); - } - - g_slist_foreach(window->meta_views, (GFunc) nv_stop_location_change_adapter, NULL); - + nautilus_window_end_location_change(window); } static void @@ -987,52 +959,43 @@ nautilus_window_request_progress_change_cb (NautilusView *view, nautilus_window_request_progress_change(window, info, view); } - - - -static void +void nautilus_window_connect_view(NautilusWindow *window, NautilusView *view) { - gtk_signal_connect(GTK_OBJECT(view), + GtkObject *viewo; + + viewo = GTK_OBJECT(view); + gtk_signal_connect(viewo, "request_location_change", nautilus_window_request_location_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_selection_change", nautilus_window_request_selection_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_status_change", nautilus_window_request_status_change_cb, window); - gtk_signal_connect(GTK_OBJECT(view), + gtk_signal_connect(viewo, "request_progress_change", nautilus_window_request_progress_change_cb, window); + gtk_signal_connect(viewo, + "destroy", + nautilus_window_view_destroyed, + window); } - -static void -nautilus_window_disconnect_view(NautilusWindow *window, NautilusView *view) +void +nautilus_window_display_error(NautilusWindow *window, const char *error_msg) { - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_location_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_selection_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_status_change_cb, - window); - gtk_signal_disconnect_by_func(GTK_OBJECT(view), - nautilus_window_request_progress_change_cb, - window); -} + GtkWidget *dialog; -static void -nautilus_window_disconnect_view_exchanged(NautilusView *view, NautilusWindow *window) -{ - nautilus_window_disconnect_view(window, view); -} + 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); +} diff --git a/src/ntl-window.h b/src/ntl-window.h index 59996249c..b21cf6604 100644 --- a/src/ntl-window.h +++ b/src/ntl-window.h @@ -47,6 +47,8 @@ typedef struct { guint window_signals[0]; } NautilusWindowClass; +typedef struct _NautilusWindowLoadInfo NautilusWindowLoadInfo; + struct _NautilusWindow { GnomeApp parent_object; @@ -70,6 +72,8 @@ struct _NautilusWindow { /* Information about current location/selection */ Nautilus_NavigationInfo *ni; Nautilus_SelectionInfo *si; + + NautilusWindowLoadInfo *load_info; }; GtkType nautilus_window_get_type(void); @@ -78,6 +82,8 @@ void nautilus_window_set_content_view(NautilusWindow *window, NautilusView *cont void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_remove_meta_view(NautilusWindow *window, NautilusView *meta_view); void nautilus_window_goto_uri(NautilusWindow *window, const char *uri); +void nautilus_window_display_error(NautilusWindow *window, const char *error_msg); + const char *nautilus_window_get_requested_uri(NautilusWindow *window); GnomeUIHandler *nautilus_window_get_uih(NautilusWindow *window); |