[gnome-builder] gui: add ide_workbench_resolve_file_async()
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] gui: add ide_workbench_resolve_file_async()
- Date: Fri, 18 Jan 2019 05:30:31 +0000 (UTC)
commit 7f0d60ed2276f429e702cce0c36c4019e2990dcb
Author: Christian Hergert <chergert redhat com>
Date: Thu Jan 17 21:23:43 2019 -0800
gui: add ide_workbench_resolve_file_async()
This helper can be used to locate a file by a given path. It might need to
start scanning from the current build directory, or the source directory.
If it fails, it may search for the file within the root for a file matching
the filename.
src/libide/gui/ide-workbench.c | 149 +++++++++++++++++++++++++++++++++++++++++
src/libide/gui/ide-workbench.h | 10 +++
2 files changed, 159 insertions(+)
---
diff --git a/src/libide/gui/ide-workbench.c b/src/libide/gui/ide-workbench.c
index ad836b707..de9439b6a 100644
--- a/src/libide/gui/ide-workbench.c
+++ b/src/libide/gui/ide-workbench.c
@@ -98,6 +98,12 @@ typedef struct
gint64 present_time;
} LoadProject;
+typedef struct
+{
+ GPtrArray *roots;
+ gchar *path;
+} ResolveFile;
+
enum {
PROP_0,
PROP_CONTEXT,
@@ -150,6 +156,14 @@ open_free (Open *o)
g_slice_free (Open, o);
}
+static void
+resolve_file_free (ResolveFile *rf)
+{
+ g_clear_pointer (&rf->roots, g_ptr_array_unref);
+ g_clear_pointer (&rf->path, g_free);
+ g_slice_free (ResolveFile, rf);
+}
+
static gboolean
ignore_error (GError *error)
{
@@ -2342,3 +2356,138 @@ ide_workbench_addin_find_by_module_name (IdeWorkbench *workbench,
return IDE_WORKBENCH_ADDIN (ret);
}
+
+static void
+ide_workbench_resolve_file_worker (IdeTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ ResolveFile *rf = task_data;
+ g_autofree gchar *basename = NULL;
+
+ g_assert (IDE_IS_TASK (task));
+ g_assert (IDE_IS_WORKBENCH (source_object));
+ g_assert (rf != NULL);
+ g_assert (rf->roots != NULL);
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ basename = g_path_get_basename (rf->path);
+
+ for (guint i = 0; i < rf->roots->len; i++)
+ {
+ GFile *root = g_ptr_array_index (rf->roots, i);
+ g_autoptr(GFile) child = g_file_get_child (root, rf->path);
+ g_autoptr(GPtrArray) found = NULL;
+
+ if (g_file_query_exists (child, cancellable))
+ {
+ ide_task_return_pointer (task, g_steal_pointer (&child), g_object_unref);
+ return;
+ }
+
+ found = ide_g_file_find_with_depth (root, basename, 0, cancellable);
+ IDE_PTR_ARRAY_SET_FREE_FUNC (found, g_object_unref);
+
+ if (found != NULL && found->len > 0)
+ {
+ GFile *match = g_ptr_array_index (found, 0);
+ ide_task_return_pointer (task, g_object_ref (match), g_object_unref);
+ return;
+ }
+ }
+
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ "Failed to locate file %s",
+ basename);
+}
+
+/**
+ * ide_workbench_resolve_file_async:
+ * @self: a #IdeWorkbench
+ * @filename: the filename to discover
+ *
+ * This function will try to locate a given file based on the filename,
+ * possibly resolving it from a build directory, or source directory.
+ *
+ * If no file was discovered, some attempt will be made to locate a file
+ * that matches appropriately.
+ *
+ * Since: 3.32
+ */
+void
+ide_workbench_resolve_file_async (IdeWorkbench *self,
+ const gchar *filename,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autofree gchar *srcpath = NULL;
+ g_autoptr(IdeTask) task = NULL;
+ ResolveFile *rf;
+
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_MAIN_THREAD ());
+ g_return_if_fail (IDE_IS_WORKBENCH (self));
+ g_return_if_fail (filename != NULL);
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, ide_workbench_resolve_file_async);
+
+ rf = g_slice_new0 (ResolveFile);
+ rf->roots = g_ptr_array_new_with_free_func (g_object_unref);
+ rf->path = g_strdup (filename);
+
+ g_ptr_array_add (rf->roots, ide_context_ref_workdir (self->context));
+
+ if (ide_workbench_has_project (self))
+ {
+ IdeBuildManager *build_manager = ide_build_manager_from_context (self->context);
+ IdePipeline *pipeline = ide_build_manager_get_pipeline (build_manager);
+
+ if (pipeline != NULL)
+ {
+ const gchar *builddir = ide_pipeline_get_builddir (pipeline);
+
+ g_ptr_array_add (rf->roots, g_file_new_for_path (builddir));
+ }
+ }
+
+ ide_task_set_task_data (task, rf, resolve_file_free);
+ ide_task_run_in_thread (task, ide_workbench_resolve_file_worker);
+
+ IDE_EXIT;
+}
+
+/**
+ * ide_workbench_resolve_file_finish:
+ * @self: a #IdeWorkbench
+ * @result: a #GAsyncResult
+ * @error: a location for a #GError
+ *
+ * Completes an asynchronous request to ide_workbench_resolve_file_async().
+ *
+ * Returns: (transfer full): a #GFile, or %NULL and @error is set
+ *
+ * Since: 3.32
+ */
+GFile *
+ide_workbench_resolve_file_finish (IdeWorkbench *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GFile *ret;
+
+ IDE_ENTRY;
+
+ g_return_val_if_fail (IDE_IS_MAIN_THREAD (), NULL);
+ g_return_val_if_fail (IDE_IS_WORKBENCH (self), NULL);
+ g_return_val_if_fail (IDE_IS_TASK (result), NULL);
+
+ ret = ide_task_propagate_pointer (IDE_TASK (result), error);
+
+ IDE_RETURN (g_steal_pointer (&ret));
+}
diff --git a/src/libide/gui/ide-workbench.h b/src/libide/gui/ide-workbench.h
index b3a0ae7cd..f27d3e0cf 100644
--- a/src/libide/gui/ide-workbench.h
+++ b/src/libide/gui/ide-workbench.h
@@ -139,6 +139,16 @@ IdeBuildSystem *ide_workbench_get_build_system (IdeWorkbench *self
IDE_AVAILABLE_IN_3_32
void ide_workbench_set_build_system (IdeWorkbench *self,
IdeBuildSystem *build_system);
+IDE_AVAILABLE_IN_3_32
+void ide_workbench_resolve_file_async (IdeWorkbench *self,
+ const gchar *filename,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IDE_AVAILABLE_IN_3_32
+GFile *ide_workbench_resolve_file_finish (IdeWorkbench *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]