[gtksourceview/wip/loader-saver] File and FileSaver: continue the quest



commit 02f1c1dfa51d60517e1a34b9ce30b13f4b8c9518
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat Dec 21 23:39:52 2013 +0100

    File and FileSaver: continue the quest
    
    The unit tests pass for me, but not all unit tests can be run. Remote
    files can not be mounted, even on localhost.

 gtksourceview/gtksourcefile.c      |   26 ++---
 gtksourceview/gtksourcefilesaver.c |  185 +++++++++++-------------------------
 gtksourceview/gtksourcefilesaver.h |    9 +-
 tests/test-file-saver.c            |    4 +
 4 files changed, 74 insertions(+), 150 deletions(-)
---
diff --git a/gtksourceview/gtksourcefile.c b/gtksourceview/gtksourcefile.c
index 456ec41..bef0a28 100644
--- a/gtksourceview/gtksourcefile.c
+++ b/gtksourceview/gtksourcefile.c
@@ -424,18 +424,13 @@ gtk_source_file_save_async (GtkSourceFile          *file,
 
        if (file->priv->saver != NULL)
        {
-               if (cancellable != NULL)
-               {
-                       /* FIXME create another saver? */
-                       g_cancellable_cancel (cancellable);
-                       return;
-               }
-               else
-               {
-                       g_warning ("Another save operation is already running on the file \"%s\".",
-                                  g_file_get_parse_name (file->priv->location));
-                       return;
-               }
+               /* FIXME create a special GTask just for returning the error and
+                * cancel the operation?
+                * Return the G_IO_ERROR_PENDING error?
+                */
+               g_warning ("Another save operation is already running on the file \"%s\".",
+                          g_file_get_parse_name (file->priv->location));
+               return;
        }
 
        file->priv->saver = gtk_source_file_saver_new (GTK_TEXT_BUFFER (file->priv->buffer),
@@ -443,10 +438,11 @@ gtk_source_file_save_async (GtkSourceFile          *file,
                                                       file->priv->encoding,
                                                       file->priv->newline_type,
                                                       file->priv->compression_type,
-                                                      flags,
-                                                      file->priv->ensure_trailing_newline);
+                                                      file->priv->ensure_trailing_newline,
+                                                      flags);
 
        gtk_source_file_saver_save_async (file->priv->saver,
+                                         file,
                                          io_priority,
                                          NULL,
                                          cancellable,
@@ -467,7 +463,7 @@ gtk_source_file_save_finish (GtkSourceFile  *file,
        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
        g_return_val_if_fail (file->priv->saver != NULL, FALSE);
 
-       ok = gtk_source_file_saver_save_finish (file->priv->saver, result, error);
+       ok = gtk_source_file_saver_save_finish (file->priv->saver, file, result, error);
 
        g_clear_object (&file->priv->saver);
 
diff --git a/gtksourceview/gtksourcefilesaver.c b/gtksourceview/gtksourcefilesaver.c
index b6449a4..b3ef0a0 100644
--- a/gtksourceview/gtksourcefilesaver.c
+++ b/gtksourceview/gtksourcefilesaver.c
@@ -22,6 +22,12 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+/* The code has been written initially in gedit (GeditDocumentSaver).
+ * It uses a GtkSourceBufferInputStream as input, create converter(s) if needed
+ * for the encoding and the compression, and write the contents to a
+ * GOutputStream (the file).
+ */
+
 #include <glib/gi18n.h>
 #include <glib.h>
 #include <gio/gio.h>
@@ -41,9 +47,6 @@
 
 #define WRITE_CHUNK_SIZE 8192
 
-#define QUERY_ATTRIBUTES G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE "," \
-                        G_FILE_ATTRIBUTE_TIME_MODIFIED
-
 enum
 {
        PROP_0,
@@ -52,57 +55,37 @@ enum
        PROP_ENCODING,
        PROP_NEWLINE_TYPE,
        PROP_COMPRESSION_TYPE,
-       PROP_FLAGS,
-       PROP_ENSURE_TRAILING_NEWLINE
+       PROP_ENSURE_TRAILING_NEWLINE,
+       PROP_FLAGS
 };
 
-#if 0
-typedef struct
-{
-       GtkSourceFileSaver *saver;
-       gchar buffer[WRITE_CHUNK_SIZE];
-       GCancellable *cancellable;
-       gboolean tried_mount;
-       gssize written;
-       gssize read;
-       GError *error;
-} AsyncData;
-#endif
-
 struct _GtkSourceFileSaverPrivate
 {
        GtkTextBuffer *buffer;
-
        GFile *location;
        const GtkSourceEncoding *encoding;
        GtkSourceNewlineType newline_type;
        GtkSourceCompressionType compression_type;
        GtkSourceFileSaveFlags flags;
 
+       GTimeVal old_mtime;
+
        GTask *task;
 
+       goffset total_size;
        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;
 
-       GFileInfo *info;
-
-       GError *error;
-
        GtkSourceMountOperationFactory mount_operation_factory;
        gpointer mount_operation_userdata;
 
@@ -153,14 +136,14 @@ gtk_source_file_saver_set_property (GObject      *object,
                        saver->priv->compression_type = g_value_get_enum (value);
                        break;
 
-               case PROP_FLAGS:
-                       saver->priv->flags = g_value_get_flags (value);
-                       break;
-
                case PROP_ENSURE_TRAILING_NEWLINE:
                        saver->priv->ensure_trailing_newline = g_value_get_boolean (value);
                        break;
 
+               case PROP_FLAGS:
+                       saver->priv->flags = g_value_get_flags (value);
+                       break;
+
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -197,14 +180,14 @@ gtk_source_file_saver_get_property (GObject    *object,
                        g_value_set_enum (value, saver->priv->compression_type);
                        break;
 
-               case PROP_FLAGS:
-                       g_value_set_flags (value, saver->priv->flags);
-                       break;
-
                case PROP_ENSURE_TRAILING_NEWLINE:
                        g_value_set_boolean (value, saver->priv->ensure_trailing_newline);
                        break;
 
+               case PROP_FLAGS:
+                       g_value_set_flags (value, saver->priv->flags);
+                       break;
+
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                        break;
@@ -216,11 +199,8 @@ gtk_source_file_saver_dispose (GObject *object)
 {
        GtkSourceFileSaverPrivate *priv = GTK_SOURCE_FILE_SAVER (object)->priv;
 
-       g_clear_error (&priv->error);
-
        g_clear_object (&priv->stream);
        g_clear_object (&priv->input);
-       g_clear_object (&priv->info);
        g_clear_object (&priv->location);
        g_clear_object (&priv->task);
 
@@ -289,6 +269,16 @@ gtk_source_file_saver_class_init (GtkSourceFileSaverClass *klass)
                                                            G_PARAM_STATIC_STRINGS));
 
        g_object_class_install_property (object_class,
+                                        PROP_ENSURE_TRAILING_NEWLINE,
+                                        g_param_spec_boolean ("ensure-trailing-newline",
+                                                              "Ensure Trailing Newline",
+                                                              "Ensure the buffer ends with a trailing 
newline",
+                                                              TRUE,
+                                                              G_PARAM_READWRITE |
+                                                              G_PARAM_CONSTRUCT_ONLY |
+                                                              G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (object_class,
                                         PROP_FLAGS,
                                         g_param_spec_flags ("flags",
                                                             "Flags",
@@ -298,16 +288,6 @@ gtk_source_file_saver_class_init (GtkSourceFileSaverClass *klass)
                                                             G_PARAM_READWRITE |
                                                             G_PARAM_CONSTRUCT_ONLY |
                                                             G_PARAM_STATIC_STRINGS));
-
-       g_object_class_install_property (object_class,
-                                        PROP_ENSURE_TRAILING_NEWLINE,
-                                        g_param_spec_boolean ("ensure-trailing-newline",
-                                                              "Ensure Trailing Newline",
-                                                              "Ensure the buffer ends with a trailing 
newline",
-                                                              TRUE,
-                                                              G_PARAM_READWRITE |
-                                                              G_PARAM_CONSTRUCT_ONLY |
-                                                              G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -322,8 +302,8 @@ gtk_source_file_saver_new (GtkTextBuffer            *buffer,
                           const GtkSourceEncoding  *encoding,
                           GtkSourceNewlineType      newline_type,
                           GtkSourceCompressionType  compression_type,
-                          GtkSourceFileSaveFlags    flags,
-                          gboolean                  ensure_trailing_newline)
+                          gboolean                  ensure_trailing_newline,
+                          GtkSourceFileSaveFlags    flags)
 {
        g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
        g_return_val_if_fail (G_IS_FILE (location), NULL);
@@ -334,8 +314,8 @@ gtk_source_file_saver_new (GtkTextBuffer            *buffer,
                             "encoding", encoding,
                             "newline_type", newline_type,
                             "compression_type", compression_type,
-                            "flags", flags,
                             "ensure-trailing-newline", ensure_trailing_newline,
+                            "flags", flags,
                             NULL);
 }
 
@@ -422,46 +402,6 @@ cancel_output_stream_and_fail (AsyncData *async,
  */
 
 static void
-query_info_cb (GFile              *location,
-              GAsyncResult       *result,
-              GtkSourceFileSaver *saver)
-{
-       GError *error = NULL;
-
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
-#if 0
-       /* check cancelled state manually */
-       if (g_cancellable_is_cancelled (async->cancellable))
-       {
-               async_data_free (async);
-               return;
-       }
-#endif
-
-       DEBUG ({
-              g_print ("Finished query info on file\n");
-       });
-
-       g_clear_object (&saver->priv->info);
-       saver->priv->info = g_file_query_info_finish (location, result, &error);
-
-       if (error != NULL)
-       {
-               DEBUG ({
-                      g_print ("Query info failed: %s\n", error->message);
-               });
-
-               g_task_return_error (saver->priv->task, error);
-               return;
-       }
-
-       g_task_return_boolean (saver->priv->task, TRUE);
-}
-
-static void
 close_output_stream_cb (GOutputStream      *output_stream,
                        GAsyncResult       *result,
                        GtkSourceFileSaver *saver)
@@ -493,23 +433,7 @@ close_output_stream_cb (GOutputStream      *output_stream,
                return;
        }
 
-       /* 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).
-        */
-       DEBUG ({
-              g_print ("Query info on file\n");
-       });
-
-       g_file_query_info_async (saver->priv->location,
-                                QUERY_ATTRIBUTES,
-                                G_FILE_QUERY_INFO_NONE,
-                                g_task_get_priority (saver->priv->task),
-                                g_task_get_cancellable (saver->priv->task),
-                                (GAsyncReadyCallback) query_info_cb,
-                                saver);
+       g_task_return_boolean (saver->priv->task, TRUE);
 }
 
 static void
@@ -591,6 +515,19 @@ write_file_chunk_cb (GOutputStream      *output_stream,
                return;
        }
 
+       if (saver->priv->progress_cb != NULL)
+       {
+               GtkSourceBufferInputStream *buffer_stream;
+               gsize total_chars_written;
+
+               buffer_stream = GTK_SOURCE_BUFFER_INPUT_STREAM (saver->priv->input);
+               total_chars_written = _gtk_source_buffer_input_stream_tell (buffer_stream);
+
+               saver->priv->progress_cb (total_chars_written,
+                                         saver->priv->total_size,
+                                         saver->priv->progress_cb_data);
+       }
+
        read_file_chunk (saver);
 }
 
@@ -616,7 +553,6 @@ write_file_chunk (GtkSourceFileSaver *saver)
 static void
 read_file_chunk (GtkSourceFileSaver *saver)
 {
-       GtkSourceBufferInputStream *buffer_stream;
        GError *error = NULL;
 
        DEBUG ({
@@ -651,13 +587,6 @@ read_file_chunk (GtkSourceFileSaver *saver)
                return;
        }
 
-       /* 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 (saver);
 }
 
@@ -738,7 +667,7 @@ replace_file_cb (GFile              *location,
                                                                  saver->priv->newline_type,
                                                                  saver->priv->ensure_trailing_newline);
 
-       saver->priv->size = _gtk_source_buffer_input_stream_get_total_size (GTK_SOURCE_BUFFER_INPUT_STREAM 
(saver->priv->input));
+       saver->priv->total_size = _gtk_source_buffer_input_stream_get_total_size 
(GTK_SOURCE_BUFFER_INPUT_STREAM (saver->priv->input));
 
        read_file_chunk (saver);
 }
@@ -754,7 +683,7 @@ begin_write (GtkSourceFileSaver *saver)
        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 ("File contents size: %" G_GINT64_FORMAT "\n", saver->priv->total_size);
               g_print ("Make backup: %s\n", make_backup ? "yes" : "no");
        });
 
@@ -912,14 +841,6 @@ check_externally_modified (GtkSourceFileSaver *saver)
                                 saver);
 }
 
-GFile *
-gtk_source_file_saver_get_location (GtkSourceFileSaver *saver)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), NULL);
-
-       return g_object_ref (saver->priv->location);
-}
-
 void
 gtk_source_file_saver_set_mount_operation_factory (GtkSourceFileSaver             *saver,
                                                   GtkSourceMountOperationFactory  callback,
@@ -933,6 +854,7 @@ gtk_source_file_saver_set_mount_operation_factory (GtkSourceFileSaver
 
 void
 gtk_source_file_saver_save_async (GtkSourceFileSaver     *saver,
+                                 GtkSourceFile          *file,
                                  gint                    io_priority,
                                  GTimeVal               *old_mtime,
                                  GCancellable           *cancellable,
@@ -942,9 +864,10 @@ gtk_source_file_saver_save_async (GtkSourceFileSaver     *saver,
                                  gpointer                user_data)
 {
        g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver));
+       g_return_if_fail (GTK_SOURCE_IS_FILE (file));
        g_return_if_fail (saver->priv->task == NULL);
 
-       saver->priv->task = g_task_new (saver, cancellable, callback, user_data);
+       saver->priv->task = g_task_new (file, cancellable, callback, user_data);
        g_task_set_priority (saver->priv->task, io_priority);
 
        if (old_mtime != NULL)
@@ -979,12 +902,14 @@ gtk_source_file_saver_save_async (GtkSourceFileSaver     *saver,
 
 gboolean
 gtk_source_file_saver_save_finish (GtkSourceFileSaver  *saver,
+                                  GtkSourceFile       *file,
                                   GAsyncResult        *result,
                                   GError             **error)
 {
        g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), FALSE);
+       g_return_val_if_fail (GTK_SOURCE_IS_FILE (file), FALSE);
        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-       g_return_val_if_fail (g_task_is_valid (result, saver), FALSE);
+       g_return_val_if_fail (g_task_is_valid (result, file), FALSE);
 
        return g_task_propagate_boolean (G_TASK (result), error);
 }
diff --git a/gtksourceview/gtksourcefilesaver.h b/gtksourceview/gtksourcefilesaver.h
index 17fb62f..0bead52 100644
--- a/gtksourceview/gtksourcefilesaver.h
+++ b/gtksourceview/gtksourcefilesaver.h
@@ -69,11 +69,8 @@ GtkSourceFileSaver   *gtk_source_file_saver_new              (GtkTextBuffer                
*
                                                                 const GtkSourceEncoding      *encoding,
                                                                 GtkSourceNewlineType          newline_type,
                                                                 GtkSourceCompressionType      
compression_type,
-                                                                GtkSourceFileSaveFlags        flags,
-                                                                gboolean                      
ensure_trailing_newline);
-
-G_GNUC_INTERNAL
-GFile                  *gtk_source_file_saver_get_location     (GtkSourceFileSaver  *saver);
+                                                                gboolean                      
ensure_trailing_newline,
+                                                                GtkSourceFileSaveFlags        flags);
 
 G_GNUC_INTERNAL
 void                    gtk_source_file_saver_set_mount_operation_factory
@@ -83,6 +80,7 @@ void                   gtk_source_file_saver_set_mount_operation_factory
 
 G_GNUC_INTERNAL
 void                    gtk_source_file_saver_save_async       (GtkSourceFileSaver     *saver,
+                                                                GtkSourceFile          *file,
                                                                 gint                    io_priority,
                                                                 GTimeVal               *old_mtime,
                                                                 GCancellable           *cancellable,
@@ -93,6 +91,7 @@ void                   gtk_source_file_saver_save_async       (GtkSourceFileSaver     
*saver,
 
 G_GNUC_INTERNAL
 gboolean                gtk_source_file_saver_save_finish      (GtkSourceFileSaver  *saver,
+                                                                GtkSourceFile       *file,
                                                                 GAsyncResult        *result,
                                                                 GError             **error);
 
diff --git a/tests/test-file-saver.c b/tests/test-file-saver.c
index 7149215..ef4e13a 100644
--- a/tests/test-file-saver.c
+++ b/tests/test-file-saver.c
@@ -143,6 +143,10 @@ mount_cb (GFile         *location,
        else if (error != NULL && error->code == G_IO_ERROR_NOT_SUPPORTED)
        {
                g_error_free (error);
+
+               /* The unit test can not be run */
+               gtk_main_quit ();
+               return;
        }
        else
        {


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