[gedit/wip/loader-saver: 21/58] Port to GtkSourceFileSaver



commit d8d96f886b95d962c4c52700cd7192cffe798061
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Thu Jun 26 15:24:56 2014 +0200

    Port to GtkSourceFileSaver

 gedit/gedit-document.c          |  287 +++----------------
 gedit/gedit-document.h          |   14 -
 gedit/gedit-io-error-info-bar.c |   44 +---
 gedit/gedit-tab.c               |  600 ++++++++++++++++++++-------------------
 4 files changed, 365 insertions(+), 580 deletions(-)
---
diff --git a/gedit/gedit-document.c b/gedit/gedit-document.c
index 9c83147..056a4f9 100644
--- a/gedit/gedit-document.c
+++ b/gedit/gedit-document.c
@@ -5,6 +5,7 @@
  * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
  * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
  * Copyright (C) 2002-2005 Paolo Maggi
+ * Copyright (C) 2014 Sébastien Wilmet
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -49,12 +50,8 @@
 static void    gedit_document_loaded_real      (GeditDocument *doc,
                                                 const GError  *error);
 
-static void    gedit_document_save_real        (GeditDocument                *doc,
-                                                GFile                        *location,
-                                                const GeditEncoding          *encoding,
-                                                GeditDocumentNewlineType      newline_type,
-                                                GeditDocumentCompressionType  compression_type,
-                                                GeditDocumentSaveFlags        flags);
+static void    gedit_document_saved_real       (GeditDocument *doc,
+                                                const GError  *error);
 
 struct _GeditDocumentPrivate
 {
@@ -87,10 +84,6 @@ struct _GeditDocumentPrivate
        /* Temp data while loading */
        gboolean             create; /* Create file if uri points
                                      * to a non existing file */
-       const GeditEncoding *requested_encoding;
-
-       /* Saving stuff */
-       GeditDocumentSaver *saver;
 
        GtkTextTag *error_tag;
 
@@ -130,7 +123,6 @@ enum
        LOAD,
        LOADED,
        SAVE,
-       SAVING,
        SAVED,
        LAST_SIGNAL
 };
@@ -435,7 +427,7 @@ gedit_document_class_init (GeditDocumentClass *klass)
        buf_class->changed = gedit_document_changed;
 
        klass->loaded = gedit_document_loaded_real;
-       klass->save = gedit_document_save_real;
+       klass->saved = gedit_document_saved_real;
 
        g_object_class_install_property (object_class, PROP_LOCATION,
                                         g_param_spec_object ("location",
@@ -622,18 +614,6 @@ gedit_document_class_init (GeditDocumentClass *klass)
                              GEDIT_TYPE_DOCUMENT_COMPRESSION_TYPE,
                              GEDIT_TYPE_DOCUMENT_SAVE_FLAGS);
 
-       document_signals[SAVING] =
-               g_signal_new ("saving",
-                             G_OBJECT_CLASS_TYPE (object_class),
-                             G_SIGNAL_RUN_LAST,
-                             G_STRUCT_OFFSET (GeditDocumentClass, saving),
-                             NULL, NULL,
-                             gedit_marshal_VOID__UINT64_UINT64,
-                             G_TYPE_NONE,
-                             2,
-                             G_TYPE_UINT64,
-                             G_TYPE_UINT64);
-
        document_signals[SAVED] =
                g_signal_new ("saved",
                              G_OBJECT_CLASS_TYPE (object_class),
@@ -1231,9 +1211,9 @@ gedit_document_get_readonly (GeditDocument *doc)
 }
 
 static void
-query_info_cb (GFile         *location,
-              GAsyncResult  *result,
-              GeditDocument *doc)
+loaded_query_info_cb (GFile         *location,
+                     GAsyncResult  *result,
+                     GeditDocument *doc)
 {
        GFileInfo *info;
        const gchar *content_type = NULL;
@@ -1302,243 +1282,68 @@ gedit_document_loaded_real (GeditDocument *doc,
                                 G_FILE_QUERY_INFO_NONE,
                                 G_PRIORITY_DEFAULT,
                                 NULL,
-                                (GAsyncReadyCallback) query_info_cb,
+                                (GAsyncReadyCallback) loaded_query_info_cb,
                                 doc);
 }
 
-static gboolean
-has_invalid_chars (GeditDocument *doc)
+static void
+saved_query_info_cb (GFile         *location,
+                    GAsyncResult  *result,
+                    GeditDocument *doc)
 {
-       GtkTextBuffer *buffer;
-       GtkTextIter start;
-
-       g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
+       GFileInfo *info;
+       const gchar *content_type = NULL;
+       GError *error = NULL;
 
-       gedit_debug (DEBUG_DOCUMENT);
+       info = g_file_query_info_finish (location, result, &error);
 
-       if (doc->priv->error_tag == NULL)
+       if (error != NULL)
        {
-               return FALSE;
+               g_warning ("Document saving: query info error: %s", error->message);
+               g_error_free (error);
+               error = NULL;
        }
 
-       buffer = GTK_TEXT_BUFFER (doc);
-
-       gtk_text_buffer_get_start_iter (buffer, &start);
-
-       if (gtk_text_iter_begins_tag (&start, doc->priv->error_tag) ||
-           gtk_text_iter_forward_to_tag_toggle (&start, doc->priv->error_tag))
+       if (info != NULL &&
+           g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
        {
-               return TRUE;
+               content_type = g_file_info_get_attribute_string (info, 
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
        }
 
-       return FALSE;
-}
-
-static void
-document_saver_saving (GeditDocumentSaver *saver,
-                      gboolean            completed,
-                      const GError       *error,
-                      GeditDocument      *doc)
-{
-       gedit_debug (DEBUG_DOCUMENT);
-
-       if (completed)
-       {
-               /* save was successful */
-               if (error == NULL)
-               {
-                       GFile *location;
-                       const gchar *content_type = NULL;
-                       GTimeVal mtime = {0, 0};
-                       GFileInfo *info;
-
-                       location = gedit_document_saver_get_location (saver);
-                       set_location (doc, location);
-                       g_object_unref (location);
-
-                       info = gedit_document_saver_get_info (saver);
-
-                       if (info != NULL)
-                       {
-                               if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE))
-                                       content_type = g_file_info_get_attribute_string (info,
-                                                                                        
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
-
-                               if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
-                                       g_file_info_get_modification_time (info, &mtime);
-                       }
-
-                       gedit_document_set_content_type (doc, content_type);
-                       doc->priv->mtime = mtime;
-
-                       g_get_current_time (&doc->priv->time_of_last_save_or_load);
-
-                       doc->priv->externally_modified = FALSE;
-                       doc->priv->deleted = FALSE;
-                       doc->priv->create = FALSE;
-
-                       _gedit_document_set_readonly (doc, FALSE);
-
-                       gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc),
-                                                     FALSE);
-
-                       set_encoding (doc,
-                                     doc->priv->requested_encoding,
-                                     TRUE);
-               }
+       gedit_document_set_content_type (doc, content_type);
 
-               g_signal_emit (doc,
-                              document_signals[SAVED],
-                              0,
-                              error);
+       g_get_current_time (&doc->priv->time_of_last_save_or_load);
 
-               /* the saver has been used, throw it away */
-               g_object_unref (doc->priv->saver);
-               doc->priv->saver = NULL;
-       }
-       else
-       {
-               goffset size = 0;
-               goffset written = 0;
+       doc->priv->externally_modified = FALSE;
+       doc->priv->deleted = FALSE;
+       doc->priv->create = FALSE;
 
-               size = gedit_document_saver_get_file_size (saver);
-               written = gedit_document_saver_get_bytes_written (saver);
+       _gedit_document_set_readonly (doc, FALSE);
 
-               gedit_debug_message (DEBUG_DOCUMENT, "save progress: %" G_GINT64_FORMAT " of %" 
G_GINT64_FORMAT, written, size);
+       set_encoding (doc,
+                     gtk_source_file_get_encoding (doc->priv->file),
+                     TRUE);
 
-               g_signal_emit (doc,
-                              document_signals[SAVING],
-                              0,
-                              written,
-                              size);
-       }
+       /* Async operation finished. */
+       g_object_unref (doc);
 }
 
 static void
-gedit_document_save_real (GeditDocument                *doc,
-                         GFile                        *location,
-                         const GeditEncoding          *encoding,
-                         GeditDocumentNewlineType      newline_type,
-                         GeditDocumentCompressionType  compression_type,
-                         GeditDocumentSaveFlags        flags)
-{
-       g_return_if_fail (doc->priv->saver == NULL);
-
-       if (!(flags & GEDIT_DOCUMENT_SAVE_IGNORE_INVALID_CHARS) && has_invalid_chars (doc))
-       {
-               GError *error = NULL;
-
-               g_set_error_literal (&error,
-                                    GEDIT_DOCUMENT_ERROR,
-                                    GEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK,
-                                    "The document contains invalid characters");
-
-               g_signal_emit (doc,
-                              document_signals[SAVED],
-                              0,
-                              error);
-
-               g_error_free (error);
-       }
-       else
-       {
-               /* create a saver, it will be destroyed once saving is complete */
-               doc->priv->saver = gedit_document_saver_new (doc,
-                                                            location,
-                                                            encoding,
-                                                            newline_type,
-                                                            compression_type,
-                                                            flags);
-
-               g_signal_connect (doc->priv->saver,
-                                 "saving",
-                                 G_CALLBACK (document_saver_saving),
-                                 doc);
-
-               doc->priv->requested_encoding = encoding;
-               doc->priv->newline_type = newline_type;
-               doc->priv->compression_type = compression_type;
-
-               gedit_document_saver_save (doc->priv->saver,
-                                          &doc->priv->mtime);
-       }
-}
-
-/*
- * _gedit_document_save:
- * @doc: the #GeditDocument.
- * @flags: optionnal #GeditDocumentSaveFlags.
- *
- * Save the document to its previous location. This results in the "save"
- * signal to be emitted.
- */
-void
-_gedit_document_save (GeditDocument          *doc,
-                     GeditDocumentSaveFlags  flags)
-{
-       g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
-       g_return_if_fail (G_IS_FILE (doc->priv->location));
-
-       g_signal_emit (doc,
-                      document_signals[SAVE],
-                      0,
-                      doc->priv->location,
-                      doc->priv->encoding,
-                      doc->priv->newline_type,
-                      doc->priv->compression_type,
-                      flags);
-}
-
-/*
- * _gedit_document_save_as:
- * @doc: the #GeditDocument.
- * @location: the location where to save the document.
- * @encoding: the #GeditEncoding to encode the document.
- * @newline_type: the #GeditDocumentNewlineType for the document.
- * @compression_type: the compression type for the file.
- * @flags: optionnal #GeditDocumentSaveFlags.
- *
- * Save the document to a new location. This results in the "save" signal
- * to be emitted.
- */
-void
-_gedit_document_save_as (GeditDocument                *doc,
-                        GFile                        *location,
-                        const GeditEncoding          *encoding,
-                        GeditDocumentNewlineType      newline_type,
-                        GeditDocumentCompressionType  compression_type,
-                        GeditDocumentSaveFlags        flags)
+gedit_document_saved_real (GeditDocument *doc,
+                          const GError  *error)
 {
-       GError *error = NULL;
-
-       g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
-       g_return_if_fail (G_IS_FILE (location));
-       g_return_if_fail (encoding != NULL);
-
-       if (has_invalid_chars (doc))
-       {
-               g_set_error_literal (&error,
-                                    GEDIT_DOCUMENT_ERROR,
-                                    GEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK,
-                                    "The document contains invalid chars");
-       }
+       GFile *location = gtk_source_file_get_location (doc->priv->file);
 
-       /* priv->mtime refers to the the old location (if any). Thus, it should be
-        * ignored when saving as. */
-       g_signal_emit (doc,
-                      document_signals[SAVE],
-                      0,
-                      location,
-                      encoding,
-                      newline_type,
-                      compression_type,
-                      flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME,
-                      error);
+       /* Keep the doc alive during the async operation. */
+       g_object_ref (doc);
 
-       if (error != NULL)
-       {
-               g_error_free (error);
-       }
+       g_file_query_info_async (location,
+                                G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+                                G_FILE_QUERY_INFO_NONE,
+                                G_PRIORITY_DEFAULT,
+                                NULL,
+                                (GAsyncReadyCallback) saved_query_info_cb,
+                                doc);
 }
 
 gboolean
diff --git a/gedit/gedit-document.h b/gedit/gedit-document.h
index 3566577..098985a 100644
--- a/gedit/gedit-document.h
+++ b/gedit/gedit-document.h
@@ -128,10 +128,6 @@ struct _GeditDocumentClass
                                         GeditDocumentCompressionType  compression_type,
                                         GeditDocumentSaveFlags        flags);
 
-       void (* saving)                 (GeditDocument    *document,
-                                        goffset           size,
-                                        goffset           total_size);
-
        void (* saved)                  (GeditDocument    *document,
                                         const GError     *error);
 };
@@ -220,16 +216,6 @@ GtkSourceSearchContext     *gedit_document_get_search_context      (GeditDocument
 
 /* Non exported functions */
 
-void            _gedit_document_save           (GeditDocument       *doc,
-                                                GeditDocumentSaveFlags flags);
-
-void            _gedit_document_save_as        (GeditDocument                *doc,
-                                                GFile                        *location,
-                                                const GeditEncoding          *encoding,
-                                                GeditDocumentNewlineType      newline_type,
-                                                GeditDocumentCompressionType  compression_type,
-                                                GeditDocumentSaveFlags        flags);
-
 void            _gedit_document_set_readonly   (GeditDocument       *doc,
                                                 gboolean             readonly);
 
diff --git a/gedit/gedit-io-error-info-bar.c b/gedit/gedit-io-error-info-bar.c
index 2fdb252..2645e99 100644
--- a/gedit/gedit-io-error-info-bar.c
+++ b/gedit/gedit-io-error-info-bar.c
@@ -286,29 +286,6 @@ parse_gio_error (gint          code,
        return ret;
 }
 
-static gboolean
-parse_gedit_error (gint          code,
-                  gchar       **error_message,
-                  gchar       **message_details,
-                  GFile        *location,
-                  const gchar  *uri_for_display)
-{
-       gboolean ret = TRUE;
-
-       switch (code)
-       {
-               case GEDIT_DOCUMENT_ERROR_TOO_BIG:
-                       *message_details = g_strdup (_("The file is too big."));
-                       break;
-
-               default:
-                       ret = FALSE;
-                       break;
-       }
-
-       return ret;
-}
-
 static void
 parse_error (const GError *error,
             gchar       **error_message,
@@ -326,14 +303,6 @@ parse_error (const GError *error,
                                       location,
                                       uri_for_display);
        }
-       else if (error->domain == GEDIT_DOCUMENT_ERROR)
-       {
-               ret = parse_gedit_error (error->code,
-                                        error_message,
-                                        message_details,
-                                        location,
-                                        uri_for_display);
-       }
 
        if (!ret)
        {
@@ -866,8 +835,8 @@ gedit_externally_modified_saving_error_info_bar_new (GFile        *location,
 
        g_return_val_if_fail (G_IS_FILE (location), NULL);
        g_return_val_if_fail (error != NULL, NULL);
-       g_return_val_if_fail (error->domain == GEDIT_DOCUMENT_ERROR, NULL);
-       g_return_val_if_fail (error->code == GEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED, NULL);
+       g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_SAVER_ERROR, NULL);
+       g_return_val_if_fail (error->code == GTK_SOURCE_FILE_SAVER_ERROR_EXTERNALLY_MODIFIED, NULL);
 
        full_formatted_uri = g_file_get_parse_name (location);
 
@@ -1054,8 +1023,8 @@ gedit_unrecoverable_saving_error_info_bar_new (GFile        *location,
 
        g_return_val_if_fail (G_IS_FILE (location), NULL);
        g_return_val_if_fail (error != NULL, NULL);
-       g_return_val_if_fail ((error->domain == GEDIT_DOCUMENT_ERROR) ||
-                             (error->domain == G_IO_ERROR), NULL);
+       g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_SAVER_ERROR ||
+                             error->domain == G_IO_ERROR, NULL);
 
        full_formatted_uri = g_file_get_parse_name (location);
 
@@ -1129,6 +1098,10 @@ gedit_unrecoverable_saving_error_info_bar_new (GFile        *location,
                                              "a limitation on length of the file names. "
                                              "Please use a shorter name."));
        }
+#if 0
+       /* FIXME this error can not occur for a file saving. Either remove the
+        * code here, or improve the GtkSourceFileSaver so this error can occur.
+        */
        else if (error->domain == GEDIT_DOCUMENT_ERROR &&
                 error->code == GEDIT_DOCUMENT_ERROR_TOO_BIG)
        {
@@ -1137,6 +1110,7 @@ gedit_unrecoverable_saving_error_info_bar_new (GFile        *location,
                                              "a smaller file or saving it to a disk that does not "
                                              "have this limitation."));
        }
+#endif
        else
        {
                parse_error (error,
diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
index 8e65f73..edbe118 100644
--- a/gedit/gedit-tab.c
+++ b/gedit/gedit-tab.c
@@ -54,21 +54,18 @@ struct _GeditTabPrivate
 
        GeditPrintJob          *print_job;
 
-       /* tmp data for saving */
-       GFile                  *tmp_save_location;
+       GtkSourceFileSaver     *saver;
+       GtkSourceFileSaverFlags save_flags;
 
        /* tmp data for loading */
        GtkSourceFileLoader    *loader;
        GCancellable           *cancellable;
        gint                    tmp_line_pos;
        gint                    tmp_column_pos;
-       const GtkSourceEncoding *tmp_encoding; /* TODO remove */
        guint                   idle_scroll;
 
        GTimer                 *timer;
 
-       GeditDocumentSaveFlags  save_flags;
-
        gint                    auto_save_interval;
        guint                   auto_save_timeout;
 
@@ -109,6 +106,8 @@ static void load (GeditTab                *tab,
                  gint                     line_pos,
                  gint                     column_pos);
 
+static void save (GeditTab *tab);
+
 static void
 install_auto_save_timeout (GeditTab *tab)
 {
@@ -229,6 +228,12 @@ clear_loading (GeditTab *tab)
 }
 
 static void
+clear_saving (GeditTab *tab)
+{
+       g_clear_object (&tab->priv->saver);
+}
+
+static void
 gedit_tab_dispose (GObject *object)
 {
        GeditTab *tab = GEDIT_TAB (object);
@@ -240,10 +245,10 @@ gedit_tab_dispose (GObject *object)
                tab->priv->print_preview = NULL;
        }
 
-       g_clear_object (&tab->priv->tmp_save_location);
        g_clear_object (&tab->priv->editor);
 
        clear_loading (tab);
+       clear_saving (tab);
 
        G_OBJECT_CLASS (gedit_tab_parent_class)->dispose (object);
 }
@@ -809,7 +814,7 @@ show_saving_info_bar (GeditTab *tab)
        gchar *msg = NULL;
        gint len;
 
-       g_return_if_fail (tab->priv->tmp_save_location != NULL);
+       g_return_if_fail (tab->priv->saver != NULL);
 
        if (tab->priv->info_bar != NULL)
        {
@@ -829,18 +834,17 @@ show_saving_info_bar (GeditTab *tab)
         */
        if (len > MAX_MSG_LENGTH)
        {
-               from = gedit_utils_str_middle_truncate (short_name,
-                                                       MAX_MSG_LENGTH);
+               from = gedit_utils_str_middle_truncate (short_name, MAX_MSG_LENGTH);
                g_free (short_name);
        }
        else
        {
                gchar *str;
+               GFile *location = gtk_source_file_saver_get_location (tab->priv->saver);
 
                from = short_name;
-               to = g_file_get_parse_name (tab->priv->tmp_save_location);
-               str = gedit_utils_str_middle_truncate (to,
-                                                      MAX (20, MAX_MSG_LENGTH - len));
+               to = g_file_get_parse_name (location);
+               str = gedit_utils_str_middle_truncate (to, MAX (20, MAX_MSG_LENGTH - len));
                g_free (to);
 
                to = str;
@@ -854,9 +858,7 @@ show_saving_info_bar (GeditTab *tab)
 
                /* Translators: the first %s is a file name (e.g. test.txt) the second one
                   is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
-               msg = g_strdup_printf (_("Saving %s to %s"),
-                                      from_markup,
-                                      to_markup);
+               msg = g_strdup_printf (_("Saving %s to %s"), from_markup, to_markup);
                g_free (to_markup);
        }
        else
@@ -864,9 +866,7 @@ show_saving_info_bar (GeditTab *tab)
                msg = g_strdup_printf (_("Saving %s"), from_markup);
        }
 
-       bar = gedit_progress_info_bar_new ("document-save",
-                                          msg,
-                                          FALSE);
+       bar = gedit_progress_info_bar_new ("document-save", msg, FALSE);
 
        set_info_bar (tab, bar, GTK_RESPONSE_NONE);
 
@@ -931,48 +931,6 @@ scroll_to_cursor (GeditTab *tab)
 }
 
 static void
-document_saving (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_SAVING);
-
-       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_saving_info_bar (tab);
-       }
-
-       info_bar_set_progress (tab, size, total_size);
-}
-
-static void
-end_saving (GeditTab *tab)
-{
-       /* Reset tmp data for saving */
-       g_clear_object (&tab->priv->tmp_save_location);
-
-       tab->priv->tmp_encoding = NULL;
-}
-
-static void
 unrecoverable_saving_error_info_bar_response (GtkWidget *info_bar,
                                              gint       response_id,
                                              GeditTab  *tab)
@@ -988,7 +946,7 @@ unrecoverable_saving_error_info_bar_response (GtkWidget *info_bar,
                gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
        }
 
-       end_saving (tab);
+       clear_saving (tab);
 
        set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
 
@@ -1003,24 +961,21 @@ invalid_character_info_bar_response (GtkWidget *info_bar,
 {
        if (response_id == GTK_RESPONSE_YES)
        {
-               GeditDocument *doc = gedit_tab_get_document (tab);
+               GtkSourceFileSaverFlags save_flags;
 
                set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
 
-               g_return_if_fail (tab->priv->tmp_save_location != NULL);
-               g_return_if_fail (tab->priv->tmp_encoding != NULL);
+               g_return_if_fail (tab->priv->saver != NULL);
 
-               gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
+               /* Don't bug the user again with this... */
+               tab->priv->save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS;
 
-               /* don't bug the user again with this... */
-               tab->priv->save_flags |= GEDIT_DOCUMENT_SAVE_IGNORE_INVALID_CHARS;
+               save_flags = gtk_source_file_saver_get_flags (tab->priv->saver);
+               save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS;
+               gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
 
                /* Force saving */
-
-               /* FIXME there is a bug here when the action was a "save as".
-                * See https://bugzilla.gnome.org/show_bug.cgi?id=695107
-                */
-               _gedit_document_save (doc, tab->priv->save_flags);
+               save (tab);
        }
        else
        {
@@ -1035,17 +990,18 @@ no_backup_error_info_bar_response (GtkWidget *info_bar,
 {
        if (response_id == GTK_RESPONSE_YES)
        {
-               GeditDocument *doc = gedit_tab_get_document (tab);
+               GtkSourceFileSaverFlags save_flags;
 
                set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
 
-               g_return_if_fail (tab->priv->tmp_save_location != NULL);
-               g_return_if_fail (tab->priv->tmp_encoding != NULL);
+               g_return_if_fail (tab->priv->saver != NULL);
 
-               gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
+               save_flags = gtk_source_file_saver_get_flags (tab->priv->saver);
+               save_flags &= ~GTK_SOURCE_FILE_SAVER_FLAGS_CREATE_BACKUP;
+               gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
 
                /* Force saving */
-               _gedit_document_save (doc, tab->priv->save_flags);
+               save (tab);
        }
        else
        {
@@ -1060,19 +1016,22 @@ externally_modified_error_info_bar_response (GtkWidget *info_bar,
 {
        if (response_id == GTK_RESPONSE_YES)
        {
-               GeditDocument *doc = gedit_tab_get_document (tab);
+               GtkSourceFileSaverFlags save_flags;
 
                set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
 
-               g_return_if_fail (tab->priv->tmp_save_location != NULL);
-               g_return_if_fail (tab->priv->tmp_encoding != NULL);
+               g_return_if_fail (tab->priv->saver != NULL);
 
-               gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
+               /* ignore_modification_time should not be persisted in save
+                * flags across saves (i.e. priv->save_flags is not modified).
+                */
 
-               /* ignore mtime should not be persisted in save flags across saves */
+               save_flags = gtk_source_file_saver_get_flags (tab->priv->saver);
+               save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME;
+               gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
 
                /* Force saving */
-               _gedit_document_save (doc, tab->priv->save_flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME);
+               save (tab);
        }
        else
        {
@@ -1085,35 +1044,19 @@ recoverable_saving_error_info_bar_response (GtkWidget *info_bar,
                                            gint       response_id,
                                            GeditTab  *tab)
 {
-       GeditDocument *doc = gedit_tab_get_document (tab);
-
        if (response_id == GTK_RESPONSE_OK)
        {
                const GtkSourceEncoding *encoding;
-               gchar *tmp_uri;
-
-               encoding = gedit_conversion_error_info_bar_get_encoding (GTK_WIDGET (info_bar));
-
-               g_return_if_fail (encoding != NULL);
 
                set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
 
-               g_return_if_fail (tab->priv->tmp_save_location != NULL);
+               g_return_if_fail (tab->priv->saver != NULL);
 
-               gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
-
-               tab->priv->tmp_encoding = encoding;
-
-               tmp_uri = g_file_get_uri (tab->priv->tmp_save_location);
-               gedit_debug_message (DEBUG_TAB, "Force saving with URI '%s'", tmp_uri);
-               g_free (tmp_uri);
+               encoding = gedit_conversion_error_info_bar_get_encoding (GTK_WIDGET (info_bar));
+               g_return_if_fail (encoding != NULL);
 
-               _gedit_document_save_as (doc,
-                                        tab->priv->tmp_save_location,
-                                        tab->priv->tmp_encoding,
-                                        gedit_document_get_newline_type (doc),
-                                        gedit_document_get_compression_type (doc),
-                                        tab->priv->save_flags);
+               gtk_source_file_saver_set_encoding (tab->priv->saver, encoding);
+               save (tab);
        }
        else
        {
@@ -1122,124 +1065,6 @@ recoverable_saving_error_info_bar_response (GtkWidget *info_bar,
 }
 
 static void
-document_saved (GeditDocument *document,
-               const GError  *error,
-               GeditTab      *tab)
-{
-       g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_SAVING);
-
-       g_return_if_fail (tab->priv->tmp_save_location != NULL);
-       g_return_if_fail (tab->priv->tmp_encoding != NULL);
-
-       if (tab->priv->timer != NULL)
-       {
-               g_timer_destroy (tab->priv->timer);
-               tab->priv->timer = NULL;
-       }
-
-       set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
-
-       if (error != NULL)
-       {
-               GtkWidget *info_bar;
-
-               gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING_ERROR);
-
-               if (error->domain == GEDIT_DOCUMENT_ERROR &&
-                   error->code == GEDIT_DOCUMENT_ERROR_EXTERNALLY_MODIFIED)
-               {
-                       /* This error is recoverable */
-                       info_bar = gedit_externally_modified_saving_error_info_bar_new 
(tab->priv->tmp_save_location,
-                                                                                       error);
-                       g_return_if_fail (info_bar != NULL);
-
-                       g_signal_connect (info_bar,
-                                         "response",
-                                         G_CALLBACK (externally_modified_error_info_bar_response),
-                                         tab);
-               }
-               else if (error->domain == G_IO_ERROR &&
-                        error->code == G_IO_ERROR_CANT_CREATE_BACKUP)
-               {
-                       /* This error is recoverable */
-                       info_bar = gedit_no_backup_saving_error_info_bar_new (tab->priv->tmp_save_location,
-                                                                             error);
-                       g_return_if_fail (info_bar != NULL);
-
-                       g_signal_connect (info_bar,
-                                         "response",
-                                         G_CALLBACK (no_backup_error_info_bar_response),
-                                         tab);
-               }
-               else if (error->domain == GEDIT_DOCUMENT_ERROR &&
-                        error->code == GEDIT_DOCUMENT_ERROR_CONVERSION_FALLBACK)
-               {
-                       /* If we have any invalid char in the document we must warn the user
-                          as it can make the document useless if it is saved */
-                       info_bar = gedit_invalid_character_info_bar_new (tab->priv->tmp_save_location);
-                       g_return_if_fail (info_bar != NULL);
-
-                       g_signal_connect (info_bar,
-                                         "response",
-                                         G_CALLBACK (invalid_character_info_bar_response),
-                                         tab);
-               }
-               else if (error->domain == GEDIT_DOCUMENT_ERROR ||
-                        (error->domain == G_IO_ERROR &&
-                         error->code != G_IO_ERROR_INVALID_DATA &&
-                         error->code != G_IO_ERROR_PARTIAL_INPUT))
-               {
-                       /* These errors are _NOT_ recoverable */
-                       gedit_recent_remove_if_local (tab->priv->tmp_save_location);
-
-                       info_bar = gedit_unrecoverable_saving_error_info_bar_new 
(tab->priv->tmp_save_location,
-                                                                                 error);
-                       g_return_if_fail (info_bar != NULL);
-
-                       g_signal_connect (info_bar,
-                                         "response",
-                                         G_CALLBACK (unrecoverable_saving_error_info_bar_response),
-                                         tab);
-               }
-               else
-               {
-                       /* This error is recoverable */
-                       g_return_if_fail (error->domain == G_CONVERT_ERROR ||
-                                         error->domain == G_IO_ERROR);
-
-                       info_bar = gedit_conversion_error_while_saving_info_bar_new 
(tab->priv->tmp_save_location,
-                                                                                    tab->priv->tmp_encoding,
-                                                                                    error);
-                       g_return_if_fail (info_bar != NULL);
-
-                       g_signal_connect (info_bar,
-                                         "response",
-                                         G_CALLBACK (recoverable_saving_error_info_bar_response),
-                                         tab);
-               }
-
-               set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
-       }
-       else
-       {
-               gedit_recent_add_document (document);
-
-               if (tab->priv->print_preview != NULL)
-               {
-                       gedit_tab_set_state (tab, GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
-               }
-               else
-               {
-                       gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
-               }
-
-               tab->priv->ask_if_externally_modified = TRUE;
-
-               end_saving (tab);
-       }
-}
-
-static void
 externally_modified_notification_info_bar_response (GtkWidget *info_bar,
                                                    gint       response_id,
                                                    GeditTab  *tab)
@@ -1400,8 +1225,6 @@ gedit_tab_init (GeditTab *tab)
 
        tab->priv->editable = TRUE;
 
-       tab->priv->save_flags = 0;
-
        tab->priv->ask_if_externally_modified = TRUE;
 
        gtk_orientable_set_orientation (GTK_ORIENTABLE (tab),
@@ -1447,16 +1270,6 @@ gedit_tab_init (GeditTab *tab)
                          G_CALLBACK (document_modified_changed),
                          tab);
 
-       g_signal_connect (doc,
-                         "saving",
-                         G_CALLBACK (document_saving),
-                         tab);
-
-       g_signal_connect (doc,
-                         "saved",
-                         G_CALLBACK (document_saved),
-                         tab);
-
        view = gedit_tab_get_view (tab);
 
        g_signal_connect_after (view,
@@ -1758,9 +1571,9 @@ gedit_tab_get_from_document (GeditDocument *doc)
 }
 
 static void
-progress_cb (goffset   size,
-            goffset   total_size,
-            GeditTab *tab)
+loader_progress_cb (goffset   size,
+                   goffset   total_size,
+                   GeditTab *tab)
 {
        gdouble elapsed_time;
        gdouble total_time;
@@ -1854,6 +1667,7 @@ load_cb (GtkSourceFileLoader *loader,
 
        if (error != NULL)
        {
+               /* TODO remove when no longer needed. */
                g_warning ("File loading error: %s", error->message);
        }
 
@@ -2106,7 +1920,7 @@ load (GeditTab                *tab,
        gtk_source_file_loader_load_async (tab->priv->loader,
                                           G_PRIORITY_DEFAULT,
                                           tab->priv->cancellable,
-                                          (GFileProgressCallback) progress_cb,
+                                          (GFileProgressCallback) loader_progress_cb,
                                           tab,
                                           NULL,
                                           (GAsyncReadyCallback) load_cb,
@@ -2210,55 +2024,244 @@ _gedit_tab_revert (GeditTab *tab)
        load (tab, NULL, 0, 0);
 }
 
+static void
+saver_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_SAVING);
+
+       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_saving_info_bar (tab);
+       }
+
+       info_bar_set_progress (tab, size, total_size);
+}
+
+static void
+save_cb (GtkSourceFileSaver *saver,
+        GAsyncResult       *result,
+        GeditTab           *tab)
+{
+       GeditDocument *doc = gedit_tab_get_document (tab);
+       GFile *location = gtk_source_file_saver_get_location (saver);
+       GError *error = NULL;
+
+       g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_SAVING);
+
+       gtk_source_file_saver_save_finish (saver, result, &error);
+
+       if (error != NULL)
+       {
+               /* TODO remove when no longer needed. */
+               g_warning ("File saving error: %s", error->message);
+       }
+
+       if (tab->priv->timer != NULL)
+       {
+               g_timer_destroy (tab->priv->timer);
+               tab->priv->timer = NULL;
+       }
+
+       set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
+
+       if (error != NULL)
+       {
+               GtkWidget *info_bar;
+
+               gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING_ERROR);
+
+               if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR &&
+                   error->code == GTK_SOURCE_FILE_SAVER_ERROR_EXTERNALLY_MODIFIED)
+               {
+                       /* This error is recoverable */
+                       info_bar = gedit_externally_modified_saving_error_info_bar_new (location, error);
+                       g_return_if_fail (info_bar != NULL);
+
+                       g_signal_connect (info_bar,
+                                         "response",
+                                         G_CALLBACK (externally_modified_error_info_bar_response),
+                                         tab);
+               }
+               else if (error->domain == G_IO_ERROR &&
+                        error->code == G_IO_ERROR_CANT_CREATE_BACKUP)
+               {
+                       /* This error is recoverable */
+                       info_bar = gedit_no_backup_saving_error_info_bar_new (location, error);
+                       g_return_if_fail (info_bar != NULL);
+
+                       g_signal_connect (info_bar,
+                                         "response",
+                                         G_CALLBACK (no_backup_error_info_bar_response),
+                                         tab);
+               }
+               else if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR &&
+                        error->code == GTK_SOURCE_FILE_SAVER_ERROR_INVALID_CHARS)
+               {
+                       /* If we have any invalid char in the document we must warn the user
+                        * as it can make the document useless if it is saved.
+                        */
+                       info_bar = gedit_invalid_character_info_bar_new (location);
+                       g_return_if_fail (info_bar != NULL);
+
+                       g_signal_connect (info_bar,
+                                         "response",
+                                         G_CALLBACK (invalid_character_info_bar_response),
+                                         tab);
+               }
+               else if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR ||
+                        (error->domain == G_IO_ERROR &&
+                         error->code != G_IO_ERROR_INVALID_DATA &&
+                         error->code != G_IO_ERROR_PARTIAL_INPUT))
+               {
+                       /* These errors are _NOT_ recoverable */
+                       gedit_recent_remove_if_local (location);
+
+                       info_bar = gedit_unrecoverable_saving_error_info_bar_new (location, error);
+                       g_return_if_fail (info_bar != NULL);
+
+                       g_signal_connect (info_bar,
+                                         "response",
+                                         G_CALLBACK (unrecoverable_saving_error_info_bar_response),
+                                         tab);
+               }
+               else
+               {
+                       const GtkSourceEncoding *encoding;
+
+                       /* This error is recoverable */
+                       g_return_if_fail (error->domain == G_CONVERT_ERROR ||
+                                         error->domain == G_IO_ERROR);
+
+                       encoding = gtk_source_file_saver_get_encoding (saver);
+
+                       info_bar = gedit_conversion_error_while_saving_info_bar_new (location, encoding, 
error);
+                       g_return_if_fail (info_bar != NULL);
+
+                       g_signal_connect (info_bar,
+                                         "response",
+                                         G_CALLBACK (recoverable_saving_error_info_bar_response),
+                                         tab);
+               }
+
+               set_info_bar (tab, info_bar, GTK_RESPONSE_CANCEL);
+       }
+       else
+       {
+               gedit_recent_add_document (doc);
+
+               if (tab->priv->print_preview != NULL)
+               {
+                       gedit_tab_set_state (tab, GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
+               }
+               else
+               {
+                       gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
+               }
+
+               tab->priv->ask_if_externally_modified = TRUE;
+
+               clear_saving (tab);
+
+               g_signal_emit_by_name (doc, "saved", NULL);
+       }
+
+       /* Async operation finished. */
+       g_object_unref (tab);
+
+       if (error != NULL)
+       {
+               g_error_free (error);
+       }
+}
+
+static void
+save (GeditTab *tab)
+{
+       g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (tab->priv->saver));
+
+       gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
+
+       /* Keep the tab alive during the async operation. */
+       g_object_ref (tab);
+
+       gtk_source_file_saver_save_async (tab->priv->saver,
+                                         G_PRIORITY_DEFAULT,
+                                         NULL, /* TODO add a cancellable */
+                                         (GFileProgressCallback) saver_progress_cb,
+                                         tab,
+                                         NULL,
+                                         (GAsyncReadyCallback) save_cb,
+                                         tab);
+}
+
 void
 _gedit_tab_save (GeditTab *tab)
 {
        GeditDocument *doc;
-       GeditDocumentSaveFlags save_flags;
+       GtkSourceFile *file;
+       GFile *location;
+       GtkSourceFileSaverFlags save_flags = tab->priv->save_flags;
 
        g_return_if_fail (GEDIT_IS_TAB (tab));
        g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_NORMAL ||
                          tab->priv->state == GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION ||
                          tab->priv->state == GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
-       g_return_if_fail (tab->priv->tmp_save_location == NULL);
-       g_return_if_fail (tab->priv->tmp_encoding == NULL);
 
        doc = gedit_tab_get_document (tab);
        g_return_if_fail (!gedit_document_is_untitled (doc));
 
        if (tab->priv->state == GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
        {
-               /* We already told the user about the external
-                * modification: hide the message bar and set
-                * the save flag.
+               /* We already told the user about the external modification:
+                * hide the message bar and set the save flag.
                 */
                set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
-               save_flags = tab->priv->save_flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME;
+               save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME;
        }
-       else
+
+       file = gedit_document_get_file (doc);
+       location = gtk_source_file_get_location (file);
+
+       if (tab->priv->saver != NULL)
        {
-               save_flags = tab->priv->save_flags;
+               g_warning ("GeditTab: file saver already exists.");
+               g_object_unref (tab->priv->saver);
        }
 
-       gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
-
-       /* location used in error messages, will be freed in document_saved */
-       tab->priv->tmp_save_location = gedit_document_get_location (doc);
-       tab->priv->tmp_encoding = gedit_document_get_encoding (doc);
+       tab->priv->saver = gtk_source_file_saver_new (file, location);
+       gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
 
-       _gedit_document_save (doc, save_flags);
+       save (tab);
 }
 
 static gboolean
 gedit_tab_auto_save (GeditTab *tab)
 {
        GeditDocument *doc;
+       GtkSourceFile *file;
+       GFile *location;
 
        gedit_debug (DEBUG_TAB);
 
-       g_return_val_if_fail (tab->priv->tmp_save_location == NULL, G_SOURCE_REMOVE);
-       g_return_val_if_fail (tab->priv->tmp_encoding == NULL, G_SOURCE_REMOVE);
-
        doc = gedit_tab_get_document (tab);
        g_return_val_if_fail (!gedit_document_is_untitled (doc), G_SOURCE_REMOVE);
        g_return_val_if_fail (!gedit_document_get_readonly (doc), G_SOURCE_REMOVE);
@@ -2270,8 +2273,8 @@ gedit_tab_auto_save (GeditTab *tab)
                return G_SOURCE_CONTINUE;
        }
 
-       if ((tab->priv->state != GEDIT_TAB_STATE_NORMAL) &&
-           (tab->priv->state != GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW))
+       if (tab->priv->state != GEDIT_TAB_STATE_NORMAL &&
+           tab->priv->state != GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)
        {
                gedit_debug_message (DEBUG_TAB, "Retry after 30 seconds");
 
@@ -2286,23 +2289,33 @@ gedit_tab_auto_save (GeditTab *tab)
        /* Set auto_save_timeout to 0 since the timeout is going to be destroyed */
        tab->priv->auto_save_timeout = 0;
 
-       gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
+       file = gedit_document_get_file (doc);
+       location = gtk_source_file_get_location (file);
 
-       /* location used in error messages, will be freed in document_saved */
-       tab->priv->tmp_save_location = gedit_document_get_location (doc);
-       tab->priv->tmp_encoding = gedit_document_get_encoding (doc);
+       if (tab->priv->saver != NULL)
+       {
+               g_warning ("GeditTab: file saver already exists.");
+               g_object_unref (tab->priv->saver);
+       }
+
+       tab->priv->saver = gtk_source_file_saver_new (file, location);
 
        /* Since we are autosaving, we need to preserve the backup that was produced
-          the last time the user "manually" saved the file. In the case a recoverable
-          error happens while saving, the last backup is not preserved since the user
-          expressed his willing of saving the file */
-       _gedit_document_save (doc, tab->priv->save_flags | GEDIT_DOCUMENT_SAVE_PRESERVE_BACKUP);
+        * the last time the user "manually" saved the file. So we don't set the
+        * CREATE_BACKUP flag for an automatic file saving.
+        * TODO In the case a recoverable error happens while saving, set the
+        * CREATE_BACKUP flag since the user expressed his willing of saving the
+        * file.
+        */
+       gtk_source_file_saver_set_flags (tab->priv->saver,
+                                        tab->priv->save_flags);
 
-       gedit_debug_message (DEBUG_TAB, "Done");
+       save (tab);
 
        return G_SOURCE_REMOVE;
 }
 
+/* TODO port to GtkSourceNewlineType and GtkSourceCompressionType */
 void
 _gedit_tab_save_as (GeditTab                     *tab,
                    GFile                        *location,
@@ -2311,7 +2324,9 @@ _gedit_tab_save_as (GeditTab                     *tab,
                    GeditDocumentCompressionType  compression_type)
 {
        GeditDocument *doc;
-       GeditDocumentSaveFlags save_flags;
+       GtkSourceFile *file;
+       GtkSourceFileSaverFlags save_flags;
+       GFile *prev_location;
 
        g_return_if_fail (GEDIT_IS_TAB (tab));
        g_return_if_fail (tab->priv->state == GEDIT_TAB_STATE_NORMAL ||
@@ -2320,41 +2335,46 @@ _gedit_tab_save_as (GeditTab                     *tab,
        g_return_if_fail (G_IS_FILE (location));
        g_return_if_fail (encoding != NULL);
 
-       g_return_if_fail (tab->priv->tmp_save_location == NULL);
-       g_return_if_fail (tab->priv->tmp_encoding == NULL);
-
        doc = gedit_tab_get_document (tab);
 
        /* reset the save flags, when saving as */
-       tab->priv->save_flags = 0;
+       tab->priv->save_flags = GTK_SOURCE_FILE_SAVER_FLAGS_NONE;
+       save_flags = tab->priv->save_flags;
 
        if (tab->priv->state == GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)
        {
-               /* We already told the user about the external
-                * modification: hide the message bar and set
-                * the save flag.
+               /* We already told the user about the external modification:
+                * hide the message bar and set the save flag.
                 */
                set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
-               save_flags = tab->priv->save_flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME;
+               save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME;
        }
-       else
+
+       file = gedit_document_get_file (doc);
+
+       prev_location = gtk_source_file_get_location (file);
+
+       if (!g_file_equal (prev_location, location))
        {
-               save_flags = tab->priv->save_flags;
+               /* Ignore modification time for a save to another location. */
+               /* TODO do that in GtkSourceFileSaver. */
+               save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME;
        }
 
-       gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
+       if (tab->priv->saver != NULL)
+       {
+               g_warning ("GeditTab: file saver already exists.");
+               g_object_unref (tab->priv->saver);
+       }
+
+       tab->priv->saver = gtk_source_file_saver_new (file, location);
+
+       gtk_source_file_saver_set_encoding (tab->priv->saver, encoding);
+       gtk_source_file_saver_set_newline_type (tab->priv->saver, newline_type);
+       gtk_source_file_saver_set_compression_type (tab->priv->saver, compression_type);
+       gtk_source_file_saver_set_flags (tab->priv->saver, save_flags);
 
-       /* location used in error messages... dup because errors are async
-        * and the location can go away. Will be freed in document_saved. */
-       tab->priv->tmp_save_location = g_file_dup (location);
-       tab->priv->tmp_encoding = encoding;
-
-       _gedit_document_save_as (doc,
-                                location,
-                                encoding,
-                                newline_type,
-                                compression_type,
-                                save_flags);
+       save (tab);
 }
 
 #define GEDIT_PAGE_SETUP_KEY "gedit-page-setup-key"



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