[gtksourceview/wip/loader-saver] Refactor the FileSaver to fit GtkSourceFile API



commit c221b18134373ff5ee94a0f7733c689e8cf682c5
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Fri Dec 13 21:48:13 2013 +0100

    Refactor the FileSaver to fit GtkSourceFile API
    
    Not finished, not compilable.

 gtksourceview/gtksourcefilesaver.c |  486 ++++++++++++++----------------------
 gtksourceview/gtksourcefilesaver.h |   14 -
 2 files changed, 194 insertions(+), 306 deletions(-)
---
diff --git a/gtksourceview/gtksourcefilesaver.c b/gtksourceview/gtksourcefilesaver.c
index fe96dac..0cf8a19 100644
--- a/gtksourceview/gtksourcefilesaver.c
+++ b/gtksourceview/gtksourcefilesaver.c
@@ -77,21 +77,32 @@ typedef struct
 
 struct _GtkSourceFileSaverPrivate
 {
-       GFileInfo *info;
        GtkTextBuffer *buffer;
 
        GFile *location;
+       GFileInfo *info;
        const GtkSourceEncoding *encoding;
        GtkSourceNewlineType newline_type;
        GtkSourceCompressionType compression_type;
        GtkSourceFileSaveFlags flags;
 
+       GTask *task;
+
+       GFileProgressCallback progress_cb;
+       gpointer progress_cb_data;
+
        GTimeVal old_mtime;
 
+       /* TODO rename these two fields */
        goffset size;
        goffset bytes_written;
 
+       gchar chunk_buffer[WRITE_CHUNK_SIZE];
+       gssize chunk_bytes_read;
+       gssize chunk_bytes_written;
+
        GCancellable *cancellable;
+       /* TODO find better names for these two fields */
        GOutputStream *stream;
        GInputStream *input;
 
@@ -100,8 +111,10 @@ struct _GtkSourceFileSaverPrivate
        GtkSourceMountOperationFactory mount_operation_factory;
        gpointer mount_operation_userdata;
 
+       /* FIXME is used used? */
        guint used : 1;
        guint ensure_trailing_newline : 1;
+       guint tried_mount : 1;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceFileSaver, gtk_source_file_saver, G_TYPE_OBJECT)
@@ -110,7 +123,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceFileSaver, gtk_source_file_saver, G_TYPE_OB
 static void read_file_chunk (AsyncData *async);
 static void write_file_chunk (AsyncData *async);
 
-static void check_modified_async (AsyncData *async);
+static void check_externally_modified (GtkSourceFileSaver *saver);
 
 static void
 gtk_source_file_saver_set_property (GObject      *object,
@@ -480,12 +493,10 @@ cancel_output_stream_and_fail (AsyncData *async,
  */
 
 static void
-remote_get_info_cb (GFile        *source,
-                   GAsyncResult *res,
-                   AsyncData    *async)
+query_info_cb (GFile              *location,
+              GAsyncResult       *result,
+              GtkSourceFileSaver *saver)
 {
-       GtkSourceFileSaver *saver;
-       GFileInfo *info;
        GError *error = NULL;
 
        DEBUG ({
@@ -499,39 +510,30 @@ remote_get_info_cb (GFile        *source,
                return;
        }
 
-       saver = async->saver;
-
        DEBUG ({
               g_print ("Finished query info on file\n");
        });
 
-       info = g_file_query_info_finish (source, res, &error);
+       g_clear_object (&saver->priv->info);
+       saver->priv->info = g_file_query_info_finish (location, result, &error);
 
-       if (info != NULL)
-       {
-               if (saver->priv->info != NULL)
-               {
-                       g_object_unref (saver->priv->info);
-               }
-
-               saver->priv->info = info;
-       }
-       else
+       if (error != NULL)
        {
                DEBUG ({
                       g_print ("Query info failed: %s\n", error->message);
                });
 
-               g_propagate_error (&saver->priv->error, error);
+               g_task_return_error (saver->priv->task, error);
+               return;
        }
 
        remote_save_completed_or_failed (saver, async);
 }
 
 static void
-close_async_ready_get_info_cb (GOutputStream *stream,
-                              GAsyncResult  *res,
-                              AsyncData     *async)
+close_output_stream_cb (GOutputStream      *output_stream,
+                       GAsyncResult       *result,
+                       GtkSourceFileSaver *saver)
 {
        GError *error = NULL;
 
@@ -546,51 +548,49 @@ close_async_ready_get_info_cb (GOutputStream *stream,
                return;
        }
 
-       DEBUG ({
-              g_print ("Finished closing stream\n");
-       });
-
-       if (!g_output_stream_close_finish (stream, res, &error))
+       if (!g_output_stream_close_finish (output_stream, result, &error))
        {
                DEBUG ({
                       g_print ("Closing stream error: %s\n", error->message);
                });
 
-               async_failed (async, error);
+               g_task_return_error (saver->priv->task, error);
                return;
        }
 
-       /* get the file info: note we cannot use
-        * g_file_output_stream_query_info_async since it is not able to get the
+       /* Get the file info: note we cannot use
+        * g_file_output_stream_query_info_async() since it is not able to get the
         * content type etc, beside it is not supported by gvfs.
         * I'm not sure this is actually necessary, can't we just use
-        * g_content_type_guess (since we have the file name and the data)
+        * g_content_type_guess (since we have the file name and the data).
         */
        DEBUG ({
               g_print ("Query info on file\n");
        });
 
-       g_file_query_info_async (async->saver->priv->location,
+       g_file_query_info_async (saver->priv->location,
                                 REMOTE_QUERY_ATTRIBUTES,
                                 G_FILE_QUERY_INFO_NONE,
-                                G_PRIORITY_HIGH,
-                                async->cancellable,
-                                (GAsyncReadyCallback) remote_get_info_cb,
-                                async);
+                                g_task_get_priority (saver->priv->task),
+                                g_task_get_cancellable (saver->priv->task),
+                                (GAsyncReadyCallback) query_info_cb,
+                                saver);
 }
 
 static void
-write_complete (AsyncData *async)
+write_complete (GtkSourceFileSaver *saver)
 {
        GError *error = NULL;
 
-       /* first we close the input stream */
        DEBUG ({
               g_print ("Close input stream\n");
        });
 
-       if (!g_input_stream_close (async->saver->priv->input,
-                                  async->cancellable, &error))
+       g_input_stream_close (saver->priv->input,
+                             g_task_get_cancellable (saver->priv->task),
+                             &error);
+
+       if (error != NULL)
        {
                DEBUG ({
                       g_print ("Closing input stream error: %s\n", error->message);
@@ -600,24 +600,22 @@ write_complete (AsyncData *async)
                return;
        }
 
-       /* now we close the output stream */
        DEBUG ({
               g_print ("Close output stream\n");
        });
 
-       g_output_stream_close_async (async->saver->priv->stream,
-                                    G_PRIORITY_HIGH,
-                                    async->cancellable,
-                                    (GAsyncReadyCallback)close_async_ready_get_info_cb,
-                                    async);
+       g_output_stream_close_async (saver->priv->stream,
+                                    g_task_get_priority (saver->priv->task),
+                                    g_task_get_cancellable (saver->priv->task),
+                                    (GAsyncReadyCallback) close_output_stream_cb,
+                                    saver);
 }
 
 static void
-async_write_cb (GOutputStream *stream,
-               GAsyncResult  *res,
-               AsyncData     *async)
+write_file_chunk_cb (GOutputStream      *output_stream,
+                    GAsyncResult       *result,
+                    GtkSourceFileSaver *saver)
 {
-       GtkSourceFileSaver *saver;
        gssize bytes_written;
        GError *error = NULL;
 
@@ -625,119 +623,101 @@ async_write_cb (GOutputStream *stream,
               g_print ("%s\n", G_STRFUNC);
        });
 
-       /* Check cancelled state manually */
-       if (g_cancellable_is_cancelled (async->cancellable))
-       {
-               cancel_output_stream (async);
-               return;
-       }
-
-       bytes_written = g_output_stream_write_finish (stream, res, &error);
+       bytes_written = g_output_stream_write_finish (output_stream, result, &error);
 
        DEBUG ({
               g_print ("Written: %" G_GSSIZE_FORMAT "\n", bytes_written);
        });
 
-       if (bytes_written == -1)
+       if (error != NULL)
        {
                DEBUG ({
                       g_print ("Write error: %s\n", error->message);
                });
 
-               cancel_output_stream_and_fail (async, error);
+               cancel_output_stream_and_fail (saver, error);
                return;
        }
 
-       saver = async->saver;
-       async->written += bytes_written;
+       saver->priv->chunk_bytes_written += bytes_written;
 
-       /* write again */
-       if (async->written != async->read)
+       /* Write again */
+       if (saver->priv->chunk_bytes_read != saver->priv->chunk_bytes_written)
        {
-               write_file_chunk (async);
+               write_file_chunk (saver);
                return;
        }
 
-       /* note that this signal blocks the write... check if it isn't
-        * a performance problem
-        */
-       gtk_source_file_saver_saving (saver,
-                                     FALSE,
-                                     NULL);
-
-       read_file_chunk (async);
+       read_file_chunk (saver);
 }
 
 static void
-write_file_chunk (AsyncData *async)
+write_file_chunk (GtkSourceFileSaver *saver)
 {
-       GtkSourceFileSaver *saver;
-
        DEBUG ({
               g_print ("%s\n", G_STRFUNC);
        });
 
-       saver = async->saver;
-
        g_output_stream_write_async (G_OUTPUT_STREAM (saver->priv->stream),
-                                    async->buffer + async->written,
-                                    async->read - async->written,
-                                    G_PRIORITY_HIGH,
-                                    async->cancellable,
-                                    (GAsyncReadyCallback) async_write_cb,
-                                    async);
+                                    saver->priv->chunk_buffer + saver->priv->chunk_bytes_written,
+                                    saver->priv->chunk_bytes_read - saver->priv->chunk_bytes_written,
+                                    g_task_get_priority (saver->priv->task),
+                                    g_task_get_cancellable (saver->priv->task),
+                                    (GAsyncReadyCallback) write_file_chunk_cb,
+                                    saver);
 }
 
 static void
-read_file_chunk (AsyncData *async)
+read_file_chunk (GtkSourceFileSaver *saver)
 {
-       GtkSourceFileSaver *saver;
-       GtkSourceBufferInputStream *dstream;
+       GtkSourceBufferInputStream *buffer_stream;
        GError *error = NULL;
 
        DEBUG ({
               g_print ("%s\n", G_STRFUNC);
        });
 
-       saver = async->saver;
-       async->written = 0;
+       saver->priv->chunk_bytes_written = 0;
 
-       /* we use sync methods on doc stream since it is in memory. Using async
-          would be racy and we can endup with invalidated iters */
-       async->read = g_input_stream_read (saver->priv->input,
-                                          async->buffer,
-                                          WRITE_CHUNK_SIZE,
-                                          async->cancellable,
-                                          &error);
+       /* We use sync methods on doc stream since it is in memory. Using async
+        * would be racy and we can end up with invalid iters.
+        */
+       saver->priv->chunk_bytes_read = g_input_stream_read (saver->priv->input,
+                                                            saver->priv->chunk_buffer,
+                                                            WRITE_CHUNK_SIZE,
+                                                            g_task_get_cancellable (saver->priv->task),
+                                                            &error);
 
        if (error != NULL)
        {
-               cancel_output_stream_and_fail (async, error);
+               cancel_output_stream_and_fail (saver, error);
                return;
        }
 
-       /* Check if we finished reading and writing */
-       if (async->read == 0)
+       /* Check if we finished reading and writing. */
+       if (saver->priv->chunk_bytes_read == 0)
        {
-               write_complete (async);
+               write_complete (saver);
                return;
        }
 
-       /* Get how many chars have been read */
-       dstream = GTK_SOURCE_BUFFER_INPUT_STREAM (saver->priv->input);
-       saver->priv->bytes_written = _gtk_source_buffer_input_stream_tell (dstream);
+       /* Get how many chars have been read. */
+       /* FIXME bytes_written, or chars_written? */
+       /* FIXME and the value must be updated after writing the chunk, not
+        * after reading it... */
+       buffer_stream = GTK_SOURCE_BUFFER_INPUT_STREAM (saver->priv->input);
+       saver->priv->bytes_written = _gtk_source_buffer_input_stream_tell (buffer_stream);
 
-       write_file_chunk (async);
+       write_file_chunk (saver);
 }
 
 static void
-async_replace_ready_callback (GFile        *source,
-                             GAsyncResult *res,
-                             AsyncData    *async)
+replace_file_cb (GFile              *location,
+                GAsyncResult       *result,
+                GtkSourceFileSaver *saver)
 {
-       GtkSourceFileSaver *saver;
-       GCharsetConverter *converter;
        GFileOutputStream *file_stream;
+       GCharsetConverter *converter;
        GOutputStream *base_stream;
        GError *error = NULL;
 
@@ -745,24 +725,17 @@ async_replace_ready_callback (GFile        *source,
               g_print ("%s\n", G_STRFUNC);
        });
 
-       /* Check cancelled state manually */
-       if (g_cancellable_is_cancelled (async->cancellable))
-       {
-               async_data_free (async);
-               return;
-       }
-
-       saver = async->saver;
-       file_stream = g_file_replace_finish (source, res, &error);
+       file_stream = g_file_replace_finish (location, result, &error);
 
-       /* handle any error that might occur */
-       if (!file_stream)
+       if (error != NULL)
        {
                DEBUG ({
                       g_print ("Opening file failed: %s\n", error->message);
                });
 
-               async_failed (async, error);
+               /* FIXME check not mounted? */
+
+               g_task_return_error (saver->priv->task, error);
                return;
        }
 
@@ -788,6 +761,7 @@ async_replace_ready_callback (GFile        *source,
        }
 
        /* FIXME: manage converter error? */
+
        DEBUG ({
               g_print ("Encoding charset: %s\n",
                        gtk_source_encoding_get_charset (saver->priv->encoding));
@@ -816,28 +790,20 @@ async_replace_ready_callback (GFile        *source,
 
        saver->priv->size = _gtk_source_buffer_input_stream_get_total_size (GTK_SOURCE_BUFFER_INPUT_STREAM 
(saver->priv->input));
 
-       read_file_chunk (async);
+       read_file_chunk (saver);
 }
 
 static void
-begin_write (AsyncData *async)
+begin_write (GtkSourceFileSaver *saver)
 {
-       GtkSourceFileSaver *saver;
        gboolean make_backup;
 
-       DEBUG ({
-              g_print ("Start replacing file contents\n");
-       });
-
-       /* For remote files we simply use g_file_replace_async. There is no
-        * backup as of yet.
-        */
-       saver = async->saver;
-
        make_backup = (saver->priv->flags & GTK_SOURCE_FILE_SAVE_IGNORE_BACKUP) == 0 &&
                      (saver->priv->flags & GTK_SOURCE_FILE_SAVE_PRESERVE_BACKUP) == 0;
 
        DEBUG ({
+              g_print ("Start replacing file contents\n");
+              /* FIXME is the size already set? */
               g_print ("File contents size: %" G_GINT64_FORMAT "\n", saver->priv->size);
               g_print ("Make backup: %s\n", make_backup ? "yes" : "no");
        });
@@ -846,41 +812,33 @@ begin_write (AsyncData *async)
                              NULL,
                              make_backup,
                              G_FILE_CREATE_NONE,
-                             G_PRIORITY_HIGH,
-                             async->cancellable,
-                             (GAsyncReadyCallback) async_replace_ready_callback,
-                             async);
+                             g_task_get_priority (saver->priv->task),
+                             g_task_get_cancellable (saver->priv->task),
+                             (GAsyncReadyCallback) replace_file_cb,
+                             saver);
 }
 
 static void
-mount_ready_callback (GFile        *file,
-                     GAsyncResult *res,
-                     AsyncData    *async)
+mount_cb (GFile              *location,
+         GAsyncResult       *result,
+         GtkSourceFileSaver *saver)
 {
        GError *error = NULL;
-       gboolean mounted;
 
        DEBUG ({
               g_print ("%s\n", G_STRFUNC);
        });
 
-       /* manual check for cancelled state */
-       if (g_cancellable_is_cancelled (async->cancellable))
-       {
-               async_data_free (async);
-               return;
-       }
-
-       mounted = g_file_mount_enclosing_volume_finish (file, res, &error);
+       g_file_mount_enclosing_volume_finish (location, result, &error);
 
-       if (!mounted)
+       if (error != NULL)
        {
-               async_failed (async, error);
+               g_task_return_error (saver->priv->task, error);
        }
        else
        {
-               /* try again to get the modified state */
-               check_modified_async (async);
+               /* Try again to get the modified state. */
+               check_externally_modified (saver);
        }
 }
 
@@ -893,31 +851,30 @@ create_mount_operation (GtkSourceFileSaver *saver)
 }
 
 static void
-recover_not_mounted (AsyncData *async)
+recover_not_mounted (GtkSourceFileSaver *saver)
 {
-       GMountOperation *mount_operation = create_mount_operation (async->saver);
+       GMountOperation *mount_operation = create_mount_operation (saver);
 
        DEBUG ({
               g_print ("%s\n", G_STRFUNC);
        });
 
-       async->tried_mount = TRUE;
-       g_file_mount_enclosing_volume (async->saver->priv->location,
+       saver->priv->tried_mount = TRUE;
+       g_file_mount_enclosing_volume (saver->priv->location,
                                       G_MOUNT_MOUNT_NONE,
                                       mount_operation,
-                                      async->cancellable,
-                                      (GAsyncReadyCallback) mount_ready_callback,
-                                      async);
+                                      g_task_get_cancellable (saver->priv->task),
+                                      (GAsyncReadyCallback) mount_cb,
+                                      saver);
 
        g_object_unref (mount_operation);
 }
 
 static void
-check_modification_callback (GFile        *source,
-                            GAsyncResult *res,
-                            AsyncData    *async)
+check_externally_modified_cb (GFile              *location,
+                             GAsyncResult       *result,
+                             GtkSourceFileSaver *saver)
 {
-       GtkSourceFileSaver *saver;
        GError *error = NULL;
        GFileInfo *info;
 
@@ -925,37 +882,35 @@ check_modification_callback (GFile        *source,
               g_print ("%s\n", G_STRFUNC);
        });
 
-       /* manually check cancelled state */
-       if (g_cancellable_is_cancelled (async->cancellable))
+       if (saver->priv->flags & GTK_SOURCE_FILE_SAVE_IGNORE_MTIME)
        {
-               async_data_free (async);
-               return;
+               g_warning ("Useless check for externally modified file.");
        }
 
-       saver = async->saver;
-       info = g_file_query_info_finish (source, res, &error);
-       if (info == NULL)
+       info = g_file_query_info_finish (location, result, &error);
+
+       if (error != NULL)
        {
-               if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount)
+               if (error->code == G_IO_ERROR_NOT_MOUNTED && !saver->priv->tried_mount)
                {
-                       recover_not_mounted (async);
+                       recover_not_mounted (saver);
                        g_error_free (error);
                        return;
                }
 
-               /* it's perfectly fine if the file doesn't exist yet */
+               /* It's perfectly fine if the file doesn't exist yet. */
                if (error->code != G_IO_ERROR_NOT_FOUND)
                {
                        DEBUG ({
                               g_print ("Error getting modification: %s\n", error->message);
                        });
 
-                       async_failed (async, error);
+                       g_task_return_error (saver->priv->task, error);
                        return;
                }
        }
 
-       /* check if the mtime is > what we know about it (if we have it) */
+       /* Check if the mtime is greater from what we know about it (if we have it). */
        if (info != NULL && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
        {
                GTimeVal mtime;
@@ -972,14 +927,12 @@ check_modification_callback (GFile        *source,
                               g_print ("File is externally modified\n");
                        });
 
-                       g_set_error (&saver->priv->error,
-                                    GTK_SOURCE_FILE_ERROR,
-                                    GTK_SOURCE_FILE_ERROR_EXTERNALLY_MODIFIED,
-                                    "Externally modified");
-
-                       remote_save_completed_or_failed (saver, async);
                        g_object_unref (info);
 
+                       g_task_return_new_error (saver->priv->task,
+                                                GTK_SOURCE_FILE_ERROR,
+                                                GTK_SOURCE_FILE_ERROR_EXTERNALLY_MODIFIED,
+                                                "Externally modified");
                        return;
                }
        }
@@ -989,150 +942,99 @@ check_modification_callback (GFile        *source,
                g_object_unref (info);
        }
 
-       /* modification check passed, start write */
-       begin_write (async);
+       /* Externally modified check passed, start write. */
+       begin_write (saver);
 }
 
 static void
-check_modified_async (AsyncData *async)
+check_externally_modified (GtkSourceFileSaver *saver)
 {
        DEBUG ({
               g_print ("Check externally modified\n");
        });
 
-       g_file_query_info_async (async->saver->priv->location,
+       g_file_query_info_async (saver->priv->location,
                                 G_FILE_ATTRIBUTE_TIME_MODIFIED,
                                 G_FILE_QUERY_INFO_NONE,
-                                G_PRIORITY_HIGH,
-                                async->cancellable,
-                                (GAsyncReadyCallback) check_modification_callback,
-                                async);
+                                g_task_get_priority (saver->priv->task),
+                                g_task_get_cancellable (saver->priv->task),
+                                (GAsyncReadyCallback)check_externally_modified_cb,
+                                saver);
 }
 
-static gboolean
-save_remote_file_real (GtkSourceFileSaver *saver)
+GFile *
+gtk_source_file_saver_get_location (GtkSourceFileSaver *saver)
 {
-       AsyncData *async;
-
-       DEBUG ({
-              g_print ("Starting  save\n");
-       });
+       g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), NULL);
 
-       /* First find out if the file is modified externally. This requires
-        * a stat, but I don't think we can do this any other way
-        */
-       async = async_data_new (saver);
+       return g_file_dup (saver->priv->location);
+}
 
-       check_modified_async (async);
+void
+gtk_source_file_saver_set_mount_operation_factory (GtkSourceFileSaver             *saver,
+                                                  GtkSourceMountOperationFactory  callback,
+                                                  gpointer                        user_data)
+{
+       g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver));
 
-       /* return false to stop timeout */
-       return FALSE;
+       saver->priv->mount_operation_factory = callback;
+       saver->priv->mount_operation_userdata = user_data;
 }
 
 void
-gtk_source_file_saver_save (GtkSourceFileSaver *saver,
-                           GTimeVal           *old_mtime)
+gtk_source_file_saver_save_async (GtkSourceFileSaver     *saver,
+                                 gint                    io_priority,
+                                 GTimeVal               *old_mtime,
+                                 GCancellable           *cancellable,
+                                 GFileProgressCallback   progress_callback,
+                                 gpointer                progress_callback_data,
+                                 GAsyncReadyCallback     callback,
+                                 gpointer                user_data)
 {
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
        g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver));
+       g_return_if_fail (saver->priv->task == NULL);
        g_return_if_fail (saver->priv->location != NULL);
+       g_return_if_fail (!saver->priv->used);
 
-       g_return_if_fail (saver->priv->used == FALSE);
        saver->priv->used = TRUE;
 
-       /* CHECK:
-        report async (in an idle handler) or sync (bool ret)
-        async is extra work here, sync is special casing in the caller */
+       saver->priv->task = g_task_new (saver, cancellable, callback, user_data);
+       g_task_set_priority (task, io_priority);
 
        saver->priv->old_mtime = *old_mtime;
+       saver->priv->progress_cb = progress_callback;
+       saver->priv->progress_cb_data = progress_callback_data;
 
-       /* saving start */
-       gtk_source_file_saver_saving (saver, FALSE, NULL);
-
-       g_timeout_add_full (G_PRIORITY_HIGH,
-                           0,
-                           (GSourceFunc) save_remote_file_real,
-                           saver,
-                           NULL);
-}
+       DEBUG ({
+              g_print ("Starting  save\n");
+       });
 
-void
-gtk_source_file_saver_saving (GtkSourceFileSaver *saver,
-                            gboolean            completed,
-                            GError             *error)
-{
-       /* the object will be unrefed in the callback of the saving
-        * signal, so we need to prevent finalization.
+       /* TODO create a thread and use sync GIO functions for the first steps.
+        * Destroy the thread for the main step, reading the buffer and writing
+        * the file. Because the buffer must be read in the main thread.
         */
-       if (completed)
+
+       if (saver->priv->flags & GTK_SOURCE_FILE_SAVE_IGNORE_MTIME)
        {
-               g_object_ref (saver);
+               begin_write (saver);
        }
-
-       g_signal_emit (saver, signals[SAVING], 0, completed, error);
-
-       if (completed)
+       else
        {
-               if (error == NULL)
-               {
-                       DEBUG ({
-                              g_print ("save completed\n");
-                       });
-               }
-               else
-               {
-                       DEBUG ({
-                              g_print ("save failed\n");
-                       });
-               }
-
-               g_object_unref (saver);
+               /* TODO install a FileMonitor in GtkSourceFile, with an
+                * externally-modified property, or a signal.
+                */
+               check_externally_modified (saver);
        }
 }
 
-GFile *
-gtk_source_file_saver_get_location (GtkSourceFileSaver *saver)
+gboolean
+gtk_source_file_saver_save_finish (GtkSourceFileSaver  *saver,
+                                  GAsyncResult        *result,
+                                  GError             **error)
 {
-       g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), NULL);
-
-       return g_file_dup (saver->priv->location);
-}
-
-/* Returns 0 if file size is unknown */
-goffset
-gtk_source_file_saver_get_file_size (GtkSourceFileSaver *saver)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), 0);
-
-       return saver->priv->size;
-}
+       g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), FALSE);
+       g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+       g_return_val_if_fail (g_task_is_valid (result, saver), FALSE);
 
-goffset
-gtk_source_file_saver_get_bytes_written (GtkSourceFileSaver *saver)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), 0);
-
-       return saver->priv->bytes_written;
-}
-
-GFileInfo *
-gtk_source_file_saver_get_info (GtkSourceFileSaver *saver)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), NULL);
-
-       return saver->priv->info;
-}
-
-void
-gtk_source_file_saver_set_mount_operation_factory (GtkSourceFileSaver             *saver,
-                                                  GtkSourceMountOperationFactory  callback,
-                                                  gpointer                        user_data)
-{
-       g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver));
-
-       saver->priv->mount_operation_factory = callback;
-       saver->priv->mount_operation_userdata = user_data;
+       return g_task_propagate_boolean (G_TASK (result), error);
 }
diff --git a/gtksourceview/gtksourcefilesaver.h b/gtksourceview/gtksourcefilesaver.h
index 4f69c01..0964e4d 100644
--- a/gtksourceview/gtksourcefilesaver.h
+++ b/gtksourceview/gtksourcefilesaver.h
@@ -84,22 +84,8 @@ void                  gtk_source_file_saver_saving           (GtkSourceFileSaver  *saver,
                                                                 GError              *error);
 
 G_GNUC_INTERNAL
-void                    gtk_source_file_saver_save             (GtkSourceFileSaver  *saver,
-                                                                GTimeVal            *old_mtime);
-
-G_GNUC_INTERNAL
 GFile                  *gtk_source_file_saver_get_location     (GtkSourceFileSaver  *saver);
 
-/* Returns 0 if file size is unknown */
-G_GNUC_INTERNAL
-goffset                         gtk_source_file_saver_get_file_size    (GtkSourceFileSaver  *saver);
-
-G_GNUC_INTERNAL
-goffset                         gtk_source_file_saver_get_bytes_written (GtkSourceFileSaver *saver);
-
-G_GNUC_INTERNAL
-GFileInfo              *gtk_source_file_saver_get_info         (GtkSourceFileSaver  *saver);
-
 G_GNUC_INTERNAL
 void                    gtk_source_file_saver_set_mount_operation_factory
                                                                (GtkSourceFileSaver             *saver,


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