[gedit/wip/tab-gtask] tab: use a GTask for the file loading and reverting



commit 06a8db2046f5ae072eace1df61ab073fe5e9ffe8
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Jun 20 18:11:04 2015 +0200

    tab: use a GTask for the file loading and reverting
    
    So that there are less object attributes in the GeditTab struct.

 gedit/gedit-tab.c |  257 +++++++++++++++++++++++++++++++----------------------
 1 files changed, 150 insertions(+), 107 deletions(-)
---
diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
index c819557..a306a2c 100644
--- a/gedit/gedit-tab.c
+++ b/gedit/gedit-tab.c
@@ -63,11 +63,6 @@ struct _GeditTab
 
        GtkSourceFileSaverFlags save_flags;
 
-       /* tmp data for loading */
-       GtkSourceFileLoader *loader;
-       GCancellable *cancellable;
-       gint tmp_line_pos;
-       gint tmp_column_pos;
        guint idle_scroll;
 
        GTimer *timer;
@@ -79,12 +74,10 @@ struct _GeditTab
        guint auto_save : 1;
 
        guint ask_if_externally_modified : 1;
-
-       /* tmp data for loading */
-       guint user_requested_encoding : 1;
 };
 
 typedef struct _SaverData SaverData;
+typedef struct _LoaderData LoaderData;
 
 struct _SaverData
 {
@@ -111,6 +104,14 @@ struct _SaverData
        guint force_no_backup : 1;
 };
 
+struct _LoaderData
+{
+       GtkSourceFileLoader *loader;
+       gint line_pos;
+       gint column_pos;
+       guint user_requested_encoding : 1;
+};
+
 G_DEFINE_TYPE (GeditTab, gedit_tab, GTK_TYPE_BOX)
 
 enum
@@ -160,6 +161,26 @@ saver_data_free (SaverData *data)
        }
 }
 
+static LoaderData *
+loader_data_new (void)
+{
+       return g_slice_new0 (LoaderData);
+}
+
+static void
+loader_data_free (LoaderData *data)
+{
+       if (data != NULL)
+       {
+               if (data->loader != NULL)
+               {
+                       g_object_unref (data->loader);
+               }
+
+               g_slice_free (LoaderData, data);
+       }
+}
+
 static void
 set_editable (GeditTab *tab,
              gboolean  editable)
@@ -287,13 +308,6 @@ gedit_tab_set_property (GObject      *object,
 }
 
 static void
-clear_loading (GeditTab *tab)
-{
-       g_clear_object (&tab->loader);
-       g_clear_object (&tab->cancellable);
-}
-
-static void
 gedit_tab_dispose (GObject *object)
 {
        GeditTab *tab = GEDIT_TAB (object);
@@ -302,8 +316,6 @@ gedit_tab_dispose (GObject *object)
        g_clear_object (&tab->print_job);
        g_clear_object (&tab->print_preview);
 
-       clear_loading (tab);
-
        G_OBJECT_CLASS (gedit_tab_parent_class)->dispose (object);
 }
 
@@ -652,14 +664,13 @@ remove_tab (GeditTab *tab)
 static void
 io_loading_error_info_bar_response (GtkWidget *info_bar,
                                    gint       response_id,
-                                   GeditTab  *tab)
+                                   GTask     *loading_task)
 {
+       LoaderData *data = g_task_get_task_data (loading_task);
        GFile *location;
        const GtkSourceEncoding *encoding;
 
-       g_return_if_fail (tab->loader != NULL);
-
-       location = gtk_source_file_loader_get_location (tab->loader);
+       location = gtk_source_file_loader_get_location (data->loader);
 
        switch (response_id)
        {
@@ -669,10 +680,7 @@ io_loading_error_info_bar_response (GtkWidget *info_bar,
                        set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
                        gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
 
-                       launch_loader (tab,
-                                      encoding,
-                                      tab->tmp_line_pos,
-                                      tab->tmp_column_pos);
+                       launch_loader (loading_task, encoding);
                        break;
 
                case GTK_RESPONSE_YES:
@@ -680,7 +688,9 @@ io_loading_error_info_bar_response (GtkWidget *info_bar,
                        set_editable (tab, TRUE);
                        set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
                        gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
-                       clear_loading (tab);
+
+                       g_task_return_boolean (loading_task, TRUE);
+                       g_object_unref (loading_task);
                        break;
 
                default:
@@ -689,6 +699,9 @@ io_loading_error_info_bar_response (GtkWidget *info_bar,
                                gedit_recent_remove_if_local (location);
                        }
 
+                       g_task_return_boolean (loading_task, FALSE);
+                       g_object_unref (loading_task);
+
                        remove_tab (tab);
                        break;
        }
@@ -714,18 +727,19 @@ file_already_open_warning_info_bar_response (GtkWidget *info_bar,
 static void
 load_cancelled (GtkWidget *bar,
                gint       response_id,
-               GeditTab  *tab)
+               GTask     *loading_task)
 {
+       GeditTab *tab = g_task_get_source_object (loading_task);
+
        g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (tab->info_bar));
-       g_return_if_fail (G_IS_CANCELLABLE (tab->cancellable));
 
-       g_cancellable_cancel (tab->cancellable);
+       g_cancellable_cancel (g_task_get_cancellable (loading_task));
 }
 
 static void
 unrecoverable_reverting_error_info_bar_response (GtkWidget *info_bar,
                                                 gint       response_id,
-                                                GeditTab  *tab)
+                                                GTask     *loading_task)
 {
        GeditView *view;
 
@@ -733,17 +747,19 @@ 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));
+
+       g_task_return_boolean (loading_task, FALSE);
+       g_object_unref (loading_task);
 }
 
 #define MAX_MSG_LENGTH 100
 
 static void
-show_loading_info_bar (GeditTab *tab)
+show_loading_info_bar (GTask *loading_task)
 {
+       GeditTab *tab = g_task_get_source_object (loading_task);
        GtkWidget *bar;
        GeditDocument *doc;
        gchar *name;
@@ -840,10 +856,11 @@ show_loading_info_bar (GeditTab *tab)
                bar = gedit_progress_info_bar_new ("document-open", msg, TRUE);
        }
 
-       g_signal_connect (bar,
-                         "response",
-                         G_CALLBACK (load_cancelled),
-                         tab);
+       g_signal_connect_object (bar,
+                                "response",
+                                G_CALLBACK (load_cancelled),
+                                loading_task,
+                                0);
 
        set_info_bar (tab, bar, GTK_RESPONSE_NONE);
 
@@ -1685,32 +1702,36 @@ gedit_tab_get_from_document (GeditDocument *doc)
 }
 
 static void
-loader_progress_cb (goffset   size,
-                   goffset   total_size,
-                   GeditTab *tab)
+loader_progress_cb (goffset  size,
+                   goffset  total_size,
+                   GTask   *loading_task)
 {
+       GeditTab *tab = g_task_get_source_object (loading_task);
+
        g_return_if_fail (tab->state == GEDIT_TAB_STATE_LOADING ||
                          tab->state == GEDIT_TAB_STATE_REVERTING);
 
        if (should_show_progress_info (tab, size, total_size))
        {
-               show_loading_info_bar (tab);
+               show_loading_info_bar (loading_task);
                info_bar_set_progress (tab, size, total_size);
        }
 }
 
 static void
-goto_line (GeditTab *tab)
+goto_line (GTask *loading_task)
 {
+       GeditTab *tab = g_task_get_source_object (loading_task);
+       LoaderData *data = g_task_get_task_data (loading_task);
        GeditDocument *doc = gedit_tab_get_document (tab);
        GtkTextIter iter;
 
        /* Move the cursor at the requested line if any. */
-       if (tab->tmp_line_pos > 0)
+       if (data->line_pos > 0)
        {
                gedit_document_goto_line_offset (doc,
-                                                tab->tmp_line_pos - 1,
-                                                MAX (0, tab->tmp_column_pos - 1));
+                                                data->line_pos - 1,
+                                                MAX (0, data->column_pos - 1));
                return;
        }
 
@@ -1790,8 +1811,10 @@ file_already_opened (GeditDocument *doc,
 }
 
 static void
-successful_load (GeditTab *tab)
+successful_load (GTask *loading_task)
 {
+       GeditTab *tab = g_task_get_source_object (loading_task);
+       LoaderData *data = g_task_get_task_data (loading_task);
        GeditDocument *doc;
        GtkSourceFile *file;
        GFile *location;
@@ -1799,9 +1822,9 @@ successful_load (GeditTab *tab)
        doc = gedit_tab_get_document (tab);
        file = gedit_document_get_file (doc);
 
-       if (tab->user_requested_encoding)
+       if (data->user_requested_encoding)
        {
-               const GtkSourceEncoding *encoding = gtk_source_file_loader_get_encoding (tab->loader);
+               const GtkSourceEncoding *encoding = gtk_source_file_loader_get_encoding (data->loader);
                const gchar *charset = gtk_source_encoding_get_charset (encoding);
 
                gedit_document_set_metadata (doc,
@@ -1809,7 +1832,7 @@ successful_load (GeditTab *tab)
                                             NULL);
        }
 
-       goto_line (tab);
+       goto_line (loading_task);
 
        /* 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
@@ -1820,7 +1843,7 @@ successful_load (GeditTab *tab)
                tab->idle_scroll = g_idle_add ((GSourceFunc)scroll_to_cursor, tab);
        }
 
-       location = gtk_source_file_loader_get_location (tab->loader);
+       location = gtk_source_file_loader_get_location (data->loader);
 
        /* If the document is readonly we don't care how many times the file
         * is opened.
@@ -1858,8 +1881,9 @@ successful_load (GeditTab *tab)
 static void
 load_cb (GtkSourceFileLoader *loader,
         GAsyncResult        *result,
-        GeditTab            *tab)
+        GTask               *loading_task)
 {
+       GeditTab *tab = g_task_get_source_object (loading_task);
        GeditDocument *doc = gedit_tab_get_document (tab);
        GFile *location = gtk_source_file_loader_get_location (loader);
        gboolean create_named_new_doc;
@@ -1896,8 +1920,13 @@ load_cb (GtkSourceFileLoader *loader,
 
        if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
+               g_task_return_boolean (loading_task, FALSE);
+               g_object_unref (loading_task);
+
                remove_tab (tab);
-               goto end;
+
+               g_error_free (error);
+               return;
        }
 
        if (g_error_matches (error,
@@ -1919,7 +1948,7 @@ load_cb (GtkSourceFileLoader *loader,
                g_signal_connect (info_bar,
                                  "response",
                                  G_CALLBACK (io_loading_error_info_bar_response),
-                                 tab);
+                                 loading_task);
 
                set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
 
@@ -1933,12 +1962,12 @@ load_cb (GtkSourceFileLoader *loader,
                        gedit_tab_set_state (tab, GEDIT_TAB_STATE_REVERTING_ERROR);
                }
 
-               /* The loading was successful, despite some invalid characters.
-                * The document can be edited.
-                */
+               /* The loading was successful, despite some invalid characters. */
                successful_load (tab);
                gedit_recent_add_document (doc);
-               goto end;
+
+               g_error_free (error);
+               return;
        }
 
        if (error != NULL)
@@ -1971,7 +2000,7 @@ load_cb (GtkSourceFileLoader *loader,
                        g_signal_connect (info_bar,
                                          "response",
                                          G_CALLBACK (io_loading_error_info_bar_response),
-                                         tab);
+                                         loading_task);
                }
                else
                {
@@ -1982,11 +2011,13 @@ load_cb (GtkSourceFileLoader *loader,
                        g_signal_connect (info_bar,
                                          "response",
                                          G_CALLBACK (unrecoverable_reverting_error_info_bar_response),
-                                         tab);
+                                         loading_task);
                }
 
                set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
-               goto end;
+
+               g_error_free (error);
+               return;
        }
 
        g_assert (error == NULL);
@@ -1999,16 +2030,8 @@ load_cb (GtkSourceFileLoader *loader,
                gedit_recent_add_document (doc);
        }
 
-       clear_loading (tab);
-
-end:
-       /* Async operation finished. */
-       g_object_unref (tab);
-
-       if (error != NULL)
-       {
-               g_error_free (error);
-       }
+       g_task_return_boolean (loading_task, TRUE);
+       g_object_unref (loading_task);
 }
 
 /* The returned list may contain duplicated encodings. Only the first occurrence
@@ -2058,36 +2081,28 @@ get_candidate_encodings (GeditTab *tab)
 }
 
 static void
-launch_loader (GeditTab                *tab,
-              const GtkSourceEncoding *encoding,
-              gint                     line_pos,
-              gint                     column_pos)
+launch_loader (GTask                   *loading_task,
+              const GtkSourceEncoding *encoding)
 {
+       GeditTab *tab = g_task_get_source_object (loading_task);
+       LoaderData *data = g_task_get_task_data (loading_task);
        GSList *candidate_encodings = NULL;
        GeditDocument *doc;
 
-       g_return_if_fail (GTK_SOURCE_IS_FILE_LOADER (tab->loader));
-
        if (encoding != NULL)
        {
-               tab->user_requested_encoding = TRUE;
+               data->user_requested_encoding = TRUE;
                candidate_encodings = g_slist_append (NULL, (gpointer) encoding);
        }
        else
        {
-               tab->user_requested_encoding = FALSE;
+               data->user_requested_encoding = FALSE;
                candidate_encodings = get_candidate_encodings (tab);
        }
 
-       gtk_source_file_loader_set_candidate_encodings (tab->loader, candidate_encodings);
+       gtk_source_file_loader_set_candidate_encodings (data->loader, candidate_encodings);
        g_slist_free (candidate_encodings);
 
-       tab->tmp_line_pos = line_pos;
-       tab->tmp_column_pos = column_pos;
-
-       g_clear_object (&tab->cancellable);
-       tab->cancellable = g_cancellable_new ();
-
        doc = gedit_tab_get_document (tab);
        g_signal_emit_by_name (doc, "load");
 
@@ -2098,29 +2113,31 @@ launch_loader (GeditTab                *tab,
 
        tab->timer = g_timer_new ();
 
-       /* Keep the tab alive during the async operation. */
-       g_object_ref (tab);
-
-       gtk_source_file_loader_load_async (tab->loader,
+       gtk_source_file_loader_load_async (data->loader,
                                           G_PRIORITY_DEFAULT,
-                                          tab->cancellable,
+                                          g_task_get_cancellable (loading_task),
                                           (GFileProgressCallback) loader_progress_cb,
-                                          tab,
+                                          loading_task,
                                           NULL,
                                           (GAsyncReadyCallback) load_cb,
-                                          tab);
+                                          loading_task);
 }
 
 void
-_gedit_tab_load (GeditTab                *tab,
-                GFile                   *location,
-                const GtkSourceEncoding *encoding,
-                gint                     line_pos,
-                gint                     column_pos,
-                gboolean                 create)
+_gedit_tab_load_async (GeditTab                *tab,
+                      GFile                   *location,
+                      const GtkSourceEncoding *encoding,
+                      gint                     line_pos,
+                      gint                     column_pos,
+                      gboolean                 create,
+                      GCancellable            *cancellable,
+                      GAsyncReadyCallback      callback,
+                      gpointer                 user_data)
 {
        GeditDocument *doc;
        GtkSourceFile *file;
+       GTask *loading_task;
+       LoaderData *data;
 
        g_return_if_fail (GEDIT_IS_TAB (tab));
        g_return_if_fail (G_IS_FILE (location));
@@ -2130,20 +2147,46 @@ _gedit_tab_load (GeditTab                *tab,
 
        doc = gedit_tab_get_document (tab);
        file = gedit_document_get_file (doc);
-
-       if (tab->loader != NULL)
-       {
-               g_warning ("GeditTab: file loader already exists.");
-               g_object_unref (tab->loader);
-       }
-
        gtk_source_file_set_location (file, location);
 
-       tab->loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (doc), file);
+       loading_task = g_task_new (tab, cancellable, callback, user_data);
+
+       data = loader_data_new ();
+       data->loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (doc), file);
+       data->line_pos = line_pos;
+       data->column_pos = column_pos;
 
        _gedit_document_set_create (doc, create);
 
-       launch_loader (tab, encoding, line_pos, column_pos);
+       launch_loader (loading_task, encoding);
+}
+
+gboolean
+_gedit_tab_load_finish (GeditTab     *tab,
+                       GAsyncResult *result)
+{
+       g_return_val_if_fail (g_task_is_valid (result, tab), FALSE);
+
+       return g_task_propagate_boolean (G_TASK (result), NULL);
+}
+
+void
+_gedit_tab_load (GeditTab                *tab,
+                GFile                   *location,
+                const GtkSourceEncoding *encoding,
+                gint                     line_pos,
+                gint                     column_pos,
+                gboolean                 create)
+{
+       _gedit_tab_load_async (tab,
+                              location,
+                              encoding,
+                              line_pos,
+                              column_pos,
+                              create,
+                              NULL,
+                              (GAsyncReadyCallback) _gedit_tab_load_finish,
+                              NULL);
 }
 
 void


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