summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Stachowiak <mstachow@src.gnome.org>2001-02-19 23:12:11 +0000
committerMaciej Stachowiak <mstachow@src.gnome.org>2001-02-19 23:12:11 +0000
commitbe34bbbe95ec8303bc21345ac886246f03c3a0e5 (patch)
tree95720c2703ab7e21498087782d6954c58cc67529
parentbe9e2a17796b5c7b21004d7198d601c7449974f8 (diff)
downloadnautilus-be34bbbe95ec8303bc21345ac886246f03c3a0e5.tar.gz
reviewed by: John Harper <jsh@eazel.com>
Fixed bugs 3743 (Summary view gives the same vague error message for many different causes), 3972 (If user can't connect to service, they end up with gray content view), 5973 (blank summary view after install view finishes) and 6166 (Summary Login dialog does not have initial focus) and 6018 (Nautilus returns to wrong directory if services are unavailable). Also did much code cleanup, and made the service and featured download icons in the summary view prelighting and clickable. Fixed many other nits as well. * components/services/nautilus-dependent-shared/eazel-services-extensions.h, components/services/nautilus-dependent-shared/eazel-services-extensions.c (eazel_services_clickable_image_new_from_uri): Convenience wrapper to make a new clickable image from a URI. * components/services/nautilus-dependent-shared/eazel-services-footer.c (eazel_services_footer_update): Clear the footer before updating, instead of just dumping the new items in along with the old ones. * components/services/trilobite/libtrilobite/trilobite-core-network.h, components/services/trilobite/libtrilobite/trilobite-core-network.c: Adjusted formatting, fixed headers. * components/services/trilobite/libtrilobite/trilobite-file-utilities.h, components/services/trilobite/libtrilobite/trilobite-file-utilities.c: Cut 'n' pasted some useful code from libnautilus-extensions to avoid depending on it, whee. * components/services/trilobite/libtrilobite/Makefile.am: Added above to the build. * components/services/trilobite/libtrilobite/trilobite-redirect.h, components/services/trilobite/libtrilobite/trilobite-redirect.c: (trilobite_redirect_fetch_table_async, trilobite_redirect_fetch_table_cancel): Asynchronous version of redirect fetching code. (redirect_fetch_callback): Helper function. (trilobite_redirect_parse_xml): Null terminate buffer properly or XML parsing code will get confused. (trilobite_redirect_fetch_table): Removed the old synchronous code since now no one is using it. * components/services/summary/lib/eazel-summary-shared.h, components/services/summary/lib/eazel-summary-shared.c: (eazel_summary_fetch_data_cancel, eazel_summary_fetch_data_async): Asynchronous version of summary fetching code. (summary_data_fetch_callback): Helper function. (eazel_summary_data_parse_xml): Same null termination trick as for redirects. (parse_summary_xml_file): Removed old synchronous code since now no one is unsing it. * components/services/summary/nautilus-view/main.c (main): Set user agent to trilobite user agent; intialize gnome-vfs. * components/services/summary/nautilus-view/nautilus-summary-dialogs.h, components/services/summary/nautilus-view/nautilus-summary-dialogs.c (nautilus_summary_show_login_failure_dialog): Renamed from `nautilus_summary_login_failure_dialog' (nautilus_summary_show_error_dialog): Renamed from `generate_error_dialog'. (nautilus_summary_show_login_dialog): Renamed from `generate_login_dialog'. (error_dialog_cancel_cb): Go back instead of (incorrectly) trying to go back to the user's homedir. (set_dialog_parent): Do the magic coordinate adjustment like gnome_dialog_set_parent, but do not set it transient, or it will not get focus in click to focus mode. * components/services/summary/nautilus-view/nautilus-summary-callbacks.c: (authn_cb_failed): Adjust to above renaming. * components/services/summary/nautilus-view/nautilus-summary-footer.c (footer_item_clicked_callback): Ditto. * components/services/summary/nautilus-view/nautilus-summary-menu-items.c: (bonobo_login_callback): Ditto. * components/services/summary/nautilus-view/nautilus-summary-view-private.h: Removed unused fields. Added async handles for redirect and summary XML fetch. * components/services/summary/nautilus-view/nautilus-summary-view.c: (services_button_callback_data_free, summary_view_button_callback, goto_uri_on_clicked, summary_view_button_new, summary_view_link_image_new): Cleaned up summary view button code, added code for the clickable icons and refactored a bit. (create_header): Start out saying "Connecting to Eazel Services..." instead of blank, and don't call `update_header' from here. (update_footer): fix incorrect polarity of offline and online. (create_footer): remove call to update_footer; leave offline items in place until connected. (create_news_pane, create_services_list_pane, create_featured_downloads_pane): Do not call corresponding update func, updating is now separate from creating. (generate_service_entry_row, generate_update_news_entry_row): Make icons clickable. (update_summary_form): New function to update the existing summary view with new data, to avoid recreating even the fixed widgets from scratch all the time. (create_summary_form): Do not destroy all widgets at the beginning. Remove some useless widgetry. (nautilus_summary_view_initialize): Create the widgetry but do not fill it with data. (nautilus_summary_view_destroy, summary_fetch_callback, redirect_fetch_callback, cancel_load_in_progress), nautilus_summary_view_load_uri, summary_load_location_callback): Change things around so loading of the summary data is asynchronous. (summary_stop_loading_callback): Handle "stop_loading".
-rw-r--r--ChangeLog112
-rw-r--r--components/services/nautilus-dependent-shared/eazel-services-extensions.c47
-rw-r--r--components/services/nautilus-dependent-shared/eazel-services-extensions.h5
-rw-r--r--components/services/nautilus-dependent-shared/eazel-services-footer.c4
-rw-r--r--components/services/summary/eazel-summary-shared.c114
-rw-r--r--components/services/summary/eazel-summary-shared.h18
-rw-r--r--components/services/summary/lib/eazel-summary-shared.c114
-rw-r--r--components/services/summary/lib/eazel-summary-shared.h18
-rw-r--r--components/services/summary/main.c14
-rw-r--r--components/services/summary/nautilus-summary-callbacks.c8
-rw-r--r--components/services/summary/nautilus-summary-dialogs.c50
-rw-r--r--components/services/summary/nautilus-summary-dialogs.h14
-rw-r--r--components/services/summary/nautilus-summary-footer.c2
-rw-r--r--components/services/summary/nautilus-summary-menu-items.c2
-rw-r--r--components/services/summary/nautilus-summary-view-private.h28
-rw-r--r--components/services/summary/nautilus-summary-view.c427
-rw-r--r--components/services/summary/nautilus-view/main.c14
-rw-r--r--components/services/summary/nautilus-view/nautilus-summary-callbacks.c8
-rw-r--r--components/services/summary/nautilus-view/nautilus-summary-dialogs.c50
-rw-r--r--components/services/summary/nautilus-view/nautilus-summary-dialogs.h14
-rw-r--r--components/services/summary/nautilus-view/nautilus-summary-footer.c2
-rw-r--r--components/services/summary/nautilus-view/nautilus-summary-menu-items.c2
-rw-r--r--components/services/summary/nautilus-view/nautilus-summary-view-private.h28
-rw-r--r--components/services/summary/nautilus-view/nautilus-summary-view.c427
-rw-r--r--components/services/trilobite/libtrilobite/Makefile.am2
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-core-network.c17
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-core-network.h2
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-file-utilities.c291
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-file-utilities.h52
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-redirect.c135
-rw-r--r--components/services/trilobite/libtrilobite/trilobite-redirect.h28
31 files changed, 1413 insertions, 636 deletions
diff --git a/ChangeLog b/ChangeLog
index f2d01ab45..7482f1cde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,117 @@
2001-02-19 Maciej Stachowiak <mjs@eazel.com>
+ reviewed by: John Harper <jsh@eazel.com>
+
+ Fixed bugs 3743 (Summary view gives the same vague error message
+ for many different causes), 3972 (If user can't connect to
+ service, they end up with gray content view), 5973 (blank summary
+ view after install view finishes) and 6166 (Summary Login dialog
+ does not have initial focus) and 6018 (Nautilus returns to wrong
+ directory if services are unavailable). Also did much code
+ cleanup, and made the service and featured download icons in the
+ summary view prelighting and clickable. Fixed many other nits as
+ well.
+
+ * components/services/nautilus-dependent-shared/eazel-services-extensions.h,
+ components/services/nautilus-dependent-shared/eazel-services-extensions.c
+ (eazel_services_clickable_image_new_from_uri): Convenience wrapper
+ to make a new clickable image from a URI.
+ * components/services/nautilus-dependent-shared/eazel-services-footer.c
+ (eazel_services_footer_update): Clear the footer before updating,
+ instead of just dumping the new items in along with the old ones.
+
+ * components/services/trilobite/libtrilobite/trilobite-core-network.h,
+ components/services/trilobite/libtrilobite/trilobite-core-network.c:
+ Adjusted formatting, fixed headers.
+
+ * components/services/trilobite/libtrilobite/trilobite-file-utilities.h,
+ components/services/trilobite/libtrilobite/trilobite-file-utilities.c:
+ Cut 'n' pasted some useful code from libnautilus-extensions to
+ avoid depending on it, whee.
+ * components/services/trilobite/libtrilobite/Makefile.am: Added
+ above to the build.
+
+ * components/services/trilobite/libtrilobite/trilobite-redirect.h,
+ components/services/trilobite/libtrilobite/trilobite-redirect.c:
+ (trilobite_redirect_fetch_table_async,
+ trilobite_redirect_fetch_table_cancel): Asynchronous version of
+ redirect fetching code.
+ (redirect_fetch_callback): Helper function.
+ (trilobite_redirect_parse_xml): Null terminate buffer properly or
+ XML parsing code will get confused.
+ (trilobite_redirect_fetch_table): Removed the old synchronous code
+ since now no one is using it.
+
+ * components/services/summary/lib/eazel-summary-shared.h,
+ components/services/summary/lib/eazel-summary-shared.c:
+ (eazel_summary_fetch_data_cancel, eazel_summary_fetch_data_async):
+ Asynchronous version of summary fetching code.
+ (summary_data_fetch_callback): Helper function.
+ (eazel_summary_data_parse_xml): Same null termination trick as for
+ redirects.
+ (parse_summary_xml_file): Removed old synchronous code since now
+ no one is unsing it.
+
+ * components/services/summary/nautilus-view/main.c (main): Set
+ user agent to trilobite user agent; intialize gnome-vfs.
+
+ * components/services/summary/nautilus-view/nautilus-summary-dialogs.h,
+ components/services/summary/nautilus-view/nautilus-summary-dialogs.c
+ (nautilus_summary_show_login_failure_dialog): Renamed from
+ `nautilus_summary_login_failure_dialog'
+ (nautilus_summary_show_error_dialog): Renamed from
+ `generate_error_dialog'.
+ (nautilus_summary_show_login_dialog): Renamed from
+ `generate_login_dialog'.
+ (error_dialog_cancel_cb): Go back instead of (incorrectly) trying
+ to go back to the user's homedir.
+ (set_dialog_parent): Do the magic coordinate adjustment like
+ gnome_dialog_set_parent, but do not set it transient, or it will
+ not get focus in click to focus mode.
+
+ * components/services/summary/nautilus-view/nautilus-summary-callbacks.c:
+ (authn_cb_failed): Adjust to above renaming.
+ * components/services/summary/nautilus-view/nautilus-summary-footer.c
+ (footer_item_clicked_callback): Ditto.
+ * components/services/summary/nautilus-view/nautilus-summary-menu-items.c:
+ (bonobo_login_callback): Ditto.
+
+ * components/services/summary/nautilus-view/nautilus-summary-view-private.h:
+ Removed unused fields. Added async handles for redirect and summary XML
+ fetch.
+
+ * components/services/summary/nautilus-view/nautilus-summary-view.c:
+ (services_button_callback_data_free, summary_view_button_callback,
+ goto_uri_on_clicked, summary_view_button_new,
+ summary_view_link_image_new): Cleaned up summary view button code,
+ added code for the clickable icons and refactored a bit.
+ (create_header): Start out saying "Connecting to Eazel
+ Services..." instead of blank, and don't call `update_header' from
+ here.
+ (update_footer): fix incorrect polarity of offline and online.
+ (create_footer): remove call to update_footer; leave offline items
+ in place until connected.
+ (create_news_pane, create_services_list_pane,
+ create_featured_downloads_pane): Do not call corresponding update
+ func, updating is now separate from creating.
+ (generate_service_entry_row, generate_update_news_entry_row): Make
+ icons clickable.
+ (update_summary_form): New function to update the existing summary
+ view with new data, to avoid recreating even the fixed widgets
+ from scratch all the time.
+ (create_summary_form): Do not destroy all widgets at the
+ beginning. Remove some useless widgetry.
+ (nautilus_summary_view_initialize): Create the widgetry but do not
+ fill it with data.
+ (nautilus_summary_view_destroy, summary_fetch_callback,
+ redirect_fetch_callback, cancel_load_in_progress),
+ nautilus_summary_view_load_uri, summary_load_location_callback):
+ Change things around so loading of the summary data is
+ asynchronous.
+ (summary_stop_loading_callback): Handle "stop_loading".
+
+2001-02-19 Maciej Stachowiak <mjs@eazel.com>
+
reviewed by: Gene Z. Ragan <gzr@eazel.com>
Added auto-prelighting feature to NautilusClickableImage, and
diff --git a/components/services/nautilus-dependent-shared/eazel-services-extensions.c b/components/services/nautilus-dependent-shared/eazel-services-extensions.c
index 29f4b499e..6a183538f 100644
--- a/components/services/nautilus-dependent-shared/eazel-services-extensions.c
+++ b/components/services/nautilus-dependent-shared/eazel-services-extensions.c
@@ -126,12 +126,6 @@ eazel_services_image_new_from_uri (const char *uri,
g_return_val_if_fail (uri != NULL, NULL);
- /* as an optimization, it can be a local file. If it doesn't start with http://,
- just pass it on to create_image_widget */
- if (!nautilus_istr_has_prefix (uri, "http://")) {
- return eazel_services_image_new (uri, tile_name, background_color);
- }
-
/* load the image - synchronously, at least at first */
pixbuf = nautilus_gdk_pixbuf_load (uri);
@@ -154,6 +148,47 @@ eazel_services_image_new_from_uri (const char *uri,
return image;
}
+
+
+GtkWidget *
+eazel_services_clickable_image_new_from_uri (const char *uri,
+ const char *tile_name,
+ guint32 background_color,
+ int max_width,
+ int max_height)
+{
+ GtkWidget *image = NULL;
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *scaled_pixbuf;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ /* load the image - synchronously, at least at first */
+ pixbuf = nautilus_gdk_pixbuf_load (uri);
+
+ /* pin the image to the specified dimensions if necessary */
+ if (pixbuf && max_width > 0 && max_height > 0) {
+ scaled_pixbuf = nautilus_gdk_pixbuf_scale_down_to_fit (pixbuf, max_width, max_height);
+ gdk_pixbuf_unref (pixbuf);
+ pixbuf = scaled_pixbuf;
+ }
+
+ /* create the image widget then release the pixbuf*/
+ image = eazel_services_image_new_clickable (NULL, tile_name, background_color);
+
+ if (pixbuf != NULL) {
+ nautilus_labeled_image_set_pixbuf (NAUTILUS_LABELED_IMAGE (image),
+ pixbuf);
+ }
+
+ nautilus_gdk_pixbuf_unref_if_not_null (pixbuf);
+
+ return image;
+}
+
+
+
+
GtkWidget *
eazel_services_label_new (const char *text,
guint drop_shadow_offset,
diff --git a/components/services/nautilus-dependent-shared/eazel-services-extensions.h b/components/services/nautilus-dependent-shared/eazel-services-extensions.h
index 68ecb1b6d..818133182 100644
--- a/components/services/nautilus-dependent-shared/eazel-services-extensions.h
+++ b/components/services/nautilus-dependent-shared/eazel-services-extensions.h
@@ -75,6 +75,11 @@ GtkWidget *eazel_services_image_new_from_uri (const char *uri,
guint32 background_color,
int max_width,
int max_height);
+GtkWidget *eazel_services_clickable_image_new_from_uri (const char *uri,
+ const char *tile_name,
+ guint32 background_color,
+ int max_width,
+ int max_height);
GtkWidget *eazel_services_label_new (const char *text,
guint drop_shadow_offset,
float xalign,
diff --git a/components/services/nautilus-dependent-shared/eazel-services-footer.c b/components/services/nautilus-dependent-shared/eazel-services-footer.c
index aebcea1d0..1c4220772 100644
--- a/components/services/nautilus-dependent-shared/eazel-services-footer.c
+++ b/components/services/nautilus-dependent-shared/eazel-services-footer.c
@@ -318,6 +318,10 @@ eazel_services_footer_update (EazelServicesFooter *footer,
g_return_if_fail (items != NULL);
g_return_if_fail (num_items > 0);
+ gtk_container_foreach (GTK_CONTAINER (footer),
+ (GtkCallback) gtk_widget_destroy,
+ NULL);
+
for (i = 0; i < num_items; i++) {
GtkWidget *item;
diff --git a/components/services/summary/eazel-summary-shared.c b/components/services/summary/eazel-summary-shared.c
index 5a01e85cb..2a0b4e9c5 100644
--- a/components/services/summary/eazel-summary-shared.c
+++ b/components/services/summary/eazel-summary-shared.c
@@ -26,13 +26,15 @@
#include "eazel-summary-shared.h"
#include <libtrilobite/libtrilobite.h>
+#include <libtrilobite/trilobite-file-utilities.h>
#include <gnome.h>
-#include <glib.h>
#include <gnome-xml/tree.h>
#include <gnome-xml/parser.h>
+#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <ctype.h>
static GList * build_services_glist_from_xml (xmlNodePtr node);
static GList * build_eazel_news_glist_from_xml (xmlNodePtr node);
@@ -251,62 +253,48 @@ build_update_news_glist_from_xml (xmlNodePtr node)
} /* end build_update_news_glist_from_xml */
-SummaryData *
-parse_summary_xml_file (const char *url)
-{
+
+static SummaryData *
+eazel_summary_data_parse_xml (char *body,
+ int length)
+{
SummaryData *return_value;
- char *body;
- int length;
xmlDocPtr doc;
xmlNodePtr base;
xmlNodePtr child;
- /* fetch remote config file into memory */
- if (! trilobite_fetch_uri (url, &body, &length)) {
- g_assert (_("Could not fetch summary configuration !"));
- return NULL;
- }
-
/* <rant> libxml will have a temper tantrum if there is whitespace before the
* * first tag. so we must babysit it.
* */
- while ((length > 0) && (*body <= ' ')) {
+ while ((length > 0) && isspace (*body)) {
body++, length--;
}
+ body[length] = '\0';
+
doc = xmlParseMemory (body, length);
- if (doc == NULL) {
- g_warning ("Invalid data in summary configuration: %s", body);
- return NULL;
+ if (doc == NULL) {
+ return NULL;
}
- return_value = summary_data_new ();
-
base = doc->root;
- if (base == NULL) {
- xmlFreeDoc (doc);
- g_warning (_("The summary configuration contains no data!\n"));
- return NULL;
- }
-
- if (g_strcasecmp (base->name, "SUMMARY_DATA")) {
- g_print (_("Cannot find the SUMMARY_DATA xmlnode!\n"));
+ if (base == NULL ||
+ g_strcasecmp (base->name, "SUMMARY_DATA") != 0) {
xmlFreeDoc (doc);
- g_warning (_("Bailing from the SUMMARY_DATA parse!\n"));
return NULL;
}
-
- child = doc->root->xmlChildrenNode;
-
+
+ return_value = summary_data_new ();
+
+ child = base->xmlChildrenNode;
+
if (child == NULL) {
- g_print (_("Could not find any summary configuration data!\n"));
xmlFreeDoc (doc);
- g_warning (_("Bailing from summary configuration parse!\n"));
return NULL;
}
-
+
while (child) {
if (g_strcasecmp (child->name, "SERVICES") == 0) {
return_value->services_list = build_services_glist_from_xml (child);
@@ -319,8 +307,64 @@ parse_summary_xml_file (const char *url)
}
child = child->next;
}
-
+
return return_value;
+}
+
+
+struct EazelSummaryFetchHandle {
+ TrilobiteReadFileHandle *handle;
+ EazelSummaryFetchCallback callback;
+ gpointer callback_data;
+};
+
+
+
+static void
+summary_data_fetch_callback (GnomeVFSResult result,
+ GnomeVFSFileSize file_size,
+ char *file_contents,
+ gpointer callback_data)
+{
+ EazelSummaryFetchHandle *handle;
+ SummaryData *summary_data;
+
+ summary_data = NULL;
+ handle = callback_data;
+
+ if (result == GNOME_VFS_OK) {
+ summary_data = eazel_summary_data_parse_xml (file_contents,
+ file_size);
+ }
+
+ (*handle->callback) (result, summary_data, handle->callback_data);
+ g_free (handle);
+ g_free (file_contents);
+}
+
+
+EazelSummaryFetchHandle *
+eazel_summary_fetch_data_async (const char *uri,
+ EazelSummaryFetchCallback callback,
+ gpointer callback_data)
+{
+ EazelSummaryFetchHandle *handle;
+
+ handle = g_new0 (EazelSummaryFetchHandle, 1);
-} /* parse_summary_xml_file */
+ handle->callback = callback;
+ handle->callback_data = callback_data;
+
+ handle->handle = trilobite_read_entire_file_async (uri, summary_data_fetch_callback, handle);
+
+ return handle;
+}
+
+
+void
+eazel_summary_fetch_data_cancel (EazelSummaryFetchHandle *handle)
+{
+ trilobite_read_file_cancel (handle->handle);
+ g_free (handle);
+}
diff --git a/components/services/summary/eazel-summary-shared.h b/components/services/summary/eazel-summary-shared.h
index 8b70a1ad3..93ec67ce6 100644
--- a/components/services/summary/eazel-summary-shared.h
+++ b/components/services/summary/eazel-summary-shared.h
@@ -23,8 +23,8 @@
#ifndef EAZEL_SUMMARY_SHARED_H
#define EAZEL_SUAMMRY_SHARED_H
-#include <libnautilus/nautilus-view.h>
-#include <gtk/gtk.h>
+#include <libgnomevfs/gnome-vfs-types.h>
+#include <glib.h>
typedef struct _ServicesData ServicesData;
typedef struct _EazelNewsData EazelNewsData;
@@ -65,6 +65,18 @@ struct _SummaryData {
GList *update_news_list;
};
-SummaryData * parse_summary_xml_file (const char *url);
+
+typedef void (* EazelSummaryFetchCallback) (GnomeVFSResult result,
+ SummaryData *summary_data,
+ gpointer callback_data);
+
+typedef struct EazelSummaryFetchHandle EazelSummaryFetchHandle;
+
+EazelSummaryFetchHandle *eazel_summary_fetch_data_async (const char *uri,
+ EazelSummaryFetchCallback callback,
+ gpointer callback_data);
+
+void eazel_summary_fetch_data_cancel (EazelSummaryFetchHandle *handle);
+
#endif /* EAZEL_SUMMARY_SHARED_H */
diff --git a/components/services/summary/lib/eazel-summary-shared.c b/components/services/summary/lib/eazel-summary-shared.c
index 5a01e85cb..2a0b4e9c5 100644
--- a/components/services/summary/lib/eazel-summary-shared.c
+++ b/components/services/summary/lib/eazel-summary-shared.c
@@ -26,13 +26,15 @@
#include "eazel-summary-shared.h"
#include <libtrilobite/libtrilobite.h>
+#include <libtrilobite/trilobite-file-utilities.h>
#include <gnome.h>
-#include <glib.h>
#include <gnome-xml/tree.h>
#include <gnome-xml/parser.h>
+#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <ctype.h>
static GList * build_services_glist_from_xml (xmlNodePtr node);
static GList * build_eazel_news_glist_from_xml (xmlNodePtr node);
@@ -251,62 +253,48 @@ build_update_news_glist_from_xml (xmlNodePtr node)
} /* end build_update_news_glist_from_xml */
-SummaryData *
-parse_summary_xml_file (const char *url)
-{
+
+static SummaryData *
+eazel_summary_data_parse_xml (char *body,
+ int length)
+{
SummaryData *return_value;
- char *body;
- int length;
xmlDocPtr doc;
xmlNodePtr base;
xmlNodePtr child;
- /* fetch remote config file into memory */
- if (! trilobite_fetch_uri (url, &body, &length)) {
- g_assert (_("Could not fetch summary configuration !"));
- return NULL;
- }
-
/* <rant> libxml will have a temper tantrum if there is whitespace before the
* * first tag. so we must babysit it.
* */
- while ((length > 0) && (*body <= ' ')) {
+ while ((length > 0) && isspace (*body)) {
body++, length--;
}
+ body[length] = '\0';
+
doc = xmlParseMemory (body, length);
- if (doc == NULL) {
- g_warning ("Invalid data in summary configuration: %s", body);
- return NULL;
+ if (doc == NULL) {
+ return NULL;
}
- return_value = summary_data_new ();
-
base = doc->root;
- if (base == NULL) {
- xmlFreeDoc (doc);
- g_warning (_("The summary configuration contains no data!\n"));
- return NULL;
- }
-
- if (g_strcasecmp (base->name, "SUMMARY_DATA")) {
- g_print (_("Cannot find the SUMMARY_DATA xmlnode!\n"));
+ if (base == NULL ||
+ g_strcasecmp (base->name, "SUMMARY_DATA") != 0) {
xmlFreeDoc (doc);
- g_warning (_("Bailing from the SUMMARY_DATA parse!\n"));
return NULL;
}
-
- child = doc->root->xmlChildrenNode;
-
+
+ return_value = summary_data_new ();
+
+ child = base->xmlChildrenNode;
+
if (child == NULL) {
- g_print (_("Could not find any summary configuration data!\n"));
xmlFreeDoc (doc);
- g_warning (_("Bailing from summary configuration parse!\n"));
return NULL;
}
-
+
while (child) {
if (g_strcasecmp (child->name, "SERVICES") == 0) {
return_value->services_list = build_services_glist_from_xml (child);
@@ -319,8 +307,64 @@ parse_summary_xml_file (const char *url)
}
child = child->next;
}
-
+
return return_value;
+}
+
+
+struct EazelSummaryFetchHandle {
+ TrilobiteReadFileHandle *handle;
+ EazelSummaryFetchCallback callback;
+ gpointer callback_data;
+};
+
+
+
+static void
+summary_data_fetch_callback (GnomeVFSResult result,
+ GnomeVFSFileSize file_size,
+ char *file_contents,
+ gpointer callback_data)
+{
+ EazelSummaryFetchHandle *handle;
+ SummaryData *summary_data;
+
+ summary_data = NULL;
+ handle = callback_data;
+
+ if (result == GNOME_VFS_OK) {
+ summary_data = eazel_summary_data_parse_xml (file_contents,
+ file_size);
+ }
+
+ (*handle->callback) (result, summary_data, handle->callback_data);
+ g_free (handle);
+ g_free (file_contents);
+}
+
+
+EazelSummaryFetchHandle *
+eazel_summary_fetch_data_async (const char *uri,
+ EazelSummaryFetchCallback callback,
+ gpointer callback_data)
+{
+ EazelSummaryFetchHandle *handle;
+
+ handle = g_new0 (EazelSummaryFetchHandle, 1);
-} /* parse_summary_xml_file */
+ handle->callback = callback;
+ handle->callback_data = callback_data;
+
+ handle->handle = trilobite_read_entire_file_async (uri, summary_data_fetch_callback, handle);
+
+ return handle;
+}
+
+
+void
+eazel_summary_fetch_data_cancel (EazelSummaryFetchHandle *handle)
+{
+ trilobite_read_file_cancel (handle->handle);
+ g_free (handle);
+}
diff --git a/components/services/summary/lib/eazel-summary-shared.h b/components/services/summary/lib/eazel-summary-shared.h
index 8b70a1ad3..93ec67ce6 100644
--- a/components/services/summary/lib/eazel-summary-shared.h
+++ b/components/services/summary/lib/eazel-summary-shared.h
@@ -23,8 +23,8 @@
#ifndef EAZEL_SUMMARY_SHARED_H
#define EAZEL_SUAMMRY_SHARED_H
-#include <libnautilus/nautilus-view.h>
-#include <gtk/gtk.h>
+#include <libgnomevfs/gnome-vfs-types.h>
+#include <glib.h>
typedef struct _ServicesData ServicesData;
typedef struct _EazelNewsData EazelNewsData;
@@ -65,6 +65,18 @@ struct _SummaryData {
GList *update_news_list;
};
-SummaryData * parse_summary_xml_file (const char *url);
+
+typedef void (* EazelSummaryFetchCallback) (GnomeVFSResult result,
+ SummaryData *summary_data,
+ gpointer callback_data);
+
+typedef struct EazelSummaryFetchHandle EazelSummaryFetchHandle;
+
+EazelSummaryFetchHandle *eazel_summary_fetch_data_async (const char *uri,
+ EazelSummaryFetchCallback callback,
+ gpointer callback_data);
+
+void eazel_summary_fetch_data_cancel (EazelSummaryFetchHandle *handle);
+
#endif /* EAZEL_SUMMARY_SHARED_H */
diff --git a/components/services/summary/main.c b/components/services/summary/main.c
index 6f6d74da6..ccc015648 100644
--- a/components/services/summary/main.c
+++ b/components/services/summary/main.c
@@ -32,6 +32,8 @@
#include <gconf/gconf.h>
#include <libtrilobite/libammonite.h>
#include <libtrilobite/trilobite-core-messaging.h>
+#include <libtrilobite/trilobite-core-utils.h>
+#include <libgnomevfs/gnome-vfs-init.h>
static int object_count =0;
@@ -91,9 +93,12 @@ main (int argc, char *argv[])
gnome_init ("nautilus-summary-view", VERSION,
argc, argv);
-
gdk_rgb_init ();
-
+
+ trilobite_setenv ("GNOME_VFS_HTTP_USER_AGENT", trilobite_get_useragent_string (NULL), 1);
+ g_thread_init (NULL);
+ gnome_vfs_init ();
+
bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL);
gconf_init (argc, argv, NULL);
@@ -114,5 +119,10 @@ main (int argc, char *argv[])
bonobo_main ();
} while (object_count > 0);
+ /* Let the factory go. */
+ bonobo_object_unref (BONOBO_OBJECT (factory));
+
+ gnome_vfs_shutdown ();
+
return 0;
}
diff --git a/components/services/summary/nautilus-summary-callbacks.c b/components/services/summary/nautilus-summary-callbacks.c
index 5ef9e42d3..ac0ac6114 100644
--- a/components/services/summary/nautilus-summary-callbacks.c
+++ b/components/services/summary/nautilus-summary-callbacks.c
@@ -94,19 +94,19 @@ authn_cb_failed (const EazelProxy_User *user, const EazelProxy_AuthnFailInfo *in
if (info && ( info->code == EAZELPROXY_AUTHN_FAIL_NETWORK
|| info->code == EAZELPROXY_AUTHN_FAIL_SERVER)) {
- nautilus_summary_login_failure_dialog (view, _("I'm sorry, network problems are preventing you from connecting to Eazel Services."));
+ nautilus_summary_show_login_failure_dialog (view, _("Sorry, network problems are preventing you from connecting to Eazel Services."));
view->details->attempt_number = 0;
view->details->current_attempt = initial;
} else if (info && ( info->code == EAZELPROXY_AUTHN_FAIL_USER_NOT_ACTIVATED)) {
/* FIXME we really should use the services alert icon here, eh? */
- nautilus_summary_login_failure_dialog (view, _("Your Eazel Services account has not yet been activated. "
+ nautilus_summary_show_login_failure_dialog (view, _("Your Eazel Services account has not yet been activated. "
"You can't log into Eazel Services until you activate your account.\n\n"
"Please check your email for activation instructions."));
view->details->attempt_number = 0;
view->details->current_attempt = initial;
} else if (info && ( info->code == EAZELPROXY_AUTHN_FAIL_USER_DISABLED)) {
/* FIXME we really should use the services alert icon here, eh? */
- nautilus_summary_login_failure_dialog (view, _("Your Eazel Service User Account has been temporarily disabled.\n\n"
+ nautilus_summary_show_login_failure_dialog (view, _("Your Eazel Service User Account has been temporarily disabled.\n\n"
"Please try again in a few minutes, or contact Eazel support if this problem continues."));
view->details->attempt_number = 0;
view->details->current_attempt = initial;
@@ -125,7 +125,7 @@ authn_cb_failed (const EazelProxy_User *user, const EazelProxy_AuthnFailInfo *in
if (view->details->attempt_number > 0 && view->details->attempt_number < 5) {
#endif
view->details->current_attempt = retry;
- generate_login_dialog (view);
+ nautilus_summary_show_login_dialog (view);
#if 0
} else {
nautilus_summary_login_failure_dialog (view, _("We're sorry, but your name and password are still not recognized."));
diff --git a/components/services/summary/nautilus-summary-dialogs.c b/components/services/summary/nautilus-summary-dialogs.c
index 3734432de..e5d15258c 100644
--- a/components/services/summary/nautilus-summary-dialogs.c
+++ b/components/services/summary/nautilus-summary-dialogs.c
@@ -62,7 +62,8 @@ static void name_or_password_field_activated (GtkWidget *caption_table,
gpointer user_data);
void
-nautilus_summary_login_failure_dialog (NautilusSummaryView *view, const char *message)
+nautilus_summary_show_login_failure_dialog (NautilusSummaryView *view,
+ const char *message)
{
nautilus_show_error_dialog (message,
_("Eazel Service Login Error"),
@@ -70,7 +71,8 @@ nautilus_summary_login_failure_dialog (NautilusSummaryView *view, const char *me
}
void
-generate_error_dialog (NautilusSummaryView *view, const char *message)
+nautilus_summary_show_error_dialog (NautilusSummaryView *view,
+ const char *message)
{
GnomeDialog *dialog;
@@ -84,7 +86,7 @@ generate_error_dialog (NautilusSummaryView *view, const char *message)
}
void
-generate_login_dialog (NautilusSummaryView *view)
+nautilus_summary_show_login_dialog (NautilusSummaryView *view)
{
GnomeDialog *dialog;
GtkWidget *hbox;
@@ -225,12 +227,10 @@ widget_set_nautilus_background_color (GtkWidget *widget, const char *color)
/* callback to handle cancel error_dialog button. */
static void
-error_dialog_cancel_cb (GtkWidget *button, NautilusSummaryView *view)
+error_dialog_cancel_cb (GtkWidget *button,
+ NautilusSummaryView *view)
{
- char *user_home;
- user_home = nautilus_get_user_main_directory ();
- nautilus_view_open_location_in_this_window (view->details->nautilus_view, user_home);
- g_free (user_home);
+ nautilus_view_go_back (view->details->nautilus_view);
}
static GtkWindow *
@@ -251,14 +251,40 @@ get_window_from_summary_view (NautilusSummaryView *view)
static void
set_dialog_parent (NautilusSummaryView *view, GnomeDialog *dialog)
{
- GtkWindow *parent_window;
+ GtkWindow *parent;
g_assert (NAUTILUS_IS_SUMMARY_VIEW (view));
g_assert (GNOME_IS_DIALOG (dialog));
- parent_window = get_window_from_summary_view (view);
- if (parent_window != NULL) {
- gnome_dialog_set_parent (dialog, parent_window);
+ parent = get_window_from_summary_view (view);
+ if (parent != NULL && gnome_preferences_get_dialog_centered ()) {
+ /* User wants us to center over parent */
+
+ /* FIXME: this is cut and pasted from gnome-dialog.h,
+ * because calling gnome_dialog_set_parent would make
+ * the dialog transient for the summary view's plug
+ * widget, not the top level window, thus making it
+ * not get focus.
+ */
+ gint x, y, w, h, dialog_x, dialog_y;
+
+ if (!GTK_WIDGET_VISIBLE (parent)) return; /* Can't get its
+ size/pos */
+
+ /* Throw out other positioning */
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_NONE);
+
+ gdk_window_get_origin (GTK_WIDGET (parent)->window, &x, &y);
+ gdk_window_get_size (GTK_WIDGET (parent)->window, &w, &h);
+
+ /* The problem here is we don't know how big the dialog is.
+ So "centered" isn't really true. We'll go with
+ "kind of more or less on top" */
+
+ dialog_x = x + w/4;
+ dialog_y = y + h/4;
+
+ gtk_widget_set_uposition (GTK_WIDGET (dialog), dialog_x, dialog_y);
}
}
diff --git a/components/services/summary/nautilus-summary-dialogs.h b/components/services/summary/nautilus-summary-dialogs.h
index a979d5499..44dfa48c2 100644
--- a/components/services/summary/nautilus-summary-dialogs.h
+++ b/components/services/summary/nautilus-summary-dialogs.h
@@ -23,14 +23,14 @@
#ifndef NAUTILUS_SUMMARY_DIALOGS_H
#define NAUTILUS_SUMMARY_DIALOGS_H
-void nautilus_summary_login_failure_dialog (NautilusSummaryView *view,
- const char *message);
+void nautilus_summary_show_login_failure_dialog (NautilusSummaryView *view,
+ const char *message);
-void generate_error_dialog (NautilusSummaryView *view,
- const char *message);
-void generate_login_dialog (NautilusSummaryView *view);
-void widget_set_nautilus_background_color (GtkWidget *widget,
- const char *color);
+void nautilus_summary_show_error_dialog (NautilusSummaryView *view,
+ const char *message);
+void nautilus_summary_show_login_dialog (NautilusSummaryView *view);
+void widget_set_nautilus_background_color (GtkWidget *widget,
+ const char *color);
#endif /* NAUTILUS_SUMMARY_DIALOGS_H */
diff --git a/components/services/summary/nautilus-summary-footer.c b/components/services/summary/nautilus-summary-footer.c
index 22bbf2fdf..98bfc1ca5 100644
--- a/components/services/summary/nautilus-summary-footer.c
+++ b/components/services/summary/nautilus-summary-footer.c
@@ -90,7 +90,7 @@ footer_item_clicked_callback (GtkWidget *widget, int index, gpointer callback_da
case FOOTER_LOGIN_OR_LOGOUT:
if (!view->details->logged_in) {
- generate_login_dialog (view);
+ nautilus_summary_show_login_dialog (view);
} else {
logout_button_cb (NULL, view);
}
diff --git a/components/services/summary/nautilus-summary-menu-items.c b/components/services/summary/nautilus-summary-menu-items.c
index 4869b458d..3137e59a9 100644
--- a/components/services/summary/nautilus-summary-menu-items.c
+++ b/components/services/summary/nautilus-summary-menu-items.c
@@ -164,7 +164,7 @@ bonobo_login_callback (BonoboUIComponent *ui, gpointer user_data, const char *ve
NautilusSummaryView *view;
view = NAUTILUS_SUMMARY_VIEW (user_data);
- generate_login_dialog (view);
+ nautilus_summary_show_login_dialog (view);
}
static void
diff --git a/components/services/summary/nautilus-summary-view-private.h b/components/services/summary/nautilus-summary-view-private.h
index 2aad3c5b8..84e85b06b 100644
--- a/components/services/summary/nautilus-summary-view-private.h
+++ b/components/services/summary/nautilus-summary-view-private.h
@@ -25,6 +25,8 @@
#include <libtrilobite/libammonite.h>
+#include <libtrilobite/trilobite-redirect.h>
+
#include <gnome.h>
#define DEFAULT_SUMMARY_BACKGROUND_COLOR_SPEC "rgb:FFFF/FFFF/FFFF"
@@ -70,8 +72,6 @@ enum {
LOGIN_DIALOG_CANCEL_BUTTON
};
-typedef struct _ServicesButtonCallbackData ServicesButtonCallbackData;
-
typedef enum {
Pending_None,
Pending_Login,
@@ -84,11 +84,6 @@ typedef enum {
} SummaryLoginAttemptType;
-struct _ServicesButtonCallbackData {
- NautilusView *nautilus_view;
- char *uri;
-};
-
/* A NautilusContentView's private information. */
struct _NautilusSummaryViewDetails {
char *uri;
@@ -118,23 +113,12 @@ struct _NautilusSummaryViewDetails {
SummaryPendingOperationType pending_operation;
EazelProxy_AuthnCallback authn_callback;
- /* Login Frame Widgets */
+ /* Login Dialog */
GnomeDialog *login_dialog;
- GtkWidget *username_label;
- GtkWidget *password_label;
- GtkWidget *username_entry;
- GtkWidget *password_entry;
- /* Buttons available if user is not logged in */
- GtkWidget *login_button;
- GtkWidget *login_label;
- GtkWidget *register_button;
- GtkWidget *register_label;
- /* Buttons available if user is logged in */
- GtkWidget *preferences_button;
- GtkWidget *preferences_label;
- GtkWidget *logout_button;
- GtkWidget *logout_label;
+ /* Async XML fetch handles */
+ TrilobiteRedirectFetchHandle *redirect_fetch_handle;
+ EazelSummaryFetchHandle *summary_fetch_handle;
};
diff --git a/components/services/summary/nautilus-summary-view.c b/components/services/summary/nautilus-summary-view.c
index 1e4d5f560..263925301 100644
--- a/components/services/summary/nautilus-summary-view.c
+++ b/components/services/summary/nautilus-summary-view.c
@@ -38,6 +38,7 @@
#include "eazel-services-header.h"
#include "eazel-services-extensions.h"
+#include <libnautilus-extensions/nautilus-clickable-image.h>
#include <libnautilus-extensions/nautilus-background.h>
#include <libnautilus-extensions/nautilus-bonobo-extensions.h>
#include <libnautilus-extensions/nautilus-file-utilities.h>
@@ -75,9 +76,12 @@
#define SUMMARY_TEXT_HEADER_SIZE_REL (0)
#define SUMMARY_TEXT_BODY_SIZE_REL (-2)
+typedef struct ServicesButtonCallbackData ServicesButtonCallbackData;
-
-
+struct ServicesButtonCallbackData {
+ NautilusView *view;
+ char *uri;
+};
static void nautilus_summary_view_initialize_class (NautilusSummaryViewClass *klass);
static void nautilus_summary_view_initialize (NautilusSummaryView *view);
@@ -85,8 +89,9 @@ static void nautilus_summary_view_destroy (GtkObject
static void summary_load_location_callback (NautilusView *nautilus_view,
const char *location,
NautilusSummaryView *view);
-static void generate_summary_form (NautilusSummaryView *view);
-static GtkWidget *generate_eazel_news_entry_row (NautilusSummaryView *view,
+static void summary_stop_loading_callback (NautilusView *nautilus_view,
+ NautilusSummaryView *view);
+static GtkWidget * generate_eazel_news_entry_row (NautilusSummaryView *view,
void *data);
static GtkWidget * generate_service_entry_row (NautilusSummaryView *view,
void *data);
@@ -94,21 +99,23 @@ static GtkWidget * generate_update_news_entry_row (NautilusSummaryView
void *data);
static void summary_view_button_callback (GtkWidget *button,
ServicesButtonCallbackData *cbdata);
+static void cancel_load_in_progress (NautilusSummaryView *view);
+
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusSummaryView, nautilus_summary_view, GTK_TYPE_EVENT_BOX)
static const char *footer_online_items[] =
{
- N_("Register"),
- N_("Login"),
+ N_("Account Preferences"),
+ N_("Logout"),
N_("Terms of Use"),
N_("Privacy Statement")
};
static const char *footer_offline_items[] =
{
- N_("Account Preferences"),
- N_("Logout"),
+ N_("Register"),
+ N_("Login"),
N_("Terms of Use"),
N_("Privacy Statement")
};
@@ -133,8 +140,7 @@ update_header (NautilusSummaryView *view)
static void
create_header (NautilusSummaryView *view)
{
- view->details->header = eazel_services_header_title_new ("");
- update_header (view);
+ view->details->header = eazel_services_header_title_new (_("Connecting to Eazel Services..."));
}
@@ -143,12 +149,12 @@ update_footer (NautilusSummaryView *view)
{
if (view->details->logged_in) {
eazel_services_footer_update (EAZEL_SERVICES_FOOTER (view->details->footer),
- footer_offline_items,
- NAUTILUS_N_ELEMENTS (footer_offline_items));
- } else {
- eazel_services_footer_update (EAZEL_SERVICES_FOOTER (view->details->footer),
footer_online_items,
NAUTILUS_N_ELEMENTS (footer_online_items));
+ } else {
+ eazel_services_footer_update (EAZEL_SERVICES_FOOTER (view->details->footer),
+ footer_offline_items,
+ NAUTILUS_N_ELEMENTS (footer_offline_items));
}
}
@@ -157,34 +163,56 @@ create_footer (NautilusSummaryView *view)
{
view->details->footer = eazel_services_footer_new ();
+ eazel_services_footer_update (EAZEL_SERVICES_FOOTER (view->details->footer),
+ footer_offline_items,
+ NAUTILUS_N_ELEMENTS (footer_offline_items));
+
gtk_signal_connect (GTK_OBJECT (view->details->footer), "item_clicked",
GTK_SIGNAL_FUNC (footer_item_clicked_callback), view);
-
- update_footer (view);
}
+static void
+services_button_callback_data_free (ServicesButtonCallbackData *cbdata)
+{
+ g_free (cbdata->uri);
+ g_free (cbdata);
+}
+
-/* callback to handle the goto a service button. */
static void
summary_view_button_callback (GtkWidget *button,
ServicesButtonCallbackData *cbdata)
{
- nautilus_view_open_location_in_this_window (cbdata->nautilus_view, cbdata->uri);
+ nautilus_view_open_location_in_this_window (cbdata->view, cbdata->uri);
+}
+
+static void
+goto_uri_on_clicked (GtkWidget *widget,
+ NautilusView *view,
+ const char *uri)
+{
+ ServicesButtonCallbackData *cbdata;
+
+ cbdata = g_new0 (ServicesButtonCallbackData, 1);
+ cbdata->view = view;
+ cbdata->uri = g_strdup (uri);
+
+ gtk_signal_connect_full (GTK_OBJECT (widget), "clicked",
+ GTK_SIGNAL_FUNC (summary_view_button_callback), NULL,
+ cbdata, (GtkDestroyNotify) services_button_callback_data_free,
+ FALSE, FALSE);
}
static GtkWidget *
summary_view_button_new (char *label_text,
NautilusView *view,
- char *uri)
+ const char *uri)
{
GtkWidget *button;
GtkWidget *label;
- ServicesButtonCallbackData *cbdata;
-
- cbdata = g_new0 (ServicesButtonCallbackData, 1);
-
+
button = gtk_button_new ();
/* FIXME: hardcoded width! */
gtk_widget_set_usize (button, 80, -1);
@@ -193,18 +221,31 @@ summary_view_button_new (char *label_text,
gtk_widget_show (label);
gtk_container_add (GTK_CONTAINER (button), label);
- cbdata->nautilus_view = view;
- cbdata->uri = uri;
-
- /* FIXME: g_free won't free all the data */
- gtk_signal_connect_full (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (summary_view_button_callback), NULL,
- cbdata, g_free, FALSE, FALSE);
+ goto_uri_on_clicked (button, view, uri);
return button;
}
static GtkWidget *
+summary_view_link_image_new (NautilusSummaryView *view,
+ const char *image_uri,
+ const char *click_uri)
+{
+ GtkWidget *image;
+
+ image = eazel_services_clickable_image_new_from_uri (image_uri,
+ NULL,
+ DEFAULT_SUMMARY_BACKGROUND_COLOR_RGB,
+ MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);
+ nautilus_clickable_image_set_prelight (NAUTILUS_CLICKABLE_IMAGE (image), TRUE);
+
+ goto_uri_on_clicked (image, view->details->nautilus_view, click_uri);
+
+ return image;
+}
+
+
+static GtkWidget *
summary_view_item_label_new (char *label_text,
int relative_font_size,
gboolean bold)
@@ -264,6 +305,8 @@ append_hseparator_to_vbox (GtkWidget *vbox)
}
+
+
static GtkWidget *
generate_eazel_news_entry_row (NautilusSummaryView *view,
void *data)
@@ -387,7 +430,6 @@ create_news_pane (NautilusSummaryView *view)
{
view->details->news_pane = summary_view_create_pane
(view, &view->details->news_item_vbox);
- update_news_pane (view);
}
@@ -416,11 +458,9 @@ generate_service_entry_row (NautilusSummaryView *view,
gtk_widget_show (icon_box);
- icon = eazel_services_image_new_from_uri (services_node->icon,
- NULL,
- DEFAULT_SUMMARY_BACKGROUND_COLOR_RGB,
- MAX_IMAGE_WIDTH,
- MAX_IMAGE_HEIGHT);
+ icon = summary_view_link_image_new (view,
+ services_node->icon,
+ services_node->uri);
gtk_widget_show (icon);
gtk_box_pack_start (GTK_BOX (icon_box), icon, FALSE, FALSE, 0);
@@ -479,7 +519,6 @@ create_services_list_pane (NautilusSummaryView *view)
{
view->details->services_list_pane = summary_view_create_pane
(view, &view->details->services_list_vbox);
- update_services_list_pane (view);
}
@@ -510,12 +549,9 @@ generate_update_news_entry_row (NautilusSummaryView *view,
gtk_widget_show (icon_box);
gtk_box_pack_start (GTK_BOX (update_row), icon_box, FALSE, FALSE, 0);
- icon = eazel_services_image_new_from_uri (update_node->icon,
- NULL,
- DEFAULT_SUMMARY_BACKGROUND_COLOR_RGB,
- MAX_IMAGE_WIDTH,
- MAX_IMAGE_HEIGHT);
-
+ icon = summary_view_link_image_new (view,
+ update_node->icon,
+ update_node->softcat_uri);
gtk_widget_show (icon);
gtk_box_pack_start (GTK_BOX (icon_box), icon, FALSE, FALSE, 0);
@@ -596,139 +632,72 @@ create_featured_downloads_pane (NautilusSummaryView *view)
{
view->details->featured_downloads_pane = summary_view_create_pane
(view, &view->details->featured_downloads_vbox);
+}
+
+
+static void
+update_summary_form (NautilusSummaryView *view,
+ SummaryData *xml_data)
+{
+ view->details->xml_data = xml_data;
+
+ update_header (view);
+ update_news_pane (view);
+ update_services_list_pane (view);
update_featured_downloads_pane (view);
+ update_footer (view);
}
static void
-generate_summary_form (NautilusSummaryView *view)
+create_summary_form (NautilusSummaryView *view)
{
- GtkWidget *notebook;
GtkWidget *notebook_tabs;
- GtkWidget *notebook_vbox;
- if (view->details->form != NULL) {
- gtk_container_remove (GTK_CONTAINER (view), view->details->form);
- view->details->form = NULL;
- }
-
-#ifdef DEBUG_pepper
- g_print ("Start summary view load.\n");
-
-#endif
/* allocate the parent box to hold everything */
view->details->form = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (view), view->details->form);
- /* setup the title */
-#ifdef DEBUG_pepper
- g_print ("Start title load.\n");
-#endif
-
create_header (view);
-
gtk_box_pack_start (GTK_BOX (view->details->form), view->details->header, FALSE, FALSE, 0);
gtk_widget_show (view->details->header);
-#ifdef DEBUG_pepper
- g_print ("end title load.\n");
-#endif
-
-
-#ifdef DEBUG_pepper
- g_print ("start news load.\n");
-#endif
+ /* Create the News pane */
create_news_pane (view);
- gtk_box_pack_start (GTK_BOX (view->details->form), view->details->news_pane, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (view->details->form), view->details->news_pane, FALSE, FALSE, 0);
gtk_widget_show (view->details->news_pane);
-
-#ifdef DEBUG_pepper
- g_print ("end news load.\n");
-#endif
-
- /* add a set of tabs to control the notebook page switching */
-#ifdef DEBUG_pepper
- g_print ("start tab load.\n");
-#endif
+ /* Header for Services pane */
notebook_tabs = nautilus_tabs_new ();
+ nautilus_tabs_add_tab (NAUTILUS_TABS (notebook_tabs), _("Services"), 0);
gtk_widget_show (notebook_tabs);
gtk_box_pack_start (GTK_BOX (view->details->form), notebook_tabs, FALSE, FALSE, 0);
- /* Create the notebook container for services */
- notebook = gtk_notebook_new ();
- gtk_widget_show (notebook);
- gtk_box_pack_start (GTK_BOX (view->details->form), notebook, TRUE, TRUE, 0);
-
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
-
- /* add the tab */
- nautilus_tabs_add_tab (NAUTILUS_TABS (notebook_tabs), _("Services"), 0);
-#ifdef DEBUG_pepper
- g_print ("end tab load.\n");
-#endif
-
- /* Create the Services Listing Box */
-#ifdef DEBUG_pepper
- g_print ("start services load.\n");
-#endif
+ /* Create the Services pane */
create_services_list_pane (view);
gtk_widget_show (view->details->services_list_pane);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), view->details->services_list_pane, NULL);
+ gtk_box_pack_start (GTK_BOX (view->details->form), view->details->services_list_pane, TRUE, TRUE, 0);
-#ifdef DEBUG_pepper
- g_print ("end services load.\n");
-#endif
-
- /* Create the notebook container for updates */
-#ifdef DEBUG_pepper
- g_print ("start updates load.\n");
-#endif
- /* add a set of tabs to control the updates page switching */
- notebook_vbox = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (notebook_vbox);
+ /* Header for Featured Downloads pane */
notebook_tabs = nautilus_tabs_new ();
- gtk_widget_show (notebook_tabs);
- gtk_box_pack_start (GTK_BOX (notebook_vbox), notebook_tabs, FALSE, FALSE, 0);
-
- notebook = gtk_notebook_new ();
- gtk_widget_show (notebook);
- gtk_container_add (GTK_CONTAINER (notebook_vbox), notebook);
- gtk_box_pack_start (GTK_BOX (view->details->form), notebook_vbox, TRUE, TRUE, 0);
-
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
-
- /* add the tab */
nautilus_tabs_add_tab (NAUTILUS_TABS (notebook_tabs), _("Featured Downloads"), 0);
+ gtk_widget_show (notebook_tabs);
+ gtk_box_pack_start (GTK_BOX (view->details->form), notebook_tabs, FALSE, FALSE, 0);
- /* Create the Update News Frame */
+ /* Create the Featured Downloads pane */
create_featured_downloads_pane (view);
-
gtk_widget_show (view->details->featured_downloads_pane);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), view->details->featured_downloads_pane, NULL);
-
-#ifdef DEBUG_pepper
- g_print ("end updates load.\n");
-
- g_print ("start footer load.\n");
-#endif
+ gtk_box_pack_start (GTK_BOX (view->details->form), view->details->featured_downloads_pane, TRUE, TRUE, 0);
create_footer (view);
gtk_widget_show (view->details->footer);
-
gtk_box_pack_start (GTK_BOX (view->details->form),
view->details->footer,
FALSE, FALSE, 0);
-#ifdef DEBUG_pepper
- g_print ("end footer load.\n");
-#endif
/* Finally, show the form that hold everything */
gtk_widget_show (view->details->form);
-#ifdef DEBUG_pepper
- g_print ("Load summary view end.\n");
-#endif
}
@@ -761,6 +730,13 @@ nautilus_summary_view_initialize (NautilusSummaryView *view)
GTK_SIGNAL_FUNC (summary_load_location_callback),
view);
+ gtk_signal_connect (GTK_OBJECT (view->details->nautilus_view),
+ "stop_loading",
+ GTK_SIGNAL_FUNC (summary_stop_loading_callback),
+ view);
+
+
+
view->details->user_control = ammonite_get_user_control ();
if (CORBA_NO_EXCEPTION != ev._major) {
@@ -776,6 +752,8 @@ nautilus_summary_view_initialize (NautilusSummaryView *view)
merge_bonobo_menu_items,
view);
+ create_summary_form (view);
+
gtk_widget_show (GTK_WIDGET (view));
CORBA_exception_free (&ev);
@@ -786,13 +764,15 @@ static void
nautilus_summary_view_destroy (GtkObject *object)
{
- NautilusSummaryView *view;
+ NautilusSummaryView *view;
CORBA_Environment ev;
CORBA_exception_init (&ev);
view = NAUTILUS_SUMMARY_VIEW (object);
+ cancel_load_in_progress (view);
+
if (view->details->uri) {
g_free (view->details->uri);
}
@@ -816,83 +796,130 @@ nautilus_summary_view_get_nautilus_view (NautilusSummaryView *view)
}
+static void
+summary_fetch_callback (GnomeVFSResult result,
+ SummaryData *xml_data,
+ gpointer callback_data)
+{
+ NautilusSummaryView *view;
+
+ view = NAUTILUS_SUMMARY_VIEW (callback_data);
+ view->details->summary_fetch_handle = NULL;
+
+ if (result != GNOME_VFS_OK) {
+ nautilus_summary_show_error_dialog
+ (view, _("Unable to get services data from Eazel's server. "
+ "The server might be unavailable right now, "
+ "or your computer might be configured incorrectly."
+ "Please contact support@eazel.com."));
+ return;
+ }
+
+
+ if (xml_data == NULL) {
+ nautilus_summary_show_error_dialog
+ (view, _("Found a problem with services data on Eazel servers. "
+ "Please contact support@eazel.com."));
+ return;
+ }
+
+ update_summary_form (view, xml_data);
+
+ if (!view->details->logged_in) {
+ nautilus_summary_show_login_dialog (view);
+ }
+
+ nautilus_view_report_load_complete (view->details->nautilus_view);
+}
+
+
+static void
+redirect_fetch_callback (GnomeVFSResult result,
+ gboolean parsed_xml,
+ gpointer callback_data)
+{
+ NautilusSummaryView *view;
+ char *uri;
+
+ view = NAUTILUS_SUMMARY_VIEW (callback_data);
+
+ view->details->redirect_fetch_handle = NULL;
+
+ if (result != GNOME_VFS_OK) {
+ nautilus_summary_show_error_dialog
+ (view, _("Unable to connect to Eazel's server. "
+ "The server might be unavailable right now, "
+ "or your computer might be configured incorrectly."
+ "You could try again later."));
+ return;
+ }
+
+
+ if (!parsed_xml) {
+ nautilus_summary_show_error_dialog
+ (view, _("Found a problem with redirect data on Eazel servers. "
+ "Please contact support@eazel.com."));
+ return;
+ }
+
+ /* Read and parse summary view XML */
+
+ uri = trilobite_redirect_lookup (SUMMARY_XML_KEY);
+
+ if (uri == NULL) {
+ nautilus_summary_show_error_dialog
+ (view, _("Information is missing from the redirect data on Eazel servers. "
+ "Please contact support@eazel.com."));
+ return;
+ }
+
+
+ view->details->summary_fetch_handle = eazel_summary_fetch_data_async
+ (uri, summary_fetch_callback, view);
+ g_free (uri);
+}
+
+
+
+
+static void
+cancel_load_in_progress (NautilusSummaryView *view)
+{
+ if (view->details->redirect_fetch_handle != NULL) {
+ trilobite_redirect_fetch_table_cancel (view->details->redirect_fetch_handle);
+ view->details->redirect_fetch_handle = NULL;
+ }
+
+ if (view->details->summary_fetch_handle != NULL) {
+ eazel_summary_fetch_data_cancel (view->details->summary_fetch_handle);
+ view->details->summary_fetch_handle = NULL;
+ }
+}
+
void
nautilus_summary_view_load_uri (NautilusSummaryView *view,
const char *uri)
{
- char *url;
char *user_name;
- gboolean got_url_table;
-
- url = NULL;
/* set up some sanity values for error control */
view->details->attempt_number = 0;
view->details->current_attempt = initial;
- /* dispose of any old uri and copy in the new one */
g_free (view->details->uri);
view->details->uri = g_strdup (uri);
- /* get xml data and verify network connections */
-#ifdef DEBUG_pepper
- g_print ("start load\n");
-#endif
-
user_name = ammonite_get_default_user_username ();
view->details->logged_in = (NULL != user_name);
g_free (user_name);
user_name = NULL;
-#ifdef DEBUG_pepper
- g_print ("start xml table fetch\n");
-#endif
- got_url_table = trilobite_redirect_fetch_table
- (view->details->logged_in
- ? URL_REDIRECT_TABLE_HOME_2
- : URL_REDIRECT_TABLE_HOME);
-
- if (!got_url_table) {
- /* FIXME bugzilla.eazel.com 3743:
- * We should do more to figure out why this failed so we can
- * present a much more helpful message. There are several different
- * reasons why it might have failed.
- */
- generate_error_dialog
- (view, _("Unable to connect to Eazel's server. "
- "The server might be unavailable right now, "
- "or your computer might be configured incorrectly."
- "You could try again later."));
- } else {
-#ifdef DEBUG_pepper
- g_print ("end xml table fetch\n");
- /* fetch and parse the xml file */
- g_print ("start xml config fetch\n");
-#endif
- url = trilobite_redirect_lookup (SUMMARY_XML_KEY);
- if (!url) {
- g_assert ("Failed to get summary xml home !\n");
- }
- view->details->xml_data = parse_summary_xml_file (url);
- g_free (url);
- if (view->details->xml_data == NULL) {
- generate_error_dialog
- (view, _("Found problem with data on Eazel servers. "
- "Please contact support@eazel.com."));
- } else {
-#ifdef DEBUG_pepper
- g_print ("end xml config fetch\n");
- g_print ("start summary draw\n");
-#endif
- generate_summary_form (view);
-#ifdef DEBUG_pepper
- g_print ("end summary draw\n");
-#endif
- if (!view->details->logged_in) {
- generate_login_dialog (view);
- }
- }
- }
+ cancel_load_in_progress (view);
+
+ view->details->redirect_fetch_handle = trilobite_redirect_fetch_table_async
+ (view->details->logged_in ? URL_REDIRECT_TABLE_HOME_2 : URL_REDIRECT_TABLE_HOME,
+ redirect_fetch_callback,
+ view);
}
static void
@@ -907,6 +934,14 @@ summary_load_location_callback (NautilusView *nautilus_view,
nautilus_view_set_title (nautilus_view, "Eazel Services");
nautilus_summary_view_load_uri (view, location);
+}
- nautilus_view_report_load_complete (nautilus_view);
+
+
+static void
+summary_stop_loading_callback (NautilusView *nautilus_view,
+ NautilusSummaryView *view)
+
+{
+ cancel_load_in_progress (view);
}
diff --git a/components/services/summary/nautilus-view/main.c b/components/services/summary/nautilus-view/main.c
index 6f6d74da6..ccc015648 100644
--- a/components/services/summary/nautilus-view/main.c
+++ b/components/services/summary/nautilus-view/main.c
@@ -32,6 +32,8 @@
#include <gconf/gconf.h>
#include <libtrilobite/libammonite.h>
#include <libtrilobite/trilobite-core-messaging.h>
+#include <libtrilobite/trilobite-core-utils.h>
+#include <libgnomevfs/gnome-vfs-init.h>
static int object_count =0;
@@ -91,9 +93,12 @@ main (int argc, char *argv[])
gnome_init ("nautilus-summary-view", VERSION,
argc, argv);
-
gdk_rgb_init ();
-
+
+ trilobite_setenv ("GNOME_VFS_HTTP_USER_AGENT", trilobite_get_useragent_string (NULL), 1);
+ g_thread_init (NULL);
+ gnome_vfs_init ();
+
bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL);
gconf_init (argc, argv, NULL);
@@ -114,5 +119,10 @@ main (int argc, char *argv[])
bonobo_main ();
} while (object_count > 0);
+ /* Let the factory go. */
+ bonobo_object_unref (BONOBO_OBJECT (factory));
+
+ gnome_vfs_shutdown ();
+
return 0;
}
diff --git a/components/services/summary/nautilus-view/nautilus-summary-callbacks.c b/components/services/summary/nautilus-view/nautilus-summary-callbacks.c
index 5ef9e42d3..ac0ac6114 100644
--- a/components/services/summary/nautilus-view/nautilus-summary-callbacks.c
+++ b/components/services/summary/nautilus-view/nautilus-summary-callbacks.c
@@ -94,19 +94,19 @@ authn_cb_failed (const EazelProxy_User *user, const EazelProxy_AuthnFailInfo *in
if (info && ( info->code == EAZELPROXY_AUTHN_FAIL_NETWORK
|| info->code == EAZELPROXY_AUTHN_FAIL_SERVER)) {
- nautilus_summary_login_failure_dialog (view, _("I'm sorry, network problems are preventing you from connecting to Eazel Services."));
+ nautilus_summary_show_login_failure_dialog (view, _("Sorry, network problems are preventing you from connecting to Eazel Services."));
view->details->attempt_number = 0;
view->details->current_attempt = initial;
} else if (info && ( info->code == EAZELPROXY_AUTHN_FAIL_USER_NOT_ACTIVATED)) {
/* FIXME we really should use the services alert icon here, eh? */
- nautilus_summary_login_failure_dialog (view, _("Your Eazel Services account has not yet been activated. "
+ nautilus_summary_show_login_failure_dialog (view, _("Your Eazel Services account has not yet been activated. "
"You can't log into Eazel Services until you activate your account.\n\n"
"Please check your email for activation instructions."));
view->details->attempt_number = 0;
view->details->current_attempt = initial;
} else if (info && ( info->code == EAZELPROXY_AUTHN_FAIL_USER_DISABLED)) {
/* FIXME we really should use the services alert icon here, eh? */
- nautilus_summary_login_failure_dialog (view, _("Your Eazel Service User Account has been temporarily disabled.\n\n"
+ nautilus_summary_show_login_failure_dialog (view, _("Your Eazel Service User Account has been temporarily disabled.\n\n"
"Please try again in a few minutes, or contact Eazel support if this problem continues."));
view->details->attempt_number = 0;
view->details->current_attempt = initial;
@@ -125,7 +125,7 @@ authn_cb_failed (const EazelProxy_User *user, const EazelProxy_AuthnFailInfo *in
if (view->details->attempt_number > 0 && view->details->attempt_number < 5) {
#endif
view->details->current_attempt = retry;
- generate_login_dialog (view);
+ nautilus_summary_show_login_dialog (view);
#if 0
} else {
nautilus_summary_login_failure_dialog (view, _("We're sorry, but your name and password are still not recognized."));
diff --git a/components/services/summary/nautilus-view/nautilus-summary-dialogs.c b/components/services/summary/nautilus-view/nautilus-summary-dialogs.c
index 3734432de..e5d15258c 100644
--- a/components/services/summary/nautilus-view/nautilus-summary-dialogs.c
+++ b/components/services/summary/nautilus-view/nautilus-summary-dialogs.c
@@ -62,7 +62,8 @@ static void name_or_password_field_activated (GtkWidget *caption_table,
gpointer user_data);
void
-nautilus_summary_login_failure_dialog (NautilusSummaryView *view, const char *message)
+nautilus_summary_show_login_failure_dialog (NautilusSummaryView *view,
+ const char *message)
{
nautilus_show_error_dialog (message,
_("Eazel Service Login Error"),
@@ -70,7 +71,8 @@ nautilus_summary_login_failure_dialog (NautilusSummaryView *view, const char *me
}
void
-generate_error_dialog (NautilusSummaryView *view, const char *message)
+nautilus_summary_show_error_dialog (NautilusSummaryView *view,
+ const char *message)
{
GnomeDialog *dialog;
@@ -84,7 +86,7 @@ generate_error_dialog (NautilusSummaryView *view, const char *message)
}
void
-generate_login_dialog (NautilusSummaryView *view)
+nautilus_summary_show_login_dialog (NautilusSummaryView *view)
{
GnomeDialog *dialog;
GtkWidget *hbox;
@@ -225,12 +227,10 @@ widget_set_nautilus_background_color (GtkWidget *widget, const char *color)
/* callback to handle cancel error_dialog button. */
static void
-error_dialog_cancel_cb (GtkWidget *button, NautilusSummaryView *view)
+error_dialog_cancel_cb (GtkWidget *button,
+ NautilusSummaryView *view)
{
- char *user_home;
- user_home = nautilus_get_user_main_directory ();
- nautilus_view_open_location_in_this_window (view->details->nautilus_view, user_home);
- g_free (user_home);
+ nautilus_view_go_back (view->details->nautilus_view);
}
static GtkWindow *
@@ -251,14 +251,40 @@ get_window_from_summary_view (NautilusSummaryView *view)
static void
set_dialog_parent (NautilusSummaryView *view, GnomeDialog *dialog)
{
- GtkWindow *parent_window;
+ GtkWindow *parent;
g_assert (NAUTILUS_IS_SUMMARY_VIEW (view));
g_assert (GNOME_IS_DIALOG (dialog));
- parent_window = get_window_from_summary_view (view);
- if (parent_window != NULL) {
- gnome_dialog_set_parent (dialog, parent_window);
+ parent = get_window_from_summary_view (view);
+ if (parent != NULL && gnome_preferences_get_dialog_centered ()) {
+ /* User wants us to center over parent */
+
+ /* FIXME: this is cut and pasted from gnome-dialog.h,
+ * because calling gnome_dialog_set_parent would make
+ * the dialog transient for the summary view's plug
+ * widget, not the top level window, thus making it
+ * not get focus.
+ */
+ gint x, y, w, h, dialog_x, dialog_y;
+
+ if (!GTK_WIDGET_VISIBLE (parent)) return; /* Can't get its
+ size/pos */
+
+ /* Throw out other positioning */
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_NONE);
+
+ gdk_window_get_origin (GTK_WIDGET (parent)->window, &x, &y);
+ gdk_window_get_size (GTK_WIDGET (parent)->window, &w, &h);
+
+ /* The problem here is we don't know how big the dialog is.
+ So "centered" isn't really true. We'll go with
+ "kind of more or less on top" */
+
+ dialog_x = x + w/4;
+ dialog_y = y + h/4;
+
+ gtk_widget_set_uposition (GTK_WIDGET (dialog), dialog_x, dialog_y);
}
}
diff --git a/components/services/summary/nautilus-view/nautilus-summary-dialogs.h b/components/services/summary/nautilus-view/nautilus-summary-dialogs.h
index a979d5499..44dfa48c2 100644
--- a/components/services/summary/nautilus-view/nautilus-summary-dialogs.h
+++ b/components/services/summary/nautilus-view/nautilus-summary-dialogs.h
@@ -23,14 +23,14 @@
#ifndef NAUTILUS_SUMMARY_DIALOGS_H
#define NAUTILUS_SUMMARY_DIALOGS_H
-void nautilus_summary_login_failure_dialog (NautilusSummaryView *view,
- const char *message);
+void nautilus_summary_show_login_failure_dialog (NautilusSummaryView *view,
+ const char *message);
-void generate_error_dialog (NautilusSummaryView *view,
- const char *message);
-void generate_login_dialog (NautilusSummaryView *view);
-void widget_set_nautilus_background_color (GtkWidget *widget,
- const char *color);
+void nautilus_summary_show_error_dialog (NautilusSummaryView *view,
+ const char *message);
+void nautilus_summary_show_login_dialog (NautilusSummaryView *view);
+void widget_set_nautilus_background_color (GtkWidget *widget,
+ const char *color);
#endif /* NAUTILUS_SUMMARY_DIALOGS_H */
diff --git a/components/services/summary/nautilus-view/nautilus-summary-footer.c b/components/services/summary/nautilus-view/nautilus-summary-footer.c
index 22bbf2fdf..98bfc1ca5 100644
--- a/components/services/summary/nautilus-view/nautilus-summary-footer.c
+++ b/components/services/summary/nautilus-view/nautilus-summary-footer.c
@@ -90,7 +90,7 @@ footer_item_clicked_callback (GtkWidget *widget, int index, gpointer callback_da
case FOOTER_LOGIN_OR_LOGOUT:
if (!view->details->logged_in) {
- generate_login_dialog (view);
+ nautilus_summary_show_login_dialog (view);
} else {
logout_button_cb (NULL, view);
}
diff --git a/components/services/summary/nautilus-view/nautilus-summary-menu-items.c b/components/services/summary/nautilus-view/nautilus-summary-menu-items.c
index 4869b458d..3137e59a9 100644
--- a/components/services/summary/nautilus-view/nautilus-summary-menu-items.c
+++ b/components/services/summary/nautilus-view/nautilus-summary-menu-items.c
@@ -164,7 +164,7 @@ bonobo_login_callback (BonoboUIComponent *ui, gpointer user_data, const char *ve
NautilusSummaryView *view;
view = NAUTILUS_SUMMARY_VIEW (user_data);
- generate_login_dialog (view);
+ nautilus_summary_show_login_dialog (view);
}
static void
diff --git a/components/services/summary/nautilus-view/nautilus-summary-view-private.h b/components/services/summary/nautilus-view/nautilus-summary-view-private.h
index 2aad3c5b8..84e85b06b 100644
--- a/components/services/summary/nautilus-view/nautilus-summary-view-private.h
+++ b/components/services/summary/nautilus-view/nautilus-summary-view-private.h
@@ -25,6 +25,8 @@
#include <libtrilobite/libammonite.h>
+#include <libtrilobite/trilobite-redirect.h>
+
#include <gnome.h>
#define DEFAULT_SUMMARY_BACKGROUND_COLOR_SPEC "rgb:FFFF/FFFF/FFFF"
@@ -70,8 +72,6 @@ enum {
LOGIN_DIALOG_CANCEL_BUTTON
};
-typedef struct _ServicesButtonCallbackData ServicesButtonCallbackData;
-
typedef enum {
Pending_None,
Pending_Login,
@@ -84,11 +84,6 @@ typedef enum {
} SummaryLoginAttemptType;
-struct _ServicesButtonCallbackData {
- NautilusView *nautilus_view;
- char *uri;
-};
-
/* A NautilusContentView's private information. */
struct _NautilusSummaryViewDetails {
char *uri;
@@ -118,23 +113,12 @@ struct _NautilusSummaryViewDetails {
SummaryPendingOperationType pending_operation;
EazelProxy_AuthnCallback authn_callback;
- /* Login Frame Widgets */
+ /* Login Dialog */
GnomeDialog *login_dialog;
- GtkWidget *username_label;
- GtkWidget *password_label;
- GtkWidget *username_entry;
- GtkWidget *password_entry;
- /* Buttons available if user is not logged in */
- GtkWidget *login_button;
- GtkWidget *login_label;
- GtkWidget *register_button;
- GtkWidget *register_label;
- /* Buttons available if user is logged in */
- GtkWidget *preferences_button;
- GtkWidget *preferences_label;
- GtkWidget *logout_button;
- GtkWidget *logout_label;
+ /* Async XML fetch handles */
+ TrilobiteRedirectFetchHandle *redirect_fetch_handle;
+ EazelSummaryFetchHandle *summary_fetch_handle;
};
diff --git a/components/services/summary/nautilus-view/nautilus-summary-view.c b/components/services/summary/nautilus-view/nautilus-summary-view.c
index 1e4d5f560..263925301 100644
--- a/components/services/summary/nautilus-view/nautilus-summary-view.c
+++ b/components/services/summary/nautilus-view/nautilus-summary-view.c
@@ -38,6 +38,7 @@
#include "eazel-services-header.h"
#include "eazel-services-extensions.h"
+#include <libnautilus-extensions/nautilus-clickable-image.h>
#include <libnautilus-extensions/nautilus-background.h>
#include <libnautilus-extensions/nautilus-bonobo-extensions.h>
#include <libnautilus-extensions/nautilus-file-utilities.h>
@@ -75,9 +76,12 @@
#define SUMMARY_TEXT_HEADER_SIZE_REL (0)
#define SUMMARY_TEXT_BODY_SIZE_REL (-2)
+typedef struct ServicesButtonCallbackData ServicesButtonCallbackData;
-
-
+struct ServicesButtonCallbackData {
+ NautilusView *view;
+ char *uri;
+};
static void nautilus_summary_view_initialize_class (NautilusSummaryViewClass *klass);
static void nautilus_summary_view_initialize (NautilusSummaryView *view);
@@ -85,8 +89,9 @@ static void nautilus_summary_view_destroy (GtkObject
static void summary_load_location_callback (NautilusView *nautilus_view,
const char *location,
NautilusSummaryView *view);
-static void generate_summary_form (NautilusSummaryView *view);
-static GtkWidget *generate_eazel_news_entry_row (NautilusSummaryView *view,
+static void summary_stop_loading_callback (NautilusView *nautilus_view,
+ NautilusSummaryView *view);
+static GtkWidget * generate_eazel_news_entry_row (NautilusSummaryView *view,
void *data);
static GtkWidget * generate_service_entry_row (NautilusSummaryView *view,
void *data);
@@ -94,21 +99,23 @@ static GtkWidget * generate_update_news_entry_row (NautilusSummaryView
void *data);
static void summary_view_button_callback (GtkWidget *button,
ServicesButtonCallbackData *cbdata);
+static void cancel_load_in_progress (NautilusSummaryView *view);
+
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusSummaryView, nautilus_summary_view, GTK_TYPE_EVENT_BOX)
static const char *footer_online_items[] =
{
- N_("Register"),
- N_("Login"),
+ N_("Account Preferences"),
+ N_("Logout"),
N_("Terms of Use"),
N_("Privacy Statement")
};
static const char *footer_offline_items[] =
{
- N_("Account Preferences"),
- N_("Logout"),
+ N_("Register"),
+ N_("Login"),
N_("Terms of Use"),
N_("Privacy Statement")
};
@@ -133,8 +140,7 @@ update_header (NautilusSummaryView *view)
static void
create_header (NautilusSummaryView *view)
{
- view->details->header = eazel_services_header_title_new ("");
- update_header (view);
+ view->details->header = eazel_services_header_title_new (_("Connecting to Eazel Services..."));
}
@@ -143,12 +149,12 @@ update_footer (NautilusSummaryView *view)
{
if (view->details->logged_in) {
eazel_services_footer_update (EAZEL_SERVICES_FOOTER (view->details->footer),
- footer_offline_items,
- NAUTILUS_N_ELEMENTS (footer_offline_items));
- } else {
- eazel_services_footer_update (EAZEL_SERVICES_FOOTER (view->details->footer),
footer_online_items,
NAUTILUS_N_ELEMENTS (footer_online_items));
+ } else {
+ eazel_services_footer_update (EAZEL_SERVICES_FOOTER (view->details->footer),
+ footer_offline_items,
+ NAUTILUS_N_ELEMENTS (footer_offline_items));
}
}
@@ -157,34 +163,56 @@ create_footer (NautilusSummaryView *view)
{
view->details->footer = eazel_services_footer_new ();
+ eazel_services_footer_update (EAZEL_SERVICES_FOOTER (view->details->footer),
+ footer_offline_items,
+ NAUTILUS_N_ELEMENTS (footer_offline_items));
+
gtk_signal_connect (GTK_OBJECT (view->details->footer), "item_clicked",
GTK_SIGNAL_FUNC (footer_item_clicked_callback), view);
-
- update_footer (view);
}
+static void
+services_button_callback_data_free (ServicesButtonCallbackData *cbdata)
+{
+ g_free (cbdata->uri);
+ g_free (cbdata);
+}
+
-/* callback to handle the goto a service button. */
static void
summary_view_button_callback (GtkWidget *button,
ServicesButtonCallbackData *cbdata)
{
- nautilus_view_open_location_in_this_window (cbdata->nautilus_view, cbdata->uri);
+ nautilus_view_open_location_in_this_window (cbdata->view, cbdata->uri);
+}
+
+static void
+goto_uri_on_clicked (GtkWidget *widget,
+ NautilusView *view,
+ const char *uri)
+{
+ ServicesButtonCallbackData *cbdata;
+
+ cbdata = g_new0 (ServicesButtonCallbackData, 1);
+ cbdata->view = view;
+ cbdata->uri = g_strdup (uri);
+
+ gtk_signal_connect_full (GTK_OBJECT (widget), "clicked",
+ GTK_SIGNAL_FUNC (summary_view_button_callback), NULL,
+ cbdata, (GtkDestroyNotify) services_button_callback_data_free,
+ FALSE, FALSE);
}
static GtkWidget *
summary_view_button_new (char *label_text,
NautilusView *view,
- char *uri)
+ const char *uri)
{
GtkWidget *button;
GtkWidget *label;
- ServicesButtonCallbackData *cbdata;
-
- cbdata = g_new0 (ServicesButtonCallbackData, 1);
-
+
button = gtk_button_new ();
/* FIXME: hardcoded width! */
gtk_widget_set_usize (button, 80, -1);
@@ -193,18 +221,31 @@ summary_view_button_new (char *label_text,
gtk_widget_show (label);
gtk_container_add (GTK_CONTAINER (button), label);
- cbdata->nautilus_view = view;
- cbdata->uri = uri;
-
- /* FIXME: g_free won't free all the data */
- gtk_signal_connect_full (GTK_OBJECT (button), "clicked",
- GTK_SIGNAL_FUNC (summary_view_button_callback), NULL,
- cbdata, g_free, FALSE, FALSE);
+ goto_uri_on_clicked (button, view, uri);
return button;
}
static GtkWidget *
+summary_view_link_image_new (NautilusSummaryView *view,
+ const char *image_uri,
+ const char *click_uri)
+{
+ GtkWidget *image;
+
+ image = eazel_services_clickable_image_new_from_uri (image_uri,
+ NULL,
+ DEFAULT_SUMMARY_BACKGROUND_COLOR_RGB,
+ MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT);
+ nautilus_clickable_image_set_prelight (NAUTILUS_CLICKABLE_IMAGE (image), TRUE);
+
+ goto_uri_on_clicked (image, view->details->nautilus_view, click_uri);
+
+ return image;
+}
+
+
+static GtkWidget *
summary_view_item_label_new (char *label_text,
int relative_font_size,
gboolean bold)
@@ -264,6 +305,8 @@ append_hseparator_to_vbox (GtkWidget *vbox)
}
+
+
static GtkWidget *
generate_eazel_news_entry_row (NautilusSummaryView *view,
void *data)
@@ -387,7 +430,6 @@ create_news_pane (NautilusSummaryView *view)
{
view->details->news_pane = summary_view_create_pane
(view, &view->details->news_item_vbox);
- update_news_pane (view);
}
@@ -416,11 +458,9 @@ generate_service_entry_row (NautilusSummaryView *view,
gtk_widget_show (icon_box);
- icon = eazel_services_image_new_from_uri (services_node->icon,
- NULL,
- DEFAULT_SUMMARY_BACKGROUND_COLOR_RGB,
- MAX_IMAGE_WIDTH,
- MAX_IMAGE_HEIGHT);
+ icon = summary_view_link_image_new (view,
+ services_node->icon,
+ services_node->uri);
gtk_widget_show (icon);
gtk_box_pack_start (GTK_BOX (icon_box), icon, FALSE, FALSE, 0);
@@ -479,7 +519,6 @@ create_services_list_pane (NautilusSummaryView *view)
{
view->details->services_list_pane = summary_view_create_pane
(view, &view->details->services_list_vbox);
- update_services_list_pane (view);
}
@@ -510,12 +549,9 @@ generate_update_news_entry_row (NautilusSummaryView *view,
gtk_widget_show (icon_box);
gtk_box_pack_start (GTK_BOX (update_row), icon_box, FALSE, FALSE, 0);
- icon = eazel_services_image_new_from_uri (update_node->icon,
- NULL,
- DEFAULT_SUMMARY_BACKGROUND_COLOR_RGB,
- MAX_IMAGE_WIDTH,
- MAX_IMAGE_HEIGHT);
-
+ icon = summary_view_link_image_new (view,
+ update_node->icon,
+ update_node->softcat_uri);
gtk_widget_show (icon);
gtk_box_pack_start (GTK_BOX (icon_box), icon, FALSE, FALSE, 0);
@@ -596,139 +632,72 @@ create_featured_downloads_pane (NautilusSummaryView *view)
{
view->details->featured_downloads_pane = summary_view_create_pane
(view, &view->details->featured_downloads_vbox);
+}
+
+
+static void
+update_summary_form (NautilusSummaryView *view,
+ SummaryData *xml_data)
+{
+ view->details->xml_data = xml_data;
+
+ update_header (view);
+ update_news_pane (view);
+ update_services_list_pane (view);
update_featured_downloads_pane (view);
+ update_footer (view);
}
static void
-generate_summary_form (NautilusSummaryView *view)
+create_summary_form (NautilusSummaryView *view)
{
- GtkWidget *notebook;
GtkWidget *notebook_tabs;
- GtkWidget *notebook_vbox;
- if (view->details->form != NULL) {
- gtk_container_remove (GTK_CONTAINER (view), view->details->form);
- view->details->form = NULL;
- }
-
-#ifdef DEBUG_pepper
- g_print ("Start summary view load.\n");
-
-#endif
/* allocate the parent box to hold everything */
view->details->form = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (view), view->details->form);
- /* setup the title */
-#ifdef DEBUG_pepper
- g_print ("Start title load.\n");
-#endif
-
create_header (view);
-
gtk_box_pack_start (GTK_BOX (view->details->form), view->details->header, FALSE, FALSE, 0);
gtk_widget_show (view->details->header);
-#ifdef DEBUG_pepper
- g_print ("end title load.\n");
-#endif
-
-
-#ifdef DEBUG_pepper
- g_print ("start news load.\n");
-#endif
+ /* Create the News pane */
create_news_pane (view);
- gtk_box_pack_start (GTK_BOX (view->details->form), view->details->news_pane, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (view->details->form), view->details->news_pane, FALSE, FALSE, 0);
gtk_widget_show (view->details->news_pane);
-
-#ifdef DEBUG_pepper
- g_print ("end news load.\n");
-#endif
-
- /* add a set of tabs to control the notebook page switching */
-#ifdef DEBUG_pepper
- g_print ("start tab load.\n");
-#endif
+ /* Header for Services pane */
notebook_tabs = nautilus_tabs_new ();
+ nautilus_tabs_add_tab (NAUTILUS_TABS (notebook_tabs), _("Services"), 0);
gtk_widget_show (notebook_tabs);
gtk_box_pack_start (GTK_BOX (view->details->form), notebook_tabs, FALSE, FALSE, 0);
- /* Create the notebook container for services */
- notebook = gtk_notebook_new ();
- gtk_widget_show (notebook);
- gtk_box_pack_start (GTK_BOX (view->details->form), notebook, TRUE, TRUE, 0);
-
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
-
- /* add the tab */
- nautilus_tabs_add_tab (NAUTILUS_TABS (notebook_tabs), _("Services"), 0);
-#ifdef DEBUG_pepper
- g_print ("end tab load.\n");
-#endif
-
- /* Create the Services Listing Box */
-#ifdef DEBUG_pepper
- g_print ("start services load.\n");
-#endif
+ /* Create the Services pane */
create_services_list_pane (view);
gtk_widget_show (view->details->services_list_pane);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), view->details->services_list_pane, NULL);
+ gtk_box_pack_start (GTK_BOX (view->details->form), view->details->services_list_pane, TRUE, TRUE, 0);
-#ifdef DEBUG_pepper
- g_print ("end services load.\n");
-#endif
-
- /* Create the notebook container for updates */
-#ifdef DEBUG_pepper
- g_print ("start updates load.\n");
-#endif
- /* add a set of tabs to control the updates page switching */
- notebook_vbox = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (notebook_vbox);
+ /* Header for Featured Downloads pane */
notebook_tabs = nautilus_tabs_new ();
- gtk_widget_show (notebook_tabs);
- gtk_box_pack_start (GTK_BOX (notebook_vbox), notebook_tabs, FALSE, FALSE, 0);
-
- notebook = gtk_notebook_new ();
- gtk_widget_show (notebook);
- gtk_container_add (GTK_CONTAINER (notebook_vbox), notebook);
- gtk_box_pack_start (GTK_BOX (view->details->form), notebook_vbox, TRUE, TRUE, 0);
-
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
-
- /* add the tab */
nautilus_tabs_add_tab (NAUTILUS_TABS (notebook_tabs), _("Featured Downloads"), 0);
+ gtk_widget_show (notebook_tabs);
+ gtk_box_pack_start (GTK_BOX (view->details->form), notebook_tabs, FALSE, FALSE, 0);
- /* Create the Update News Frame */
+ /* Create the Featured Downloads pane */
create_featured_downloads_pane (view);
-
gtk_widget_show (view->details->featured_downloads_pane);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), view->details->featured_downloads_pane, NULL);
-
-#ifdef DEBUG_pepper
- g_print ("end updates load.\n");
-
- g_print ("start footer load.\n");
-#endif
+ gtk_box_pack_start (GTK_BOX (view->details->form), view->details->featured_downloads_pane, TRUE, TRUE, 0);
create_footer (view);
gtk_widget_show (view->details->footer);
-
gtk_box_pack_start (GTK_BOX (view->details->form),
view->details->footer,
FALSE, FALSE, 0);
-#ifdef DEBUG_pepper
- g_print ("end footer load.\n");
-#endif
/* Finally, show the form that hold everything */
gtk_widget_show (view->details->form);
-#ifdef DEBUG_pepper
- g_print ("Load summary view end.\n");
-#endif
}
@@ -761,6 +730,13 @@ nautilus_summary_view_initialize (NautilusSummaryView *view)
GTK_SIGNAL_FUNC (summary_load_location_callback),
view);
+ gtk_signal_connect (GTK_OBJECT (view->details->nautilus_view),
+ "stop_loading",
+ GTK_SIGNAL_FUNC (summary_stop_loading_callback),
+ view);
+
+
+
view->details->user_control = ammonite_get_user_control ();
if (CORBA_NO_EXCEPTION != ev._major) {
@@ -776,6 +752,8 @@ nautilus_summary_view_initialize (NautilusSummaryView *view)
merge_bonobo_menu_items,
view);
+ create_summary_form (view);
+
gtk_widget_show (GTK_WIDGET (view));
CORBA_exception_free (&ev);
@@ -786,13 +764,15 @@ static void
nautilus_summary_view_destroy (GtkObject *object)
{
- NautilusSummaryView *view;
+ NautilusSummaryView *view;
CORBA_Environment ev;
CORBA_exception_init (&ev);
view = NAUTILUS_SUMMARY_VIEW (object);
+ cancel_load_in_progress (view);
+
if (view->details->uri) {
g_free (view->details->uri);
}
@@ -816,83 +796,130 @@ nautilus_summary_view_get_nautilus_view (NautilusSummaryView *view)
}
+static void
+summary_fetch_callback (GnomeVFSResult result,
+ SummaryData *xml_data,
+ gpointer callback_data)
+{
+ NautilusSummaryView *view;
+
+ view = NAUTILUS_SUMMARY_VIEW (callback_data);
+ view->details->summary_fetch_handle = NULL;
+
+ if (result != GNOME_VFS_OK) {
+ nautilus_summary_show_error_dialog
+ (view, _("Unable to get services data from Eazel's server. "
+ "The server might be unavailable right now, "
+ "or your computer might be configured incorrectly."
+ "Please contact support@eazel.com."));
+ return;
+ }
+
+
+ if (xml_data == NULL) {
+ nautilus_summary_show_error_dialog
+ (view, _("Found a problem with services data on Eazel servers. "
+ "Please contact support@eazel.com."));
+ return;
+ }
+
+ update_summary_form (view, xml_data);
+
+ if (!view->details->logged_in) {
+ nautilus_summary_show_login_dialog (view);
+ }
+
+ nautilus_view_report_load_complete (view->details->nautilus_view);
+}
+
+
+static void
+redirect_fetch_callback (GnomeVFSResult result,
+ gboolean parsed_xml,
+ gpointer callback_data)
+{
+ NautilusSummaryView *view;
+ char *uri;
+
+ view = NAUTILUS_SUMMARY_VIEW (callback_data);
+
+ view->details->redirect_fetch_handle = NULL;
+
+ if (result != GNOME_VFS_OK) {
+ nautilus_summary_show_error_dialog
+ (view, _("Unable to connect to Eazel's server. "
+ "The server might be unavailable right now, "
+ "or your computer might be configured incorrectly."
+ "You could try again later."));
+ return;
+ }
+
+
+ if (!parsed_xml) {
+ nautilus_summary_show_error_dialog
+ (view, _("Found a problem with redirect data on Eazel servers. "
+ "Please contact support@eazel.com."));
+ return;
+ }
+
+ /* Read and parse summary view XML */
+
+ uri = trilobite_redirect_lookup (SUMMARY_XML_KEY);
+
+ if (uri == NULL) {
+ nautilus_summary_show_error_dialog
+ (view, _("Information is missing from the redirect data on Eazel servers. "
+ "Please contact support@eazel.com."));
+ return;
+ }
+
+
+ view->details->summary_fetch_handle = eazel_summary_fetch_data_async
+ (uri, summary_fetch_callback, view);
+ g_free (uri);
+}
+
+
+
+
+static void
+cancel_load_in_progress (NautilusSummaryView *view)
+{
+ if (view->details->redirect_fetch_handle != NULL) {
+ trilobite_redirect_fetch_table_cancel (view->details->redirect_fetch_handle);
+ view->details->redirect_fetch_handle = NULL;
+ }
+
+ if (view->details->summary_fetch_handle != NULL) {
+ eazel_summary_fetch_data_cancel (view->details->summary_fetch_handle);
+ view->details->summary_fetch_handle = NULL;
+ }
+}
+
void
nautilus_summary_view_load_uri (NautilusSummaryView *view,
const char *uri)
{
- char *url;
char *user_name;
- gboolean got_url_table;
-
- url = NULL;
/* set up some sanity values for error control */
view->details->attempt_number = 0;
view->details->current_attempt = initial;
- /* dispose of any old uri and copy in the new one */
g_free (view->details->uri);
view->details->uri = g_strdup (uri);
- /* get xml data and verify network connections */
-#ifdef DEBUG_pepper
- g_print ("start load\n");
-#endif
-
user_name = ammonite_get_default_user_username ();
view->details->logged_in = (NULL != user_name);
g_free (user_name);
user_name = NULL;
-#ifdef DEBUG_pepper
- g_print ("start xml table fetch\n");
-#endif
- got_url_table = trilobite_redirect_fetch_table
- (view->details->logged_in
- ? URL_REDIRECT_TABLE_HOME_2
- : URL_REDIRECT_TABLE_HOME);
-
- if (!got_url_table) {
- /* FIXME bugzilla.eazel.com 3743:
- * We should do more to figure out why this failed so we can
- * present a much more helpful message. There are several different
- * reasons why it might have failed.
- */
- generate_error_dialog
- (view, _("Unable to connect to Eazel's server. "
- "The server might be unavailable right now, "
- "or your computer might be configured incorrectly."
- "You could try again later."));
- } else {
-#ifdef DEBUG_pepper
- g_print ("end xml table fetch\n");
- /* fetch and parse the xml file */
- g_print ("start xml config fetch\n");
-#endif
- url = trilobite_redirect_lookup (SUMMARY_XML_KEY);
- if (!url) {
- g_assert ("Failed to get summary xml home !\n");
- }
- view->details->xml_data = parse_summary_xml_file (url);
- g_free (url);
- if (view->details->xml_data == NULL) {
- generate_error_dialog
- (view, _("Found problem with data on Eazel servers. "
- "Please contact support@eazel.com."));
- } else {
-#ifdef DEBUG_pepper
- g_print ("end xml config fetch\n");
- g_print ("start summary draw\n");
-#endif
- generate_summary_form (view);
-#ifdef DEBUG_pepper
- g_print ("end summary draw\n");
-#endif
- if (!view->details->logged_in) {
- generate_login_dialog (view);
- }
- }
- }
+ cancel_load_in_progress (view);
+
+ view->details->redirect_fetch_handle = trilobite_redirect_fetch_table_async
+ (view->details->logged_in ? URL_REDIRECT_TABLE_HOME_2 : URL_REDIRECT_TABLE_HOME,
+ redirect_fetch_callback,
+ view);
}
static void
@@ -907,6 +934,14 @@ summary_load_location_callback (NautilusView *nautilus_view,
nautilus_view_set_title (nautilus_view, "Eazel Services");
nautilus_summary_view_load_uri (view, location);
+}
- nautilus_view_report_load_complete (nautilus_view);
+
+
+static void
+summary_stop_loading_callback (NautilusView *nautilus_view,
+ NautilusSummaryView *view)
+
+{
+ cancel_load_in_progress (view);
}
diff --git a/components/services/trilobite/libtrilobite/Makefile.am b/components/services/trilobite/libtrilobite/Makefile.am
index 5f7ca881b..75a0dac5f 100644
--- a/components/services/trilobite/libtrilobite/Makefile.am
+++ b/components/services/trilobite/libtrilobite/Makefile.am
@@ -53,6 +53,7 @@ libtrilobiteinclude_HEADERS = \
trilobite-core-distribution.h \
trilobite-core-network.h \
trilobite-core-utils.h \
+ trilobite-file-utilities.h \
trilobite-root-helper.h \
trilobite-root-client-public.h \
trilobite-redirect.h \
@@ -65,6 +66,7 @@ libtrilobite_la_SOURCES = \
trilobite-core-distribution.c \
trilobite-core-network.c \
trilobite-core-utils.c \
+ trilobite-file-utilities.c \
trilobite-root-helper.c \
trilobite-root-client.c \
trilobite-redirect.c \
diff --git a/components/services/trilobite/libtrilobite/trilobite-core-network.c b/components/services/trilobite/libtrilobite/trilobite-core-network.c
index 4fede526f..aa68245b2 100644
--- a/components/services/trilobite/libtrilobite/trilobite-core-network.c
+++ b/components/services/trilobite/libtrilobite/trilobite-core-network.c
@@ -3,7 +3,7 @@
* trilobite-core-network: functions for retrieving files from the
* network and parsing XML documents
*
- * Copyright (C) 2000 Eazel, Inc
+ * Copyright (C) 2000, 2001 Eazel, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,16 +23,14 @@
* Robey Pointer <robey@eazel.com>
*/
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
+#include "trilobite-core-network.h"
+#include "trilobite-core-utils.h"
+#include <libgnomevfs/gnome-vfs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <libgnomevfs/gnome-vfs.h>
-#include "trilobite-core-utils.h"
-#include "trilobite-core-network.h"
/* function for lazy bastards who can't be bothered to figure out the format of the xml they're parsing:
@@ -109,7 +107,9 @@ trilobite_open_uri (const char *uri_text)
* and also makes it easy to manipulate a small body using string operations).
*/
gboolean
-trilobite_fetch_uri (const char *uri_text, char **body, int *length)
+trilobite_fetch_uri (const char *uri_text,
+ char **body,
+ int *length)
{
GnomeVFSResult err;
GnomeVFSHandle *handle;
@@ -127,6 +127,7 @@ trilobite_fetch_uri (const char *uri_text, char **body, int *length)
*length = 0;
while (1) {
+ /* FIXME: this is almost certainly a mistake */
/* i think this is probably pretty loser: */
g_main_iteration (FALSE);
err = gnome_vfs_read (handle, (*body) + (*length), buffer_size - (*length), &bytes);
@@ -192,3 +193,5 @@ trilobite_fetch_uri_to_file (const char *uri_text, const char *filename)
return (err == GNOME_VFS_OK);
}
+
+
diff --git a/components/services/trilobite/libtrilobite/trilobite-core-network.h b/components/services/trilobite/libtrilobite/trilobite-core-network.h
index b5a5e846c..cf836fa69 100644
--- a/components/services/trilobite/libtrilobite/trilobite-core-network.h
+++ b/components/services/trilobite/libtrilobite/trilobite-core-network.h
@@ -28,9 +28,11 @@
#include <gnome-xml/parser.h>
#include <gnome-xml/xmlmemory.h>
+#include <glib.h>
char *trilobite_xml_get_string (xmlNode *node, const char *name);
gboolean trilobite_fetch_uri (const char *uri_text, char **body, int *length);
gboolean trilobite_fetch_uri_to_file (const char *uri_text, const char *filename);
+
#endif /* TRILOBITE_CORE_NETWORK_H */
diff --git a/components/services/trilobite/libtrilobite/trilobite-file-utilities.c b/components/services/trilobite/libtrilobite/trilobite-file-utilities.c
new file mode 100644
index 000000000..231117abb
--- /dev/null
+++ b/components/services/trilobite/libtrilobite/trilobite-file-utilities.c
@@ -0,0 +1,291 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * trilobite-core-network: functions for retrieving files from the
+ * network and parsing XML documents
+ *
+ * Copyright (C) 2000 Eazel, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Authors: J Shane Culpepper <pepper@eazel.com>
+ * Robey Pointer <robey@eazel.com>
+ */
+
+#include <config.h>
+#include "trilobite-file-utilities.h"
+
+
+/* FIXME: cut and pasted from libnautilus-extensions/nautilus-file-utilities.c */
+
+#define READ_CHUNK_SIZE 8192
+
+struct TrilobiteReadFileHandle {
+ GnomeVFSAsyncHandle *handle;
+ TrilobiteReadFileCallback callback;
+ TrilobiteReadMoreCallback read_more_callback;
+ gpointer callback_data;
+ gboolean is_open;
+ char *buffer;
+ GnomeVFSFileSize bytes_read;
+};
+
+GnomeVFSResult
+trilobite_read_entire_file (const char *uri,
+ int *file_size,
+ char **file_contents)
+{
+ GnomeVFSResult result;
+ GnomeVFSHandle *handle;
+ char *buffer;
+ GnomeVFSFileSize total_bytes_read;
+ GnomeVFSFileSize bytes_read;
+
+ *file_size = 0;
+ *file_contents = NULL;
+
+ /* Open the file. */
+ result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK) {
+ return result;
+ }
+
+ /* Read the whole thing. */
+ buffer = NULL;
+ total_bytes_read = 0;
+ do {
+ buffer = g_realloc (buffer, total_bytes_read + READ_CHUNK_SIZE);
+ result = gnome_vfs_read (handle,
+ buffer + total_bytes_read,
+ READ_CHUNK_SIZE,
+ &bytes_read);
+ if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
+ g_free (buffer);
+ gnome_vfs_close (handle);
+ return result;
+ }
+
+ /* Check for overflow. */
+ if (total_bytes_read + bytes_read < total_bytes_read) {
+ g_free (buffer);
+ gnome_vfs_close (handle);
+ return GNOME_VFS_ERROR_TOO_BIG;
+ }
+
+ total_bytes_read += bytes_read;
+ } while (result == GNOME_VFS_OK);
+
+ /* Close the file. */
+ result = gnome_vfs_close (handle);
+ if (result != GNOME_VFS_OK) {
+ g_free (buffer);
+ return result;
+ }
+
+ /* Return the file. */
+ *file_size = total_bytes_read;
+ *file_contents = g_realloc (buffer, total_bytes_read);
+ return GNOME_VFS_OK;
+}
+
+/* When close is complete, there's no more work to do. */
+static void
+read_file_close_callback (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+}
+
+/* Do a close if it's needed.
+ * Be sure to get this right, or we have extra threads hanging around.
+ */
+static void
+read_file_close (TrilobiteReadFileHandle *read_handle)
+{
+ if (read_handle->is_open) {
+ gnome_vfs_async_close (read_handle->handle,
+ read_file_close_callback,
+ NULL);
+ read_handle->is_open = FALSE;
+ }
+}
+
+
+/* Close the file and then tell the caller we succeeded, handing off
+ * the buffer to the caller.
+ */
+static void
+read_file_succeeded (TrilobiteReadFileHandle *read_handle)
+{
+ read_file_close (read_handle);
+
+ /* Reallocate the buffer to the exact size since it might be
+ * around for a while.
+ */
+ (* read_handle->callback) (GNOME_VFS_OK,
+ read_handle->bytes_read,
+ g_realloc (read_handle->buffer,
+ read_handle->bytes_read),
+ read_handle->callback_data);
+
+ g_free (read_handle);
+}
+
+/* Tell the caller we failed. */
+static void
+read_file_failed (TrilobiteReadFileHandle *read_handle, GnomeVFSResult result)
+{
+ read_file_close (read_handle);
+ g_free (read_handle->buffer);
+
+ (* read_handle->callback) (result, 0, NULL, read_handle->callback_data);
+ g_free (read_handle);
+}
+
+
+static void read_file_read_chunk (TrilobiteReadFileHandle *handle);
+
+/* A read is complete, so we might or might not be done. */
+static void
+read_file_read_callback (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer buffer,
+ GnomeVFSFileSize bytes_requested,
+ GnomeVFSFileSize bytes_read,
+ gpointer callback_data)
+{
+ TrilobiteReadFileHandle *read_handle;
+ gboolean read_more;
+
+ /* Do a few reality checks. */
+ g_assert (bytes_requested == READ_CHUNK_SIZE);
+ read_handle = callback_data;
+ g_assert (read_handle->handle == handle);
+ g_assert (read_handle->buffer + read_handle->bytes_read == buffer);
+ g_assert (bytes_read <= bytes_requested);
+
+ /* Check for a failure. */
+ if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
+ read_file_failed (read_handle, result);
+ return;
+ }
+
+ /* Check for the extremely unlikely case where the file size overflows. */
+ if (read_handle->bytes_read + bytes_read < read_handle->bytes_read) {
+ read_file_failed (read_handle, GNOME_VFS_ERROR_TOO_BIG);
+ return;
+ }
+
+ /* Bump the size. */
+ read_handle->bytes_read += bytes_read;
+
+ /* Read more unless we are at the end of the file. */
+ if (bytes_read == 0 || result != GNOME_VFS_OK) {
+ read_more = FALSE;
+ } else {
+ if (read_handle->read_more_callback == NULL) {
+ read_more = TRUE;
+ } else {
+ read_more = (* read_handle->read_more_callback)
+ (read_handle->bytes_read,
+ read_handle->buffer,
+ read_handle->callback_data);
+ }
+ }
+ if (read_more) {
+ read_file_read_chunk (read_handle);
+ return;
+ }
+
+ /* If at the end of the file, we win! */
+ read_file_succeeded (read_handle);
+}
+
+/* Start reading a chunk. */
+static void
+read_file_read_chunk (TrilobiteReadFileHandle *handle)
+{
+ handle->buffer = g_realloc (handle->buffer, handle->bytes_read + READ_CHUNK_SIZE);
+ gnome_vfs_async_read (handle->handle,
+ handle->buffer + handle->bytes_read,
+ READ_CHUNK_SIZE,
+ read_file_read_callback,
+ handle);
+}
+
+
+/* Once the open is finished, read a first chunk. */
+static void
+read_file_open_callback (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+ TrilobiteReadFileHandle *read_handle;
+
+ read_handle = callback_data;
+ g_assert (read_handle->handle == handle);
+
+ /* Handle the failure case. */
+ if (result != GNOME_VFS_OK) {
+ read_file_failed (read_handle, result);
+ return;
+ }
+
+ /* Handle success by reading the first chunk. */
+ read_handle->is_open = TRUE;
+ read_file_read_chunk (read_handle);
+}
+
+
+/* Set up the read handle and start reading. */
+TrilobiteReadFileHandle *
+trilobite_read_file_async (const char *uri,
+ TrilobiteReadFileCallback callback,
+ TrilobiteReadMoreCallback read_more_callback,
+ gpointer callback_data)
+{
+ TrilobiteReadFileHandle *handle;
+
+ handle = g_new0 (TrilobiteReadFileHandle, 1);
+
+ handle->callback = callback;
+ handle->read_more_callback = read_more_callback;
+ handle->callback_data = callback_data;
+
+ gnome_vfs_async_open (&handle->handle,
+ uri,
+ GNOME_VFS_OPEN_READ,
+ read_file_open_callback,
+ handle);
+ return handle;
+}
+
+/* Set up the read handle and start reading. */
+TrilobiteReadFileHandle *
+trilobite_read_entire_file_async (const char *uri,
+ TrilobiteReadFileCallback callback,
+ gpointer callback_data)
+{
+ return trilobite_read_file_async (uri, callback, NULL, callback_data);
+}
+
+/* Stop the presses! */
+void
+trilobite_read_file_cancel (TrilobiteReadFileHandle *handle)
+{
+ gnome_vfs_async_cancel (handle->handle);
+ read_file_close (handle);
+ g_free (handle->buffer);
+ g_free (handle);
+}
diff --git a/components/services/trilobite/libtrilobite/trilobite-file-utilities.h b/components/services/trilobite/libtrilobite/trilobite-file-utilities.h
new file mode 100644
index 000000000..5dba48643
--- /dev/null
+++ b/components/services/trilobite/libtrilobite/trilobite-file-utilities.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/*
+ * Copyright (C) 2000, 2001 Eazel, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef TRILOBITE_FILE_UTILITIES_H
+#define TRILOBITE_FILE_UTILITIES_H
+
+#include <libgnomevfs/gnome-vfs.h>
+
+/* FIXME: cut and pasted from libnautilus-extensions/nautilus-file-utilities.c */
+
+typedef void (* TrilobiteReadFileCallback) (GnomeVFSResult result,
+ GnomeVFSFileSize file_size,
+ char *file_contents,
+ gpointer callback_data);
+typedef gboolean (* TrilobiteReadMoreCallback) (GnomeVFSFileSize file_size,
+ const char *file_contents,
+ gpointer callback_data);
+typedef struct TrilobiteReadFileHandle TrilobiteReadFileHandle;
+
+/* Read an entire file at once with gnome-vfs. */
+GnomeVFSResult trilobite_read_entire_file (const char *uri,
+ int *file_size,
+ char **file_contents);
+TrilobiteReadFileHandle *trilobite_read_entire_file_async (const char *uri,
+ TrilobiteReadFileCallback callback,
+ gpointer callback_data);
+TrilobiteReadFileHandle *trilobite_read_file_async (const char *uri,
+ TrilobiteReadFileCallback callback,
+ TrilobiteReadMoreCallback read_more_callback,
+ gpointer callback_data);
+void trilobite_read_file_cancel (TrilobiteReadFileHandle *handle);
+
+
+
+#endif /* TRILOBITE_FILE_UTILITIES_H */
diff --git a/components/services/trilobite/libtrilobite/trilobite-redirect.c b/components/services/trilobite/libtrilobite/trilobite-redirect.c
index c8d31728b..bce8fbac8 100644
--- a/components/services/trilobite/libtrilobite/trilobite-redirect.c
+++ b/components/services/trilobite/libtrilobite/trilobite-redirect.c
@@ -5,7 +5,7 @@
* a remote xml file, store it in gconf, and then lookup entries
* later. this may only be useful for eazel services.
*
- * Copyright (C) 2000 Eazel, Inc
+ * Copyright (C) 2000, 2001 Eazel, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,19 +25,25 @@
*/
#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
+#include "trilobite-redirect.h"
+
+#include "trilobite-core-network.h"
+#include "trilobite-core-utils.h"
+#include "trilobite-file-utilities.h"
#include <libgnomevfs/gnome-vfs.h>
-#include <gnome-xml/parser.h>
#include <gconf/gconf.h>
#include <gconf/gconf-engine.h>
-#include "trilobite-core-utils.h"
-#include "trilobite-core-network.h"
-#include "trilobite-redirect.h"
+#include <gnome-xml/parser.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
-#define REDIRECT_TABLE_URL "eazel-services:/table.xml"
+static gboolean trilobite_redirect_parse_xml (char *blob,
+ int length);
+
+#define REDIRECT_TABLE_URI "eazel-services:/table.xml"
#define REDIRECT_GCONF_PATH "/apps/eazel-trilobite/redirect-table"
#define SERVICES_DEFAULT_HOST "services.eazel.com"
@@ -126,45 +132,41 @@ add_redirect (const char *key, const char *value)
}
/* parse an xml file into the redirect table */
-void
+gboolean
trilobite_redirect_parse_xml (char *blob, int length)
{
xmlDocPtr doc;
xmlNodePtr base, child, child2;
char *name, *uri;
- g_return_if_fail (blob != NULL);
- g_return_if_fail (length > 0);
+ g_return_val_if_fail (blob != NULL, FALSE);
+ g_return_val_if_fail (length > 0, FALSE);
/* <rant> libxml will have a temper tantrum if there is whitespace before the
* first tag. so we must babysit it.
*/
- while ((length > 0) && (*blob <= ' ')) {
- blob++, length--;
+ while ((length > 0) && (isspace (*blob))) {
+ blob++;
+ length--;
}
+ blob[length] = '\0';
+
doc = xmlParseMemory (blob, length);
- if (doc == NULL) {
- g_warning ("trilobite redirect: bad XML: '%s'", blob);
- return;
+ if (doc == NULL || doc->root == NULL ||
+ g_strcasecmp (doc->root->name, "location_data") != 0) {
+ goto bad;
}
base = doc->root;
- if (base == NULL) {
- g_warning ("trilobite redirect: empty XML!");
- goto out;
- }
- if (g_strcasecmp (base->name, "location_data") != 0) {
- g_warning ("trilobite redirect: no redirect table!");
- goto bad;
- }
wipe_redirect_table ();
for (child = base->xmlChildrenNode; child; child = child->next) {
if (g_strcasecmp (child->name, "location") == 0) {
/* libxml sucks */
- name = uri = NULL;
+ name = NULL;
+ uri = NULL;
for (child2 = child->xmlChildrenNode; child2; child2 = child2->next) {
if (g_strcasecmp (child2->name, "name") == 0) {
@@ -177,47 +179,78 @@ trilobite_redirect_parse_xml (char *blob, int length)
if ((name != NULL) && (uri != NULL)) {
add_redirect (name, uri);
- } else {
- g_warning ("trilobite redirect: incomplete node");
- }
+ }
g_free (name);
g_free (uri);
- } else {
- g_warning ("trilobite redirect: ignoring directive '%s'", child->name);
- }
+
+ }
}
xmlFreeDoc (doc);
- return;
+ return TRUE;
bad:
- g_warning ("trilobite redirect: dysfunctional XML was '%s'", blob);
-
-out:
xmlFreeDoc (doc);
+ return FALSE;
}
-/* fetch xml file all at once, blocking until we have some closure.
- * you will definitely want to ref any objects you own before calling this function,
- * since it involves iterations of gtk_main.
- * ( is this really needed? )
- */
-gboolean
-trilobite_redirect_fetch_table (const char *url)
+struct TrilobiteRedirectFetchHandle {
+ TrilobiteReadFileHandle *handle;
+ TrilobiteRedirectFetchCallback callback;
+ gpointer callback_data;
+};
+
+
+static void
+redirect_fetch_callback (GnomeVFSResult result,
+ GnomeVFSFileSize file_size,
+ char *file_contents,
+ gpointer callback_data)
{
- char *body;
- int length;
+ TrilobiteRedirectFetchHandle *handle;
+ gboolean parsed_xml;
+
+ parsed_xml = FALSE;
- if (! trilobite_fetch_uri (url == NULL ? REDIRECT_TABLE_URL : url, &body, &length)) {
- return FALSE;
+ handle = callback_data;
+
+ if (result == GNOME_VFS_OK) {
+ parsed_xml = trilobite_redirect_parse_xml (file_contents, file_size);
}
- trilobite_redirect_parse_xml (body, length);
- return TRUE;
+ (*handle->callback) (result, parsed_xml, handle->callback_data);
+ g_free (handle);
+ g_free (file_contents);
}
-/* find the url for a redirect (you must free the string when done) */
+TrilobiteRedirectFetchHandle *
+trilobite_redirect_fetch_table_async (const char *uri,
+ TrilobiteRedirectFetchCallback callback,
+ gpointer callback_data)
+{
+ TrilobiteRedirectFetchHandle *handle;
+
+ handle = g_new0 (TrilobiteRedirectFetchHandle, 1);
+
+ handle->callback = callback;
+ handle->callback_data = callback_data;
+
+ handle->handle = trilobite_read_entire_file_async (uri, redirect_fetch_callback, handle);
+
+ return handle;
+}
+
+void
+trilobite_redirect_fetch_table_cancel (TrilobiteRedirectFetchHandle *handle)
+{
+ trilobite_read_file_cancel (handle->handle);
+ g_free (handle);
+}
+
+
+
+/* find the uri for a redirect (you must free the string when done) */
char *
trilobite_redirect_lookup (const char *key)
{
diff --git a/components/services/trilobite/libtrilobite/trilobite-redirect.h b/components/services/trilobite/libtrilobite/trilobite-redirect.h
index b686b00be..61d12bc1d 100644
--- a/components/services/trilobite/libtrilobite/trilobite-redirect.h
+++ b/components/services/trilobite/libtrilobite/trilobite-redirect.h
@@ -5,7 +5,7 @@
* a remote xml file, store it in gconf, and then lookup entries
* later. this may only be useful for eazel services.
*
- * Copyright (C) 2000 Eazel, Inc
+ * Copyright (C) 2000, 2001 Eazel, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,12 +24,28 @@
* Authors: Robey Pointer <robey@eazel.com>
*/
-#ifndef _TRILOBITE_REDIRECT_H_
-#define _TRILOBITE_REDIRECT_H_
+#ifndef TRILOBITE_REDIRECT_H
+#define TRILOBITE_REDIRECT_H
+
+#include <libgnomevfs/gnome-vfs.h>
+#include <glib.h>
+
+typedef void (* TrilobiteRedirectFetchCallback) (GnomeVFSResult result,
+ gboolean parsed_xml,
+ gpointer callback_data);
+
+typedef struct TrilobiteRedirectFetchHandle TrilobiteRedirectFetchHandle;
+
+
+TrilobiteRedirectFetchHandle *trilobite_redirect_fetch_table_async (const char *uri,
+ TrilobiteRedirectFetchCallback callback,
+ gpointer callback_data);
+
+void trilobite_redirect_fetch_table_cancel (TrilobiteRedirectFetchHandle *handle);
+
-void trilobite_redirect_parse_xml (char *blob, int length);
-gboolean trilobite_redirect_fetch_table (const char *url);
char *trilobite_redirect_lookup (const char *key);
+
const char *trilobite_get_services_address (void);
-#endif /* _TRILOBITE_REDIRECT_H_ */
+#endif /* TRILOBITE_REDIRECT_H */