summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Hertzfeld <andy@src.gnome.org>2001-01-11 01:58:39 +0000
committerAndy Hertzfeld <andy@src.gnome.org>2001-01-11 01:58:39 +0000
commit92350d01b3a15c4b63fea32e6ceeef39de265c73 (patch)
treeb42385dcd0bf45e048485cac6ae1b8de123ea4d3
parent58b53fc55f33ff348144c966d8fca3c460d44764 (diff)
downloadnautilus-INSTALLER_PR3_ANCHOR.tar.gz
fixed bug 3256, loading a huge text file crashes nautilus. Now, if theINSTALLER_PR3_ANCHOR
* components/text/nautilus-text-view.c: (nautilus_text_view_initialize), (nautilus_text_view_destroy), (done_file_read), (file_read_callback), (file_opened_callback), (nautilus_text_view_update): fixed bug 3256, loading a huge text file crashes nautilus. Now, if the file size exceeds a predetermined threshold, currently set at a megabyte, it truncates it to the threshold amount and warns the user with an error dialog. As part of this, I made the text view load files asynchronously and progressively, as Maciej suggested; however, we won't see the benefit of this until Pavel checks in some gnome-vfs optimizations he's working on since currently gnome-vfs doesn't give the main loop much time to run if it has ongoing activity. * components/text/services/Makefile.am: * components/text/services/french_to_english.xml: at Bud's request, checked in the "frech to english" text service * src/file-manager/fm-properties-window.c: (create_emblems_page): removed debug message that I accidentally checked in.
-rw-r--r--ChangeLog23
-rw-r--r--components/text/nautilus-text-view.c151
-rw-r--r--components/text/services/Makefile.am1
-rw-r--r--components/text/services/french_to_english.xml3
-rw-r--r--src/file-manager/fm-properties-window.c1
5 files changed, 156 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index a87237466..93e09bfb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2001-01-10 Andy Hertzfeld <andy@eazel.com>
+
+ * components/text/nautilus-text-view.c:
+ (nautilus_text_view_initialize), (nautilus_text_view_destroy),
+ (done_file_read), (file_read_callback), (file_opened_callback),
+ (nautilus_text_view_update):
+ fixed bug 3256, loading a huge text file crashes nautilus. Now,
+ if the file size exceeds a predetermined threshold, currently
+ set at a megabyte, it truncates it to the threshold amount and
+ warns the user with an error dialog. As part of this, I made
+ the text view load files asynchronously and progressively, as
+ Maciej suggested; however, we won't see the benefit of this
+ until Pavel checks in some gnome-vfs optimizations he's working
+ on since currently gnome-vfs doesn't give the main loop much
+ time to run if it has ongoing activity.
+
+ * components/text/services/Makefile.am:
+ * components/text/services/french_to_english.xml:
+ at Bud's request, checked in the "frech to english" text service
+
+ * src/file-manager/fm-properties-window.c: (create_emblems_page):
+ removed debug message that I accidentally checked in.
+
2001-01-10 Gene Z. Ragan <gzr@eazel.com>
reviewed by: Pavel Cisler <pavel@eazel.com>
diff --git a/components/text/nautilus-text-view.c b/components/text/nautilus-text-view.c
index bdffbc547..d9c98fa4e 100644
--- a/components/text/nautilus-text-view.c
+++ b/components/text/nautilus-text-view.c
@@ -45,6 +45,7 @@
#include <libnautilus-extensions/nautilus-gtk-macros.h>
#include <libnautilus-extensions/nautilus-string.h>
#include <libnautilus-extensions/nautilus-font-factory.h>
+#include <libnautilus-extensions/nautilus-stock-dialogs.h>
#include <gnome.h>
#include <libgnomevfs/gnome-vfs.h>
@@ -54,10 +55,15 @@
#include <ghttp.h>
#define MAX_SERVICE_ITEMS 32
+#define TEXT_VIEW_CHUNK_SIZE 65536
+#define MAX_FILE_SIZE 1024*1024
struct _NautilusTextViewDetails {
NautilusFile *file;
NautilusView *nautilus_view;
+ GnomeVFSAsyncHandle *file_handle;
+ char *buffer;
+
BonoboZoomable *zoomable;
int zoom_index;
@@ -68,6 +74,7 @@ struct _NautilusTextViewDetails {
GdkFont *current_font;
int service_item_count;
+ GnomeVFSFileSize file_size;
gboolean service_item_uses_selection[MAX_SERVICE_ITEMS];
};
@@ -178,11 +185,8 @@ nautilus_text_view_initialize (NautilusTextView *text_view)
gtk_container_set_border_width (GTK_CONTAINER (text_view->details->container), 0);
gtk_container_add (GTK_CONTAINER (text_view), GTK_WIDGET (text_view->details->container));
- gtk_widget_show (GTK_WIDGET (text_view->details->container));
-
/* allocate the text object */
text_view->details->text_display = gtk_text_new (NULL, NULL);
- gtk_widget_show (text_view->details->text_display);
gtk_text_set_editable (GTK_TEXT (text_view->details->text_display), FALSE);
/* add signal handlers to the text field to enable/disable the service menu items */
@@ -203,7 +207,6 @@ nautilus_text_view_initialize (NautilusTextView *text_view)
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (scrolled_window), text_view->details->text_display);
- gtk_widget_show (scrolled_window);
gtk_container_add (GTK_CONTAINER (text_view->details->container), scrolled_window);
/* get notified when we are activated so we can merge in our menu items */
@@ -213,8 +216,8 @@ nautilus_text_view_initialize (NautilusTextView *text_view)
merge_bonobo_menu_items,
text_view);
- /* finally, show the view itself */
- gtk_widget_show (GTK_WIDGET (text_view));
+ /* finally, we can show everything */
+ gtk_widget_show_all (GTK_WIDGET (text_view));
}
static void
@@ -235,6 +238,12 @@ nautilus_text_view_destroy (GtkObject *object)
detach_file (text_view);
gdk_font_unref (text_view->details->current_font);
+
+ if (text_view->details->file_handle) {
+ gnome_vfs_async_cancel (text_view->details->file_handle);
+ }
+
+ g_free (text_view->details->buffer);
g_free (text_view->details);
@@ -249,29 +258,127 @@ nautilus_text_view_get_nautilus_view (NautilusTextView *text_view)
return text_view->details->nautilus_view;
}
-
-/* here's where we do the real work of inserting the text from the file into the view */
+/* this routine is called when we're finished reading to deallocate the buffer and
+ * put up an error message if necessary
+ */
static void
-nautilus_text_view_update (NautilusTextView *text_view)
+done_file_read (NautilusTextView *text_view, gboolean succeeded)
{
- char *uri;
- int text_size;
- int position;
- char *text_ptr;
-
- uri = nautilus_file_get_uri (text_view->details->file);
- gtk_editable_delete_text (GTK_EDITABLE (text_view->details->text_display), 0, -1);
+ if (text_view->details->buffer != NULL) {
+ g_free (text_view->details->buffer);
+ text_view->details->buffer = NULL;
+ }
+}
+
+/* this callback handles the next chunk of data from the file by copying it into the
+ * text field and reading more if necessary */
+static void
+file_read_callback (GnomeVFSAsyncHandle *vfs_handle,
+ GnomeVFSResult result,
+ gpointer buffer,
+ GnomeVFSFileSize bytes_requested,
+ GnomeVFSFileSize bytes_read,
+ gpointer callback_data)
+{
+ int byte_count;
+ NautilusTextView *text_view;
+ text_view = NAUTILUS_TEXT_VIEW (callback_data);
- if (nautilus_read_entire_file (uri, &text_size, &text_ptr) == GNOME_VFS_OK) {
- position = 0;
+ byte_count = bytes_read;
+ text_view->details->file_size += bytes_read;
+
+ if (result == GNOME_VFS_OK && bytes_read != 0) {
+ /* write the buffer into the text field */
+ gtk_text_freeze (GTK_TEXT (text_view->details->text_display));
+
+ gtk_text_set_point (GTK_TEXT (text_view->details->text_display),
+ gtk_text_get_length (GTK_TEXT (text_view->details->text_display)));
gtk_text_insert (GTK_TEXT (text_view->details->text_display),
NULL, NULL, NULL,
- text_ptr, text_size);
-
- g_free (text_ptr);
- }
+ buffer, bytes_read);
+
+ gtk_text_set_point (GTK_TEXT (text_view->details->text_display), 0);
+ gtk_text_thaw (GTK_TEXT (text_view->details->text_display));
+ /* read more if necessary */
+ if (text_view->details->file_size < MAX_FILE_SIZE) {
+ if (bytes_read == bytes_requested) {
+ gnome_vfs_async_read (text_view->details->file_handle,
+ text_view->details->buffer,
+ TEXT_VIEW_CHUNK_SIZE,
+ file_read_callback,
+ callback_data);
+ return;
+ }
+ } else {
+ char *filename = nautilus_file_get_name(text_view->details->file);
+ char *message = g_strdup_printf (_("Sorry, but %s is too large for Nautilus to load all of it."), filename);
+ nautilus_error_dialog (message, _("Couldn't delete pattern"),
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (text_view))));
+ g_free (filename);
+ g_free (message);
+ }
+
+ }
+
+ done_file_read (text_view, result == GNOME_VFS_OK || result == GNOME_VFS_ERROR_EOF);
+}
+
+
+/* this callback gets invoked when the open call has completed */
+static void
+file_opened_callback (GnomeVFSAsyncHandle *vfs_handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+ NautilusTextView *text_view;
+ text_view = NAUTILUS_TEXT_VIEW (callback_data);
+
+ if (result != GNOME_VFS_OK) {
+ text_view->details->file_handle = NULL;
+ done_file_read (text_view, FALSE);
+ return;
+ }
+
+ text_view->details->file_size = 0;
+
+ /* read the next chunck of the file */
+ gnome_vfs_async_read (text_view->details->file_handle,
+ text_view->details->buffer,
+ TEXT_VIEW_CHUNK_SIZE,
+ file_read_callback,
+ callback_data);
+}
+
+/* callback to handle reading a chunk of the file
+ * here's where we do the real work of inserting the text from the file into the view
+ * Since the file may be large, and possibly remote, we load the text asynchronously and
+ * progressively, one chunk at a time.
+ */
+static void
+nautilus_text_view_update (NautilusTextView *text_view)
+{
+ char *uri;
+
+ uri = nautilus_file_get_uri (text_view->details->file);
+ gtk_editable_delete_text (GTK_EDITABLE (text_view->details->text_display), 0, -1);
+
+ if (text_view->details->file_handle) {
+ gnome_vfs_async_cancel (text_view->details->file_handle);
+ }
+
+ /* if necessary, allocate the buffer */
+ if (text_view->details->buffer == NULL) {
+ text_view->details->buffer = g_malloc (TEXT_VIEW_CHUNK_SIZE);
+ }
+
+ /* kick things off by opening the file asynchronously */
+ gnome_vfs_async_open (&text_view->details->file_handle,
+ uri,
+ GNOME_VFS_OPEN_READ,
+ file_opened_callback,
+ text_view);
g_free (uri);
}
diff --git a/components/text/services/Makefile.am b/components/text/services/Makefile.am
index 13994aabd..0d8b82ecd 100644
--- a/components/text/services/Makefile.am
+++ b/components/text/services/Makefile.am
@@ -4,6 +4,7 @@ servicesdir = $(datadir)/nautilus/services/text
services_DATA = \
english_to_french.xml \
+ french_to_english.xml \
google.xml \
webster.xml \
$(NULL)
diff --git a/components/text/services/french_to_english.xml b/components/text/services/french_to_english.xml
new file mode 100644
index 000000000..2df40fa92
--- /dev/null
+++ b/components/text/services/french_to_english.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<service label="Translate from French to English" source="document"
+template="http://dellbert.differnet.com/catalog/FetchBabel.cgi?lang=fr_en&amp;text=%s" tooltip="Translate this document from French to English using BabelFish"/>
diff --git a/src/file-manager/fm-properties-window.c b/src/file-manager/fm-properties-window.c
index e84b12fcd..2d22a9faa 100644
--- a/src/file-manager/fm-properties-window.c
+++ b/src/file-manager/fm-properties-window.c
@@ -1349,7 +1349,6 @@ create_emblems_page (GtkNotebook *notebook, NautilusFile *file)
continue;
}
- g_message ("emblem name is %s", emblem_name);
button = gtk_check_button_new ();
image_and_label_table = gtk_table_new (2, 1, FALSE);