[gedit/wip/loader-saver: 15/19] tab: start the port to GtkSourceFileLoader



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

    tab: start the port to GtkSourceFileLoader

 gedit/gedit-tab.c |  290 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 212 insertions(+), 78 deletions(-)
---
diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
index 15d37e4..9edd657 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,11 @@ 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 */
 
        GTimer                 *timer;
 
@@ -72,6 +75,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)
@@ -638,15 +645,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
@@ -742,13 +744,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 +764,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 +897,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)
 {
@@ -1656,11 +1618,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);
@@ -1975,6 +1932,192 @@ 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;
+
+       gtk_source_file_loader_load_finish (loader, result, &error);
+
+       if (error != NULL)
+       {
+               g_warning ("File loading error: %s", error->message);
+               g_error_free (error);
+       }
+
+       /* 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;
+       }
+
+       g_clear_object (&tab->priv->loader);
+       g_clear_object (&tab->priv->cancellable);
+       tab->priv->load_create = FALSE;
+
+       g_signal_emit_by_name (doc, "loaded", NULL);
+
+       gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
+
+       /* 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));
+       g_return_if_fail (tab->priv->cancellable == NULL);
+
+       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
+
+       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;
+
+       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 +2127,21 @@ _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);
+       g_return_if_fail (tab->priv->loader == NULL);
 
        doc = gedit_tab_get_document (tab);
+       file = gedit_document_get_file (doc);
 
-       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
+       tab->priv->loader = gtk_source_file_loader_new (file, location);
 
-       tab->priv->tmp_line_pos = line_pos;
-       tab->priv->tmp_column_pos = column_pos;
-       tab->priv->tmp_encoding = encoding;
+       tab->priv->load_create = create != FALSE;
 
-       _gedit_document_load (doc,
-                             location,
-                             encoding,
-                             line_pos,
-                             column_pos,
-                             create);
+       load (tab, encoding, line_pos, column_pos);
 }
 
 void
@@ -2013,24 +2152,19 @@ _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);
+       g_return_if_fail (tab->priv->loader == NULL);
 
        doc = gedit_tab_get_document (tab);
+       file = gedit_document_get_file (doc);
 
-       gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
-
-       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


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