[gtksourceview/wip/loader-saver] File and FileSaver: continue the quest
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/loader-saver] File and FileSaver: continue the quest
- Date: Sat, 21 Dec 2013 23:55:54 +0000 (UTC)
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]