diff options
author | Alexander Larsson <alla@lysator.liu.se> | 2002-04-14 02:08:07 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@src.gnome.org> | 2002-04-14 02:08:07 +0000 |
commit | 516f65d074706dacc9524d69f65b25cc95a3a774 (patch) | |
tree | e3ff5395c9f0d23a1f88e51b7b0af108a7e85dec | |
parent | 9d79e3731c643d8f4cceea40f7d8afe49d6a30a0 (diff) | |
download | nautilus-516f65d074706dacc9524d69f65b25cc95a3a774.tar.gz |
New text view, by Dave Camp <dave@ximian.com>
2002-04-13 Alexander Larsson <alla@lysator.liu.se>
* components/text/Makefile.am:
* components/text/Nautilus_View_text.server.in:
* components/text/nautilus-text-view.c:
New text view, by Dave Camp <dave@ximian.com>
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | components/text/Makefile.am | 23 | ||||
-rw-r--r-- | components/text/Nautilus_View_text.server.in | 3 | ||||
-rw-r--r-- | components/text/Nautilus_View_text.server.in.in | 3 | ||||
-rw-r--r-- | components/text/nautilus-text-view.c | 965 |
5 files changed, 183 insertions, 818 deletions
@@ -1,5 +1,12 @@ 2002-04-13 Alexander Larsson <alla@lysator.liu.se> + * components/text/Makefile.am: + * components/text/Nautilus_View_text.server.in: + * components/text/nautilus-text-view.c: + New text view, by Dave Camp <dave@ximian.com> + +2002-04-13 Alexander Larsson <alla@lysator.liu.se> + * src/nautilus-shell-ui.xml: Fix tooltip name for Home. Patch from dave <dm9211@bris.ac.uk> diff --git a/components/text/Makefile.am b/components/text/Makefile.am index 68b069388..b108400a3 100644 --- a/components/text/Makefile.am +++ b/components/text/Makefile.am @@ -12,25 +12,22 @@ INCLUDES = \ -DGTK_ENABLE_BROKEN \ $(NULL) -# bin_PROGRAMS = nautilus-text-view +bin_PROGRAMS = nautilus-text-view nautilus_text_view_SOURCES = \ - nautilus-text-view.c \ - nautilus-text-view.h \ - main.c + nautilus-text-view.c -#nautilus_text_view_LDADD = \ -# $(top_builddir)/libnautilus/libnautilus.la \ -# $(top_builddir)/libnautilus-private/libnautilus-private.la \ -# $(COMPONENT_LIBS) \ -# $(NULL) +nautilus_text_view_LDADD = \ + ../../libnautilus/libnautilus.la \ + $(COMPONENT_LIBS) \ + $(NULL) -uidir = $(datadir)/gnome-2.0/ui -ui_DATA = nautilus-text-view-ui.xml +#uidir = $(datadir)/gnome-2.0/ui +#ui_DATA = nautilus-text-view-ui.xml serverdir = $(libdir)/bonobo/servers server_in_files = Nautilus_View_text.server.in -# server_DATA = $(server_in_files:.server.in=.server) +server_DATA = $(server_in_files:.server.in=.server) @INTLTOOL_SERVER_RULE@ -EXTRA_DIST = $(server_in_files) $(ui_DATA) $(nautilus_text_view_SOURCES) # $(server_DATA) +EXTRA_DIST = $(server_in_files) $(nautilus_text_view_SOURCES) # $(server_DATA) #$(ui_data) diff --git a/components/text/Nautilus_View_text.server.in b/components/text/Nautilus_View_text.server.in index 7b6ea351b..1ffb0f646 100644 --- a/components/text/Nautilus_View_text.server.in +++ b/components/text/Nautilus_View_text.server.in @@ -13,7 +13,6 @@ <item value="IDL:Bonobo/Unknown:1.0"/> <item value="IDL:Bonobo/Control:1.0"/> <item value="IDL:Nautilus/View:1.0"/> - <item value="IDL:Bonobo/Zoomable:1.0"/> </oaf_attribute> <oaf_attribute name="name" type="string" _value="Text view"/> <oaf_attribute name="description" type="string" _value="Text view"/> @@ -21,8 +20,6 @@ <oaf_attribute name="bonobo:supported_mime_types" type="stringv"> <item value="text/plain"/> <item value="text/*"/> - <item value="x-directory/webdav"/> - <item value="x-directory/webdav-prefer-directory"/> </oaf_attribute> <oaf_attribute name="nautilus:view_as_name" type="string" _value="Text"/> <oaf_attribute name="nautilus:view_as_label" type="string" _value="View as Text"/> diff --git a/components/text/Nautilus_View_text.server.in.in b/components/text/Nautilus_View_text.server.in.in index 7b6ea351b..1ffb0f646 100644 --- a/components/text/Nautilus_View_text.server.in.in +++ b/components/text/Nautilus_View_text.server.in.in @@ -13,7 +13,6 @@ <item value="IDL:Bonobo/Unknown:1.0"/> <item value="IDL:Bonobo/Control:1.0"/> <item value="IDL:Nautilus/View:1.0"/> - <item value="IDL:Bonobo/Zoomable:1.0"/> </oaf_attribute> <oaf_attribute name="name" type="string" _value="Text view"/> <oaf_attribute name="description" type="string" _value="Text view"/> @@ -21,8 +20,6 @@ <oaf_attribute name="bonobo:supported_mime_types" type="stringv"> <item value="text/plain"/> <item value="text/*"/> - <item value="x-directory/webdav"/> - <item value="x-directory/webdav-prefer-directory"/> </oaf_attribute> <oaf_attribute name="nautilus:view_as_name" type="string" _value="Text"/> <oaf_attribute name="nautilus:view_as_label" type="string" _value="View as Text"/> diff --git a/components/text/nautilus-text-view.c b/components/text/nautilus-text-view.c index a0155cf36..8c7778fcb 100644 --- a/components/text/nautilus-text-view.c +++ b/components/text/nautilus-text-view.c @@ -2,6 +2,7 @@ /* * Copyright (C) 2000 Eazel, Inc. + * Copyright (C) 2002 Sun Microsystems Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,870 +18,236 @@ * along with this library; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Author: Andy Hertzfeld <andy@eazel.com> + * Authors: Dave Camp <dave@ximian.com> + * based on component by Andy Hertzfeld <andy@eazel.com> + * * */ /* text view - display a text file */ #include <config.h> -#include "nautilus-text-view.h" - -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-zoomable.h> -#include <eel/eel-background.h> -#include <eel/eel-gdk-extensions.h> -#include <eel/eel-gdk-pixbuf-extensions.h> -#include <eel/eel-glib-extensions.h> -#include <eel/eel-gtk-extensions.h> -#include <eel/eel-gtk-macros.h> -#include <eel/eel-stock-dialogs.h> -#include <eel/eel-string.h> + +#include <string.h> +#include <eel/eel-debug.h> #include <eel/eel-vfs-extensions.h> -#include <eel/eel-xml-extensions.h> - -#include <libxml/parser.h> -#include <gnome.h> -#include <gtk/gtkeventbox.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomevfs/gnome-vfs.h> -#include <libnautilus-private/nautilus-bonobo-extensions.h> -#include <libnautilus-private/nautilus-file-utilities.h> -#include <libnautilus-private/nautilus-file.h> -#include <libnautilus-private/nautilus-global-preferences.h> -#include <libnautilus/libnautilus.h> -#include <libnautilus/nautilus-clipboard.h> -#include <limits.h> - -#define MAX_SERVICE_ITEMS 32 -#define TEXT_VIEW_CHUNK_SIZE 65536 -#define MAX_FILE_SIZE 1024*1024 -#define MAX_SELECTION_SIZE 256 - -#define ADDITIONAL_SERVICES_MENU_PATH "/menu/Text view/Services Placeholder" - -#define NAUTILUS_PREFERENCES_TEXT_VIEW_FONT "components/text_view/font" -#define NAUTILUS_PREFERENCES_TEXT_VIEW_STANDARD_FONT_SIZE "components/text_view/standard_font_size" - -struct NautilusTextViewDetails { - NautilusFile *file; - GtkWidget *event_box; - GnomeVFSAsyncHandle *file_handle; - char *buffer; - - BonoboZoomable *zoomable; - int zoom_index; - - GtkWidget *container; - GtkWidget *text_display; - - int service_item_count; - GnomeVFSFileSize file_size; - gboolean service_item_uses_selection[MAX_SERVICE_ITEMS]; -}; - -/* structure for handling service menu item execution */ -typedef struct { - NautilusTextView *text_view; - char *service_template; - char *source_mode; -} ServiceMenuItemParameters; - -static void nautilus_text_view_class_init (NautilusTextViewClass *klass); -static void nautilus_text_view_init (NautilusTextView *view); -static void nautilus_text_view_destroy (BonoboObject *object); -static void nautilus_text_view_finalize (GObject *object); -static void nautilus_text_view_update (NautilusTextView *text_view); -static void text_view_load_location_callback (NautilusView *view, - const char *location, - NautilusTextView *text_view); -static void merge_bonobo_menu_items (BonoboControl *control, - gboolean state, - gpointer user_data); -static void nautilus_text_view_update_font (NautilusTextView *text_view); -static int update_service_menu_items (GtkWidget *widget, - GdkEventButton *event, - gpointer *user_data); -static void zoomable_set_zoom_level_callback (BonoboZoomable *zoomable, - float level, - NautilusTextView *view); -static void zoomable_zoom_in_callback (BonoboZoomable *zoomable, - NautilusTextView *directory_view); -static void zoomable_zoom_out_callback (BonoboZoomable *zoomable, - NautilusTextView *directory_view); -static void zoomable_zoom_to_fit_callback (BonoboZoomable *zoomable, - NautilusTextView *directory_view); -static void nautilus_text_view_load_uri (NautilusTextView *view, - const char *uri); -static void font_changed_callback (gpointer callback_data); - -EEL_CLASS_BOILERPLATE (NautilusTextView, - nautilus_text_view, - NAUTILUS_TYPE_VIEW) - -static float text_view_preferred_zoom_levels[] = { .25, .50, .75, 1.0, 1.5, 2.0, 4.0 }; -static int text_view_font_size_deltas[] = { -6, -4, -2, 0, +4, +10, +22 }; -static const int max_preferred_zoom_levels = (sizeof (text_view_preferred_zoom_levels) / - sizeof (float)) - 1; +#include <gtk/gtktextview.h> +#include <gtk/gtkscrolledwindow.h> +#include <libnautilus/nautilus-view.h> +#include <libnautilus/nautilus-view-standard-main.h> -static void -nautilus_text_view_class_init (NautilusTextViewClass *klass) -{ - GObjectClass *gobject_class; - BonoboObjectClass *object_class; - - gobject_class = G_OBJECT_CLASS (klass); - object_class = BONOBO_OBJECT_CLASS (klass); - - gobject_class->finalize = nautilus_text_view_finalize; - object_class->destroy = nautilus_text_view_destroy; - - /* Text view component fonts */ - eel_preferences_default_set_string (NAUTILUS_PREFERENCES_TEXT_VIEW_FONT, - EEL_USER_LEVEL_INTERMEDIATE, - "fixed"); - eel_preferences_default_set_integer (NAUTILUS_PREFERENCES_TEXT_VIEW_STANDARD_FONT_SIZE, - EEL_USER_LEVEL_INTERMEDIATE, - 14); -} +#define FACTORY_IID "OAFIID:nautilus_text_view_factory:124ae209-d356-418f-8757-54e071cb3a21" +#define VIEW_IID "OAFIID:nautilus_text_view:fa466311-17c1-435c-8231-c9fc434b6437" -/* initialize ourselves by connecting to the location change signal and allocating our subviews */ +typedef struct { + NautilusView base; -static void -nautilus_text_view_init (NautilusTextView *text_view) -{ - GtkWidget *scrolled_window; - - text_view->details = g_new0 (NautilusTextViewDetails, 1); - - text_view->details->event_box = gtk_event_box_new (); - - nautilus_view_construct (NAUTILUS_VIEW (text_view), text_view->details->event_box); - - /* set up the zoomable interface */ - text_view->details->zoomable = bonobo_zoomable_new (); - text_view->details->zoom_index = 3; - - g_signal_connect_object (text_view->details->zoomable, "set_zoom_level", - G_CALLBACK (zoomable_set_zoom_level_callback), text_view, 0); - g_signal_connect_object (text_view->details->zoomable, "zoom_in", - G_CALLBACK (zoomable_zoom_in_callback), text_view, 0); - g_signal_connect_object (text_view->details->zoomable, "zoom_out", - G_CALLBACK (zoomable_zoom_out_callback), text_view, 0); - g_signal_connect_object (text_view->details->zoomable, "zoom_to_fit", - G_CALLBACK (zoomable_zoom_to_fit_callback), text_view, 0); - - bonobo_zoomable_set_parameters_full (text_view->details->zoomable, - 1.0, .25, 4.0, TRUE, TRUE, FALSE, - text_view_preferred_zoom_levels, NULL, - G_N_ELEMENTS (text_view_preferred_zoom_levels)); - - bonobo_object_add_interface (BONOBO_OBJECT (text_view), - BONOBO_OBJECT (text_view->details->zoomable)); - - - g_signal_connect_object (text_view, "load_location", - G_CALLBACK (text_view_load_location_callback), text_view, 0); - - /* allocate a vbox to contain the text widget */ - text_view->details->container = gtk_vbox_new (FALSE, 0); - gtk_container_set_border_width (GTK_CONTAINER (text_view->details->container), 0); - gtk_container_add (GTK_CONTAINER (text_view->details->event_box), GTK_WIDGET (text_view->details->container)); - - /* allocate the text object */ - text_view->details->text_display = gtk_text_new (NULL, NULL); - g_object_ref (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 */ - gtk_signal_connect_after (GTK_OBJECT (text_view->details->text_display), - "button_release_event", - G_CALLBACK (update_service_menu_items), - text_view); - gtk_signal_connect_after (GTK_OBJECT (text_view->details->text_display), - "key_press_event", - G_CALLBACK (update_service_menu_items), - text_view); - - /* set the font of the text object */ - nautilus_text_view_update_font (text_view); - - /* Keep track of font changes */ - eel_preferences_add_callback_while_alive (NAUTILUS_PREFERENCES_TEXT_VIEW_FONT, - font_changed_callback, - text_view, - G_OBJECT (text_view)); - eel_preferences_add_callback_while_alive (NAUTILUS_PREFERENCES_TEXT_VIEW_STANDARD_FONT_SIZE, - font_changed_callback, - text_view, - G_OBJECT (text_view)); - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (scrolled_window), text_view->details->text_display); - 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 */ - g_signal_connect_object (nautilus_view_get_bonobo_control (NAUTILUS_VIEW (text_view)), - "activate", - G_CALLBACK (merge_bonobo_menu_items), text_view, 0); - - /* finally, we can show everything */ - gtk_widget_show_all (GTK_WIDGET (text_view->details->event_box)); -} + GtkTextBuffer *buffer; -static void -detach_file (NautilusTextView *text_view) -{ - nautilus_file_unref (text_view->details->file); - text_view->details->file = NULL; -} + EelReadFileHandle *read_handle; +} NautilusTextView; -static void -nautilus_text_view_destroy (BonoboObject *object) -{ - NautilusTextView *text_view; - - text_view = NAUTILUS_TEXT_VIEW (object); - - detach_file (text_view); - - if (text_view->details->file_handle) { - gnome_vfs_async_cancel (text_view->details->file_handle); - } - - if (text_view->details->text_display) { - g_object_unref (text_view->details->text_display); - text_view->details->text_display = NULL; - } -} +typedef struct { + NautilusViewClass base; +} NautilusTextViewClass; -static void -nautilus_text_view_finalize (GObject *object) -{ - NautilusTextView *text_view; - - text_view = NAUTILUS_TEXT_VIEW (object); +static const char *encodings_to_try[2]; +static int n_encodings_to_try; - g_free (text_view->details->buffer); - g_free (text_view->details); +static GType nautilus_text_view_get_type (void); - EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); -} +BONOBO_CLASS_BOILERPLATE (NautilusTextView, nautilus_text_view, + NautilusView, NAUTILUS_TYPE_VIEW); -/* here's a callback for the async close, which does nothing */ static void -file_close_callback (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer callback_data) +unload_contents (NautilusTextView *view) { -} - -/* this routine is called when we're finished reading to deallocate the buffer and - * put up an error message if necessary - */ -static void -done_file_read (NautilusTextView *text_view, gboolean succeeded) -{ - if (text_view->details->buffer != NULL) { - g_free (text_view->details->buffer); - text_view->details->buffer = NULL; - } - - if (text_view->details->file_handle != NULL) { - gnome_vfs_async_close (text_view->details->file_handle, - file_close_callback, - 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) -{ - NautilusTextView *text_view; - GtkText *display; - char *name, *message; - - text_view = NAUTILUS_TEXT_VIEW (callback_data); - - text_view->details->file_size += bytes_read; + GtkTextIter start; + GtkTextIter end; - /* at EOF, bytes_read is 0 and result is GNOME_VFS_OK */ - if (result == GNOME_VFS_OK && bytes_read > 0) { - if (text_view->details->text_display != NULL) { - /* write the buffer into the text field */ - display = GTK_TEXT (text_view->details->text_display); + gtk_text_buffer_get_start_iter (view->buffer, &start); + gtk_text_buffer_get_end_iter (view->buffer, &end); - gtk_text_freeze (display); - gtk_text_set_point (display, - gtk_text_get_length (display)); - gtk_text_insert (display, - NULL, NULL, NULL, - buffer, bytes_read); - gtk_text_thaw (display); - } - - /* read more if necessary */ - if (text_view->details->file_size < MAX_FILE_SIZE) { - gnome_vfs_async_read (text_view->details->file_handle, - text_view->details->buffer, - TEXT_VIEW_CHUNK_SIZE, - file_read_callback, - callback_data); - return; - } else { - name = nautilus_file_get_display_name (text_view->details->file); - message = g_strdup_printf (_("Sorry, but %s is too large for Nautilus to load all of it."), - name); - - eel_show_error_dialog (message, _("File too large"), NULL); - - g_free (name); - g_free (message); - } - } - - done_file_read (text_view, result == GNOME_VFS_OK || result == GNOME_VFS_ERROR_EOF); + gtk_text_buffer_delete (view->buffer, &start, &end); } - -/* this callback gets invoked when the open call has completed */ static void -file_opened_callback (GnomeVFSAsyncHandle *vfs_handle, - GnomeVFSResult result, - gpointer callback_data) +cancel_load (NautilusTextView *view) { - 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, - GNOME_VFS_PRIORITY_DEFAULT, - file_opened_callback, - text_view); - g_free (uri); + if (view->read_handle) { + eel_read_file_cancel (view->read_handle); + view->read_handle = NULL; + } } - -static void -nautilus_text_view_load_uri (NautilusTextView *text_view, - const char *uri) +static GnomeVFSFileSize +my_strnlen(char *str, GnomeVFSFileSize file_size) { - - detach_file (text_view); - text_view->details->file = nautilus_file_get (uri); - - nautilus_text_view_update (text_view); -} + GnomeVFSFileSize len; -static void -text_view_load_location_callback (NautilusView *view, - const char *location, - NautilusTextView *text_view) -{ - nautilus_view_report_load_underway (NAUTILUS_VIEW (text_view)); - nautilus_text_view_load_uri (text_view, location); - nautilus_view_report_load_complete (NAUTILUS_VIEW (text_view)); + len = 0; + while (*str != 0 && len < file_size) { + str++; + len++; + } + return len; } -/* update the font and redraw */ static void -nautilus_text_view_update_font (NautilusTextView *text_view) +read_file_callback (GnomeVFSResult result, + GnomeVFSFileSize file_size, + char *file_contents, + gpointer callback_data) { - char *font_name; - GdkFont *font; - int font_size; - - font_size = eel_preferences_get_enum (NAUTILUS_PREFERENCES_TEXT_VIEW_STANDARD_FONT_SIZE); - - font_size += text_view_font_size_deltas[text_view->details->zoom_index]; - - font_name = eel_preferences_get (NAUTILUS_PREFERENCES_TEXT_VIEW_FONT); - g_return_if_fail (font_name != NULL); - - font = nautilus_font_factory_get_font_by_family (font_name, font_size); - g_free (font_name); + NautilusView *view; + NautilusTextView *text_view; + GnomeVFSFileSize length; + gsize converted_length; + char *utf8_contents; + GError *conversion_error; + GtkTextIter iter; + int i; - g_return_if_fail (font != NULL); - - eel_gtk_widget_set_font (text_view->details->text_display, font); - gdk_font_unref (font); + view = callback_data; + text_view = callback_data; - gtk_editable_changed (GTK_EDITABLE (text_view->details->text_display)); -} - -/* handle merging in the menu items */ -static void -handle_ui_event (BonoboUIComponent *ui, - const char *id, - Bonobo_UIComponent_EventType type, - const char *state, - NautilusTextView *view) -{ - if (type == Bonobo_UIComponent_STATE_CHANGED - && eel_str_is_equal (state, "1")) { - eel_preferences_set (NAUTILUS_PREFERENCES_TEXT_VIEW_FONT, id); - } -} - -static char * -get_selected_text (GtkEditable *text_widget) -{ - if (!text_widget->has_selection || text_widget->selection_start_pos == text_widget->selection_end_pos) { - return NULL; - } + text_view->read_handle = NULL; + + if (result != GNOME_VFS_OK) { + nautilus_view_report_load_failed (view); + return; + } - return gtk_editable_get_chars (text_widget, text_widget->selection_start_pos, text_widget->selection_end_pos); + /* Find first embedded zero, if any */ + length = my_strnlen (file_contents, file_size); + + utf8_contents = NULL; + if (!g_utf8_validate (file_contents, length, NULL)) { + for (i = 0; i < n_encodings_to_try; i++) { + conversion_error = NULL; + utf8_contents = g_convert (file_contents, length, + "UTF-8", encodings_to_try[i], + NULL, &converted_length, &conversion_error); + if (utf8_contents != NULL) { + length = converted_length; + break; + } + g_error_free (conversion_error); + } + + if (utf8_contents == NULL) { + nautilus_view_report_load_failed (view); + return; + } + file_contents = utf8_contents; + } + + gtk_text_buffer_get_start_iter (text_view->buffer, &iter); + + gtk_text_buffer_insert (text_view->buffer, &iter, + file_contents, length); + + if (utf8_contents) { + g_free (utf8_contents); + } + + nautilus_view_report_load_complete (view); } -/* here's the callback to handle the actual work for service menu items */ static void -handle_service_menu_item (BonoboUIComponent *ui, gpointer user_data, const char *verb) +load_location (NautilusView *view, const char *location_uri) { - char *selected_text, *mapped_text, *uri; - ServiceMenuItemParameters *parameters; - int text_size; - char *text_ptr; - - parameters = (ServiceMenuItemParameters *) user_data; - - /* determine if we should operate on the whole document or just the selection */ - if (eel_strcmp (parameters->source_mode, "document") == 0) { - selected_text = gtk_editable_get_chars (GTK_EDITABLE (parameters->text_view->details->text_display), 0, -1); - if (selected_text && strlen (selected_text) > 0) { - /* formulate the url */ - mapped_text = gnome_vfs_escape_string (selected_text); - uri = g_strdup_printf (parameters->service_template, mapped_text); - g_free (mapped_text); - - /* load the resultant page through gnome-vfs */ - /* FIXME: This uses sync. I/O. */ - if (eel_read_entire_file (uri, &text_size, &text_ptr) == GNOME_VFS_OK) { - gtk_editable_delete_text (GTK_EDITABLE (parameters->text_view->details->text_display), 0, -1); - gtk_text_insert (GTK_TEXT (parameters->text_view->details->text_display), - NULL, NULL, NULL, - text_ptr, text_size); - g_free (text_ptr); - } - - g_free (uri); - } - g_free (selected_text); - } else { - selected_text = get_selected_text (GTK_EDITABLE (parameters->text_view->details->text_display)); - if (selected_text != NULL) { - /* truncate the selection to a reasonable size */ - if (strlen (selected_text) > MAX_SELECTION_SIZE) { - selected_text [MAX_SELECTION_SIZE] = '\0'; - } - - /* formulate the url */ - mapped_text = gnome_vfs_escape_string (selected_text); - uri = g_strdup_printf (parameters->service_template, mapped_text); - - /* goto the url */ - nautilus_view_open_location_in_this_window (NAUTILUS_VIEW (parameters->text_view), uri); - - g_free (uri); - g_free (selected_text); - g_free (mapped_text); - } - - } -} - -/* utility routines to add service items to the services menu by iterating the services/text directory */ + NautilusTextView *text_view; + + text_view = (NautilusTextView *)view; + + cancel_load (text_view); + unload_contents (text_view); + + nautilus_view_report_load_underway (view); -static ServiceMenuItemParameters * -service_menu_item_parameters_new (NautilusTextView *text_view, const char *service_template, const char *source_mode) -{ - ServiceMenuItemParameters *result; - - result = g_new0 (ServiceMenuItemParameters, 1); - result->text_view = text_view; - result->service_template = g_strdup (service_template); - if (source_mode != NULL) { - result->source_mode = g_strdup (source_mode); - } else { - result->source_mode = NULL; - } - - return result; + text_view->read_handle = + eel_read_entire_file_async (location_uri, 0, + read_file_callback, view); } static void -service_menu_item_parameters_free (gpointer data, GClosure *closure) +nautilus_text_view_instance_init (NautilusTextView *view) { - ServiceMenuItemParameters *parameters = (ServiceMenuItemParameters *) data; + GtkWidget *text_view; + GtkWidget *scrolled_window; + + text_view = gtk_text_view_new (); + gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE); - g_free (parameters->service_template); - g_free (parameters->source_mode); - g_free (parameters); -} + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_container_add (GTK_CONTAINER (scrolled_window), text_view); -/* add a service menu entry from the passed in xml file */ -static void -add_one_service (NautilusTextView *text_view, BonoboControl *control, const char *xml_path, int* index) -{ - xmlDocPtr service_definition; - xmlNodePtr service_node; - char *label, *escaped_label; - char *tooltip, *template; - char *verb_name, *item_path, *verb_path, *source_mode; - ServiceMenuItemParameters *parameters; - BonoboUIComponent *ui; - - /* load and parse the xml file */ - service_definition = xmlParseFile(xml_path); - ui = bonobo_control_get_ui_component (control); - - if (service_definition != NULL) { - service_node = xmlDocGetRootElement (service_definition); - - /* extract the label and template */ - label = eel_xml_get_property_translated (service_node, "label"); - tooltip = eel_xml_get_property_translated (service_node, "tooltip"); - template = xmlGetProp (service_node, "template"); - source_mode = xmlGetProp (service_node, "source"); - - if (label != NULL && template != NULL) { - /* allocate a structure containing the text_view and template to pass in as the user data */ - escaped_label = eel_str_double_underscores (label); - parameters = service_menu_item_parameters_new (text_view, template, source_mode); - - text_view->details->service_item_uses_selection[*index] = - eel_strcmp (source_mode, "document") != 0; - - /* use bonobo to add the menu item */ - nautilus_bonobo_add_numbered_menu_item - (ui, - ADDITIONAL_SERVICES_MENU_PATH, - *index, - escaped_label, - NULL); - g_free (escaped_label); - - /* set the tooltip if one was present */ - if (tooltip) { - item_path = nautilus_bonobo_get_numbered_menu_item_path - (ui, ADDITIONAL_SERVICES_MENU_PATH, *index); - nautilus_bonobo_set_tip (ui, item_path, tooltip); - g_free (item_path); - } - - verb_name = nautilus_bonobo_get_numbered_menu_item_command - (ui, ADDITIONAL_SERVICES_MENU_PATH, *index); - bonobo_ui_component_add_verb_full (ui, verb_name, - g_cclosure_new (G_CALLBACK (handle_service_menu_item), - parameters, - service_menu_item_parameters_free)); - - /* initially disable the item unless it's document-based; it will be enabled if there's a selection */ - verb_path = g_strdup_printf ("/commands/%s", verb_name); - if (eel_strcmp (source_mode, "document") != 0) { - nautilus_bonobo_set_sensitive (ui, verb_path, FALSE); - } - g_free (verb_name); - g_free (verb_path); - - *index += 1; - } - - xmlFree (label); - xmlFree (template); - xmlFree (tooltip); - - /* release the xml file */ - xmlFreeDoc (service_definition); - } -} + gtk_widget_show (text_view); + gtk_widget_show (scrolled_window); -/* iterate through the passed in services directory to add services to the menu. - * Don't add a service with the same name as one that has already been added. - */ -static GList * -add_services_to_menu (NautilusTextView *text_view, - BonoboControl *control, - const char *services_directory, - GList *added_services, - int* index) -{ - GnomeVFSResult result; - GList *file_list, *element; - GnomeVFSFileInfo *current_file_info; - char *services_uri, *service_xml_path; - - services_uri = gnome_vfs_get_uri_from_local_path (services_directory); - result = gnome_vfs_directory_list_load (&file_list, services_uri, GNOME_VFS_FILE_INFO_DEFAULT); - - if (result != GNOME_VFS_OK) { - g_free (services_uri); - return added_services; - } - - /* iterate through the directory */ - for (element = file_list; element != NULL; element = element->next) { - current_file_info = element->data; - - if (*index >= MAX_SERVICE_ITEMS) { - break; - } - - if (eel_istr_has_suffix (current_file_info->name, ".xml")) { - if (g_list_find_custom (added_services, current_file_info->name, - (GCompareFunc) strcmp) == NULL) { - service_xml_path = nautilus_make_path (services_directory, current_file_info->name); - add_one_service (text_view, control, service_xml_path, index); - added_services = g_list_prepend (added_services, g_strdup (current_file_info->name)); - g_free (service_xml_path); - } - } - } - - g_free (services_uri); - gnome_vfs_file_info_list_free (file_list); - return added_services; -} + view->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); -/* build the services menu from the shared and private services/text directories */ -static void -nautilus_text_view_build_service_menu (NautilusTextView *text_view, BonoboControl *control) -{ - char *services_directory, *user_directory, *nautilus_datadir; - GList *added_services; - int index; - - index = 0; - - /* first, add the services from the global directory */ - nautilus_datadir = nautilus_make_path (DATADIR, "nautilus"); - services_directory = nautilus_make_path (nautilus_datadir, "services/text"); - added_services = add_services_to_menu (text_view, control, services_directory, NULL, &index); - g_free (nautilus_datadir); - g_free (services_directory); - - /* now add services from the user-specific directory, if any */ - user_directory = nautilus_get_user_directory (); - services_directory = nautilus_make_path (user_directory, "services/text"); - added_services = add_services_to_menu (text_view, control, services_directory, added_services, &index); - g_free (services_directory); - g_free (user_directory); - - /* add any services that are present in the updates folder */ - user_directory = nautilus_get_user_directory (); - services_directory = nautilus_make_path (user_directory, "updates/services/text"); - added_services = add_services_to_menu (text_view, control, services_directory, added_services, &index); - g_free (services_directory); - g_free (user_directory); - - text_view->details->service_item_count = index; - eel_g_list_free_deep (added_services); + nautilus_view_construct (NAUTILUS_VIEW (view), scrolled_window); } -/* handle updating the service menu items according to the selection state of the text display */ -static int -update_service_menu_items (GtkWidget *widget, GdkEventButton *event, gpointer *user_data) -{ - NautilusTextView *text_view; - BonoboUIComponent *ui; - BonoboControl *control; - GtkEditable *text_widget; - gboolean has_selection; - char *verb_name, *verb_path; - int index; - - text_view = NAUTILUS_TEXT_VIEW (user_data); - control = nautilus_view_get_bonobo_control (NAUTILUS_VIEW (text_view)); - ui = bonobo_control_get_ui_component (control); - - /* determine if there is a selection */ - text_widget = GTK_EDITABLE (text_view->details->text_display); - has_selection = text_widget->has_selection && text_widget->selection_start_pos != text_widget->selection_end_pos; - - /* iterate through the menu items, handling the selection state */ - - for (index = 0; index < text_view->details->service_item_count; index++) { - verb_name = nautilus_bonobo_get_numbered_menu_item_command - (ui, ADDITIONAL_SERVICES_MENU_PATH, index); - - verb_path = g_strdup_printf ("/commands/%s", verb_name); - if (text_view->details->service_item_uses_selection[index]) { - nautilus_bonobo_set_sensitive (ui, - verb_path, - has_selection); - } - g_free (verb_name); - g_free (verb_path); - } - - return FALSE; -} - -/* this routine is invoked when the view is activated to merge in our menu items */ static void -merge_bonobo_menu_items (BonoboControl *control, gboolean state, gpointer user_data) +nautilus_text_view_destroy (GtkObject *object) { - NautilusTextView *text_view; - - g_assert (BONOBO_IS_CONTROL (control)); - - text_view = NAUTILUS_TEXT_VIEW (user_data); - - if (state) { - /* FIXME bugzilla.gnome.org 41274: - * See nautilus-text-view-ui.xml. Need to query system for - * available fonts instead of hard coding the font list - */ - - /* FIXME bugzilla.gnome.org 47907: - * The "GTK System Font" string is hard coded in many places. - * Please see nautilus-text-view-ui.xml. - */ - nautilus_view_set_up_ui (NAUTILUS_VIEW (text_view), - DATADIR, - "nautilus-text-view-ui.xml", - "nautilus-text-view"); - - nautilus_text_view_build_service_menu (text_view, control); - - g_signal_connect_object (bonobo_control_get_ui_component (control), "ui_event", - G_CALLBACK (handle_ui_event), text_view, 0); + NautilusTextView *view; + + view = (NautilusTextView*)object; - nautilus_clipboard_set_up_editable_in_control (GTK_EDITABLE (text_view->details->text_display), - control, - FALSE); - - } - - /* Note that we do nothing if state is FALSE. Nautilus content - * views are never explicitly deactivated - */ + cancel_load (view); } -/* handle the zoomable signals */ static void -nautilus_text_view_zoom_to_level (NautilusTextView *text_view, int zoom_index) +nautilus_text_view_class_init (NautilusTextViewClass *class) { - int pinned_zoom_index; - pinned_zoom_index = zoom_index; - - if (pinned_zoom_index < 0) { - pinned_zoom_index = 0; - } else if (pinned_zoom_index > max_preferred_zoom_levels) { - pinned_zoom_index = max_preferred_zoom_levels; - } - - if (pinned_zoom_index != text_view->details->zoom_index) { - text_view->details->zoom_index = pinned_zoom_index; - bonobo_zoomable_report_zoom_level_changed ( - text_view->details->zoomable, - text_view_preferred_zoom_levels[pinned_zoom_index], NULL); - nautilus_text_view_update_font (text_view); - } - } + GtkObjectClass *object_class = GTK_OBJECT_CLASS (class); + NautilusViewClass *view_class = NAUTILUS_VIEW_CLASS (class); + const char *charset; + gboolean utf8; -static void -nautilus_text_view_bump_zoom_level (NautilusTextView *text_view, int increment) -{ - nautilus_text_view_zoom_to_level (text_view, text_view->details->zoom_index + increment); -} + view_class->load_location = load_location; -static void -zoomable_zoom_in_callback (BonoboZoomable *zoomable, NautilusTextView *text_view) -{ - nautilus_text_view_bump_zoom_level (text_view, 1); -} + object_class->destroy = nautilus_text_view_destroy; -static void -zoomable_zoom_out_callback (BonoboZoomable *zoomable, NautilusTextView *text_view) -{ - nautilus_text_view_bump_zoom_level (text_view, -1); + n_encodings_to_try = 0; + utf8 = g_get_charset (&charset); + + if (!utf8) { + encodings_to_try[n_encodings_to_try++] = charset; + } + + if (g_ascii_strcasecmp (charset, "ISO-8859-1") != 0) { + encodings_to_try[n_encodings_to_try++] = "ISO-8859-1"; + } } -static int -zoom_index_from_float (float zoom_level) +int +main (int argc, char *argv[]) { - int i; - - for (i = 0; i < max_preferred_zoom_levels; i++) { - float this, epsilon; - - /* if we're close to a zoom level */ - this = text_view_preferred_zoom_levels [i]; - epsilon = this * 0.01; - - if (zoom_level < this + epsilon) - return i; - } + if (g_getenv ("NAUTILUS_DEBUG") != NULL) { + eel_make_warnings_and_criticals_stop_in_debugger (); + } - return max_preferred_zoom_levels; + return nautilus_view_standard_main ("nautilus-text-view", + VERSION, + GETTEXT_PACKAGE, + GNOMELOCALEDIR, + argc, + argv, + FACTORY_IID, + VIEW_IID, + nautilus_view_create_from_get_type_function, + NULL, + nautilus_text_view_get_type); } -static void -zoomable_set_zoom_level_callback (BonoboZoomable *zoomable, float level, NautilusTextView *view) -{ - nautilus_text_view_zoom_to_level (view, zoom_index_from_float (level)); -} -static void -zoomable_zoom_to_fit_callback (BonoboZoomable *zoomable, NautilusTextView *view) -{ - nautilus_text_view_zoom_to_level (view, zoom_index_from_float (1.0)); -} -static void -font_changed_callback (gpointer callback_data) -{ - g_return_if_fail (NAUTILUS_IS_TEXT_VIEW (callback_data)); - - nautilus_text_view_update_font (NAUTILUS_TEXT_VIEW (callback_data)); -} |