[gnome-builder/wip/chergert/suggestion] search: port search to DzlSuggestion
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/chergert/suggestion] search: port search to DzlSuggestion
- Date: Thu, 8 Jun 2017 04:20:14 +0000 (UTC)
commit d816a50eb19e9b4171b0c731d9229953739c4547
Author: Christian Hergert <chergert redhat com>
Date: Wed Jun 7 18:06:05 2017 -0700
search: port search to DzlSuggestion
This is a bit different style of search engine than we had before. It aims
to just be as simple as we can and still get the same performance and ease
of implementation.
libide/diagnostics/ide-source-location.c | 17 +
libide/diagnostics/ide-source-location.h | 4 +
libide/ide.h | 3 +-
libide/meson.build | 15 +-
libide/resources/libide.gresource.xml | 2 -
libide/search/ide-omni-search-display.c | 678 --------------------
libide/search/ide-omni-search-display.h | 41 --
libide/search/ide-omni-search-entry.c | 403 ------------
libide/search/ide-omni-search-entry.h | 39 --
libide/search/ide-omni-search-group.c | 571 ----------------
libide/search/ide-omni-search-group.h | 50 --
libide/search/ide-omni-search-group.ui | 14 -
libide/search/ide-omni-search-row.c | 189 ------
libide/search/ide-omni-search-row.ui | 26 -
libide/search/ide-search-context.c | 263 --------
libide/search/ide-search-context.h | 50 --
libide/search/ide-search-engine.c | 294 +++++++--
libide/search/ide-search-engine.h | 14 +-
libide/search/ide-search-entry.c | 128 ++++
.../{ide-omni-search-row.h => ide-search-entry.h} | 22 +-
libide/search/ide-search-provider.c | 140 ++---
libide/search/ide-search-provider.h | 52 +-
libide/search/ide-search-reducer.c | 104 +++-
libide/search/ide-search-reducer.h | 28 +-
libide/search/ide-search-result.c | 352 ++++-------
libide/search/ide-search-result.h | 45 +-
libide/workbench/ide-workbench-header-bar.c | 14 +-
libide/workbench/ide-workbench-header-bar.ui | 2 +-
plugins/file-search/gb-file-search-index.c | 42 +-
plugins/file-search/gb-file-search-index.h | 33 +-
plugins/file-search/gb-file-search-provider.c | 75 +--
plugins/file-search/gb-file-search-result.c | 43 ++-
32 files changed, 841 insertions(+), 2912 deletions(-)
---
diff --git a/libide/diagnostics/ide-source-location.c b/libide/diagnostics/ide-source-location.c
index e4c11de..9a997cc 100644
--- a/libide/diagnostics/ide-source-location.c
+++ b/libide/diagnostics/ide-source-location.c
@@ -20,6 +20,8 @@
#include <dazzle.h>
+#include "ide-context.h"
+
#include "files/ide-file.h"
#include "diagnostics/ide-source-location.h"
@@ -221,3 +223,18 @@ ide_source_location_hash (IdeSourceLocation *self)
{
return ide_file_hash (self->file) ^ g_int_hash (&self->line) ^ g_int_hash (&self->line_offset);
}
+
+IdeSourceLocation *
+ide_source_location_new_for_path (IdeContext *context,
+ const gchar *path,
+ guint line,
+ guint line_offset)
+{
+ g_autoptr(IdeFile) ifile = NULL;
+
+ g_return_val_if_fail (!context || IDE_IS_CONTEXT (context), NULL);
+
+ ifile = ide_file_new_for_path (context, path);
+
+ return ide_source_location_new (ifile, line, line_offset, 0);
+}
diff --git a/libide/diagnostics/ide-source-location.h b/libide/diagnostics/ide-source-location.h
index 1dad31b..2f999b1 100644
--- a/libide/diagnostics/ide-source-location.h
+++ b/libide/diagnostics/ide-source-location.h
@@ -34,6 +34,10 @@ IdeSourceLocation *ide_source_location_new (IdeFile
guint line,
guint line_offset,
guint offset);
+IdeSourceLocation *ide_source_location_new_for_path (IdeContext *context,
+ const gchar *path,
+ guint line,
+ guint line_offset);
guint ide_source_location_get_line (IdeSourceLocation *self);
guint ide_source_location_get_line_offset (IdeSourceLocation *self);
guint ide_source_location_get_offset (IdeSourceLocation *self);
diff --git a/libide/ide.h b/libide/ide.h
index 8e5a8f3..5065986 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -106,9 +106,8 @@ G_BEGIN_DECLS
#include "runtimes/ide-runtime-manager.h"
#include "runtimes/ide-runtime-provider.h"
#include "runtimes/ide-runtime.h"
-#include "search/ide-omni-search-row.h"
-#include "search/ide-search-context.h"
#include "search/ide-search-engine.h"
+#include "search/ide-search-entry.h"
#include "search/ide-search-provider.h"
#include "search/ide-search-reducer.h"
#include "search/ide-search-result.h"
diff --git a/libide/meson.build b/libide/meson.build
index e96ca2d..9943ab1 100644
--- a/libide/meson.build
+++ b/libide/meson.build
@@ -122,14 +122,9 @@ libide_public_headers = [
'runtimes/ide-runtime-manager.h',
'runtimes/ide-runtime-provider.h',
'runtimes/ide-runtime.h',
- 'search/ide-omni-search-display.h',
- 'search/ide-omni-search-entry.h',
- 'search/ide-omni-search-group.h',
- 'search/ide-omni-search-row.h',
- 'search/ide-search-context.h',
'search/ide-search-engine.h',
+ 'search/ide-search-entry.h',
'search/ide-search-provider.h',
- 'search/ide-search-reducer.h',
'search/ide-search-result.h',
'snippets/ide-source-snippet-chunk.h',
'snippets/ide-source-snippet-context.h',
@@ -321,12 +316,8 @@ libide_public_sources = [
'runtimes/ide-runtime-manager.c',
'runtimes/ide-runtime-provider.c',
'runtimes/ide-runtime.c',
- 'search/ide-omni-search-display.c',
- 'search/ide-omni-search-entry.c',
- 'search/ide-omni-search-group.c',
- 'search/ide-omni-search-row.c',
- 'search/ide-search-context.c',
'search/ide-search-engine.c',
+ 'search/ide-search-entry.c',
'search/ide-search-provider.c',
'search/ide-search-result.c',
'snippets/ide-source-snippet-chunk.c',
@@ -502,6 +493,7 @@ libide_sources = libide_generated_headers + libide_public_sources + [
'preferences/ide-preferences-language-row.h',
'runner/ide-run-manager-private.h',
'search/ide-search-reducer.c',
+ 'search/ide-search-reducer.h',
'snippets/ide-source-snippet-completion-item.c',
'snippets/ide-source-snippet-completion-item.h',
'snippets/ide-source-snippet-completion-provider.c',
@@ -663,6 +655,7 @@ libide_plugin_dep = declare_dependency(
libgd_dep,
libgio_dep,
libgtk_dep,
+ libgd_dep,
libgtksource_dep,
libtemplate_glib_dep,
libjson_glib_dep,
diff --git a/libide/resources/libide.gresource.xml b/libide/resources/libide.gresource.xml
index ba3f08c..2b79289 100644
--- a/libide/resources/libide.gresource.xml
+++ b/libide/resources/libide.gresource.xml
@@ -64,8 +64,6 @@
<file compressed="true" alias="ide-layout-stack.ui">../workbench/ide-layout-stack.ui</file>
<file compressed="true" alias="ide-omni-bar.ui">../workbench/ide-omni-bar.ui</file>
<file compressed="true" alias="ide-omni-bar-row.ui">../workbench/ide-omni-bar-row.ui</file>
- <file compressed="true" alias="ide-omni-search-group.ui">../search/ide-omni-search-group.ui</file>
- <file compressed="true" alias="ide-omni-search-row.ui">../search/ide-omni-search-row.ui</file>
<file compressed="true"
alias="ide-perspective-menu-button.ui">../workbench/ide-perspective-menu-button.ui</file>
<file compressed="true"
alias="ide-preferences-language-row.ui">../preferences/ide-preferences-language-row.ui</file>
<file compressed="true" alias="ide-run-button.ui">../runner/ide-run-button.ui</file>
diff --git a/libide/search/ide-search-engine.c b/libide/search/ide-search-engine.c
index 43e47b5..8c35476 100644
--- a/libide/search/ide-search-engine.c
+++ b/libide/search/ide-search-engine.c
@@ -1,6 +1,6 @@
/* ide-search-engine.c
*
- * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015-2017 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,71 +16,61 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <glib/gi18n.h>
-#include <libpeas/peas.h>
+#define G_LOG_DOMAIN "ide-search-engine"
-#include "ide-internal.h"
+#include <libpeas/peas.h>
-#include "plugins/ide-extension-util.h"
-#include "search/ide-search-context.h"
-#include "search/ide-search-engine.h"
-#include "search/ide-search-provider.h"
-#include "search/ide-search-result.h"
+#include "ide-search-engine.h"
+#include "ide-search-provider.h"
+#include "ide-search-result.h"
struct _IdeSearchEngine
{
IdeObject parent_instance;
-
PeasExtensionSet *extensions;
+ guint active_count;
};
-G_DEFINE_TYPE (IdeSearchEngine, ide_search_engine, IDE_TYPE_OBJECT)
-
-static void
-add_provider_to_context (PeasExtensionSet *extensions,
- PeasPluginInfo *plugin_info,
- PeasExtension *extension,
- IdeSearchContext *search_context)
+typedef struct
{
- g_assert (PEAS_IS_EXTENSION_SET (extensions));
- g_assert (plugin_info != NULL);
- g_assert (IDE_IS_SEARCH_PROVIDER (extension));
- g_assert (IDE_IS_SEARCH_CONTEXT (search_context));
+ GTask *task;
+ gchar *query;
+ GListStore *store;
+ guint outstanding;
+ guint max_results;
+} Request;
- _ide_search_context_add_provider (search_context, IDE_SEARCH_PROVIDER (extension), 0);
-}
+enum {
+ PROP_0,
+ PROP_BUSY,
+ N_PROPS
+};
-/**
- * ide_search_engine_search:
- * @search_terms: The search terms.
- *
- * Begins a query against the requested search providers.
- *
- * If @providers is %NULL, all registered providers will be used.
- *
- * Returns: (transfer full) (nullable): An #IdeSearchContext or %NULL if no
- * providers could be loaded.
- */
-IdeSearchContext *
-ide_search_engine_search (IdeSearchEngine *self,
- const gchar *search_terms)
-{
- IdeSearchContext *search_context;
- IdeContext *context;
+G_DEFINE_TYPE (IdeSearchEngine, ide_search_engine, IDE_TYPE_OBJECT)
- g_return_val_if_fail (IDE_IS_SEARCH_ENGINE (self), NULL);
- g_return_val_if_fail (search_terms, NULL);
+static GParamSpec *properties [N_PROPS];
- context = ide_object_get_context (IDE_OBJECT (self));
- search_context = g_object_new (IDE_TYPE_SEARCH_CONTEXT,
- "context", context,
- NULL);
+static Request *
+request_new (void)
+{
+ Request *r;
- peas_extension_set_foreach (self->extensions,
- (PeasExtensionSetForeachFunc)add_provider_to_context,
- search_context);
+ r = g_slice_new0 (Request);
+ r->store = NULL;
+ r->outstanding = 0;
+ r->query = NULL;
+
+ return r;
+}
- return search_context;
+static void
+request_destroy (Request *r)
+{
+ g_assert (r->outstanding == 0);
+ g_clear_object (&r->store);
+ g_clear_pointer (&r->query, g_free);
+ r->task = NULL;
+ g_slice_free (Request, r);
}
static void
@@ -89,14 +79,16 @@ ide_search_engine_constructed (GObject *object)
IdeSearchEngine *self = (IdeSearchEngine *)object;
IdeContext *context;
- context = ide_object_get_context (IDE_OBJECT (self));
-
- self->extensions = ide_extension_set_new (peas_engine_get_default (),
- IDE_TYPE_SEARCH_PROVIDER,
- "context", context,
- NULL);
+ g_assert (IDE_IS_SEARCH_ENGINE (self));
G_OBJECT_CLASS (ide_search_engine_parent_class)->constructed (object);
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+
+ self->extensions = peas_extension_set_new (peas_engine_get_default (),
+ IDE_TYPE_SEARCH_PROVIDER,
+ "context", context,
+ NULL);
}
static void
@@ -110,15 +102,205 @@ ide_search_engine_dispose (GObject *object)
}
static void
+ide_search_engine_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeSearchEngine *self = IDE_SEARCH_ENGINE (object);
+
+ switch (prop_id)
+ {
+ case PROP_BUSY:
+ g_value_set_boolean (value, ide_search_engine_get_busy (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
ide_search_engine_class_init (IdeSearchEngineClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = ide_search_engine_constructed;
object_class->dispose = ide_search_engine_dispose;
+ object_class->get_property = ide_search_engine_get_property;
+
+ properties [PROP_BUSY] =
+ g_param_spec_boolean ("busy",
+ "Busy",
+ "If the search engine is busy",
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
ide_search_engine_init (IdeSearchEngine *self)
{
}
+
+IdeSearchEngine *
+ide_search_engine_new (void)
+{
+ return g_object_new (IDE_TYPE_SEARCH_ENGINE, NULL);
+}
+
+/**
+ * ide_search_engine_get_busy:
+ * @self: a #IdeSearchEngine
+ *
+ * Checks if the #IdeSearchEngine is currently executing a query.
+ *
+ * Returns: %TRUE if queries are being processed.
+ */
+gboolean
+ide_search_engine_get_busy (IdeSearchEngine *self)
+{
+ g_return_val_if_fail (IDE_IS_SEARCH_ENGINE (self), FALSE);
+
+ return self->active_count > 0;
+}
+
+static void
+ide_search_engine_search_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeSearchProvider *provider = (IdeSearchProvider *)object;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GPtrArray) ar = NULL;
+ Request *r;
+
+ g_assert (IDE_IS_SEARCH_PROVIDER (provider));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (G_IS_TASK (task));
+
+ r = g_task_get_task_data (task);
+ g_assert (r != NULL);
+ g_assert (r->task == task);
+ g_assert (r->outstanding > 0);
+ g_assert (G_IS_LIST_STORE (r->store));
+
+ ar = ide_search_provider_search_finish (provider, result, &error);
+
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ goto cleanup;
+ }
+
+ for (guint i = 0; i < ar->len; i++)
+ {
+ IdeSearchResult *item = g_ptr_array_index (ar, i);
+
+ g_assert (IDE_IS_SEARCH_RESULT (item));
+
+ g_list_store_insert_sorted (r->store,
+ item,
+ (GCompareDataFunc)ide_search_result_compare,
+ NULL);
+
+ }
+
+cleanup:
+ r->outstanding--;
+
+ if (r->outstanding == 0)
+ g_task_return_pointer (task, g_steal_pointer (&r->store), g_object_unref);
+}
+
+static void
+ide_search_engine_search_foreach (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeSearchProvider *provider = (IdeSearchProvider *)exten;
+ Request *r = user_data;
+
+ g_assert (PEAS_IS_EXTENSION_SET (set));
+ g_assert (plugin_info != NULL);
+ g_assert (IDE_IS_SEARCH_PROVIDER (provider));
+ g_assert (r != NULL);
+ g_assert (G_IS_TASK (r->task));
+ g_assert (G_IS_LIST_STORE (r->store));
+
+ r->outstanding++;
+
+ ide_search_provider_search_async (provider,
+ r->query,
+ r->max_results,
+ g_task_get_cancellable (r->task),
+ ide_search_engine_search_cb,
+ g_object_ref (r->task));
+}
+
+void
+ide_search_engine_search_async (IdeSearchEngine *self,
+ const gchar *query,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+ g_autoptr(GListStore) store = NULL;
+ Request *r;
+
+ g_return_if_fail (IDE_IS_SEARCH_ENGINE (self));
+ g_return_if_fail (query != NULL);
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, ide_search_engine_search_async);
+ g_task_set_priority (task, G_PRIORITY_LOW);
+
+ r = request_new ();
+ r->query = g_strdup (query);
+ r->max_results = 25;
+ r->task = task;
+ r->store = g_list_store_new (IDE_TYPE_SEARCH_RESULT);
+ r->outstanding = 0;
+ g_task_set_task_data (task, r, (GDestroyNotify)request_destroy);
+
+ peas_extension_set_foreach (self->extensions,
+ ide_search_engine_search_foreach,
+ r);
+
+ self->active_count += r->outstanding;
+
+ if (r->outstanding == 0)
+ g_task_return_pointer (task,
+ g_object_ref (r->store),
+ g_object_unref);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BUSY]);
+}
+
+/**
+ * ide_search_engine_search_finish:
+ * @self: a #IdeSearchEngine
+ * @result: a #GAsyncResult
+ * @error: a location for a #GError, or %NULL
+ *
+ * Completes an asynchronous request to ide_search_engine_search_async().
+ *
+ * The result is a #GListModel of #IdeSearchResult when successful.
+ *
+ * Returns: (transfer full): A #GListModel of #IdeSearchResult items.
+ */
+GListModel *
+ide_search_engine_search_finish (IdeSearchEngine *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (IDE_IS_SEARCH_ENGINE (self), NULL);
+ g_return_val_if_fail (G_IS_TASK (result), NULL);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
diff --git a/libide/search/ide-search-engine.h b/libide/search/ide-search-engine.h
index 38dab7a..2f14b1a 100644
--- a/libide/search/ide-search-engine.h
+++ b/libide/search/ide-search-engine.h
@@ -1,6 +1,6 @@
/* ide-search-engine.h
*
- * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015-2017 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,8 +27,16 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeSearchEngine, ide_search_engine, IDE, SEARCH_ENGINE, IdeObject)
-IdeSearchContext *ide_search_engine_search (IdeSearchEngine *self,
- const gchar *search_terms);
+IdeSearchEngine *ide_search_engine_new (void);
+gboolean ide_search_engine_get_busy (IdeSearchEngine *self);
+void ide_search_engine_search_async (IdeSearchEngine *self,
+ const gchar *query,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GListModel *ide_search_engine_search_finish (IdeSearchEngine *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/libide/search/ide-search-entry.c b/libide/search/ide-search-entry.c
new file mode 100644
index 0000000..1d623b8
--- /dev/null
+++ b/libide/search/ide-search-entry.c
@@ -0,0 +1,128 @@
+/* ide-search-entry.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-search-entry"
+
+#include "ide-context.h"
+#include "ide-macros.h"
+
+#include "editor/ide-editor-perspective.h"
+#include "search/ide-search-engine.h"
+#include "search/ide-search-entry.h"
+#include "search/ide-search-result.h"
+#include "util/ide-gtk.h"
+#include "workbench/ide-workbench.h"
+
+struct _IdeSearchEntry
+{
+ DzlSuggestionEntry parent_instance;
+};
+
+G_DEFINE_TYPE (IdeSearchEntry, ide_search_entry, DZL_TYPE_SUGGESTION_ENTRY)
+
+static void
+ide_search_entry_search_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeSearchEngine *engine = (IdeSearchEngine *)object;
+ g_autoptr(IdeSearchEntry) self = user_data;
+ g_autoptr(GListModel) suggestions = NULL;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (IDE_IS_SEARCH_ENTRY (self));
+ g_assert (IDE_IS_SEARCH_ENGINE (engine));
+
+ suggestions = ide_search_engine_search_finish (engine, result, &error);
+
+ if (error != NULL)
+ {
+ /* TODO: Elevate to workbench message once we have that capability */
+ g_warning ("%s", error->message);
+ return;
+ }
+
+ g_assert (suggestions != NULL);
+ g_assert (G_IS_LIST_MODEL (suggestions));
+ g_assert (g_type_is_a (g_list_model_get_item_type (suggestions), DZL_TYPE_SUGGESTION));
+
+ dzl_suggestion_entry_set_model (DZL_SUGGESTION_ENTRY (self), suggestions);
+}
+
+static void
+ide_search_entry_changed (IdeSearchEntry *self)
+{
+ IdeSearchEngine *engine;
+ IdeContext *context;
+ const gchar *typed_text;
+
+ g_assert (IDE_IS_SEARCH_ENTRY (self));
+
+ if (NULL == (context = ide_widget_get_context (GTK_WIDGET (self))))
+ return;
+
+ typed_text = dzl_suggestion_entry_get_typed_text (DZL_SUGGESTION_ENTRY (self));
+
+ if (ide_str_empty0 (typed_text))
+ {
+ dzl_suggestion_entry_set_model (DZL_SUGGESTION_ENTRY (self), NULL);
+ return;
+ }
+
+ engine = ide_context_get_search_engine (context);
+
+ ide_search_engine_search_async (engine,
+ typed_text,
+ NULL,
+ ide_search_entry_search_cb,
+ g_object_ref (self));
+}
+
+static void
+suggestion_activated (DzlSuggestionEntry *entry,
+ DzlSuggestion *suggestion)
+{
+ g_autoptr(IdeSourceLocation) location = NULL;
+
+ g_assert (IDE_IS_SEARCH_ENTRY (entry));
+ g_assert (IDE_IS_SEARCH_RESULT (suggestion));
+
+ location = ide_search_result_get_source_location (IDE_SEARCH_RESULT (suggestion));
+
+ if (location != NULL)
+ {
+ IdeWorkbench *workbench = ide_widget_get_workbench (GTK_WIDGET (entry));
+ IdePerspective *perspective = ide_workbench_get_perspective_by_name (workbench, "editor");
+
+ ide_editor_perspective_focus_location (IDE_EDITOR_PERSPECTIVE (perspective), location);
+ }
+}
+
+static void
+ide_search_entry_class_init (IdeSearchEntryClass *klass)
+{
+ DzlSuggestionEntryClass *suggestion_entry_class = DZL_SUGGESTION_ENTRY_CLASS (klass);
+
+ suggestion_entry_class->suggestion_activated = suggestion_activated;
+}
+
+static void
+ide_search_entry_init (IdeSearchEntry *self)
+{
+ g_signal_connect (self, "changed", G_CALLBACK (ide_search_entry_changed), NULL);
+}
diff --git a/libide/search/ide-omni-search-row.h b/libide/search/ide-search-entry.h
similarity index 52%
rename from libide/search/ide-omni-search-row.h
rename to libide/search/ide-search-entry.h
index 2e950ec..e594d1e 100644
--- a/libide/search/ide-omni-search-row.h
+++ b/libide/search/ide-search-entry.h
@@ -1,6 +1,6 @@
-/* ide-omni-search-row.h
+/* ide-search-entry.h
*
- * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015-2017 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,23 +16,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef IDE_OMNI_SEARCH_ROW_H
-#define IDE_OMNI_SEARCH_ROW_H
+#ifndef IDE_SEARCH_ENTRY_H
+#define IDE_SEARCH_ENTRY_H
-#include <gtk/gtk.h>
-
-#include "ide-search-result.h"
+#include <dazzle.h>
G_BEGIN_DECLS
-#define IDE_TYPE_OMNI_SEARCH_ROW (ide_omni_search_row_get_type())
+#define IDE_TYPE_SEARCH_ENTRY (ide_search_entry_get_type())
-G_DECLARE_FINAL_TYPE (IdeOmniSearchRow, ide_omni_search_row, IDE, OMNI_SEARCH_ROW, GtkListBoxRow)
+G_DECLARE_FINAL_TYPE (IdeSearchEntry, ide_search_entry, IDE, SEARCH_ENTRY, DzlSuggestionEntry)
-IdeSearchResult *ide_omni_search_row_get_result (IdeOmniSearchRow *row);
-void ide_omni_search_row_set_result (IdeOmniSearchRow *row,
- IdeSearchResult *result);
+GtkWidget *ide_search_entry_new (void);
G_END_DECLS
-#endif /* IDE_OMNI_SEARCH_ROW_H */
+#endif /* IDE_SEARCH_ENTRY_H */
diff --git a/libide/search/ide-search-provider.c b/libide/search/ide-search-provider.c
index 187d607..0924e1c 100644
--- a/libide/search/ide-search-provider.c
+++ b/libide/search/ide-search-provider.c
@@ -1,6 +1,6 @@
/* ide-search-provider.c
*
- * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,127 +16,83 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <glib/gi18n.h>
+#define G_LOG_DOMAIN "ide-search-provider"
-#include "ide-context.h"
-#include "ide-search-context.h"
#include "ide-search-provider.h"
-#include "ide-search-result.h"
G_DEFINE_INTERFACE (IdeSearchProvider, ide_search_provider, IDE_TYPE_OBJECT)
-static const gchar *
-ide_search_provider_real_get_verb (IdeSearchProvider *self)
+static void
+ide_search_provider_real_search_async (IdeSearchProvider *self,
+ const gchar *query,
+ guint max_results,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- return "";
-}
+ g_autoptr(GTask) task = NULL;
-static gint
-ide_search_provider_real_get_priority (IdeSearchProvider *self)
-{
- return -1;
-}
+ g_assert (IDE_IS_SEARCH_PROVIDER (self));
+ g_assert (query != NULL);
-static gunichar
-ide_search_provider_real_get_prefix (IdeSearchProvider *self)
-{
- return '\0';
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "search not implemented");
}
-static GtkWidget *
-ide_search_provider_real_create_row (IdeSearchProvider *self,
- IdeSearchResult *result)
+static GPtrArray *
+ide_search_provider_real_search_finish (IdeSearchProvider *self,
+ GAsyncResult *result,
+ GError **error)
{
- return NULL;
-}
+ g_assert (IDE_IS_SEARCH_PROVIDER (self));
+ g_assert (G_IS_TASK (result));
-static void
-ide_search_provider_real_activate (IdeSearchProvider *self,
- GtkWidget *row,
- IdeSearchResult *result)
-{
+ return g_task_propagate_pointer (G_TASK (result), error);
}
static void
ide_search_provider_default_init (IdeSearchProviderInterface *iface)
{
- iface->get_verb = ide_search_provider_real_get_verb;
- iface->get_priority = ide_search_provider_real_get_priority;
- iface->get_prefix = ide_search_provider_real_get_prefix;
- iface->create_row = ide_search_provider_real_create_row;
- iface->activate = ide_search_provider_real_activate;
-}
-
-const gchar *
-ide_search_provider_get_verb (IdeSearchProvider *provider)
-{
- g_return_val_if_fail (IDE_IS_SEARCH_PROVIDER (provider), NULL);
-
- return IDE_SEARCH_PROVIDER_GET_IFACE (provider)->get_verb (provider);
-}
-
-gint
-ide_search_provider_get_priority (IdeSearchProvider *provider)
-{
- g_return_val_if_fail (IDE_IS_SEARCH_PROVIDER (provider), -1);
-
- return IDE_SEARCH_PROVIDER_GET_IFACE (provider)->get_priority (provider);
-}
-
-gunichar
-ide_search_provider_get_prefix (IdeSearchProvider *provider)
-{
- g_return_val_if_fail (IDE_IS_SEARCH_PROVIDER (provider), -1);
-
- return IDE_SEARCH_PROVIDER_GET_IFACE (provider)->get_prefix (provider);
+ iface->search_async = ide_search_provider_real_search_async;
+ iface->search_finish = ide_search_provider_real_search_finish;
}
void
-ide_search_provider_populate (IdeSearchProvider *provider,
- IdeSearchContext *context,
- const gchar *search_terms,
- gsize max_results,
- GCancellable *cancellable)
+ide_search_provider_search_async (IdeSearchProvider *self,
+ const gchar *query,
+ guint max_results,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
- g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
- g_return_if_fail (search_terms != NULL);
+ g_return_if_fail (IDE_IS_SEARCH_PROVIDER (self));
+ g_return_if_fail (query != NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- return IDE_SEARCH_PROVIDER_GET_IFACE (provider)->populate (provider,
- context,
- search_terms,
- max_results,
- cancellable);
+ IDE_SEARCH_PROVIDER_GET_IFACE (self)->search_async (self, query, max_results, cancellable, callback,
user_data);
}
/**
- * ide_search_provider_create_row:
- * @provider: A #IdeSearchProvider.
- * @result: A #IdeSearchResult.
+ * ide_search_provider_search_finish:
+ * @self: a #IdeSearchProvider
+ * @result: a #GAsyncResult
+ * @error: a location for a #GError, or %NULL
*
- * Create a row to display the search result.
+ * Completes a request to a search provider.
*
- * Returns: (transfer full): A #GtkWidget.
+ * Returns: (transfer container) (element-type Ide.SearchResult): A #GPtrArray
+ * of #IdeSearchResult elements.
*/
-GtkWidget *
-ide_search_provider_create_row (IdeSearchProvider *self,
- IdeSearchResult *result)
+GPtrArray *
+ide_search_provider_search_finish (IdeSearchProvider *self,
+ GAsyncResult *result,
+ GError **error)
{
g_return_val_if_fail (IDE_IS_SEARCH_PROVIDER (self), NULL);
- g_return_val_if_fail (IDE_IS_SEARCH_RESULT (result), NULL);
-
- return IDE_SEARCH_PROVIDER_GET_IFACE (self)->create_row (self, result);
-}
-
-void
-ide_search_provider_activate (IdeSearchProvider *self,
- GtkWidget *row,
- IdeSearchResult *result)
-{
- g_return_if_fail (IDE_IS_SEARCH_PROVIDER (self));
- g_return_if_fail (GTK_IS_WIDGET (row));
- g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
- return IDE_SEARCH_PROVIDER_GET_IFACE (self)->activate (self, row, result);
+ return IDE_SEARCH_PROVIDER_GET_IFACE (self)->search_finish (self, result, error);
}
diff --git a/libide/search/ide-search-provider.h b/libide/search/ide-search-provider.h
index c6f3448..6000cf9 100644
--- a/libide/search/ide-search-provider.h
+++ b/libide/search/ide-search-provider.h
@@ -1,6 +1,6 @@
/* ide-search-provider.h
*
- * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015-2017 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,8 +19,6 @@
#ifndef IDE_SEARCH_PROVIDER_H
#define IDE_SEARCH_PROVIDER_H
-#include <gtk/gtk.h>
-
#include "ide-object.h"
G_BEGIN_DECLS
@@ -31,36 +29,28 @@ G_DECLARE_INTERFACE (IdeSearchProvider, ide_search_provider, IDE, SEARCH_PROVIDE
struct _IdeSearchProviderInterface
{
- GTypeInterface parent_iface;
-
- gunichar (*get_prefix) (IdeSearchProvider *provider);
- gint (*get_priority) (IdeSearchProvider *provider);
- const gchar *(*get_verb) (IdeSearchProvider *provider);
- void (*populate) (IdeSearchProvider *provider,
- IdeSearchContext *context,
- const gchar *search_terms,
- gsize max_results,
- GCancellable *cancellable);
- GtkWidget *(*create_row) (IdeSearchProvider *provider,
- IdeSearchResult *result);
- void (*activate) (IdeSearchProvider *provider,
- GtkWidget *row,
- IdeSearchResult *result);
+ GTypeInterface parent_interface;
+
+ void (*search_async) (IdeSearchProvider *self,
+ const gchar *query,
+ guint max_results,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ GPtrArray *(*search_finish) (IdeSearchProvider *self,
+ GAsyncResult *result,
+ GError **error);
};
-gunichar ide_search_provider_get_prefix (IdeSearchProvider *provider);
-gint ide_search_provider_get_priority (IdeSearchProvider *provider);
-const gchar *ide_search_provider_get_verb (IdeSearchProvider *provider);
-void ide_search_provider_populate (IdeSearchProvider *provider,
- IdeSearchContext *context,
- const gchar *search_terms,
- gsize max_results,
- GCancellable *cancellable);
-GtkWidget *ide_search_provider_create_row (IdeSearchProvider *provider,
- IdeSearchResult *result);
-void ide_search_provider_activate (IdeSearchProvider *provider,
- GtkWidget *row,
- IdeSearchResult *result);
+void ide_search_provider_search_async (IdeSearchProvider *self,
+ const gchar *query,
+ guint max_results,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GPtrArray *ide_search_provider_search_finish (IdeSearchProvider *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/libide/search/ide-search-reducer.c b/libide/search/ide-search-reducer.c
index 5d765de..e4c6592 100644
--- a/libide/search/ide-search-reducer.c
+++ b/libide/search/ide-search-reducer.c
@@ -16,61 +16,105 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ide-search-context.h"
-#include "ide-search-provider.h"
+#define G_LOG_DOMAIN "ide-search-reducer"
+
#include "ide-search-reducer.h"
#include "ide-search-result.h"
+#define DEFAULT_MAX_ITEMS 1000
+
void
ide_search_reducer_init (IdeSearchReducer *reducer,
- IdeSearchContext *context,
- IdeSearchProvider *provider,
gsize max_results)
{
- g_return_if_fail (reducer);
- g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
- g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+ g_return_if_fail (reducer != NULL);
- reducer->context = context;
- reducer->provider = provider;
reducer->sequence = g_sequence_new (g_object_unref);
- reducer->max_results = max_results ?: G_MAXSIZE;
+ reducer->max_results = max_results ? max_results : DEFAULT_MAX_ITEMS;
reducer->count = 0;
}
void
ide_search_reducer_destroy (IdeSearchReducer *reducer)
{
- g_return_if_fail (reducer);
+ g_return_if_fail (reducer != NULL);
- if (reducer->sequence)
+ if (reducer->sequence != NULL)
g_sequence_free (reducer->sequence);
}
-void
-ide_search_reducer_push (IdeSearchReducer *reducer,
- IdeSearchResult *result)
+GPtrArray *
+ide_search_reducer_free (IdeSearchReducer *reducer,
+ gboolean free_results)
{
- g_return_if_fail (reducer);
- g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
+ GPtrArray *ar;
+ GSequenceIter *iter;
+ GSequenceIter *end;
+
+ g_return_val_if_fail (reducer != NULL, NULL);
+
+ if (free_results)
+ {
+ ide_search_reducer_destroy (reducer);
+ return NULL;
+ }
+
+ ar = g_ptr_array_new_with_free_func (g_object_unref);
+
+ end = g_sequence_get_end_iter (reducer->sequence);
- if (reducer->max_results <= g_sequence_get_length (reducer->sequence))
+ for (iter = g_sequence_get_begin_iter (reducer->sequence);
+ iter != end;
+ iter = g_sequence_iter_next (iter))
{
- GSequenceIter *iter;
- IdeSearchResult *lowest;
-
- /* Remove lowest score */
- iter = g_sequence_get_begin_iter (reducer->sequence);
- lowest = g_sequence_get (iter);
- ide_search_context_remove_result (reducer->context, reducer->provider, lowest);
- g_sequence_remove (iter);
+ IdeSearchResult *result = g_sequence_get (iter);
+ g_ptr_array_add (ar, g_object_ref (result));
}
+ g_sequence_free (reducer->sequence);
+
+ reducer->sequence = NULL;
+ reducer->max_results = 0;
+ reducer->count = 0;
+
+ return ar;
+}
+
+/**
+ * ide_search_reducer_take:
+ * @self: an #IdeSearchReducer
+ * @result: (transfer full): an #IdeSearchResult
+ *
+ * Like ide_search_reducer_push() but takes ownership of @result by
+ * stealing the reference.
+ */
+void
+ide_search_reducer_take (IdeSearchReducer *reducer,
+ IdeSearchResult *result)
+{
+ g_assert (reducer != NULL);
+ g_assert (IDE_IS_SEARCH_RESULT (result));
+
+ if (reducer->count == reducer->max_results)
+ /* Remove lowest score */
+ g_sequence_remove (g_sequence_get_begin_iter (reducer->sequence));
+ else
+ reducer->count++;
+
g_sequence_insert_sorted (reducer->sequence,
- g_object_ref (result),
+ result,
(GCompareDataFunc)ide_search_result_compare,
NULL);
- ide_search_context_add_result (reducer->context, reducer->provider, result);
+}
+
+void
+ide_search_reducer_push (IdeSearchReducer *reducer,
+ IdeSearchResult *result)
+{
+ g_assert (reducer != NULL);
+ g_assert (IDE_IS_SEARCH_RESULT (result));
+
+ ide_search_reducer_take (reducer, g_object_ref (result));
}
gboolean
@@ -81,12 +125,12 @@ ide_search_reducer_accepts (IdeSearchReducer *reducer,
g_return_val_if_fail (reducer, FALSE);
- if (g_sequence_get_length (reducer->sequence) < reducer->max_results)
+ if (reducer->count < reducer->max_results)
return TRUE;
iter = g_sequence_get_begin_iter (reducer->sequence);
- if (iter)
+ if (iter != NULL)
{
IdeSearchResult *result;
diff --git a/libide/search/ide-search-reducer.h b/libide/search/ide-search-reducer.h
index e67b689..a38a852 100644
--- a/libide/search/ide-search-reducer.h
+++ b/libide/search/ide-search-reducer.h
@@ -25,22 +25,22 @@ G_BEGIN_DECLS
typedef struct
{
- IdeSearchContext *context;
- IdeSearchProvider *provider;
- GSequence *sequence;
- gsize max_results;
- gsize count;
+ GSequence *sequence;
+ gsize max_results;
+ gsize count;
} IdeSearchReducer;
-void ide_search_reducer_init (IdeSearchReducer *reducer,
- IdeSearchContext *context,
- IdeSearchProvider *provider,
- gsize max_results);
-gboolean ide_search_reducer_accepts (IdeSearchReducer *reducer,
- gfloat score);
-void ide_search_reducer_push (IdeSearchReducer *reducer,
- IdeSearchResult *result);
-void ide_search_reducer_destroy (IdeSearchReducer *reducer);
+void ide_search_reducer_init (IdeSearchReducer *reducer,
+ gsize max_results);
+gboolean ide_search_reducer_accepts (IdeSearchReducer *reducer,
+ gfloat score);
+void ide_search_reducer_take (IdeSearchReducer *reducer,
+ IdeSearchResult *result);
+void ide_search_reducer_push (IdeSearchReducer *reducer,
+ IdeSearchResult *result);
+void ide_search_reducer_destroy (IdeSearchReducer *reducer);
+GPtrArray *ide_search_reducer_free (IdeSearchReducer *reducer,
+ gboolean free_results);
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (IdeSearchReducer, ide_search_reducer_destroy)
diff --git a/libide/search/ide-search-result.c b/libide/search/ide-search-result.c
index 1fed0a2..ab8cfa8 100644
--- a/libide/search/ide-search-result.c
+++ b/libide/search/ide-search-result.c
@@ -1,6 +1,6 @@
/* ide-search-result.c
*
- * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,304 +16,206 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <glib/gi18n.h>
+#define G_LOG_DOMAIN "ide-search-result"
-#include "ide-context.h"
#include "ide-search-result.h"
typedef struct
{
- IdeSearchProvider *provider;
- gchar *title;
- gchar *subtitle;
- gfloat score;
+ gfloat score;
+ guint priority;
} IdeSearchResultPrivate;
-G_DEFINE_TYPE_WITH_PRIVATE (IdeSearchResult, ide_search_result, IDE_TYPE_OBJECT)
-
enum {
PROP_0,
- PROP_PROVIDER,
PROP_SCORE,
- PROP_SUBTITLE,
- PROP_TITLE,
- LAST_PROP
+ PROP_PRIORITY,
+ N_PROPS
};
-static GParamSpec *properties [LAST_PROP];
-
-IdeSearchResult *
-ide_search_result_new (IdeSearchProvider *provider,
- const gchar *title,
- const gchar *subtitle,
- gfloat score)
-{
- IdeSearchResult *self;
- IdeContext *context;
-
- g_return_val_if_fail (IDE_IS_SEARCH_PROVIDER (provider), NULL);
+G_DEFINE_TYPE_WITH_PRIVATE (IdeSearchResult, ide_search_result, DZL_TYPE_SUGGESTION)
- context = ide_object_get_context (IDE_OBJECT (provider));
+static GParamSpec *properties [N_PROPS];
- self = g_object_new (IDE_TYPE_SEARCH_RESULT,
- "context", context,
- "provider", provider,
- "score", score,
- "subtitle", subtitle,
- "title", title,
- NULL);
-
- return self;
-}
-
-/**
- * ide_search_result_get_provider:
- * @result: A #IdeSearchResult.
- *
- * Gets the provider that created the search result.
- *
- * Returns: (transfer none): An #IdeSearchProvider.
- */
-IdeSearchProvider *
-ide_search_result_get_provider (IdeSearchResult *self)
+static void
+ide_search_result_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
+ IdeSearchResult *self = IDE_SEARCH_RESULT (object);
- g_return_val_if_fail (IDE_IS_SEARCH_RESULT (self), NULL);
+ switch (prop_id)
+ {
+ case PROP_SCORE:
+ g_value_set_float (value, ide_search_result_get_score (self));
+ break;
- return priv->provider;
+ case PROP_PRIORITY:
+ g_value_set_int (value, ide_search_result_get_priority (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
-ide_search_result_set_provider (IdeSearchResult *self,
- IdeSearchProvider *provider)
+ide_search_result_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
+ IdeSearchResult *self = IDE_SEARCH_RESULT (object);
- g_return_if_fail (IDE_IS_SEARCH_RESULT (self));
- g_return_if_fail (!provider || IDE_IS_SEARCH_PROVIDER (provider));
+ switch (prop_id)
+ {
+ case PROP_SCORE:
+ ide_search_result_set_score (self, g_value_get_float (value));
+ break;
- g_set_object (&priv->provider, provider);
+ case PROP_PRIORITY:
+ ide_search_result_set_priority (self, g_value_get_int (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
-const gchar *
-ide_search_result_get_title (IdeSearchResult *self)
+static void
+ide_search_result_class_init (IdeSearchResultClass *klass)
{
- IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- g_return_val_if_fail (IDE_IS_SEARCH_RESULT (self), NULL);
+ object_class->get_property = ide_search_result_get_property;
+ object_class->set_property = ide_search_result_set_property;
- return priv->title;
+ properties [PROP_SCORE] =
+ g_param_spec_float ("score",
+ "Score",
+ "The score of the result",
+ -G_MINFLOAT,
+ G_MAXFLOAT,
+ 0.0f,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ properties [PROP_PRIORITY] =
+ g_param_spec_int ("priority",
+ "Priority",
+ "The priority of search result group",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
}
-const gchar *
-ide_search_result_get_subtitle (IdeSearchResult *self)
+static void
+ide_search_result_init (IdeSearchResult *self)
{
- IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
-
- g_return_val_if_fail (IDE_IS_SEARCH_RESULT (self), NULL);
-
- return priv->subtitle;
}
-gfloat
-ide_search_result_get_score (IdeSearchResult *self)
+IdeSearchResult *
+ide_search_result_new (void)
{
- IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
-
- g_return_val_if_fail (IDE_IS_SEARCH_RESULT (self), 0.0);
-
- return priv->score;
+ return g_object_new (IDE_TYPE_SEARCH_RESULT, NULL);
}
-static void
-ide_search_result_set_title (IdeSearchResult *self,
- const gchar *title)
+gint
+ide_search_result_compare (gconstpointer a,
+ gconstpointer b)
{
- IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
+ IdeSearchResult *ra = (IdeSearchResult *)a;
+ IdeSearchResult *rb = (IdeSearchResult *)b;
+ IdeSearchResultPrivate *priva = ide_search_result_get_instance_private (ra);
+ IdeSearchResultPrivate *privb = ide_search_result_get_instance_private (rb);
+ gint ret;
- g_return_if_fail (IDE_IS_SEARCH_RESULT (self));
+ ret = priva->priority - privb->priority;
- if (priv->title != title)
+ if (ret == 0)
{
- g_free (priv->title);
- priv->title = g_strdup (title);
+ if (priva->score < privb->score)
+ priva->score = -1;
+ else if (priva->score > privb->score)
+ priva->score = 1;
}
+
+ return ret;
}
-static void
-ide_search_result_set_subtitle (IdeSearchResult *self,
- const gchar *subtitle)
+gfloat
+ide_search_result_get_score (IdeSearchResult *self)
{
IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
- g_return_if_fail (IDE_IS_SEARCH_RESULT (self));
+ g_return_val_if_fail (IDE_IS_SEARCH_RESULT (self), 0.0f);
- if (priv->subtitle != subtitle)
- {
- g_free (priv->subtitle);
- priv->subtitle = g_strdup (subtitle);
- }
+ return priv->score;
}
-static void
+void
ide_search_result_set_score (IdeSearchResult *self,
gfloat score)
{
IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
g_return_if_fail (IDE_IS_SEARCH_RESULT (self));
- g_return_if_fail (score >= 0.0);
- g_return_if_fail (score <= 1.0);
- priv->score = score;
+ if (priv->score != score)
+ {
+ priv->score = score;
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SCORE]);
+ }
}
gint
-ide_search_result_compare (const IdeSearchResult *a,
- const IdeSearchResult *b)
-{
- gfloat fa;
- gfloat fb;
-
- g_return_val_if_fail (IDE_IS_SEARCH_RESULT ((IdeSearchResult*)a), 0);
- g_return_val_if_fail (IDE_IS_SEARCH_RESULT ((IdeSearchResult*)b), 0);
-
- fa = ide_search_result_get_score ((IdeSearchResult *)a);
- fb = ide_search_result_get_score ((IdeSearchResult *)b);
-
- if (fa < fb)
- return -1;
- else if (fa > fb)
- return 1;
- else
- return 0;
-}
-
-static void
-ide_search_result_finalize (GObject *object)
+ide_search_result_get_priority (IdeSearchResult *self)
{
- IdeSearchResult *self = (IdeSearchResult *)object;
IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
- g_clear_object (&priv->provider);
- g_clear_pointer (&priv->title, g_free);
- g_clear_pointer (&priv->subtitle, g_free);
+ g_return_val_if_fail (IDE_IS_SEARCH_RESULT (self), 0.0);
- G_OBJECT_CLASS (ide_search_result_parent_class)->finalize (object);
+ return priv->priority;
}
-static void
-ide_search_result_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+void
+ide_search_result_set_priority (IdeSearchResult *self,
+ gint priority)
{
- IdeSearchResult *self = IDE_SEARCH_RESULT (object);
-
- switch (prop_id)
- {
- case PROP_PROVIDER:
- g_value_set_object (value, ide_search_result_get_provider (self));
- break;
-
- case PROP_TITLE:
- g_value_set_string (value, ide_search_result_get_title (self));
- break;
-
- case PROP_SUBTITLE:
- g_value_set_string (value, ide_search_result_get_subtitle (self));
- break;
-
- case PROP_SCORE:
- g_value_set_float (value, ide_search_result_get_score (self));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
+ IdeSearchResultPrivate *priv = ide_search_result_get_instance_private (self);
-static void
-ide_search_result_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- IdeSearchResult *self = IDE_SEARCH_RESULT (object);
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (self));
- switch (prop_id)
+ if (priv->priority != priority)
{
- case PROP_PROVIDER:
- ide_search_result_set_provider (self, g_value_get_object (value));
- break;
-
- case PROP_TITLE:
- ide_search_result_set_title (self, g_value_get_string (value));
- break;
-
- case PROP_SUBTITLE:
- ide_search_result_set_subtitle (self, g_value_get_string (value));
- break;
-
- case PROP_SCORE:
- ide_search_result_set_score (self, g_value_get_float (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ priv->priority = priority;
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PRIORITY]);
}
}
-static void
-ide_search_result_class_init (IdeSearchResultClass *klass)
+/**
+ * ide_search_result_get_source_location:
+ * @self: a #IdeSearchResult
+ *
+ * Gets the file associated with the search result if any.
+ *
+ * Many search providers ultimately just open a file, so this may
+ * be used in lieu of handling the activate signal.
+ *
+ * Returns: (transfer full): An #IdeUri
+ */
+IdeSourceLocation *
+ide_search_result_get_source_location (IdeSearchResult *self)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = ide_search_result_finalize;
- object_class->get_property = ide_search_result_get_property;
- object_class->set_property = ide_search_result_set_property;
+ g_return_val_if_fail (IDE_IS_SEARCH_RESULT (self), NULL);
- properties [PROP_PROVIDER] =
- g_param_spec_object ("provider",
- "Provider",
- "The Search Provider",
- IDE_TYPE_SEARCH_PROVIDER,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
- properties [PROP_TITLE] =
- g_param_spec_string ("title",
- "Title",
- "The title of the search result.",
- NULL,
- (G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- properties [PROP_SUBTITLE] =
- g_param_spec_string ("subtitle",
- "Subtitle",
- "The subtitle of the search result.",
- NULL,
- (G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
+ if (IDE_SEARCH_RESULT_GET_CLASS (self)->get_source_location != NULL)
+ return IDE_SEARCH_RESULT_GET_CLASS (self)->get_source_location (self);
- properties [PROP_SCORE] =
- g_param_spec_float ("score",
- "Score",
- "The score of the search result.",
- 0.0,
- 1.0,
- 0.0,
- (G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_properties (object_class, LAST_PROP, properties);
-}
+ g_print ("nope\n");
-static void
-ide_search_result_init (IdeSearchResult *self)
-{
+ return NULL;
}
diff --git a/libide/search/ide-search-result.h b/libide/search/ide-search-result.h
index 7a69e3b..21a7c18 100644
--- a/libide/search/ide-search-result.h
+++ b/libide/search/ide-search-result.h
@@ -1,6 +1,6 @@
/* ide-search-result.h
*
- * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,34 +19,43 @@
#ifndef IDE_SEARCH_RESULT_H
#define IDE_SEARCH_RESULT_H
-#include "ide-object.h"
+#include <gio/gio.h>
+#include <dazzle.h>
-#include "ide-search-provider.h"
+#include "diagnostics/ide-source-location.h"
G_BEGIN_DECLS
#define IDE_TYPE_SEARCH_RESULT (ide_search_result_get_type())
-G_DECLARE_DERIVABLE_TYPE (IdeSearchResult, ide_search_result, IDE, SEARCH_RESULT, IdeObject)
+G_DECLARE_DERIVABLE_TYPE (IdeSearchResult, ide_search_result, IDE, SEARCH_RESULT, DzlSuggestion)
struct _IdeSearchResultClass
{
- IdeObjectClass parent;
-
- void (*activate) (IdeSearchResult *result);
+ DzlSuggestionClass parent_class;
+
+ IdeSourceLocation *(*get_source_location) (IdeSearchResult *self);
+
+ gpointer _reserved1;
+ gpointer _reserved2;
+ gpointer _reserved3;
+ gpointer _reserved4;
+ gpointer _reserved5;
+ gpointer _reserved6;
+ gpointer _reserved7;
+ gpointer _reserved8;
};
-IdeSearchResult *ide_search_result_new (IdeSearchProvider *provider,
- const gchar *title,
- const gchar *subtitle,
- gfloat score);
-IdeSearchProvider *ide_search_result_get_provider (IdeSearchResult *result);
-gfloat ide_search_result_get_score (IdeSearchResult *result);
-const gchar *ide_search_result_get_title (IdeSearchResult *result);
-const gchar *ide_search_result_get_subtitle (IdeSearchResult *result);
-gint ide_search_result_compare (const IdeSearchResult *a,
- const IdeSearchResult *b);
-void ide_search_result_activate (IdeSearchResult *result);
+IdeSearchResult *ide_search_result_new (void);
+IdeSourceLocation *ide_search_result_get_source_location (IdeSearchResult *self);
+gint ide_search_result_compare (gconstpointer a,
+ gconstpointer b);
+gint ide_search_result_get_priority (IdeSearchResult *self);
+void ide_search_result_set_priority (IdeSearchResult *self,
+ gint priority);
+gfloat ide_search_result_get_score (IdeSearchResult *self);
+void ide_search_result_set_score (IdeSearchResult *self,
+ gfloat score);
G_END_DECLS
diff --git a/libide/workbench/ide-workbench-header-bar.c b/libide/workbench/ide-workbench-header-bar.c
index 7e9e64d..4a62703 100644
--- a/libide/workbench/ide-workbench-header-bar.c
+++ b/libide/workbench/ide-workbench-header-bar.c
@@ -21,7 +21,7 @@
#include <dazzle.h>
#include "application/ide-application.h"
-#include "search/ide-omni-search-entry.h"
+#include "search/ide-search-entry.h"
#include "util/ide-gtk.h"
#include "workbench/ide-perspective.h"
#include "workbench/ide-workbench.h"
@@ -29,11 +29,11 @@
typedef struct
{
- GtkMenuButton *menu_button;
- DzlPriorityBox *right_box;
- DzlPriorityBox *left_box;
- IdeOmniBar *omni_bar;
- IdeOmniSearchEntry *search_entry;
+ GtkMenuButton *menu_button;
+ DzlPriorityBox *right_box;
+ DzlPriorityBox *left_box;
+ IdeOmniBar *omni_bar;
+ IdeSearchEntry *search_entry;
} IdeWorkbenchHeaderBarPrivate;
static void buildable_iface_init (GtkBuildableIface *iface);
@@ -59,6 +59,8 @@ ide_workbench_header_bar_class_init (IdeWorkbenchHeaderBarClass *klass)
gtk_widget_class_bind_template_child_private (widget_class, IdeWorkbenchHeaderBar, omni_bar);
gtk_widget_class_bind_template_child_private (widget_class, IdeWorkbenchHeaderBar, right_box);
gtk_widget_class_bind_template_child_private (widget_class, IdeWorkbenchHeaderBar, search_entry);
+
+ g_type_ensure (IDE_TYPE_SEARCH_ENTRY);
}
static void
diff --git a/libide/workbench/ide-workbench-header-bar.ui b/libide/workbench/ide-workbench-header-bar.ui
index 1f83171..8705244 100644
--- a/libide/workbench/ide-workbench-header-bar.ui
+++ b/libide/workbench/ide-workbench-header-bar.ui
@@ -68,7 +68,7 @@
</packing>
</child>
<child>
- <object class="IdeOmniSearchEntry" id="search_entry">
+ <object class="IdeSearchEntry" id="search_entry">
<property name="max-width-chars">30</property>
<property name="placeholder-text" translatable="yes">Press Ctrl+. to search</property>
<property name="visible">true</property>
diff --git a/plugins/file-search/gb-file-search-index.c b/plugins/file-search/gb-file-search-index.c
index 44d5384..c3301c9 100644
--- a/plugins/file-search/gb-file-search-index.c
+++ b/plugins/file-search/gb-file-search-index.c
@@ -261,6 +261,8 @@ gb_file_search_index_build_async (GbFileSearchIndex *self,
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, gb_file_search_index_build_async);
+ g_task_set_priority (task, G_PRIORITY_LOW);
if (self->root_directory == NULL)
{
@@ -289,31 +291,27 @@ gb_file_search_index_build_finish (GbFileSearchIndex *self,
return g_task_propagate_boolean (task, error);
}
-void
+GPtrArray *
gb_file_search_index_populate (GbFileSearchIndex *self,
- IdeSearchContext *context,
- IdeSearchProvider *provider,
- const gchar *query)
+ const gchar *query,
+ gsize max_results)
{
- g_autoptr(GArray) ar = NULL;
g_auto(IdeSearchReducer) reducer = { 0 };
g_autoptr(GString) delimited = NULL;
+ g_autoptr(GArray) ar = NULL;
const gchar *iter = query;
- IdeContext *icontext;
- gsize max_matches;
+ IdeContext *context;
gsize i;
- g_return_if_fail (GB_IS_FILE_SEARCH_INDEX (self));
- g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
- g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
- g_return_if_fail (query != NULL);
+ g_return_val_if_fail (GB_IS_FILE_SEARCH_INDEX (self), NULL);
+ g_return_val_if_fail (query != NULL, NULL);
if (self->fuzzy == NULL)
- return;
+ return g_ptr_array_new_with_free_func (g_object_unref);
- icontext = ide_object_get_context (IDE_OBJECT (provider));
- max_matches = ide_search_context_get_max_results (context);
- ide_search_reducer_init (&reducer, context, provider, max_matches);
+ context = ide_object_get_context (IDE_OBJECT (self));
+
+ ide_search_reducer_init (&reducer, max_results);
delimited = g_string_new (NULL);
@@ -325,13 +323,11 @@ gb_file_search_index_populate (GbFileSearchIndex *self,
g_string_append_unichar (delimited, ch);
}
- ar = dzl_fuzzy_mutable_index_match (self->fuzzy, delimited->str, max_matches);
+ ar = dzl_fuzzy_mutable_index_match (self->fuzzy, delimited->str, max_results);
for (i = 0; i < ar->len; i++)
{
- const DzlFuzzyMutableIndexMatch *match;
-
- match = &g_array_index (ar, DzlFuzzyMutableIndexMatch, i);
+ const DzlFuzzyMutableIndexMatch *match = &g_array_index (ar, DzlFuzzyMutableIndexMatch, i);
if (ide_search_reducer_accepts (&reducer, match->score))
{
@@ -339,16 +335,18 @@ gb_file_search_index_populate (GbFileSearchIndex *self,
g_autofree gchar *markup = NULL;
markup = dzl_fuzzy_highlight (match->key, delimited->str, FALSE);
+
result = g_object_new (GB_TYPE_FILE_SEARCH_RESULT,
- "context", icontext,
- "provider", provider,
+ "context", context,
"score", match->score,
"title", markup,
"path", match->key,
NULL);
- ide_search_reducer_push (&reducer, IDE_SEARCH_RESULT (result));
+ ide_search_reducer_take (&reducer, g_steal_pointer (&result));
}
}
+
+ return ide_search_reducer_free (&reducer, FALSE);
}
gboolean
diff --git a/plugins/file-search/gb-file-search-index.h b/plugins/file-search/gb-file-search-index.h
index 6f1924a..5384b18 100644
--- a/plugins/file-search/gb-file-search-index.h
+++ b/plugins/file-search/gb-file-search-index.h
@@ -27,23 +27,22 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GbFileSearchIndex, gb_file_search_index, GB, FILE_SEARCH_INDEX, IdeObject)
-void gb_file_search_index_populate (GbFileSearchIndex *self,
- IdeSearchContext *context,
- IdeSearchProvider *provider,
- const gchar *query);
-void gb_file_search_index_build_async (GbFileSearchIndex *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean gb_file_search_index_build_finish (GbFileSearchIndex *self,
- GAsyncResult *result,
- GError **error);
-gboolean gb_file_search_index_contains (GbFileSearchIndex *self,
- const gchar *relative_path);
-void gb_file_search_index_insert (GbFileSearchIndex *self,
- const gchar *relative_path);
-void gb_file_search_index_remove (GbFileSearchIndex *self,
- const gchar *relative_path);
+GPtrArray *gb_file_search_index_populate (GbFileSearchIndex *self,
+ const gchar *query,
+ gsize max_results);
+void gb_file_search_index_build_async (GbFileSearchIndex *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean gb_file_search_index_build_finish (GbFileSearchIndex *self,
+ GAsyncResult *result,
+ GError **error);
+gboolean gb_file_search_index_contains (GbFileSearchIndex *self,
+ const gchar *relative_path);
+void gb_file_search_index_insert (GbFileSearchIndex *self,
+ const gchar *relative_path);
+void gb_file_search_index_remove (GbFileSearchIndex *self,
+ const gchar *relative_path);
G_END_DECLS
diff --git a/plugins/file-search/gb-file-search-provider.c b/plugins/file-search/gb-file-search-provider.c
index 7cc142c..e4b5659 100644
--- a/plugins/file-search/gb-file-search-provider.c
+++ b/plugins/file-search/gb-file-search-provider.c
@@ -35,33 +35,45 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (GbFileSearchProvider,
gb_file_search_provider,
IDE_TYPE_OBJECT,
0,
- G_IMPLEMENT_INTERFACE (IDE_TYPE_SEARCH_PROVIDER,
- search_provider_iface_init))
-
-static const gchar *
-gb_file_search_provider_get_verb (IdeSearchProvider *provider)
-{
- return _("Switch To");
-}
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_SEARCH_PROVIDER, search_provider_iface_init))
static void
-gb_file_search_provider_populate (IdeSearchProvider *provider,
- IdeSearchContext *context,
- const gchar *search_terms,
- gsize max_results,
- GCancellable *cancellable)
+gb_file_search_provider_search_async (IdeSearchProvider *provider,
+ const gchar *search_terms,
+ guint max_results,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GbFileSearchProvider *self = (GbFileSearchProvider *)provider;
+ g_autoptr(GTask) task = NULL;
+ g_autoptr(GPtrArray) results = NULL;
- g_assert (IDE_IS_SEARCH_PROVIDER (provider));
- g_assert (IDE_IS_SEARCH_CONTEXT (context));
+ g_assert (GB_IS_FILE_SEARCH_PROVIDER (self));
g_assert (search_terms != NULL);
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, gb_file_search_provider_search_async);
+ g_task_set_priority (task, G_PRIORITY_LOW);
+
if (self->index != NULL)
- gb_file_search_index_populate (self->index, context, provider, search_terms);
+ results = gb_file_search_index_populate (self->index, search_terms, max_results);
+ else
+ results = g_ptr_array_new_with_free_func (g_object_unref);
+
+ g_task_return_pointer (task, g_steal_pointer (&results), (GDestroyNotify)g_ptr_array_unref);
+}
+
+static GPtrArray *
+gb_file_search_provider_search_finish (IdeSearchProvider *provider,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_assert (GB_IS_FILE_SEARCH_PROVIDER (provider));
+ g_assert (G_IS_TASK (result));
- ide_search_context_provider_completed (context, provider);
+ return g_task_propagate_pointer (G_TASK (result), error);
}
static void
@@ -167,20 +179,7 @@ gb_file_search_provider_build_cb (GObject *object,
g_set_object (&self->index, index);
}
-static GtkWidget *
-gb_file_search_provider_create_row (IdeSearchProvider *provider,
- IdeSearchResult *result)
-{
- g_assert (IDE_IS_SEARCH_PROVIDER (provider));
- g_assert (IDE_IS_SEARCH_RESULT (result));
-
- return g_object_new (IDE_TYPE_OMNI_SEARCH_ROW,
- "icon-name", "text-x-generic-symbolic",
- "result", result,
- "visible", TRUE,
- NULL);
-}
-
+#if 0
static void
gb_file_search_provider_activate (IdeSearchProvider *provider,
GtkWidget *row,
@@ -218,12 +217,7 @@ gb_file_search_provider_activate (IdeSearchProvider *provider,
NULL);
}
}
-
-static gint
-gb_file_search_provider_get_priority (IdeSearchProvider *provider)
-{
- return 0;
-}
+#endif
static void
gb_file_search_provider_vcs_changed_cb (GbFileSearchProvider *self,
@@ -342,11 +336,8 @@ gb_file_search_provider_init (GbFileSearchProvider *self)
static void
search_provider_iface_init (IdeSearchProviderInterface *iface)
{
- iface->populate = gb_file_search_provider_populate;
- iface->get_verb = gb_file_search_provider_get_verb;
- iface->create_row = gb_file_search_provider_create_row;
- iface->activate = gb_file_search_provider_activate;
- iface->get_priority = gb_file_search_provider_get_priority;
+ iface->search_async = gb_file_search_provider_search_async;
+ iface->search_finish = gb_file_search_provider_search_finish;
}
void
diff --git a/plugins/file-search/gb-file-search-result.c b/plugins/file-search/gb-file-search-result.c
index 986d034..0cde0e0 100644
--- a/plugins/file-search/gb-file-search-result.c
+++ b/plugins/file-search/gb-file-search-result.c
@@ -22,26 +22,49 @@
struct _GbFileSearchResult
{
- IdeSearchResult parent_instance;
- gchar *path;
+ IdeSearchResult parent_instance;
+
+ IdeContext *context;
+ gchar *path;
};
G_DEFINE_TYPE (GbFileSearchResult, gb_file_search_result, IDE_TYPE_SEARCH_RESULT)
enum {
PROP_0,
+ PROP_CONTEXT,
PROP_PATH,
LAST_PROP
};
static GParamSpec *properties [LAST_PROP];
+static IdeSourceLocation *
+gb_file_search_result_get_source_location (IdeSearchResult *result)
+{
+ GbFileSearchResult *self = (GbFileSearchResult *)result;
+ g_autoptr(GFile) file = NULL;
+ g_autoptr(IdeFile) ifile = NULL;
+ IdeVcs *vcs;
+ GFile *workdir;
+
+ g_return_val_if_fail (GB_IS_FILE_SEARCH_RESULT (self), NULL);
+
+ vcs = ide_context_get_vcs (self->context);
+ workdir = ide_vcs_get_working_directory (vcs);
+ file = g_file_get_child (workdir, self->path);
+ ifile = ide_file_new (self->context, file);
+
+ return ide_source_location_new (ifile, 0, 0, 0);
+}
+
static void
gb_file_search_result_finalize (GObject *object)
{
GbFileSearchResult *self = (GbFileSearchResult *)object;
- g_free (self->path);
+ ide_clear_weak_pointer (&self->context);
+ g_clear_pointer (&self->path, g_free);
G_OBJECT_CLASS (gb_file_search_result_parent_class)->finalize (object);
}
@@ -75,6 +98,10 @@ gb_file_search_result_set_property (GObject *object,
switch (prop_id)
{
+ case PROP_CONTEXT:
+ ide_set_weak_pointer (&self->context, g_value_get_object (value));
+ break;
+
case PROP_PATH:
self->path = g_value_dup_string (value);
break;
@@ -88,11 +115,21 @@ static void
gb_file_search_result_class_init (GbFileSearchResultClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ IdeSearchResultClass *result_class = IDE_SEARCH_RESULT_CLASS (klass);
object_class->finalize = gb_file_search_result_finalize;
object_class->get_property = gb_file_search_result_get_property;
object_class->set_property = gb_file_search_result_set_property;
+ result_class->get_source_location = gb_file_search_result_get_source_location;
+
+ properties [PROP_CONTEXT] =
+ g_param_spec_object ("context",
+ "Context",
+ "The context for the result",
+ IDE_TYPE_CONTEXT,
+ (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
properties [PROP_PATH] =
g_param_spec_string ("path",
"Path",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]