[gedit/wip/loader-saver: 19/54] Port to GtkSourceFileLoader



commit 83c665e10c493c0ed790c9794114a7cc98e614ad
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun Jun 22 19:18:00 2014 +0200

    Port to GtkSourceFileLoader

 gedit/gedit-document.c          |  336 +++---------------
 gedit/gedit-document.h          |   19 -
 gedit/gedit-io-error-info-bar.c |   33 +-
 gedit/gedit-tab.c               |  744 +++++++++++++++++++++++----------------
 4 files changed, 509 insertions(+), 623 deletions(-)
---
diff --git a/gedit/gedit-document.c b/gedit/gedit-document.c
index 598e14d..9c83147 100644
--- a/gedit/gedit-document.c
+++ b/gedit/gedit-document.c
@@ -46,12 +46,8 @@
 
 #define NO_LANGUAGE_NAME "_NORMAL_"
 
-static void    gedit_document_load_real        (GeditDocument                *doc,
-                                                GFile                        *location,
-                                                const GeditEncoding          *encoding,
-                                                gint                          line_pos,
-                                                gint                          column_pos,
-                                                gboolean                      create);
+static void    gedit_document_loaded_real      (GeditDocument *doc,
+                                                const GError  *error);
 
 static void    gedit_document_save_real        (GeditDocument                *doc,
                                                 GFile                        *location,
@@ -89,12 +85,9 @@ struct _GeditDocumentPrivate
        GeditDocumentCompressionType compression_type;
 
        /* Temp data while loading */
-       GeditDocumentLoader *loader;
        gboolean             create; /* Create file if uri points
                                      * to a non existing file */
        const GeditEncoding *requested_encoding;
-       gint                 requested_line_pos;
-       gint                 requested_column_pos;
 
        /* Saving stuff */
        GeditDocumentSaver *saver;
@@ -135,7 +128,6 @@ enum
 {
        CURSOR_MOVED,
        LOAD,
-       LOADING,
        LOADED,
        SAVE,
        SAVING,
@@ -278,7 +270,6 @@ gedit_document_dispose (GObject *object)
                doc->priv->location = NULL;
        }
 
-       g_clear_object (&doc->priv->loader);
        g_clear_object (&doc->priv->editor_settings);
        g_clear_object (&doc->priv->metadata_info);
        g_clear_object (&doc->priv->search_context);
@@ -443,7 +434,7 @@ gedit_document_class_init (GeditDocumentClass *klass)
        buf_class->mark_set = gedit_document_mark_set;
        buf_class->changed = gedit_document_changed;
 
-       klass->load = gedit_document_load_real;
+       klass->loaded = gedit_document_loaded_real;
        klass->save = gedit_document_save_real;
 
        g_object_class_install_property (object_class, PROP_LOCATION,
@@ -590,19 +581,6 @@ gedit_document_class_init (GeditDocumentClass *klass)
                              G_TYPE_INT,
                              G_TYPE_BOOLEAN);
 
-
-       document_signals[LOADING] =
-               g_signal_new ("loading",
-                             G_OBJECT_CLASS_TYPE (object_class),
-                             G_SIGNAL_RUN_LAST,
-                             G_STRUCT_OFFSET (GeditDocumentClass, loading),
-                             NULL, NULL,
-                             gedit_marshal_VOID__UINT64_UINT64,
-                             G_TYPE_NONE,
-                             2,
-                             G_TYPE_UINT64,
-                             G_TYPE_UINT64);
-
        document_signals[LOADED] =
                g_signal_new ("loaded",
                              G_OBJECT_CLASS_TYPE (object_class),
@@ -1253,291 +1231,79 @@ gedit_document_get_readonly (GeditDocument *doc)
 }
 
 static void
-reset_temp_loading_data (GeditDocument *doc)
+query_info_cb (GFile         *location,
+              GAsyncResult  *result,
+              GeditDocument *doc)
 {
-       /* the loader has been used, throw it away */
-       g_object_unref (doc->priv->loader);
-       doc->priv->loader = NULL;
+       GFileInfo *info;
+       const gchar *content_type = NULL;
+       gboolean read_only = FALSE;
+       GError *error = NULL;
 
-       doc->priv->requested_encoding = NULL;
-       doc->priv->requested_line_pos = 0;
-       doc->priv->requested_column_pos = 0;
-}
+       info = g_file_query_info_finish (location, result, &error);
 
-static void
-document_loader_loaded (GeditDocumentLoader *loader,
-                       const GError        *error,
-                       GeditDocument       *doc)
-{
-       /* load was successful */
-       if (error == NULL ||
-           (error->domain == GEDIT_DOCUMENT_ERROR &&
-            error->code == GEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK))
+       if (error != NULL)
        {
-               GtkTextIter iter;
-               GFileInfo *info;
-               const gchar *content_type = NULL;
-               gboolean read_only = FALSE;
-               GTimeVal mtime = {0, 0};
-
-               info = gedit_document_loader_get_info (loader);
+               g_warning ("Document loading: query info error: %s", error->message);
+               g_error_free (error);
+               error = NULL;
+       }
 
-               if (info)
+       if (info != NULL)
+       {
+               if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
                {
-                       if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
-                       {
-                               content_type = g_file_info_get_attribute_string (info,
-                                                                                
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
-                       }
-
-                       if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
-                               g_file_info_get_modification_time (info, &mtime);
-
-                       if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
-                       {
-                               read_only = !g_file_info_get_attribute_boolean (info,
-                                                                               
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
-                       }
+                       content_type = g_file_info_get_attribute_string (info, 
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
                }
 
-               doc->priv->mtime = mtime;
-               doc->priv->readonly = read_only;
-
-               g_get_current_time (&doc->priv->time_of_last_save_or_load);
-
-               doc->priv->externally_modified = FALSE;
-               doc->priv->deleted = FALSE;
-
-               set_encoding (doc,
-                             gedit_document_loader_get_encoding (loader),
-                             (doc->priv->requested_encoding != NULL));
-
-               gedit_document_set_content_type (doc, content_type);
-
-               set_newline_type (doc,
-                                 gedit_document_loader_get_newline_type (loader));
-
-               set_compression_type (doc,
-                                     gedit_document_loader_get_compression_type (loader));
-
-               /* move the cursor at the requested line if any */
-               if (doc->priv->requested_line_pos > 0)
-               {
-                       gedit_document_goto_line_offset (doc,
-                                                        doc->priv->requested_line_pos - 1,
-                                                        doc->priv->requested_column_pos < 1 ? 0 : 
doc->priv->requested_column_pos - 1);
-               }
-               else
+               if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
                {
-                       /* if enabled, move to the position stored in the metadata */
-                       if (g_settings_get_boolean (doc->priv->editor_settings, 
GEDIT_SETTINGS_RESTORE_CURSOR_POSITION))
-                       {
-                               gchar *pos;
-                               gint offset;
-
-                               pos = gedit_document_get_metadata (doc, GEDIT_METADATA_ATTRIBUTE_POSITION);
-
-                               offset = pos ? atoi (pos) : 0;
-                               g_free (pos);
-
-                               gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc),
-                                                                   &iter,
-                                                                   MAX (offset, 0));
-
-                               /* make sure it's a valid position, if the file
-                                * changed we may have ended up in the middle of
-                                * a utf8 character cluster */
-                               if (!gtk_text_iter_is_cursor_position (&iter))
-                               {
-                                       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc),
-                                                                       &iter);
-                               }
-                       }
-                       /* otherwise to the top */
-                       else
-                       {
-                               gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc),
-                                                               &iter);
-                       }
-
-                       gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
+                       read_only = !g_file_info_get_attribute_boolean (info, 
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
                }
 
-               if (!doc->priv->language_set_by_user)
-               {
-                       GtkSourceLanguage *language = guess_language (doc);
-
-                       gedit_debug_message (DEBUG_DOCUMENT, "Language: %s",
-                                            language != NULL ? gtk_source_language_get_name (language) : 
"None");
-
-                       set_language (doc, language, FALSE);
-               }
+               g_object_unref (info);
        }
 
-       /* special case creating a named new doc */
-       else if (doc->priv->create &&
-                (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_FOUND) &&
-                (g_file_has_uri_scheme (doc->priv->location, "file")))
-       {
-               reset_temp_loading_data (doc);
-
-               g_signal_emit (doc,
-                              document_signals[LOADED],
-                              0,
-                              NULL);
+       _gedit_document_set_readonly (doc, read_only);
 
-               return;
-       }
+       g_get_current_time (&doc->priv->time_of_last_save_or_load);
 
-       g_signal_emit (doc,
-                      document_signals[LOADED],
-                      0,
-                      error);
+       doc->priv->externally_modified = FALSE;
+       doc->priv->deleted = FALSE;
 
-       reset_temp_loading_data (doc);
-}
+       gedit_document_set_content_type (doc, content_type);
 
-static void
-document_loader_loading (GeditDocumentLoader *loader,
-                        gboolean             completed,
-                        const GError        *error,
-                        GeditDocument       *doc)
-{
-       if (completed)
-       {
-               document_loader_loaded (loader, error, doc);
-       }
-       else
+       if (!doc->priv->language_set_by_user)
        {
-               goffset size = 0;
-               goffset read;
-               GFileInfo *info;
-
-               info = gedit_document_loader_get_info (loader);
-
-               if (info && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
-               {
-                       size = g_file_info_get_attribute_uint64 (info,
-                                                                G_FILE_ATTRIBUTE_STANDARD_SIZE);
-               }
+               GtkSourceLanguage *language = guess_language (doc);
 
-               read = gedit_document_loader_get_bytes_read (loader);
+               gedit_debug_message (DEBUG_DOCUMENT, "Language: %s",
+                                    language != NULL ? gtk_source_language_get_name (language) : "None");
 
-               g_signal_emit (doc,
-                              document_signals[LOADING],
-                              0,
-                              read,
-                              size);
+               set_language (doc, language, FALSE);
        }
-}
-
-static void
-gedit_document_load_real (GeditDocument       *doc,
-                         GFile               *location,
-                         const GeditEncoding *encoding,
-                         gint                 line_pos,
-                         gint                 column_pos,
-                         gboolean             create)
-{
-       gchar *uri;
-
-       g_return_if_fail (doc->priv->loader == NULL);
 
-       uri = g_file_get_uri (location);
-       gedit_debug_message (DEBUG_DOCUMENT, "load_real: uri = %s", uri);
-       g_free (uri);
-
-       /* create a loader. It will be destroyed when loading is completed */
-       doc->priv->loader = gedit_document_loader_new (doc, location, encoding);
-
-       g_signal_connect (doc->priv->loader,
-                         "loading",
-                         G_CALLBACK (document_loader_loading),
-                         doc);
-
-       doc->priv->create = create;
-       doc->priv->requested_encoding = encoding;
-       doc->priv->requested_line_pos = line_pos;
-       doc->priv->requested_column_pos = column_pos;
-
-       gedit_document_set_location (doc, location);
-
-       gedit_document_loader_load (doc->priv->loader);
+       /* Async operation finished. */
+       g_object_unref (doc);
 }
 
-void
-_gedit_document_load_stream (GeditDocument       *doc,
-                            GInputStream        *stream,
-                            const GeditEncoding *encoding,
-                            gint                 line_pos,
-                            gint                 column_pos)
-{
-       g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
-       g_return_if_fail (G_IS_INPUT_STREAM (stream));
-       g_return_if_fail (doc->priv->loader == NULL);
-
-       gedit_debug_message (DEBUG_DOCUMENT, "load stream");
-
-       /* create a loader. It will be destroyed when loading is completed */
-       doc->priv->loader = gedit_document_loader_new_from_stream (doc, stream, encoding);
-
-       g_signal_connect (doc->priv->loader,
-                         "loading",
-                         G_CALLBACK (document_loader_loading),
-                         doc);
-
-       doc->priv->create = FALSE;
-       doc->priv->requested_encoding = encoding;
-       doc->priv->requested_line_pos = line_pos;
-       doc->priv->requested_column_pos = column_pos;
-
-       gedit_document_set_location (doc, NULL);
-
-       gedit_document_loader_load (doc->priv->loader);
-}
-
-/*
- * _gedit_document_load:
- * @doc: the #GeditDocument.
- * @location: the location where to load the document from.
- * @encoding: (allow-none): the #GeditEncoding to encode the document, or %NULL.
- * @line_pos: the line to show.
- * @column_pos: the column to show.
- * @create: whether the document should be created if it doesn't exist.
- *
- * Load a document. This results in the "load" signal to be emitted.
- */
-void
-_gedit_document_load (GeditDocument       *doc,
-                     GFile               *location,
-                     const GeditEncoding *encoding,
-                     gint                 line_pos,
-                     gint                 column_pos,
-                     gboolean             create)
-{
-       g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
-       g_return_if_fail (location != NULL);
-       g_return_if_fail (gedit_utils_is_valid_location (location));
-
-       g_signal_emit (doc, document_signals[LOAD], 0, location, encoding,
-                      line_pos, column_pos, create);
-}
-
-/*
- * _gedit_document_load_cancel:
- * @doc: the #GeditDocument.
- *
- * Cancel load of a document.
- */
-gboolean
-_gedit_document_load_cancel (GeditDocument *doc)
-{
-       g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
-
-       if (doc->priv->loader == NULL)
-               return FALSE;
-
-       return gedit_document_loader_cancel (doc->priv->loader);
+static void
+gedit_document_loaded_real (GeditDocument *doc,
+                           const GError  *error)
+{
+       GFile *location = gtk_source_file_get_location (doc->priv->file);
+
+       /* Keep the doc alive during the async operation. */
+       g_object_ref (doc);
+
+       g_file_query_info_async (location,
+                                G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+                                G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
+                                G_FILE_QUERY_INFO_NONE,
+                                G_PRIORITY_DEFAULT,
+                                NULL,
+                                (GAsyncReadyCallback) query_info_cb,
+                                doc);
 }
 
 static gboolean
diff --git a/gedit/gedit-document.h b/gedit/gedit-document.h
index 6db609c..3566577 100644
--- a/gedit/gedit-document.h
+++ b/gedit/gedit-document.h
@@ -118,10 +118,6 @@ struct _GeditDocumentClass
                                         gint                 column_pos,
                                         gboolean             create);
 
-       void (* loading)                (GeditDocument    *document,
-                                        goffset           size,
-                                        goffset           total_size);
-
        void (* loaded)                 (GeditDocument    *document,
                                         const GError     *error);
 
@@ -224,21 +220,6 @@ GtkSourceSearchContext     *gedit_document_get_search_context      (GeditDocument
 
 /* Non exported functions */
 
-void            _gedit_document_load           (GeditDocument       *doc,
-                                                GFile               *location,
-                                                const GeditEncoding *encoding,
-                                                gint                 line_pos,
-                                                gint                 column_pos,
-                                                gboolean             create);
-
-void            _gedit_document_load_stream    (GeditDocument       *doc,
-                                                GInputStream        *stream,
-                                                const GeditEncoding *encoding,
-                                                gint                 line_pos,
-                                                gint                 column_pos);
-
-gboolean        _gedit_document_load_cancel    (GeditDocument       *doc);
-
 void            _gedit_document_save           (GeditDocument       *doc,
                                                 GeditDocumentSaveFlags flags);
 
diff --git a/gedit/gedit-io-error-info-bar.c b/gedit/gedit-io-error-info-bar.c
index ce0d02a..2fdb252 100644
--- a/gedit/gedit-io-error-info-bar.c
+++ b/gedit/gedit-io-error-info-bar.c
@@ -346,7 +346,7 @@ parse_error (const GError *error,
 
 GtkWidget *
 gedit_unrecoverable_reverting_error_info_bar_new (GFile        *location,
-                                                     const GError *error)
+                                                 const GError *error)
 {
        gchar *error_message = NULL;
        gchar *message_details = NULL;
@@ -357,8 +357,8 @@ gedit_unrecoverable_reverting_error_info_bar_new (GFile        *location,
 
        g_return_val_if_fail (G_IS_FILE (location), NULL);
        g_return_val_if_fail (error != NULL, NULL);
-       g_return_val_if_fail ((error->domain == GEDIT_DOCUMENT_ERROR) ||
-                             (error->domain == G_IO_ERROR), NULL);
+       g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_LOADER_ERROR ||
+                             error->domain == G_IO_ERROR, NULL);
 
        full_formatted_uri = g_file_get_parse_name (location);
 
@@ -590,7 +590,6 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
        gchar *error_message = NULL;
        gchar *message_details = NULL;
        gchar *full_formatted_uri;
-       gchar *encoding_name;
        gchar *uri_for_display;
        gchar *temp_uri_for_display;
        GtkWidget *info_bar;
@@ -598,11 +597,11 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
        gboolean convert_error = FALSE;
 
        g_return_val_if_fail (error != NULL, NULL);
-       g_return_val_if_fail ((error->domain == G_CONVERT_ERROR) ||
-                             (error->domain == GEDIT_DOCUMENT_ERROR) ||
-                             (error->domain == G_IO_ERROR), NULL);
+       g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_LOADER_ERROR ||
+                             error->domain == G_IO_ERROR ||
+                             error->domain == G_CONVERT_ERROR, NULL);
 
-       if (location)
+       if (location != NULL)
        {
                full_formatted_uri = g_file_get_parse_name (location);
        }
@@ -622,11 +621,6 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
        uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
        g_free (temp_uri_for_display);
 
-       if (encoding != NULL)
-               encoding_name = gtk_source_encoding_to_string (encoding);
-       else
-               encoding_name = g_strdup ("UTF-8");
-
        if (is_gio_error (error, G_IO_ERROR_TOO_MANY_LINKS))
        {
                message_details = g_strdup (_("The number of followed links is limited and the actual file 
could not be found within this limit."));
@@ -636,16 +630,16 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
                message_details = g_strdup (_("You do not have the permissions necessary to open the file."));
        }
        else if ((is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding == NULL) ||
-                (error->domain == GEDIT_DOCUMENT_ERROR &&
-                error->code == GEDIT_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED))
+                (error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
+                 error->code == GTK_SOURCE_FILE_LOADER_ERROR_ENCODING_AUTO_DETECTION_FAILED))
        {
                message_details = g_strconcat (_("Unable to detect the character encoding."), "\n",
                                               _("Please check that you are not trying to open a binary 
file."), "\n",
                                               _("Select a character encoding from the menu and try again."), 
NULL);
                convert_error = TRUE;
        }
-       else if (error->domain == GEDIT_DOCUMENT_ERROR &&
-                error->code == GEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK)
+       else if (error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
+                error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK)
        {
                error_message = g_strdup_printf (_("There was a problem opening the file “%s”."),
                                                 uri_for_display);
@@ -659,12 +653,16 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
        }
        else if (is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding != NULL)
        {
+               gchar *encoding_name = gtk_source_encoding_to_string (encoding);
+
                error_message = g_strdup_printf (_("Could not open the file “%s” using the “%s” character 
encoding."),
                                                 uri_for_display,
                                                 encoding_name);
                message_details = g_strconcat (_("Please check that you are not trying to open a binary 
file."), "\n",
                                               _("Select a different character encoding from the menu and try 
again."), NULL);
                convert_error = TRUE;
+
+               g_free (encoding_name);
        }
        else
        {
@@ -691,7 +689,6 @@ gedit_io_loading_error_info_bar_new (GFile                   *location,
        }
 
        g_free (uri_for_display);
-       g_free (encoding_name);
        g_free (error_message);
        g_free (message_details);
 
diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
index 15d37e4..8e65f73 100644
--- a/gedit/gedit-tab.c
+++ b/gedit/gedit-tab.c
@@ -23,6 +23,7 @@
 #include <config.h>
 #endif
 
+#include <stdlib.h>
 #include <glib/gi18n.h>
 
 #include "gedit-tab.h"
@@ -57,9 +58,12 @@ struct _GeditTabPrivate
        GFile                  *tmp_save_location;
 
        /* tmp data for loading */
+       GtkSourceFileLoader    *loader;
+       GCancellable           *cancellable;
        gint                    tmp_line_pos;
        gint                    tmp_column_pos;
-       const GtkSourceEncoding *tmp_encoding;
+       const GtkSourceEncoding *tmp_encoding; /* TODO remove */
+       guint                   idle_scroll;
 
        GTimer                 *timer;
 
@@ -72,6 +76,10 @@ struct _GeditTabPrivate
        gint                    auto_save : 1;
 
        gint                    ask_if_externally_modified : 1;
+
+       /* tmp data for loading */
+       guint                   load_create : 1;
+       guint                   user_requested_encoding : 1;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GeditTab, gedit_tab, GTK_TYPE_BOX)
@@ -96,6 +104,11 @@ static guint signals[LAST_SIGNAL] = { 0 };
 
 static gboolean gedit_tab_auto_save (GeditTab *tab);
 
+static void load (GeditTab                *tab,
+                 const GtkSourceEncoding *encoding,
+                 gint                     line_pos,
+                 gint                     column_pos);
+
 static void
 install_auto_save_timeout (GeditTab *tab)
 {
@@ -208,6 +221,14 @@ gedit_tab_set_property (GObject      *object,
 }
 
 static void
+clear_loading (GeditTab *tab)
+{
+       g_clear_object (&tab->priv->loader);
+       g_clear_object (&tab->priv->cancellable);
+       tab->priv->load_create = FALSE;
+}
+
+static void
 gedit_tab_dispose (GObject *object)
 {
        GeditTab *tab = GEDIT_TAB (object);
@@ -222,6 +243,8 @@ gedit_tab_dispose (GObject *object)
        g_clear_object (&tab->priv->tmp_save_location);
        g_clear_object (&tab->priv->editor);
 
+       clear_loading (tab);
+
        G_OBJECT_CLASS (gedit_tab_parent_class)->dispose (object);
 }
 
@@ -237,6 +260,12 @@ gedit_tab_finalize (GObject *object)
 
        remove_auto_save_timeout (tab);
 
+       if (tab->priv->idle_scroll != 0)
+       {
+               g_source_remove (tab->priv->idle_scroll);
+               tab->priv->idle_scroll = 0;
+       }
+
        G_OBJECT_CLASS (gedit_tab_parent_class)->finalize (object);
 }
 
@@ -559,37 +588,30 @@ io_loading_error_info_bar_response (GtkWidget *info_bar,
                                    gint       response_id,
                                    GeditTab  *tab)
 {
-       GeditDocument *doc;
        GeditView *view;
        GFile *location;
        const GtkSourceEncoding *encoding;
 
-       doc = gedit_tab_get_document (tab);
+       g_return_if_fail (tab->priv->loader != NULL);
+
        view = gedit_tab_get_view (tab);
 
-       location = gedit_document_get_location (doc);
+       location = gtk_source_file_loader_get_location (tab->priv->loader);
 
        switch (response_id)
        {
                case GTK_RESPONSE_OK:
-                       g_return_if_fail (location != NULL);
-
                        encoding = gedit_conversion_error_info_bar_get_encoding (GTK_WIDGET (info_bar));
 
-                       if (encoding != NULL)
-                       {
-                               tab->priv->tmp_encoding = encoding;
-                       }
-
                        set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
                        gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
 
-                       _gedit_document_load (doc,
-                                             location,
-                                             tab->priv->tmp_encoding,
-                                             tab->priv->tmp_line_pos,
-                                             tab->priv->tmp_column_pos,
-                                             FALSE);
+                       tab->priv->load_create = FALSE;
+
+                       load (tab,
+                             encoding,
+                             tab->priv->tmp_line_pos,
+                             tab->priv->tmp_column_pos);
                        break;
 
                case GTK_RESPONSE_YES:
@@ -597,6 +619,7 @@ io_loading_error_info_bar_response (GtkWidget *info_bar,
                        tab->priv->editable = TRUE;
                        gtk_text_view_set_editable (GTK_TEXT_VIEW (view), TRUE);
                        set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
+                       clear_loading (tab);
                        break;
 
                default:
@@ -608,11 +631,6 @@ io_loading_error_info_bar_response (GtkWidget *info_bar,
                        remove_tab (tab);
                        break;
        }
-
-       if (location != NULL)
-       {
-               g_object_unref (location);
-       }
 }
 
 static void
@@ -638,15 +656,10 @@ load_cancelled (GtkWidget *bar,
                gint       response_id,
                GeditTab  *tab)
 {
-       GeditDocument *doc;
-
        g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (tab->priv->info_bar));
+       g_return_if_fail (G_IS_CANCELLABLE (tab->priv->cancellable));
 
-       doc = gedit_tab_get_document (tab);
-
-       g_object_ref (tab);
-       _gedit_document_load_cancel (doc);
-       g_object_unref (tab);
+       g_cancellable_cancel (tab->priv->cancellable);
 }
 
 static void
@@ -660,6 +673,8 @@ unrecoverable_reverting_error_info_bar_response (GtkWidget *info_bar,
 
        set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
 
+       clear_loading (tab);
+
        view = gedit_tab_get_view (tab);
        gtk_widget_grab_focus (GTK_WIDGET (view));
 }
@@ -742,13 +757,10 @@ show_loading_info_bar (GeditTab *tab)
                }
                else
                {
-                       msg = g_strdup_printf (_("Reverting %s"),
-                                              name_markup);
+                       msg = g_strdup_printf (_("Reverting %s"), name_markup);
                }
 
-               bar = gedit_progress_info_bar_new ("document-revert",
-                                                  msg,
-                                                  TRUE);
+               bar = gedit_progress_info_bar_new ("document-revert", msg, TRUE);
        }
        else
        {
@@ -765,13 +777,10 @@ show_loading_info_bar (GeditTab *tab)
                }
                else
                {
-                       msg = g_strdup_printf (_("Loading %s"),
-                                              name_markup);
+                       msg = g_strdup_printf (_("Loading %s"), name_markup);
                }
 
-               bar = gedit_progress_info_bar_new ("document-open",
-                                                  msg,
-                                                  TRUE);
+               bar = gedit_progress_info_bar_new ("document-open", msg, TRUE);
        }
 
        g_signal_connect (bar,
@@ -901,40 +910,6 @@ info_bar_set_progress (GeditTab *tab,
        }
 }
 
-static void
-document_loading (GeditDocument *document,
-                 goffset        size,
-                 goffset        total_size,
-                 GeditTab      *tab)
-{
-       gdouble elapsed_time;
-       gdouble total_time;
-       gdouble remaining_time;
-
-       g_return_if_fail ((tab->priv->state == GEDIT_TAB_STATE_LOADING) ||
-                         (tab->priv->state == GEDIT_TAB_STATE_REVERTING));
-
-       if (tab->priv->timer == NULL)
-       {
-               tab->priv->timer = g_timer_new ();
-       }
-
-       elapsed_time = g_timer_elapsed (tab->priv->timer, NULL);
-
-       /* elapsed_time / total_time = size / total_size */
-       total_time = (elapsed_time * total_size) / size;
-
-       remaining_time = total_time - elapsed_time;
-
-       /* Approximately more than 3 seconds remaining. */
-       if (remaining_time > 3.0)
-       {
-               show_loading_info_bar (tab);
-       }
-
-       info_bar_set_progress (tab, size, total_size);
-}
-
 static gboolean
 remove_tab_idle (GeditTab *tab)
 {
@@ -951,191 +926,8 @@ scroll_to_cursor (GeditTab *tab)
        view = gedit_tab_get_view (tab);
        gedit_view_scroll_to_cursor (view);
 
-       return FALSE;
-}
-
-static void
-document_loaded (GeditDocument *document,
-                const GError  *error,
-                GeditTab      *tab)
-{
-       GFile *location;
-
-       g_return_if_fail ((tab->priv->state == GEDIT_TAB_STATE_LOADING) ||
-                         (tab->priv->state == GEDIT_TAB_STATE_REVERTING));
-
-       if (tab->priv->timer != NULL)
-       {
-               g_timer_destroy (tab->priv->timer);
-               tab->priv->timer = NULL;
-       }
-
-       set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
-
-       location = gedit_document_get_location (document);
-
-       /* if the error is CONVERSION FALLBACK don't treat it as a normal error */
-       if (error != NULL &&
-           (error->domain != GEDIT_DOCUMENT_ERROR || error->code != 
GEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK))
-       {
-               if (tab->priv->state == GEDIT_TAB_STATE_LOADING)
-               {
-                       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING_ERROR);
-               }
-               else
-               {
-                       gedit_tab_set_state (tab, GEDIT_TAB_STATE_REVERTING_ERROR);
-               }
-
-               if (error->domain == G_IO_ERROR &&
-                   error->code == G_IO_ERROR_CANCELLED)
-               {
-                       /* remove the tab, but in an idle handler, since
-                        * we are in the handler of doc loaded and we
-                        * don't want doc and tab to be finalized now.
-                        */
-                       g_idle_add ((GSourceFunc) remove_tab_idle, tab);
-
-                       goto end;
-               }
-               else
-               {
-                       GtkWidget *info_bar;
-
-                       if (location != NULL)
-                       {
-                               gedit_recent_remove_if_local (location);
-                       }
-
-                       if (tab->priv->state == GEDIT_TAB_STATE_LOADING_ERROR)
-                       {
-                               info_bar = gedit_io_loading_error_info_bar_new (location,
-                                                                               tab->priv->tmp_encoding,
-                                                                               error);
-                               g_signal_connect (info_bar,
-                                                 "response",
-                                                 G_CALLBACK (io_loading_error_info_bar_response),
-                                                 tab);
-                       }
-                       else
-                       {
-                               g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_REVERTING_ERROR);
-
-                               info_bar = gedit_unrecoverable_reverting_error_info_bar_new (location, error);
-
-                               g_signal_connect (info_bar,
-                                                 "response",
-                                                 G_CALLBACK 
(unrecoverable_reverting_error_info_bar_response),
-                                                 tab);
-                       }
-
-                       set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
-               }
-
-               if (location)
-               {
-                       g_object_unref (location);
-               }
-
-               return;
-       }
-
-       gedit_recent_add_document (document);
-
-       if (error != NULL &&
-           error->domain == GEDIT_DOCUMENT_ERROR &&
-           error->code == GEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK)
-       {
-               GtkWidget *info_bar;
-
-               /* Set the tab as not editable as we have an error, the
-                  user can decide to make it editable again */
-               tab->priv->editable = FALSE;
-
-               info_bar = gedit_io_loading_error_info_bar_new (location,
-                                                               tab->priv->tmp_encoding,
-                                                               error);
-
-               g_signal_connect (info_bar,
-                                 "response",
-                                 G_CALLBACK (io_loading_error_info_bar_response),
-                                 tab);
-
-               set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
-       }
-
-       /* Scroll to the cursor when the document is loaded, we need
-          to do it in an idle as after the document is loaded the
-          textview is still redrawing and relocating its internals */
-       g_idle_add ((GSourceFunc)scroll_to_cursor, tab);
-
-       /* if the document is readonly we don't care how many times the document
-          is opened */
-       if (!gedit_document_get_readonly (document))
-       {
-               GList *all_documents;
-               GList *l;
-
-               all_documents = gedit_app_get_documents (GEDIT_APP (g_application_get_default ()));
-
-               for (l = all_documents; l != NULL; l = g_list_next (l))
-               {
-                       GeditDocument *cur_doc = l->data;
-
-                       if (cur_doc != document)
-                       {
-                               GFile *cur_location;
-
-                               cur_location = gedit_document_get_location (cur_doc);
-
-                               if (cur_location != NULL && location != NULL &&
-                                   g_file_equal (location, cur_location))
-                               {
-                                       GtkWidget *info_bar;
-
-                                       tab->priv->editable = FALSE;
-
-                                       info_bar = gedit_file_already_open_warning_info_bar_new (location);
-
-                                       g_signal_connect (info_bar,
-                                                         "response",
-                                                         G_CALLBACK 
(file_already_open_warning_info_bar_response),
-                                                         tab);
-
-                                       set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
-
-                                       g_object_unref (cur_location);
-                                       break;
-                               }
-
-                               if (cur_location != NULL)
-                               {
-                                       g_object_unref (cur_location);
-                               }
-                       }
-               }
-
-               g_list_free (all_documents);
-       }
-
-       gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
-
-       if (location == NULL)
-       {
-               /* FIXME: hackish */
-               gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (document), TRUE);
-       }
-
-       tab->priv->ask_if_externally_modified = TRUE;
-
-end:
-       if (location != NULL)
-       {
-               g_object_unref (location);
-       }
-
-       tab->priv->tmp_line_pos = 0;
-       tab->priv->tmp_encoding = NULL;
+       tab->priv->idle_scroll = 0;
+       return G_SOURCE_REMOVE;
 }
 
 static void
@@ -1656,16 +1448,6 @@ gedit_tab_init (GeditTab *tab)
                          tab);
 
        g_signal_connect (doc,
-                         "loading",
-                         G_CALLBACK (document_loading),
-                         tab);
-
-       g_signal_connect (doc,
-                         "loaded",
-                         G_CALLBACK (document_loaded),
-                         tab);
-
-       g_signal_connect (doc,
                          "saving",
                          G_CALLBACK (document_saving),
                          tab);
@@ -1975,6 +1757,362 @@ gedit_tab_get_from_document (GeditDocument *doc)
        return g_object_get_data (G_OBJECT (doc), GEDIT_TAB_KEY);
 }
 
+static void
+progress_cb (goffset   size,
+            goffset   total_size,
+            GeditTab *tab)
+{
+       gdouble elapsed_time;
+       gdouble total_time;
+       gdouble remaining_time;
+
+       g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_LOADING ||
+                         tab->priv->state == GEDIT_TAB_STATE_REVERTING);
+
+       if (tab->priv->timer == NULL)
+       {
+               tab->priv->timer = g_timer_new ();
+       }
+
+       elapsed_time = g_timer_elapsed (tab->priv->timer, NULL);
+
+       /* elapsed_time / total_time = size / total_size */
+       total_time = (elapsed_time * total_size) / size;
+
+       remaining_time = total_time - elapsed_time;
+
+       /* Approximately more than 3 seconds remaining. */
+       if (remaining_time > 3.0)
+       {
+               show_loading_info_bar (tab);
+       }
+
+       info_bar_set_progress (tab, size, total_size);
+}
+
+static void
+goto_line (GeditTab *tab)
+{
+       GeditDocument *doc = gedit_tab_get_document (tab);
+       GtkTextIter iter;
+
+       /* Move the cursor at the requested line if any. */
+       if (tab->priv->tmp_line_pos > 0)
+       {
+               gedit_document_goto_line_offset (doc,
+                                                tab->priv->tmp_line_pos - 1,
+                                                MAX (0, tab->priv->tmp_column_pos - 1));
+               return;
+       }
+
+       /* If enabled, move to the position stored in the metadata. */
+       if (g_settings_get_boolean (tab->priv->editor, GEDIT_SETTINGS_RESTORE_CURSOR_POSITION))
+       {
+               gchar *pos;
+               gint offset;
+
+               pos = gedit_document_get_metadata (doc, GEDIT_METADATA_ATTRIBUTE_POSITION);
+
+               offset = pos != NULL ? atoi (pos) : 0;
+               g_free (pos);
+
+               gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc),
+                                                   &iter,
+                                                   MAX (0, offset));
+
+               /* make sure it's a valid position, if the file
+                * changed we may have ended up in the middle of
+                * a utf8 character cluster */
+               if (!gtk_text_iter_is_cursor_position (&iter))
+               {
+                       gtk_text_iter_set_line_offset (&iter, 0);
+               }
+       }
+
+       /* Otherwise to the top. */
+       else
+       {
+               gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc), &iter);
+       }
+
+       gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
+}
+
+static void
+load_cb (GtkSourceFileLoader *loader,
+        GAsyncResult        *result,
+        GeditTab            *tab)
+{
+       GeditDocument *doc = gedit_tab_get_document (tab);
+       GFile *location = gtk_source_file_loader_get_location (loader);
+       GError *error = NULL;
+
+       g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_LOADING ||
+                         tab->priv->state == GEDIT_TAB_STATE_REVERTING);
+
+       gtk_source_file_loader_load_finish (loader, result, &error);
+
+       if (error != NULL)
+       {
+               g_warning ("File loading error: %s", error->message);
+       }
+
+       if (tab->priv->timer != NULL)
+       {
+               g_timer_destroy (tab->priv->timer);
+               tab->priv->timer = NULL;
+       }
+
+       set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
+
+       /* Load was successful. */
+       if (error == NULL ||
+           (error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
+            error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK))
+       {
+               if (tab->priv->user_requested_encoding)
+               {
+                       const GtkSourceEncoding *encoding = gtk_source_file_loader_get_encoding (loader);
+                       const gchar *charset = gtk_source_encoding_get_charset (encoding);
+
+                       gedit_document_set_metadata (doc,
+                                                    GEDIT_METADATA_ATTRIBUTE_ENCODING, charset,
+                                                    NULL);
+               }
+
+               goto_line (tab);
+       }
+
+       /* Special case creating a named new doc. */
+       else if (tab->priv->load_create &&
+                error->domain == G_IO_ERROR &&
+                error->code == G_IO_ERROR_NOT_FOUND &&
+                g_file_has_uri_scheme (location, "file"))
+       {
+               g_error_free (error);
+               error = NULL;
+       }
+
+       /* If the error is CONVERSION FALLBACK don't treat it as a normal error. */
+       if (error != NULL &&
+           (error->domain != GTK_SOURCE_FILE_LOADER_ERROR ||
+            error->code != GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK))
+       {
+               if (tab->priv->state == GEDIT_TAB_STATE_LOADING)
+               {
+                       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING_ERROR);
+               }
+               else
+               {
+                       gedit_tab_set_state (tab, GEDIT_TAB_STATE_REVERTING_ERROR);
+               }
+
+               if (error->domain == G_IO_ERROR &&
+                   error->code == G_IO_ERROR_CANCELLED)
+               {
+                       /* remove the tab, but in an idle handler, since
+                        * we are in the handler of doc loaded and we
+                        * don't want doc and tab to be finalized now.
+                        */
+                       /* FIXME idle still needed? */
+                       /* FIXME if an idle is still needed, it's safer to
+                        * remove the idle source during dispose().
+                        */
+                       g_idle_add ((GSourceFunc) remove_tab_idle, tab);
+               }
+               else
+               {
+                       GtkWidget *info_bar;
+
+                       if (location != NULL)
+                       {
+                               gedit_recent_remove_if_local (location);
+                       }
+
+                       if (tab->priv->state == GEDIT_TAB_STATE_LOADING_ERROR)
+                       {
+                               const GtkSourceEncoding *encoding;
+
+                               encoding = gtk_source_file_loader_get_encoding (loader);
+
+                               info_bar = gedit_io_loading_error_info_bar_new (location, encoding, error);
+
+                               g_signal_connect (info_bar,
+                                                 "response",
+                                                 G_CALLBACK (io_loading_error_info_bar_response),
+                                                 tab);
+                       }
+                       else
+                       {
+                               g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_REVERTING_ERROR);
+
+                               info_bar = gedit_unrecoverable_reverting_error_info_bar_new (location, error);
+
+                               g_signal_connect (info_bar,
+                                                 "response",
+                                                 G_CALLBACK 
(unrecoverable_reverting_error_info_bar_response),
+                                                 tab);
+                       }
+
+                       set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
+               }
+
+               goto end;
+       }
+
+       gedit_recent_add_document (doc);
+
+       if (error != NULL &&
+           error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
+           error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK)
+       {
+               GtkWidget *info_bar;
+               const GtkSourceEncoding *encoding;
+
+               /* Set the tab as not editable as we have an error, the user can
+                * decide to make it editable again.
+                */
+               tab->priv->editable = FALSE;
+
+               encoding = gtk_source_file_loader_get_encoding (loader);
+
+               info_bar = gedit_io_loading_error_info_bar_new (location, encoding, error);
+
+               g_signal_connect (info_bar,
+                                 "response",
+                                 G_CALLBACK (io_loading_error_info_bar_response),
+                                 tab);
+
+               set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
+       }
+
+       /* Scroll to the cursor when the document is loaded, we need to do it in
+        * an idle as after the document is loaded the textview is still
+        * redrawing and relocating its internals.
+        */
+       if (tab->priv->idle_scroll == 0)
+       {
+               tab->priv->idle_scroll = g_idle_add ((GSourceFunc)scroll_to_cursor, tab);
+       }
+
+       /* If the document is readonly we don't care how many times the document
+        * is opened.
+        */
+       if (!gedit_document_get_readonly (doc))
+       {
+               GList *all_documents;
+               GList *l;
+
+               all_documents = gedit_app_get_documents (GEDIT_APP (g_application_get_default ()));
+
+               for (l = all_documents; l != NULL; l = g_list_next (l))
+               {
+                       GeditDocument *cur_doc = l->data;
+
+                       if (cur_doc != doc)
+                       {
+                               GFile *cur_location;
+
+                               cur_location = gedit_document_get_location (cur_doc);
+
+                               if (cur_location != NULL && location != NULL &&
+                                   g_file_equal (location, cur_location))
+                               {
+                                       GtkWidget *info_bar;
+
+                                       tab->priv->editable = FALSE;
+
+                                       info_bar = gedit_file_already_open_warning_info_bar_new (location);
+
+                                       g_signal_connect (info_bar,
+                                                         "response",
+                                                         G_CALLBACK 
(file_already_open_warning_info_bar_response),
+                                                         tab);
+
+                                       set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
+
+                                       g_object_unref (cur_location);
+                                       break;
+                               }
+
+                               if (cur_location != NULL)
+                               {
+                                       g_object_unref (cur_location);
+                               }
+                       }
+               }
+
+               g_list_free (all_documents);
+       }
+
+       gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
+
+       if (location == NULL)
+       {
+               /* FIXME: hackish */
+               gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), TRUE);
+       }
+
+       tab->priv->ask_if_externally_modified = TRUE;
+
+       if (error == NULL)
+       {
+               clear_loading (tab);
+       }
+
+       g_signal_emit_by_name (doc, "loaded", NULL);
+
+end:
+       /* Async operation finished. */
+       g_object_unref (tab);
+
+       if (error != NULL)
+       {
+               g_error_free (error);
+       }
+}
+
+static void
+load (GeditTab                *tab,
+      const GtkSourceEncoding *encoding,
+      gint                     line_pos,
+      gint                     column_pos)
+{
+       g_return_if_fail (GTK_SOURCE_IS_FILE_LOADER (tab->priv->loader));
+
+       if (encoding != NULL)
+       {
+               tab->priv->user_requested_encoding = TRUE;
+
+               GSList *list = g_slist_append (NULL, (gpointer) encoding);
+               gtk_source_file_loader_set_candidate_encodings (tab->priv->loader, list);
+               g_slist_free (list);
+       }
+       else
+       {
+               tab->priv->user_requested_encoding = FALSE;
+               /* TODO */
+       }
+
+       tab->priv->tmp_line_pos = line_pos;
+       tab->priv->tmp_column_pos = column_pos;
+
+       g_clear_object (&tab->priv->cancellable);
+       tab->priv->cancellable = g_cancellable_new ();
+
+       /* Keep the tab alive during the async operation. */
+       g_object_ref (tab);
+
+       gtk_source_file_loader_load_async (tab->priv->loader,
+                                          G_PRIORITY_DEFAULT,
+                                          tab->priv->cancellable,
+                                          (GFileProgressCallback) progress_cb,
+                                          tab,
+                                          NULL,
+                                          (GAsyncReadyCallback) load_cb,
+                                          tab);
+}
+
 void
 _gedit_tab_load (GeditTab                *tab,
                 GFile                   *location,
@@ -1984,25 +2122,28 @@ _gedit_tab_load (GeditTab                *tab,
                 gboolean                 create)
 {
        GeditDocument *doc;
+       GtkSourceFile *file;
 
        g_return_if_fail (GEDIT_IS_TAB (tab));
        g_return_if_fail (G_IS_FILE (location));
        g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_NORMAL);
 
+       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
+
        doc = gedit_tab_get_document (tab);
+       file = gedit_document_get_file (doc);
 
-       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
+       if (tab->priv->loader != NULL)
+       {
+               g_warning ("GeditTab: file loader already exists.");
+               g_object_unref (tab->priv->loader);
+       }
 
-       tab->priv->tmp_line_pos = line_pos;
-       tab->priv->tmp_column_pos = column_pos;
-       tab->priv->tmp_encoding = encoding;
+       tab->priv->loader = gtk_source_file_loader_new (file, location);
 
-       _gedit_document_load (doc,
-                             location,
-                             encoding,
-                             line_pos,
-                             column_pos,
-                             create);
+       tab->priv->load_create = create != FALSE;
+
+       load (tab, encoding, line_pos, column_pos);
 }
 
 void
@@ -2013,59 +2154,60 @@ _gedit_tab_load_stream (GeditTab                *tab,
                        gint                     column_pos)
 {
        GeditDocument *doc;
+       GtkSourceFile *file;
 
        g_return_if_fail (GEDIT_IS_TAB (tab));
        g_return_if_fail (G_IS_INPUT_STREAM (stream));
        g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_NORMAL);
 
+       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
+
        doc = gedit_tab_get_document (tab);
+       file = gedit_document_get_file (doc);
 
-       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
+       if (tab->priv->loader != NULL)
+       {
+               g_warning ("GeditTab: file loader already exists.");
+               g_object_unref (tab->priv->loader);
+       }
 
-       tab->priv->tmp_line_pos = line_pos;
-       tab->priv->tmp_column_pos = column_pos;
-       tab->priv->tmp_encoding = encoding;
+       tab->priv->loader = gtk_source_file_loader_new_from_stream (file, stream);
 
-       _gedit_document_load_stream (doc,
-                                    stream,
-                                    encoding,
-                                    line_pos,
-                                    column_pos);
+       load (tab, encoding, line_pos, column_pos);
 }
 
 void
 _gedit_tab_revert (GeditTab *tab)
 {
        GeditDocument *doc;
+       GtkSourceFile *file;
        GFile *location;
 
        g_return_if_fail (GEDIT_IS_TAB (tab));
-       g_return_if_fail ((tab->priv->state == GEDIT_TAB_STATE_NORMAL) ||
-                         (tab->priv->state == GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION));
+       g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_NORMAL ||
+                         tab->priv->state == GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
 
        if (tab->priv->state == GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
        {
                set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
        }
 
-       doc = gedit_tab_get_document (tab);
-
        gedit_tab_set_state (tab, GEDIT_TAB_STATE_REVERTING);
 
-       location = gedit_document_get_location (doc);
+       doc = gedit_tab_get_document (tab);
+       file = gedit_document_get_file (doc);
+       location = gtk_source_file_get_location (file);
        g_return_if_fail (location != NULL);
 
-       tab->priv->tmp_line_pos = 0;
-       tab->priv->tmp_encoding = gedit_document_get_encoding (doc);
+       if (tab->priv->loader != NULL)
+       {
+               g_warning ("GeditTab: file loader already exists.");
+               g_object_unref (tab->priv->loader);
+       }
 
-       _gedit_document_load (doc,
-                             location,
-                             tab->priv->tmp_encoding,
-                             0,
-                             0,
-                             FALSE);
+       tab->priv->loader = gtk_source_file_loader_new (file, location);
 
-       g_object_unref (location);
+       load (tab, NULL, 0, 0);
 }
 
 void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]