[gedit/wip/loader-saver] Use GtkSourceFile for file saving (not finished!)



commit 911125e2099515219e2a16b29cbc2289141fc8a0
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Mon Dec 30 16:47:03 2013 +0100

    Use GtkSourceFile for file saving (not finished!)
    
    The plan is to write an adapter between the GeditDocument and
    GtkSourceFile APIs.
    
    It removes GeditMountOperationFactory (which was used only in private
    functions) and uses GtkSourceMountOperationFactory instead. The first
    argument to the callback function has been removed (a pointer to a
    GeditDocument). The userdata argument is sufficient.

 docs/reference/Makefile.am          |    1 -
 gedit/Makefile.am                   |    4 -
 gedit/gedit-document-input-stream.c |  506 -----------------
 gedit/gedit-document-input-stream.h |   71 ---
 gedit/gedit-document-saver.c        | 1061 -----------------------------------
 gedit/gedit-document-saver.h        |  121 ----
 gedit/gedit-document.c              |  272 ++++++----
 gedit/gedit-document.h              |   14 +-
 gedit/gedit-settings.h              |    1 +
 gedit/gedit-view-frame.c            |    3 +-
 po/POTFILES.in                      |    1 -
 tests/Makefile.am                   |   12 +-
 tests/document-input-stream.c       |  156 -----
 tests/document-saver.c              |  750 -------------------------
 tests/setup-document-saver.sh       |   27 -
 15 files changed, 166 insertions(+), 2834 deletions(-)
---
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index 8e18e30..9518c13 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -42,7 +42,6 @@ CFILE_GLOB=$(top_srcdir)/gedit/*.c
 IGNORE_HFILES=         \
        gedit-commands.h                        \
        gedit-document-loader.h                 \
-       gedit-document-saver.h                  \
        gedit-documents-panel.h                 \
        gedit-io-error-info-bar.h               \
        gedit-languages-manager.h               \
diff --git a/gedit/Makefile.am b/gedit/Makefile.am
index 9ce957c..c569fc2 100644
--- a/gedit/Makefile.am
+++ b/gedit/Makefile.am
@@ -99,10 +99,8 @@ NOINST_H_FILES =                     \
        gedit-cell-renderer-button.h    \
        gedit-close-confirmation-dialog.h \
        gedit-dirs.h                    \
-       gedit-document-input-stream.h   \
        gedit-document-loader.h         \
        gedit-document-output-stream.h  \
-       gedit-document-saver.h          \
        gedit-documents-panel.h         \
        gedit-encodings-dialog.h        \
        gedit-file-chooser-dialog.h     \
@@ -178,10 +176,8 @@ libgedit_c_files =                 \
        gedit-debug.c                   \
        gedit-dirs.c                    \
        gedit-document.c                \
-       gedit-document-input-stream.c   \
        gedit-document-loader.c         \
        gedit-document-output-stream.c  \
-       gedit-document-saver.c          \
        gedit-documents-panel.c         \
        gedit-encodings.c               \
        gedit-encodings-combo-box.c     \
diff --git a/gedit/gedit-document.c b/gedit/gedit-document.c
index 33b4bd5..7240962 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
@@ -22,14 +23,6 @@
  * Boston, MA 02111-1307, USA.
  */
 
-/*
- * Modified by the gedit Team, 1998-2005. See the AUTHORS file for a
- * list of people on the gedit Team.
- * See the ChangeLog files for a list of changes.
- *
- * $Id$
- */
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -45,7 +38,6 @@
 #include "gedit-debug.h"
 #include "gedit-utils.h"
 #include "gedit-document-loader.h"
-#include "gedit-document-saver.h"
 #include "gedit-marshal.h"
 #include "gedit-enum-types.h"
 
@@ -79,6 +71,7 @@ static void   gedit_document_load_real        (GeditDocument                *doc,
                                                 gint                          line_pos,
                                                 gint                          column_pos,
                                                 gboolean                      create);
+
 static void    gedit_document_save_real        (GeditDocument                *doc,
                                                 GFile                        *location,
                                                 const GeditEncoding          *encoding,
@@ -123,13 +116,13 @@ struct _GeditDocumentPrivate
        gint                 requested_column_pos;
 
        /* Saving stuff */
-       GeditDocumentSaver *saver;
+       GtkSourceFile *source_file;
 
        GtkTextTag *error_tag;
 
        /* Mount operation factory */
-       GeditMountOperationFactory  mount_operation_factory;
-       gpointer                    mount_operation_userdata;
+       GtkSourceMountOperationFactory mount_operation_factory;
+       gpointer                       mount_operation_userdata;
 
        guint readonly : 1;
        guint externally_modified : 1;
@@ -1445,8 +1438,8 @@ document_loader_loaded (GeditDocumentLoader *loader,
 
                g_get_current_time (&doc->priv->time_of_last_save_or_load);
 
-               doc->priv->externally_modified = FALSE;
-               doc->priv->deleted = FALSE;
+               doc->priv->externally_modified = FALSE;
+               doc->priv->deleted = FALSE;
 
                set_encoding (doc,
                              gedit_document_loader_get_encoding (loader),
@@ -1718,83 +1711,131 @@ has_invalid_chars (GeditDocument *doc)
        return FALSE;
 }
 
-static void
-document_saver_saving (GeditDocumentSaver *saver,
-                      gboolean            completed,
-                      const GError       *error,
-                      GeditDocument      *doc)
+static GtkSourceNewlineType
+convert_newline_type (GeditDocumentNewlineType gedit_newline_type)
 {
-       gedit_debug (DEBUG_DOCUMENT);
+       switch (gedit_newline_type)
+       {
+               case GEDIT_DOCUMENT_NEWLINE_TYPE_LF:
+                       return GTK_SOURCE_NEWLINE_TYPE_LF;
 
-       if (completed)
+               case GEDIT_DOCUMENT_NEWLINE_TYPE_CR:
+                       return GTK_SOURCE_NEWLINE_TYPE_CR;
+
+               case GEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF:
+                       return GTK_SOURCE_NEWLINE_TYPE_CR_LF;
+       }
+
+       g_return_val_if_reached (GTK_SOURCE_NEWLINE_TYPE_LF);
+}
+
+static GtkSourceCompressionType
+convert_compression_type (GeditDocumentCompressionType gedit_compression_type)
+{
+       switch (gedit_compression_type)
        {
-               /* save was successful */
-               if (error == NULL)
-               {
-                       GFile *location;
-                       const gchar *content_type = NULL;
-                       GTimeVal mtime = {0, 0};
-                       GFileInfo *info;
+               case GEDIT_DOCUMENT_COMPRESSION_TYPE_NONE:
+                       return GTK_SOURCE_COMPRESSION_TYPE_NONE;
 
-                       location = gedit_document_saver_get_location (saver);
-                       set_location (doc, location);
-                       g_object_unref (location);
+               case GEDIT_DOCUMENT_COMPRESSION_TYPE_GZIP:
+                       return GTK_SOURCE_COMPRESSION_TYPE_GZIP;
+       }
 
-                       info = gedit_document_saver_get_info (saver);
+       g_return_val_if_reached (GTK_SOURCE_COMPRESSION_TYPE_NONE);
+}
 
-                       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);
+static GtkSourceFileSaveFlags
+convert_save_flags (GeditDocumentSaveFlags gedit_flags)
+{
+       GtkSourceFileSaveFlags source_flags = 0;
 
-                               if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
-                                       g_file_info_get_modification_time (info, &mtime);
-                       }
+       if (gedit_flags & GEDIT_DOCUMENT_SAVE_IGNORE_MTIME)
+       {
+               source_flags |= GTK_SOURCE_FILE_SAVE_IGNORE_MTIME;
+       }
 
-                       set_content_type (doc, content_type);
-                       doc->priv->mtime = mtime;
+       if (gedit_flags & GEDIT_DOCUMENT_SAVE_IGNORE_INVALID_CHARS)
+       {
+               source_flags |= GTK_SOURCE_FILE_SAVE_IGNORE_INVALID_CHARS;
+       }
+
+       if ((gedit_flags & GEDIT_DOCUMENT_SAVE_PRESERVE_BACKUP) == 0 &&
+           (gedit_flags & GEDIT_DOCUMENT_SAVE_IGNORE_BACKUP) == 0)
+       {
+               source_flags |= GTK_SOURCE_FILE_SAVE_CREATE_BACKUP;
+       }
+}
+
+static void
+save_progress_cb (goffset        current_position,
+                 goffset        total_size,
+                 GeditDocument *doc)
+{
+       g_signal_emit (doc,
+                      document_signals[SAVING],
+                      0,
+                      current_position,
+                      total_size);
+}
+
+static void
+saved_cb (GtkSourceFile *source_file,
+         GAsyncResult  *result,
+         GeditDocument *doc)
+{
+       GError *error = NULL;
 
-                       g_get_current_time (&doc->priv->time_of_last_save_or_load);
+       gtk_source_file_save_finish (source_file, result, &error);
 
-                       doc->priv->externally_modified = FALSE;
-                       doc->priv->deleted = FALSE;
+       /* save was successful */
+       if (error == NULL)
+       {
+               GFile *location;
+               const gchar *content_type = NULL;
+               GTimeVal mtime = {0, 0};
+               GFileInfo *info;
+
+               location = gtk_source_file_get_location (source_file);
+               set_location (doc, location);
+               g_object_unref (location);
 
-                       _gedit_document_set_readonly (doc, FALSE);
+               info = gedit_document_saver_get_info (saver);
 
-                       gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc),
-                                                     FALSE);
+               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);
 
-                       set_encoding (doc,
-                                     doc->priv->requested_encoding,
-                                     TRUE);
+                       if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
+                               g_file_info_get_modification_time (info, &mtime);
                }
 
-               g_signal_emit (doc,
-                              document_signals[SAVED],
-                              0,
-                              error);
+               set_content_type (doc, content_type);
+               doc->priv->mtime = mtime;
 
-               /* 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;
+               g_get_current_time (&doc->priv->time_of_last_save_or_load);
 
-               size = gedit_document_saver_get_file_size (saver);
-               written = gedit_document_saver_get_bytes_written (saver);
+               doc->priv->externally_modified = FALSE;
+               doc->priv->deleted = FALSE;
 
-               gedit_debug_message (DEBUG_DOCUMENT, "save progress: %" G_GINT64_FORMAT " of %" 
G_GINT64_FORMAT, written, size);
+               _gedit_document_set_readonly (doc, FALSE);
 
-               g_signal_emit (doc,
-                              document_signals[SAVING],
-                              0,
-                              written,
-                              size);
+               gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc),
+                                             FALSE);
+
+               set_encoding (doc,
+                             doc->priv->requested_encoding,
+                             TRUE);
        }
+
+       g_signal_emit (doc,
+                      document_signals[SAVED],
+                      0,
+                      error);
+
+       /* the saver has been used, throw it away */
+       g_clear_object (&doc->priv->source_file);
 }
 
 static void
@@ -1805,7 +1846,9 @@ gedit_document_save_real (GeditDocument                *doc,
                          GeditDocumentCompressionType  compression_type,
                          GeditDocumentSaveFlags        flags)
 {
-       g_return_if_fail (doc->priv->saver == NULL);
+       gboolean ensure_trailing_newline;
+
+       g_return_if_fail (doc->priv->source_file == NULL);
 
        if (!(flags & GEDIT_DOCUMENT_SAVE_IGNORE_INVALID_CHARS) && has_invalid_chars (doc))
        {
@@ -1822,29 +1865,51 @@ gedit_document_save_real (GeditDocument                *doc,
                               error);
 
                g_error_free (error);
+               return;
        }
-       else
+
+       /* Do not make backups for remote files so they do not clutter
+        * remote systems. */
+       if (!gedit_document_is_local (doc) ||
+           !g_settings_get_boolean (doc->priv->editor_settings,
+                                    GEDIT_SETTINGS_CREATE_BACKUP_COPY))
        {
-               /* 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);
+               flags |= GEDIT_DOCUMENT_SAVE_IGNORE_BACKUP;
+       }
 
-               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;
 
-               doc->priv->requested_encoding = encoding;
-               doc->priv->newline_type = newline_type;
-               doc->priv->compression_type = compression_type;
+       /* Create source file, it will be destroyed when the saving is finished. */
+       doc->priv->source_file = gtk_source_file_new (location, GTK_SOURCE_BUFFER (doc));
 
-               gedit_document_saver_save (doc->priv->saver,
-                                          &doc->priv->mtime);
-       }
+       gtk_source_file_set_encoding (doc->priv->source_file,
+                                     (const GtkSourceEncoding *)encoding);
+
+       gtk_source_file_set_newline_type (doc->priv->source_file,
+                                         convert_newline_type (newline_type));
+
+       gtk_source_file_set_compression_type (doc->priv->source_file,
+                                             convert_compression_type (compression_type));
+
+       ensure_trailing_newline = g_settings_get_boolean (doc->priv->editor_settings,
+                                                         GEDIT_SETTINGS_ENSURE_TRAILING_NEWLINE);
+
+       gtk_source_file_set_ensure_trailing_newline (doc->priv->source_file, ensure_trailing_newline);
+
+       gtk_source_file_set_mount_operation_factory (doc->priv->source_file,
+                                                    doc->priv->mount_operation_factory,
+                                                    doc->priv->mount_operation_userdata);
+
+       gtk_source_file_save_async (doc->priv->source_file,
+                                   convert_save_flags (flags),
+                                   G_PRIORITY_HIGH,
+                                   NULL,
+                                   (GFileProgressCallback) save_progress_cb,
+                                   doc,
+                                   (GAsyncReadyCallback) saved_cb,
+                                   doc);
 }
 
 /**
@@ -1891,20 +1956,10 @@ gedit_document_save_as (GeditDocument                *doc,
                        GeditDocumentCompressionType  compression_type,
                        GeditDocumentSaveFlags        flags)
 {
-       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");
-       }
-
        /* priv->mtime refers to the the old location (if any). Thus, it should be
         * ignored when saving as. */
        g_signal_emit (doc,
@@ -1914,13 +1969,7 @@ gedit_document_save_as (GeditDocument                *doc,
                       encoding,
                       newline_type,
                       compression_type,
-                      flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME,
-                      error);
-
-       if (error != NULL)
-       {
-               g_error_free (error);
-       }
+                      flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME);
 }
 
 gboolean
@@ -2830,9 +2879,9 @@ gedit_document_get_compression_type (GeditDocument *doc)
 }
 
 void
-_gedit_document_set_mount_operation_factory (GeditDocument            *doc,
-                                           GeditMountOperationFactory  callback,
-                                           gpointer                    userdata)
+_gedit_document_set_mount_operation_factory (GeditDocument                  *doc,
+                                            GtkSourceMountOperationFactory  callback,
+                                            gpointer                        userdata)
 {
        g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 
@@ -2851,8 +2900,7 @@ _gedit_document_create_mount_operation (GeditDocument *doc)
        }
        else
        {
-               return doc->priv->mount_operation_factory (doc,
-                                                          doc->priv->mount_operation_userdata);
+               return doc->priv->mount_operation_factory (doc->priv->mount_operation_userdata);
        }
 }
 
diff --git a/gedit/gedit-document.h b/gedit/gedit-document.h
index 7696062..e0c962a 100644
--- a/gedit/gedit-document.h
+++ b/gedit/gedit-document.h
@@ -362,18 +362,10 @@ gboolean   _gedit_document_needs_saving   (GeditDocument       *doc);
 #define GEDIT_SEARCH_SET_CASE_SENSITIVE(sflags,state) ((state == TRUE) ? \
 (sflags |= GEDIT_SEARCH_CASE_SENSITIVE) : (sflags &= ~GEDIT_SEARCH_CASE_SENSITIVE))
 
-/**
- * GeditMountOperationFactory: (skip)
- * @doc:
- * @userdata:
- */
-typedef GMountOperation *(*GeditMountOperationFactory)(GeditDocument *doc,
-                                                      gpointer       userdata);
-
 void            _gedit_document_set_mount_operation_factory
-                                               (GeditDocument              *doc,
-                                                GeditMountOperationFactory  callback,
-                                                gpointer                    userdata);
+                                               (GeditDocument                  *doc,
+                                                GtkSourceMountOperationFactory  callback,
+                                                gpointer                        userdata);
 GMountOperation
                *_gedit_document_create_mount_operation
                                                (GeditDocument       *doc);
diff --git a/gedit/gedit-settings.h b/gedit/gedit-settings.h
index 3b2224c..83bd843 100644
--- a/gedit/gedit-settings.h
+++ b/gedit/gedit-settings.h
@@ -108,6 +108,7 @@ void                         gedit_settings_set_list                        (GSettings    
 *settings,
 #define GEDIT_SETTINGS_ENCODING_AUTO_DETECTED          "auto-detected"
 #define GEDIT_SETTINGS_ENCODING_SHOWN_IN_MENU          "shown-in-menu"
 #define GEDIT_SETTINGS_ACTIVE_PLUGINS                  "active-plugins"
+#define GEDIT_SETTINGS_ENSURE_TRAILING_NEWLINE         "ensure-trailing-newline"
 
 /* window state keys */
 #define GEDIT_SETTINGS_WINDOW_STATE                    "state"
diff --git a/gedit/gedit-view-frame.c b/gedit/gedit-view-frame.c
index 8d52777..15d2a24 100644
--- a/gedit/gedit-view-frame.c
+++ b/gedit/gedit-view-frame.c
@@ -1412,8 +1412,7 @@ gedit_view_frame_class_init (GeditViewFrameClass *klass)
 }
 
 static GMountOperation *
-view_frame_mount_operation_factory (GeditDocument *doc,
-                                   gpointer       user_data)
+view_frame_mount_operation_factory (gpointer user_data)
 {
        GtkWidget *frame = user_data;
        GtkWidget *window = gtk_widget_get_toplevel (frame);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7989a66..5c93719 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -13,7 +13,6 @@ gedit/gedit-commands-help.c
 gedit/gedit-commands-search.c
 gedit/gedit-debug.c
 gedit/gedit-document.c
-gedit/gedit-document-saver.c
 gedit/gedit-documents-panel.c
 gedit/gedit-encodings.c
 gedit/gedit-encodings-combo-box.c
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7d03798..cd9ec02 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -6,11 +6,7 @@ AM_CPPFLAGS = \
 noinst_PROGRAMS        = $(TEST_PROGS) $(TEST_GTK_PROGS)
 progs_ldadd    = $(top_builddir)/gedit/libgedit.la
 
-TEST_PROGS                     = document-input-stream
-document_input_stream_SOURCES  = document-input-stream.c
-document_input_stream_LDADD    = $(progs_ldadd)
-
-TEST_PROGS                     += document-output-stream
+TEST_PROGS                     = document-output-stream
 document_output_stream_SOURCES = document-output-stream.c
 document_output_stream_LDADD   = $(progs_ldadd)
 
@@ -18,12 +14,6 @@ TEST_PROGS                   += document-loader
 document_loader_SOURCES                = document-loader.c
 document_loader_LDADD          = $(progs_ldadd)
 
-TEST_PROGS                     += document-saver
-document_saver_SOURCES         = document-saver.c
-document_saver_LDADD           = $(progs_ldadd)
-
 TESTS = $(TEST_PROGS)
 
-EXTRA_DIST = setup-document-saver.sh
-
 -include $(top_srcdir)/git.mk


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