[gedit/wip/tab-gtask: 4/4] tab: use a GTask for the file loading and reverting
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gedit/wip/tab-gtask: 4/4] tab: use a GTask for the file loading and reverting
- Date: Wed, 24 Jun 2015 09:10:58 +0000 (UTC)
commit 1958f1ece7b6ed0103275b5111d07be9c9c3c3ae
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.
The change is only internal to GeditTab. Later commits will use the
async/finish functions externally.
gedit/gedit-tab.c | 383 +++++++++++++++++++++++++++++++++--------------------
1 files changed, 242 insertions(+), 141 deletions(-)
---
diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
index c819557..e27b1d4 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
@@ -133,10 +134,8 @@ static guint signals[LAST_SIGNAL] = { 0 };
static gboolean gedit_tab_auto_save (GeditTab *tab);
-static void launch_loader (GeditTab *tab,
- const GtkSourceEncoding *encoding,
- gint line_pos,
- gint column_pos);
+static void launch_loader (GTask *loading_task,
+ const GtkSourceEncoding *encoding);
static void launch_saver (GTask *saving_task);
@@ -160,6 +159,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 +306,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 +314,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 +662,14 @@ remove_tab (GeditTab *tab)
static void
io_loading_error_info_bar_response (GtkWidget *info_bar,
gint response_id,
- GeditTab *tab)
+ GTask *loading_task)
{
+ GeditTab *tab = g_task_get_source_object (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 +679,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 +687,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 +698,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,36 +726,40 @@ 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)
{
+ GeditTab *tab = g_task_get_source_object (loading_task);
GeditView *view;
gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
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,18 +1811,17 @@ file_already_opened (GeditDocument *doc,
}
static void
-successful_load (GeditTab *tab)
+successful_load (GTask *loading_task)
{
- GeditDocument *doc;
- GtkSourceFile *file;
+ 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);
+ GtkSourceFile *file = gedit_document_get_file (doc);
GFile *location;
- 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 +1829,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 +1840,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 +1878,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 +1917,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 +1945,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 +1959,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.
- */
- successful_load (tab);
+ /* The loading was successful, despite some invalid characters. */
+ successful_load (loading_task);
gedit_recent_add_document (doc);
- goto end;
+
+ g_error_free (error);
+ return;
}
if (error != NULL)
@@ -1971,7 +1997,7 @@ load_cb (GtkSourceFileLoader *loader,
g_signal_connect (info_bar,
"response",
G_CALLBACK (io_loading_error_info_bar_response),
- tab);
+ loading_task);
}
else
{
@@ -1982,33 +2008,27 @@ 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);
gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
- successful_load (tab);
+ successful_load (loading_task);
if (!create_named_new_doc)
{
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 +2078,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,66 +2110,109 @@ 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)
+static void
+_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));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
g_return_if_fail (tab->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);
+ gtk_source_file_set_location (file, location);
- if (tab->loader != NULL)
- {
- g_warning ("GeditTab: file loader already exists.");
- g_object_unref (tab->loader);
- }
+ loading_task = g_task_new (tab, cancellable, callback, user_data);
- gtk_source_file_set_location (file, location);
+ data = loader_data_new ();
+ g_task_set_task_data (loading_task, data, (GDestroyNotify) loader_data_free);
- tab->loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (doc), file);
+ 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);
+}
+
+static 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_stream (GeditTab *tab,
- GInputStream *stream,
- const GtkSourceEncoding *encoding,
- gint line_pos,
- gint column_pos)
+_gedit_tab_load (GeditTab *tab,
+ GFile *location,
+ const GtkSourceEncoding *encoding,
+ gint line_pos,
+ gint column_pos,
+ gboolean create)
+{
+ GCancellable *cancellable;
+
+ cancellable = g_cancellable_new ();
+
+ _gedit_tab_load_async (tab,
+ location,
+ encoding,
+ line_pos,
+ column_pos,
+ create,
+ cancellable,
+ (GAsyncReadyCallback) _gedit_tab_load_finish,
+ NULL);
+
+ g_object_unref (cancellable);
+}
+
+static void
+_gedit_tab_load_stream_async (GeditTab *tab,
+ GInputStream *stream,
+ const GtkSourceEncoding *encoding,
+ gint line_pos,
+ gint column_pos,
+ 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_INPUT_STREAM (stream));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
g_return_if_fail (tab->state == GEDIT_TAB_STATE_NORMAL);
gedit_tab_set_state (tab, GEDIT_TAB_STATE_LOADING);
@@ -2165,31 +2220,61 @@ _gedit_tab_load_stream (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, NULL);
- tab->loader = gtk_source_file_loader_new_from_stream (GTK_SOURCE_BUFFER (doc),
- file,
- stream);
+ loading_task = g_task_new (tab, cancellable, callback, user_data);
+
+ data = loader_data_new ();
+ g_task_set_task_data (loading_task, data, (GDestroyNotify) loader_data_free);
+
+ data->loader = gtk_source_file_loader_new_from_stream (GTK_SOURCE_BUFFER (doc),
+ file,
+ stream);
+ data->line_pos = line_pos;
+ data->column_pos = column_pos;
_gedit_document_set_create (doc, FALSE);
- launch_loader (tab, encoding, line_pos, column_pos);
+ launch_loader (loading_task, encoding);
}
void
-_gedit_tab_revert (GeditTab *tab)
+_gedit_tab_load_stream (GeditTab *tab,
+ GInputStream *stream,
+ const GtkSourceEncoding *encoding,
+ gint line_pos,
+ gint column_pos)
+{
+ GCancellable *cancellable;
+
+ cancellable = g_cancellable_new ();
+
+ _gedit_tab_load_stream_async (tab,
+ stream,
+ encoding,
+ line_pos,
+ column_pos,
+ cancellable,
+ (GAsyncReadyCallback) _gedit_tab_load_finish,
+ NULL);
+
+ g_object_unref (cancellable);
+}
+
+static void
+_gedit_tab_revert_async (GeditTab *tab,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GeditDocument *doc;
GtkSourceFile *file;
GFile *location;
+ GTask *loading_task;
+ LoaderData *data;
g_return_if_fail (GEDIT_IS_TAB (tab));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
g_return_if_fail (tab->state == GEDIT_TAB_STATE_NORMAL ||
tab->state == GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
@@ -2205,15 +2290,31 @@ _gedit_tab_revert (GeditTab *tab)
gedit_tab_set_state (tab, GEDIT_TAB_STATE_REVERTING);
- if (tab->loader != NULL)
- {
- g_warning ("GeditTab: file loader already exists.");
- g_object_unref (tab->loader);
- }
+ loading_task = g_task_new (tab, cancellable, callback, user_data);
+
+ data = loader_data_new ();
+ g_task_set_task_data (loading_task, data, (GDestroyNotify) loader_data_free);
+
+ data->loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (doc), file);
+ data->line_pos = 0;
+ data->column_pos = 0;
+
+ launch_loader (loading_task, NULL);
+}
+
+void
+_gedit_tab_revert (GeditTab *tab)
+{
+ GCancellable *cancellable;
+
+ cancellable = g_cancellable_new ();
- tab->loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (doc), file);
+ _gedit_tab_revert_async (tab,
+ cancellable,
+ (GAsyncReadyCallback) _gedit_tab_load_finish,
+ NULL);
- launch_loader (tab, NULL, 0, 0);
+ g_object_unref (cancellable);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]