summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliot Lee <sopwith@src.gnome.org>2000-01-05 23:21:06 +0000
committerElliot Lee <sopwith@src.gnome.org>2000-01-05 23:21:06 +0000
commit6018bcea245c2e4a9c50055fe6207435850549ff (patch)
tree2de36703f80e7a24435e69d4194eb56f62b55454
parentcdf570ee034dc1349846eeb5f78775a23ea2eb47 (diff)
downloadnautilus-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.
-rw-r--r--ChangeLog-2000041411
-rw-r--r--TODO4
-rw-r--r--components/html/ntl-web-browser.c19
-rw-r--r--src/file-manager/fm-directory-view.c12
-rw-r--r--src/nautilus-applicable-views.c36
-rw-r--r--src/nautilus-applicable-views.h9
-rw-r--r--src/nautilus-navigation-window.c99
-rw-r--r--src/nautilus-navigation-window.h6
-rw-r--r--src/nautilus-object-window.c99
-rw-r--r--src/nautilus-object-window.h6
-rw-r--r--src/nautilus-spatial-window.c99
-rw-r--r--src/nautilus-spatial-window.h6
-rw-r--r--src/nautilus-view-frame-nautilus-view.c13
-rw-r--r--src/nautilus-view-frame.c65
-rw-r--r--src/nautilus-view-frame.h5
-rw-r--r--src/nautilus-window-manage-views.c380
-rw-r--r--src/nautilus-window-private.h5
-rw-r--r--src/nautilus-window.c99
-rw-r--r--src/nautilus-window.h6
-rw-r--r--src/ntl-meta-view.c11
-rw-r--r--src/ntl-types.h12
-rw-r--r--src/ntl-uri-map.c36
-rw-r--r--src/ntl-uri-map.h9
-rw-r--r--src/ntl-view-nautilus.c13
-rw-r--r--src/ntl-view.c65
-rw-r--r--src/ntl-view.h5
-rw-r--r--src/ntl-window-msgs.c380
-rw-r--r--src/ntl-window-private.h5
-rw-r--r--src/ntl-window.c99
-rw-r--r--src/ntl-window.h6
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):
diff --git a/TODO b/TODO
index c20a1fd8c..c76c78356 100644
--- a/TODO
+++ b/TODO
@@ -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);