[gtksourceview/wip/loader-saver] Refactor the FileSaver to fit GtkSourceFile API
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/loader-saver] Refactor the FileSaver to fit GtkSourceFile API
- Date: Mon, 16 Dec 2013 17:59:07 +0000 (UTC)
commit 1199263dab1614b152d6ffd553f239884e1bdfa9
Author: Sébastien Wilmet <swilmet gnome org>
Date: Fri Dec 13 21:48:13 2013 +0100
Refactor the FileSaver to fit GtkSourceFile API
Not finished, not compilable.
gtksourceview/gtksourcefilesaver.c | 254 ++++++++++++++----------------------
gtksourceview/gtksourcefilesaver.h | 14 --
2 files changed, 98 insertions(+), 170 deletions(-)
---
diff --git a/gtksourceview/gtksourcefilesaver.c b/gtksourceview/gtksourcefilesaver.c
index fe96dac..07dc732 100644
--- a/gtksourceview/gtksourcefilesaver.c
+++ b/gtksourceview/gtksourcefilesaver.c
@@ -77,15 +77,20 @@ typedef struct
struct _GtkSourceFileSaverPrivate
{
- GFileInfo *info;
GtkTextBuffer *buffer;
GFile *location;
+ GFileInfo *info;
const GtkSourceEncoding *encoding;
GtkSourceNewlineType newline_type;
GtkSourceCompressionType compression_type;
GtkSourceFileSaveFlags flags;
+ GTask *task;
+
+ GFileProgressCallback progress_cb;
+ gpointer progress_cb_data;
+
GTimeVal old_mtime;
goffset size;
@@ -102,6 +107,7 @@ struct _GtkSourceFileSaverPrivate
guint used : 1;
guint ensure_trailing_newline : 1;
+ guint tried_mount : 1;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceFileSaver, gtk_source_file_saver, G_TYPE_OBJECT)
@@ -110,7 +116,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceFileSaver, gtk_source_file_saver, G_TYPE_OB
static void read_file_chunk (AsyncData *async);
static void write_file_chunk (AsyncData *async);
-static void check_modified_async (AsyncData *async);
+static void check_externally_modified (GtkSourceFileSaver *saver);
static void
gtk_source_file_saver_set_property (GObject *object,
@@ -756,7 +762,7 @@ async_replace_ready_callback (GFile *source,
file_stream = g_file_replace_finish (source, res, &error);
/* handle any error that might occur */
- if (!file_stream)
+ if (file_stream == NULL)
{
DEBUG ({
g_print ("Opening file failed: %s\n", error->message);
@@ -853,34 +859,26 @@ begin_write (AsyncData *async)
}
static void
-mount_ready_callback (GFile *file,
- GAsyncResult *res,
- AsyncData *async)
+mount_cb (GFile *location,
+ GAsyncResult *result,
+ GtkSourceFileSaver *saver)
{
GError *error = NULL;
- gboolean mounted;
DEBUG ({
g_print ("%s\n", G_STRFUNC);
});
- /* manual check for cancelled state */
- if (g_cancellable_is_cancelled (async->cancellable))
- {
- async_data_free (async);
- return;
- }
-
- mounted = g_file_mount_enclosing_volume_finish (file, res, &error);
+ g_file_mount_enclosing_volume_finish (location, result, &error);
- if (!mounted)
+ if (error != NULL)
{
- async_failed (async, error);
+ g_task_return_error (saver->priv->task, error);
}
else
{
- /* try again to get the modified state */
- check_modified_async (async);
+ /* Try again to get the modified state. */
+ check_externally_modified (saver);
}
}
@@ -893,31 +891,30 @@ create_mount_operation (GtkSourceFileSaver *saver)
}
static void
-recover_not_mounted (AsyncData *async)
+recover_not_mounted (GtkSourceFileSaver *saver)
{
- GMountOperation *mount_operation = create_mount_operation (async->saver);
+ GMountOperation *mount_operation = create_mount_operation (saver);
DEBUG ({
g_print ("%s\n", G_STRFUNC);
});
- async->tried_mount = TRUE;
- g_file_mount_enclosing_volume (async->saver->priv->location,
+ saver->priv->tried_mount = TRUE;
+ g_file_mount_enclosing_volume (saver->priv->location,
G_MOUNT_MOUNT_NONE,
mount_operation,
- async->cancellable,
- (GAsyncReadyCallback) mount_ready_callback,
- async);
+ g_task_get_cancellable (saver->priv->task),
+ (GAsyncReadyCallback) mount_cb,
+ saver);
g_object_unref (mount_operation);
}
static void
-check_modification_callback (GFile *source,
- GAsyncResult *res,
- AsyncData *async)
+check_externally_modified_cb (GFile *location,
+ GAsyncResult *result,
+ GtkSourceFileSaver *saver)
{
- GtkSourceFileSaver *saver;
GError *error = NULL;
GFileInfo *info;
@@ -925,37 +922,35 @@ check_modification_callback (GFile *source,
g_print ("%s\n", G_STRFUNC);
});
- /* manually check cancelled state */
- if (g_cancellable_is_cancelled (async->cancellable))
+ if (saver->priv->flags & GTK_SOURCE_FILE_SAVE_IGNORE_MTIME)
{
- async_data_free (async);
- return;
+ g_warning ("Useless check for externally modified file.");
}
- saver = async->saver;
- info = g_file_query_info_finish (source, res, &error);
- if (info == NULL)
+ info = g_file_query_info_finish (location, result, &error);
+
+ if (error != NULL)
{
- if (error->code == G_IO_ERROR_NOT_MOUNTED && !async->tried_mount)
+ if (error->code == G_IO_ERROR_NOT_MOUNTED && !saver->priv->tried_mount)
{
- recover_not_mounted (async);
+ recover_not_mounted (saver);
g_error_free (error);
return;
}
- /* it's perfectly fine if the file doesn't exist yet */
+ /* It's perfectly fine if the file doesn't exist yet. */
if (error->code != G_IO_ERROR_NOT_FOUND)
{
DEBUG ({
g_print ("Error getting modification: %s\n", error->message);
});
- async_failed (async, error);
+ g_task_return_error (saver->priv->task, error);
return;
}
}
- /* check if the mtime is > what we know about it (if we have it) */
+ /* Check if the mtime is greater from what we know about it (if we have it). */
if (info != NULL && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
{
GTimeVal mtime;
@@ -972,14 +967,12 @@ check_modification_callback (GFile *source,
g_print ("File is externally modified\n");
});
- g_set_error (&saver->priv->error,
- GTK_SOURCE_FILE_ERROR,
- GTK_SOURCE_FILE_ERROR_EXTERNALLY_MODIFIED,
- "Externally modified");
-
- remote_save_completed_or_failed (saver, async);
g_object_unref (info);
+ g_task_return_new_error (saver->priv->task,
+ GTK_SOURCE_FILE_ERROR,
+ GTK_SOURCE_FILE_ERROR_EXTERNALLY_MODIFIED,
+ "Externally modified");
return;
}
}
@@ -989,150 +982,99 @@ check_modification_callback (GFile *source,
g_object_unref (info);
}
- /* modification check passed, start write */
- begin_write (async);
+ /* Externally modified check passed, start write. */
+ begin_write (saver);
}
static void
-check_modified_async (AsyncData *async)
+check_externally_modified (GtkSourceFileSaver *saver)
{
DEBUG ({
g_print ("Check externally modified\n");
});
- g_file_query_info_async (async->saver->priv->location,
+ g_file_query_info_async (saver->priv->location,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_HIGH,
- async->cancellable,
- (GAsyncReadyCallback) check_modification_callback,
- async);
+ g_task_get_priority (saver->priv->task),
+ g_task_get_cancellable (saver->priv->task),
+ (GAsyncReadyCallback)check_externally_modified_cb,
+ saver);
}
-static gboolean
-save_remote_file_real (GtkSourceFileSaver *saver)
+GFile *
+gtk_source_file_saver_get_location (GtkSourceFileSaver *saver)
{
- AsyncData *async;
-
- DEBUG ({
- g_print ("Starting save\n");
- });
+ g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), NULL);
- /* First find out if the file is modified externally. This requires
- * a stat, but I don't think we can do this any other way
- */
- async = async_data_new (saver);
+ return g_file_dup (saver->priv->location);
+}
- check_modified_async (async);
+void
+gtk_source_file_saver_set_mount_operation_factory (GtkSourceFileSaver *saver,
+ GtkSourceMountOperationFactory callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver));
- /* return false to stop timeout */
- return FALSE;
+ saver->priv->mount_operation_factory = callback;
+ saver->priv->mount_operation_userdata = user_data;
}
void
-gtk_source_file_saver_save (GtkSourceFileSaver *saver,
- GTimeVal *old_mtime)
+gtk_source_file_saver_save_async (GtkSourceFileSaver *saver,
+ gint io_priority,
+ GTimeVal *old_mtime,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- DEBUG ({
- g_print ("%s\n", G_STRFUNC);
- });
-
g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver));
+ g_return_if_fail (saver->priv->task == NULL);
g_return_if_fail (saver->priv->location != NULL);
+ g_return_if_fail (!saver->priv->used);
- g_return_if_fail (saver->priv->used == FALSE);
saver->priv->used = TRUE;
- /* CHECK:
- report async (in an idle handler) or sync (bool ret)
- async is extra work here, sync is special casing in the caller */
+ saver->priv->task = g_task_new (saver, cancellable, callback, user_data);
+ g_task_set_priority (task, io_priority);
saver->priv->old_mtime = *old_mtime;
+ saver->priv->progress_cb = progress_callback;
+ saver->priv->progress_cb_data = progress_callback_data;
- /* saving start */
- gtk_source_file_saver_saving (saver, FALSE, NULL);
-
- g_timeout_add_full (G_PRIORITY_HIGH,
- 0,
- (GSourceFunc) save_remote_file_real,
- saver,
- NULL);
-}
+ DEBUG ({
+ g_print ("Starting save\n");
+ });
-void
-gtk_source_file_saver_saving (GtkSourceFileSaver *saver,
- gboolean completed,
- GError *error)
-{
- /* the object will be unrefed in the callback of the saving
- * signal, so we need to prevent finalization.
+ /* TODO create a thread and use sync GIO functions for the first steps.
+ * Destroy the thread for the main step, reading the buffer and writing
+ * the file. Because the buffer must be read in the main thread.
*/
- if (completed)
+
+ if (saver->priv->flags & GTK_SOURCE_FILE_SAVE_IGNORE_MTIME)
{
- g_object_ref (saver);
+ begin_write (saver);
}
-
- g_signal_emit (saver, signals[SAVING], 0, completed, error);
-
- if (completed)
+ else
{
- if (error == NULL)
- {
- DEBUG ({
- g_print ("save completed\n");
- });
- }
- else
- {
- DEBUG ({
- g_print ("save failed\n");
- });
- }
-
- g_object_unref (saver);
+ /* TODO install a FileMonitor in GtkSourceFile, with an
+ * externally-modified property, or a signal.
+ */
+ check_externally_modified (saver);
}
}
-GFile *
-gtk_source_file_saver_get_location (GtkSourceFileSaver *saver)
-{
- g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), NULL);
-
- return g_file_dup (saver->priv->location);
-}
-
-/* Returns 0 if file size is unknown */
-goffset
-gtk_source_file_saver_get_file_size (GtkSourceFileSaver *saver)
-{
- g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), 0);
-
- return saver->priv->size;
-}
-
-goffset
-gtk_source_file_saver_get_bytes_written (GtkSourceFileSaver *saver)
-{
- g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), 0);
-
- return saver->priv->bytes_written;
-}
-
-GFileInfo *
-gtk_source_file_saver_get_info (GtkSourceFileSaver *saver)
+gboolean
+gtk_source_file_saver_save_finish (GtkSourceFileSaver *saver,
+ GAsyncResult *result,
+ GError **error)
{
- g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), NULL);
+ g_return_val_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, saver), FALSE);
- return saver->priv->info;
-}
-
-void
-gtk_source_file_saver_set_mount_operation_factory (GtkSourceFileSaver *saver,
- GtkSourceMountOperationFactory callback,
- gpointer user_data)
-{
- g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver));
-
- saver->priv->mount_operation_factory = callback;
- saver->priv->mount_operation_userdata = user_data;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
diff --git a/gtksourceview/gtksourcefilesaver.h b/gtksourceview/gtksourcefilesaver.h
index 4f69c01..0964e4d 100644
--- a/gtksourceview/gtksourcefilesaver.h
+++ b/gtksourceview/gtksourcefilesaver.h
@@ -84,22 +84,8 @@ void gtk_source_file_saver_saving (GtkSourceFileSaver *saver,
GError *error);
G_GNUC_INTERNAL
-void gtk_source_file_saver_save (GtkSourceFileSaver *saver,
- GTimeVal *old_mtime);
-
-G_GNUC_INTERNAL
GFile *gtk_source_file_saver_get_location (GtkSourceFileSaver *saver);
-/* Returns 0 if file size is unknown */
-G_GNUC_INTERNAL
-goffset gtk_source_file_saver_get_file_size (GtkSourceFileSaver *saver);
-
-G_GNUC_INTERNAL
-goffset gtk_source_file_saver_get_bytes_written (GtkSourceFileSaver *saver);
-
-G_GNUC_INTERNAL
-GFileInfo *gtk_source_file_saver_get_info (GtkSourceFileSaver *saver);
-
G_GNUC_INTERNAL
void gtk_source_file_saver_set_mount_operation_factory
(GtkSourceFileSaver *saver,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]