[gedit/wip/loader-saver: 15/15] Port GeditDocument and GeditTab to GtkSourceFile (not finished)



commit 7821976d1b0b2a6247df0826841b67a8df7a6645
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Wed Jun 18 18:23:26 2014 +0200

    Port GeditDocument and GeditTab to GtkSourceFile (not finished)

 gedit/gedit-document.c |  288 ++++++++++++++++++++++++++++++++++++++++++++++++
 gedit/gedit-document.h |   17 +++
 2 files changed, 305 insertions(+), 0 deletions(-)
---
diff --git a/gedit/gedit-document.c b/gedit/gedit-document.c
index 1e89509..e168064 100644
--- a/gedit/gedit-document.c
+++ b/gedit/gedit-document.c
@@ -134,6 +134,13 @@ struct _GeditDocumentPrivate
        guint empty_search : 1;
 };
 
+typedef struct
+{
+       gint line_pos;
+       gint column_pos;
+       guint create : 1;
+} TaskData;
+
 enum {
        PROP_0,
 
@@ -2622,4 +2629,285 @@ gedit_document_get_file (GeditDocument *doc)
        return doc->priv->file;
 }
 
+static TaskData *
+task_data_new (void)
+{
+       return g_slice_new (TaskData);
+}
+
+static void
+task_data_free (TaskData *data)
+{
+       if (data != NULL)
+       {
+               g_slice_free (TaskData, data);
+       }
+}
+
+static void
+load_succeeded (GTask *task)
+{
+       GeditDocument *doc = g_task_get_source_object (task);
+       TaskData *data = g_task_get_task_data (task);
+
+       g_get_current_time (&doc->priv->time_of_last_save_or_load);
+
+       doc->priv->externally_modified = FALSE;
+       doc->priv->deleted = FALSE;
+
+       /* move the cursor at the requested line if any */
+       if (data->line_pos > 0)
+       {
+               gedit_document_goto_line_offset (doc,
+                                                data->line_pos - 1,
+                                                data->column_pos < 1 ? 0 : data->column_pos - 1);
+       }
+       else
+       {
+               GtkTextIter iter;
+
+               /* if enabled, move to the position stored in the metadata */
+               if (g_settings_get_boolean (doc->priv->editor_settings, 
GEDIT_SETTINGS_RESTORE_CURSOR_POSITION))
+               {
+                       gchar *pos;
+                       gint offset;
+
+                       pos = gedit_document_get_metadata (doc, GEDIT_METADATA_ATTRIBUTE_POSITION);
+
+                       offset = pos ? atoi (pos) : 0;
+                       g_free (pos);
+
+                       gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc),
+                                                           &iter,
+                                                           MAX (offset, 0));
+
+                       /* make sure it's a valid position, if the file
+                        * changed we may have ended up in the middle of
+                        * a utf8 character cluster */
+                       if (!gtk_text_iter_is_cursor_position (&iter))
+                       {
+                               gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc),
+                                                               &iter);
+                       }
+               }
+
+               /* otherwise to the top */
+               else
+               {
+                       gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (doc),
+                                                       &iter);
+               }
+
+               gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
+       }
+
+       if (!doc->priv->language_set_by_user)
+       {
+               GtkSourceLanguage *language = guess_language (doc, doc->priv->content_type);
+
+               gedit_debug_message (DEBUG_DOCUMENT, "Language: %s",
+                                    language != NULL ? gtk_source_language_get_name (language) : "None");
+
+               set_language (doc, language, FALSE);
+       }
+
+       g_task_return_boolean (task, TRUE);
+       g_object_unref (task);
+}
+
+static void
+query_info_cb (GFile        *location,
+              GAsyncResult *result,
+              GTask        *task)
+{
+       GFileInfo *info;
+       GeditDocument *doc = g_task_get_source_object (task);
+       const gchar *content_type = NULL;
+       gboolean read_only = FALSE;
+       GError *error = NULL;
+
+       info = g_file_query_info_finish (location, result, &error);
+
+       if (error != NULL)
+       {
+               g_warning ("Query file info error: %s", error->message);
+               g_error_free (error);
+               error = NULL;
+       }
+
+       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_ACCESS_CAN_WRITE))
+               {
+                       read_only = !g_file_info_get_attribute_boolean (info, 
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
+               }
+
+               g_object_unref (info);
+       }
+
+       set_content_type (doc, content_type);
+       set_readonly (doc, read_only);
+
+       load_succeeded (task);
+}
+
+static void
+load_cb (GtkSourceFileLoader *loader,
+        GAsyncResult        *result,
+        GTask               *task)
+{
+       TaskData *data = g_task_get_task_data (task);
+       GError *error = NULL;
+
+       gtk_source_file_loader_load_finish (loader, result, &error);
+       g_object_unref (loader);
+
+       /* load was successful */
+       if (error == NULL ||
+           (error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
+            error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK))
+       {
+               GeditDocument *doc = g_task_get_source_object (task);
+               GFile *location = gtk_source_file_get_location (doc->priv->file);
+
+               if (location != NULL)
+               {
+                       g_file_query_info_async (location,
+                                                G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+                                                G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
+                                                G_FILE_QUERY_INFO_NONE,
+                                                g_task_get_priority (task),
+                                                g_task_get_cancellable (task),
+                                                (GAsyncReadyCallback)query_info_cb,
+                                                task);
+               }
+
+               /* loaded from stream */
+               else
+               {
+                       set_content_type (doc, NULL);
+                       set_readonly (doc, FALSE);
+
+                       load_succeeded (task);
+               }
+
+               if (error != NULL)
+               {
+                       g_error_free (error);
+               }
+       }
+
+       /* special case creating a named new doc */
+       else if (data->create &&
+                error->domain == G_IO_ERROR &&
+                error->code == G_IO_ERROR_NOT_FOUND &&
+                g_file_has_uri_scheme (location, "file"))
+       {
+               g_task_return_boolean (task, TRUE);
+               g_object_unref (task);
+       }
+
+       else
+       {
+               g_task_return_error (task, error);
+               g_object_unref (task);
+       }
+}
+
+void
+_gedit_document_load_async (GeditDocument           *doc,
+                           GFile                   *location,
+                           GInputStream            *stream,
+                           const GtkSourceEncoding *encoding,
+                           gint                     line_pos,
+                           gint                     column_pos,
+                           gboolean                 create,
+                           GCancellable            *cancellable,
+                           GFileProgressCallback    progress_callback,
+                           gpointer                 progress_callback_data,
+                           GAsyncReadyCallback      callback,
+                           gpointer                 user_data)
+{
+       GTask *task;
+       TaskData *data;
+       GtkSourceFileLoader *loader;
+
+       g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
+       g_return_if_fail (location != NULL || stream != NULL);
+       g_return_if_fail (location == NULL || G_IS_FILE (location));
+       g_return_if_fail (stream == NULL || G_IS_INPUT_STREAM (stream));
+       g_return_if_fail (G_IS_CANCELLABLE (cancellable));
+
+       task = g_task_new (doc, cancellable, callback, user_data);
+       g_task_set_priority (task, G_PRIORITY_HIGH);
+
+       data = task_data_new ();
+       data->line_pos = line_pos;
+       data->column_pos = column_pos;
+       data->create = create != FALSE;
+
+       g_task_set_task_data (task, data, (GDestroyNotify)task_data_free);
+
+       if (location != NULL)
+       {
+               loader = gtk_source_file_loader_new (doc->priv->file, location);
+       }
+       else
+       {
+               loader = gtk_source_file_loader_new_from_stream (doc->priv->file, stream);
+       }
+
+       if (encoding != NULL)
+       {
+               GSList *list = g_slist_append (NULL, (gpointer)encoding);
+               gtk_source_file_loader_set_candidate_encodings (loader, list);
+               g_slist_free (list);
+       }
+       else
+       {
+               /* TODO */
+       }
+
+       gtk_source_file_loader_load_async (loader,
+                                          g_task_get_priority (task),
+                                          g_task_get_cancellable (task),
+                                          progress_callback,
+                                          progress_callback_data,
+                                          NULL,
+                                          (GAsyncReadyCallback)load_cb,
+                                          task);
+}
+
+gboolean
+_gedit_document_load_finish (GeditDocument  *doc,
+                            GAsyncResult   *result,
+                            GError        **error)
+{
+       gboolean ok;
+
+       g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
+       g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+       g_return_val_if_fail (g_task_is_valid (result, doc), FALSE);
+
+       ok = g_task_propagate_boolean (G_TASK (result), error);
+
+       /* Emit signal only on success. Normally plugins don't need the error,
+        * it is already handled by GeditTab.
+        */
+       if (ok)
+       {
+               g_signal_emit (doc,
+                              document_signals[LOADED],
+                              0,
+                              NULL);
+       }
+
+       return ok;
+}
+
 /* ex:set ts=8 noet: */
diff --git a/gedit/gedit-document.h b/gedit/gedit-document.h
index be122c4..4fdbd76 100644
--- a/gedit/gedit-document.h
+++ b/gedit/gedit-document.h
@@ -304,6 +304,23 @@ gboolean            _gedit_document_get_empty_search       (GeditDocument          *doc);
 
 GtkSourceFile          *gedit_document_get_file                (GeditDocument *doc);
 
+void                    _gedit_document_load_async             (GeditDocument           *doc,
+                                                                GFile                   *location,
+                                                                GInputStream            *stream,
+                                                                const GtkSourceEncoding *encoding,
+                                                                gint                     line_pos,
+                                                                gint                     column_pos,
+                                                                gboolean                 create,
+                                                                GCancellable            *cancellable,
+                                                                GFileProgressCallback    progress_callback,
+                                                                gpointer                 
progress_callback_data,
+                                                                GAsyncReadyCallback      callback,
+                                                                gpointer                 user_data);
+
+gboolean                _gedit_document_load_finish            (GeditDocument  *doc,
+                                                                GAsyncResult   *result,
+                                                                GError        **error);
+
 G_END_DECLS
 
 #endif /* __GEDIT_DOCUMENT_H__ */


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