[gnome-builder/wip/gtk4-port: 326/1774] plugins/editorui: implement opening of files with editor




commit ffd9659b4c806f78ec460ed0ea71bade788c5a2e
Author: Christian Hergert <chergert redhat com>
Date:   Sat Apr 2 02:29:04 2022 -0700

    plugins/editorui: implement opening of files with editor
    
    A port of the old editor plugin bits although simplified to our new API
    in libide-editor and friends.

 .../editorui/gbp-editorui-workbench-addin.c        | 214 +++++++++++++++++++++
 1 file changed, 214 insertions(+)
---
diff --git a/src/plugins/editorui/gbp-editorui-workbench-addin.c 
b/src/plugins/editorui/gbp-editorui-workbench-addin.c
index 533c76c64..ad4ffe6e1 100644
--- a/src/plugins/editorui/gbp-editorui-workbench-addin.c
+++ b/src/plugins/editorui/gbp-editorui-workbench-addin.c
@@ -22,7 +22,9 @@
 
 #include "config.h"
 
+#include <libide-editor.h>
 #include <libide-gui.h>
+#include <libide-sourceview.h>
 
 #include "gbp-editorui-workbench-addin.h"
 
@@ -32,6 +34,25 @@ struct _GbpEditoruiWorkbenchAddin
   IdeWorkbench *workbench;
 };
 
+typedef struct
+{
+  GFile              *file;
+  IdeBufferOpenFlags  flags;
+  gint                at_line;
+  gint                at_line_offset;
+} OpenFileTaskData;
+
+static GHashTable *overrides;
+
+static void
+open_file_task_data_free (gpointer data)
+{
+  OpenFileTaskData *td = data;
+
+  g_clear_object (&td->file);
+  g_slice_free (OpenFileTaskData, td);
+}
+
 static void
 gbp_editorui_workbench_addin_load (IdeWorkbenchAddin *addin,
                                    IdeWorkbench      *workbench)
@@ -56,11 +77,202 @@ gbp_editorui_workbench_addin_unload (IdeWorkbenchAddin *addin,
   self->workbench = NULL;
 }
 
+static gboolean
+gbp_editorui_workbench_addin_can_open (IdeWorkbenchAddin *addin,
+                                       GFile             *file,
+                                       const gchar       *content_type,
+                                       gint              *priority)
+{
+  const char *path;
+  const char *suffix;
+
+  g_assert (GBP_IS_EDITORUI_WORKBENCH_ADDIN (addin));
+  g_assert (G_IS_FILE (file));
+  g_assert (priority != NULL);
+
+  *priority = 0;
+
+  path = g_file_peek_path (file);
+
+  if (path != NULL || content_type != NULL)
+    {
+      GtkSourceLanguageManager *manager;
+      GtkSourceLanguage *language;
+
+      manager = gtk_source_language_manager_get_default ();
+      language = gtk_source_language_manager_guess_language (manager, path, content_type);
+
+      if (language != NULL)
+        return TRUE;
+    }
+
+  /* Escape hatch in case shared-mime-info fails us */
+  suffix = strrchr (path, '.');
+  if (suffix && g_hash_table_contains (overrides, suffix))
+    return TRUE;
+
+  if (content_type != NULL)
+    {
+      g_autofree gchar *text_type = NULL;
+
+      text_type = g_content_type_from_mime_type ("text/plain");
+      return g_content_type_is_a (content_type, text_type);
+    }
+
+  return FALSE;
+}
+
+static void
+find_preferred_workspace_cb (IdeWorkspace *workspace,
+                             gpointer      user_data)
+{
+  IdeWorkspace **out_workspace = user_data;
+
+  g_assert (IDE_IS_WORKSPACE (workspace));
+  g_assert (out_workspace != NULL);
+  g_assert (*out_workspace == NULL || IDE_IS_WORKSPACE (*out_workspace));
+
+  if (IDE_IS_PRIMARY_WORKSPACE (workspace))
+    *out_workspace = workspace;
+#if 0
+  else if (*out_workspace == NULL && IDE_IS_EDITOR_WORKSPACE (workspace))
+    *out_workspace = workspace;
+#endif
+}
+
+static void
+gbp_editorui_workbench_addin_open_cb (GObject      *object,
+                                      GAsyncResult *result,
+                                      gpointer      user_data)
+{
+  IdeBufferManager *buffer_manager = (IdeBufferManager *)object;
+  GbpEditoruiWorkbenchAddin *self;
+  g_autoptr(IdeBuffer) buffer = NULL;
+  g_autoptr(IdeTask) task = user_data;
+  g_autoptr(GError) error = NULL;
+  OpenFileTaskData *state;
+  IdeWorkspace *workspace = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_TASK (task));
+
+  self = ide_task_get_source_object (task);
+  buffer = ide_buffer_manager_load_file_finish (buffer_manager, result, &error);
+
+  g_assert (GBP_IS_EDITORUI_WORKBENCH_ADDIN (self));
+  g_assert (!buffer || IDE_IS_BUFFER (buffer));
+
+  if (buffer == NULL)
+    {
+      IDE_TRACE_MSG ("Failed to load buffer: %s", error->message);
+      ide_task_return_error (task, g_steal_pointer (&error));
+      IDE_EXIT;
+    }
+
+  if (self->workbench == NULL)
+    IDE_GOTO (failure);
+
+  ide_workbench_foreach_workspace (self->workbench,
+                                   find_preferred_workspace_cb,
+                                   &workspace);
+
+  if (workspace == NULL)
+    IDE_GOTO (failure);
+
+  state = ide_task_get_task_data (task);
+
+  g_assert (IDE_IS_WORKSPACE (workspace));
+  g_assert (state != NULL);
+  g_assert (G_IS_FILE (state->file));
+
+  if (state->at_line > -1)
+    {
+      g_autoptr(IdeLocation) location = NULL;
+
+      location = ide_location_new (state->file,
+                                   state->at_line,
+                                   state->at_line_offset);
+      ide_editor_focus_location (workspace, NULL, location);
+    }
+  else if (!(state->flags & IDE_BUFFER_OPEN_FLAGS_NO_VIEW) &&
+           !(state->flags & IDE_BUFFER_OPEN_FLAGS_BACKGROUND))
+    {
+      IdeFrame *frame = ide_workspace_get_most_recent_frame (workspace);
+
+      ide_editor_focus_buffer (workspace, frame, buffer);
+    }
+
+failure:
+  ide_task_return_boolean (task, TRUE);
+
+  IDE_EXIT;
+}
+
+static void
+gbp_editorui_workbench_addin_open_async (IdeWorkbenchAddin   *addin,
+                                         GFile               *file,
+                                         const gchar         *content_type,
+                                         gint                 at_line,
+                                         gint                 at_line_offset,
+                                         IdeBufferOpenFlags   flags,
+                                         GCancellable        *cancellable,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             user_data)
+{
+  GbpEditoruiWorkbenchAddin *self = (GbpEditoruiWorkbenchAddin *)addin;
+  IdeBufferManager *buffer_manager;
+  IdeContext *context;
+  OpenFileTaskData *state;
+  g_autoptr(IdeTask) task = NULL;
+
+  g_assert (GBP_IS_EDITORUI_WORKBENCH_ADDIN (self));
+  g_assert (G_IS_FILE (file));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+  g_assert (IDE_IS_WORKBENCH (self->workbench));
+
+  task = ide_task_new (self, cancellable, callback, user_data);
+  state = g_slice_new0 (OpenFileTaskData);
+  state->flags = flags;
+  state->file = g_object_ref (file);
+  state->at_line = at_line;
+  state->at_line_offset = at_line_offset;
+  ide_task_set_task_data (task, state, open_file_task_data_free);
+
+  context = ide_workbench_get_context (self->workbench);
+  buffer_manager = ide_buffer_manager_from_context (context);
+
+  ide_buffer_manager_load_file_async (buffer_manager,
+                                      file,
+                                      state->flags,
+                                      NULL,
+                                      cancellable,
+                                      gbp_editorui_workbench_addin_open_cb,
+                                      g_steal_pointer (&task));
+}
+
+static gboolean
+gbp_editorui_workbench_addin_open_finish (IdeWorkbenchAddin  *addin,
+                                          GAsyncResult       *result,
+                                          GError            **error)
+{
+  g_assert (GBP_IS_EDITORUI_WORKBENCH_ADDIN (addin));
+  g_assert (IDE_IS_TASK (result));
+
+  return ide_task_propagate_boolean (IDE_TASK (result), error);
+}
+
 static void
 workbench_addin_iface_init (IdeWorkbenchAddinInterface *iface)
 {
   iface->load = gbp_editorui_workbench_addin_load;
   iface->unload = gbp_editorui_workbench_addin_unload;
+
+  iface->can_open = gbp_editorui_workbench_addin_can_open;
+  iface->open_async = gbp_editorui_workbench_addin_open_async;
+  iface->open_finish = gbp_editorui_workbench_addin_open_finish;
 }
 
 G_DEFINE_TYPE_WITH_CODE (GbpEditoruiWorkbenchAddin, gbp_editorui_workbench_addin, G_TYPE_OBJECT,
@@ -69,6 +281,8 @@ G_DEFINE_TYPE_WITH_CODE (GbpEditoruiWorkbenchAddin, gbp_editorui_workbench_addin
 static void
 gbp_editorui_workbench_addin_class_init (GbpEditoruiWorkbenchAddinClass *klass)
 {
+  overrides = g_hash_table_new (g_str_hash, g_str_equal);
+  g_hash_table_add (overrides, (char *)".dts"); /* #1572 */
 }
 
 static void


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