[gnome-builder/search: 1/3] search: import search types



commit 3ca6950d26bf8b3ec4dc008c8b9c0bb7a3d5909a
Author: Christian Hergert <christian hergert me>
Date:   Sun Dec 14 05:00:29 2014 -0800

    search: import search types

 src/gnome-builder.mk                      |   12 +
 src/resources/gnome-builder.gresource.xml |    1 +
 src/resources/ui/gb-search-display.ui     |   19 ++
 src/search/gb-search-context.c            |  313 +++++++++++++++++++++++++++++
 src/search/gb-search-context.h            |   66 ++++++
 src/search/gb-search-display.c            |  187 +++++++++++++++++
 src/search/gb-search-display.h            |   61 ++++++
 src/search/gb-search-manager.c            |  144 +++++++++++++
 src/search/gb-search-manager.h            |   63 ++++++
 src/search/gb-search-provider.c           |   69 +++++++
 src/search/gb-search-provider.h           |   51 +++++
 src/search/gb-search-result.c             |  113 +++++++++++
 src/search/gb-search-result.h             |   56 +++++
 src/search/gb-search-types.h              |   39 ++++
 14 files changed, 1194 insertions(+), 0 deletions(-)
---
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index 2f2d090..2f434df 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -153,6 +153,17 @@ libgnome_builder_la_SOURCES = \
        src/log/gb-log.h \
        src/nautilus/nautilus-floating-bar.c \
        src/nautilus/nautilus-floating-bar.h \
+       src/search/gb-search-context.c \
+       src/search/gb-search-context.h \
+       src/search/gb-search-display.c \
+       src/search/gb-search-display.h \
+       src/search/gb-search-manager.c \
+       src/search/gb-search-manager.h \
+       src/search/gb-search-provider.c \
+       src/search/gb-search-provider.h \
+       src/search/gb-search-result.c \
+       src/search/gb-search-result.h \
+       src/search/gb-search-types.h \
        src/theatrics/gb-box-theatric.c \
        src/theatrics/gb-box-theatric.h \
        src/tree/gb-tree.c \
@@ -225,6 +236,7 @@ libgnome_builder_la_CFLAGS = \
        -I$(top_srcdir)/src/preferences \
        -I$(top_srcdir)/src/resources \
        -I$(top_builddir)/src/resources \
+       -I$(top_srcdir)/src/search \
        -I$(top_srcdir)/src/snippets \
        -I$(top_srcdir)/src/tabs \
        -I$(top_srcdir)/src/tree \
diff --git a/src/resources/gnome-builder.gresource.xml b/src/resources/gnome-builder.gresource.xml
index 59723b9..66bf705 100644
--- a/src/resources/gnome-builder.gresource.xml
+++ b/src/resources/gnome-builder.gresource.xml
@@ -33,6 +33,7 @@
     <file>ui/gb-preferences-page-editor.ui</file>
     <file>ui/gb-preferences-page-git.ui</file>
     <file>ui/gb-preferences-page-language.ui</file>
+    <file>ui/gb-search-display.ui</file>
     <file>ui/gb-workbench.ui</file>
   </gresource>
 </gresources>
diff --git a/src/resources/ui/gb-search-display.ui b/src/resources/ui/gb-search-display.ui
new file mode 100644
index 0000000..a109773
--- /dev/null
+++ b/src/resources/ui/gb-search-display.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.14 -->
+  <template class="GbSearchDisplay" parent="GtkBin">
+    <property name="border_width">10</property>
+    <property name="width_request">800</property>
+    <property name="height_request">600</property>
+    <child>
+      <object class="GtkScrolledWindow" id="scroller">
+        <property name="visible">true</property>
+        <child>
+          <object class="GtkListBox" id="list_box">
+            <property name="visible">true</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/search/gb-search-context.c b/src/search/gb-search-context.c
new file mode 100644
index 0000000..ad3712f
--- /dev/null
+++ b/src/search/gb-search-context.c
@@ -0,0 +1,313 @@
+/* gb-search-context.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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 "search-context"
+
+#include <glib/gi18n.h>
+
+#include "gb-log.h"
+#include "gb-search-context.h"
+#include "gb-search-provider.h"
+#include "gb-search-result.h"
+
+struct _GbSearchContextPrivate
+{
+  GCancellable *cancellable;
+  GList        *providers;
+  gchar        *search_text;
+  GList        *results;
+  guint         executed : 1;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GbSearchContext, gb_search_context, G_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  PROP_PROVIDERS,
+  PROP_SEARCH_TEXT,
+  LAST_PROP
+};
+
+enum {
+  RESULTS_ADDED,
+  LAST_SIGNAL
+};
+
+static guint       gSignals [LAST_SIGNAL];
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * gb_search_context_new:
+ * @providers: (element-type GbSearchProvider*) (transfer none): A #GList
+ *
+ * Creates a new search context with the provided search providers.
+ *
+ * Returns: (transfer full): A newly allocated #GbSearchContext.
+ */
+GbSearchContext *
+gb_search_context_new (const GList *providers,
+                       const gchar *search_text)
+{
+  return g_object_new (GB_TYPE_SEARCH_CONTEXT,
+                       "providers", providers,
+                       "search-text", search_text,
+                       NULL);
+}
+
+void
+gb_search_context_execute (GbSearchContext *context)
+{
+  GbSearchContextPrivate *priv;
+  GList *iter;
+
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+
+  priv = context->priv;
+
+  if (priv->executed)
+    {
+      g_warning ("GbSearchContext has already been executed.");
+      return;
+    }
+
+  priv->executed = 1;
+
+  for (iter = priv->providers; iter; iter = iter->next)
+    gb_search_provider_populate (iter->data, context, priv->cancellable);
+}
+
+/**
+ * gb_search_context_get_cancellable:
+ * @context: A #GbSearchContext
+ *
+ * Retrieves the cancellable to cancel the search request. If the search has
+ * completed, this will return NULL.
+ *
+ * Returns: (transfer none): A #GCancellable or %NULL.
+ */
+GCancellable *
+gb_search_context_get_cancellable (GbSearchContext *context)
+{
+  g_return_val_if_fail (GB_IS_SEARCH_CONTEXT (context), NULL);
+
+  return context->priv->cancellable;
+}
+
+void
+gb_search_context_cancel (GbSearchContext *context)
+{
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+
+  g_cancellable_cancel (context->priv->cancellable);
+}
+
+/**
+ * gb_search_context_get_results:
+ * @context: A #GbSearchContext
+ *
+ * Fetches the current results.
+ *
+ * Returns: (transfer none): A #GList of current results.
+ */
+const GList *
+gb_search_context_get_results (GbSearchContext *context)
+{
+  g_return_val_if_fail (GB_IS_SEARCH_CONTEXT (context), NULL);
+
+  return context->priv->results;
+}
+
+static void
+gb_search_context_results_added (GbSearchContext  *context,
+                                 GbSearchProvider *provider,
+                                 GList            *results,
+                                 gboolean          finished)
+{
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+  g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
+
+  context->priv->results = g_list_concat (context->priv->results, results);
+}
+
+void
+gb_search_context_add_results (GbSearchContext  *context,
+                               GbSearchProvider *provider,
+                               GList            *proposals,
+                               gboolean          finished)
+{
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+  g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
+
+  g_signal_emit (context, gSignals [RESULTS_ADDED], 0,
+                 provider, proposals, finished);
+
+}
+
+const gchar *
+gb_search_context_get_search_text (GbSearchContext *context)
+{
+  g_return_val_if_fail (GB_IS_SEARCH_CONTEXT (context), NULL);
+
+  return context->priv->search_text;
+}
+
+static void
+gb_search_context_set_search_text (GbSearchContext *context,
+                                   const gchar     *search_text)
+{
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+  g_return_if_fail (search_text);
+
+  if (search_text != context->priv->search_text)
+    {
+      g_free (context->priv->search_text);
+      context->priv->search_text = g_strdup (search_text);
+      g_object_notify_by_pspec (G_OBJECT (context),
+                                gParamSpecs [PROP_SEARCH_TEXT]);
+    }
+}
+
+static void
+gb_search_context_set_providers (GbSearchContext *context,
+                                 const GList     *providers)
+{
+  GbSearchContextPrivate *priv;
+
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+
+  priv = context->priv;
+
+  g_list_foreach (priv->providers, (GFunc)g_object_unref, NULL);
+  g_list_free (priv->providers);
+
+  priv->providers = g_list_copy ((GList *)providers);
+  g_list_foreach (priv->providers, (GFunc)g_object_ref, NULL);
+}
+
+static void
+gb_search_context_finalize (GObject *object)
+{
+  GbSearchContextPrivate *priv = GB_SEARCH_CONTEXT (object)->priv;
+
+  g_list_foreach (priv->providers, (GFunc)g_object_unref, NULL);
+  g_clear_pointer (&priv->providers, g_list_free);
+
+  g_list_foreach (priv->results, (GFunc)g_object_unref, NULL);
+  g_clear_pointer (&priv->results, g_list_free);
+
+  g_clear_pointer (&priv->search_text, g_free);
+
+  G_OBJECT_CLASS (gb_search_context_parent_class)->finalize (object);
+}
+
+static void
+gb_search_context_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  GbSearchContext *self = GB_SEARCH_CONTEXT (object);
+
+  switch (prop_id)
+    {
+    case PROP_SEARCH_TEXT:
+      g_value_set_string (value, gb_search_context_get_search_text (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_search_context_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  GbSearchContext *self = GB_SEARCH_CONTEXT (object);
+
+  switch (prop_id)
+    {
+    case PROP_PROVIDERS:
+      gb_search_context_set_providers (self, g_value_get_pointer (value));
+      break;
+
+    case PROP_SEARCH_TEXT:
+      gb_search_context_set_search_text (self, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_search_context_class_init (GbSearchContextClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gb_search_context_finalize;
+  object_class->get_property = gb_search_context_get_property;
+  object_class->set_property = gb_search_context_set_property;
+
+  klass->results_added = gb_search_context_results_added;
+
+  gParamSpecs [PROP_SEARCH_TEXT] =
+    g_param_spec_string ("search-text",
+                         _("Search Text"),
+                         _("The search text for the context."),
+                         NULL,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_SEARCH_TEXT,
+                                   gParamSpecs [PROP_SEARCH_TEXT]);
+
+  gParamSpecs [PROP_PROVIDERS] =
+    g_param_spec_pointer ("providers",
+                          _("Providers"),
+                          _("The providers for the search context."),
+                          (G_PARAM_READABLE |
+                           G_PARAM_CONSTRUCT_ONLY |
+                           G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_PROVIDERS,
+                                   gParamSpecs [PROP_PROVIDERS]);
+
+  gSignals [RESULTS_ADDED] =
+    g_signal_new ("results-added",
+                  GB_TYPE_SEARCH_CONTEXT,
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL,
+                  NULL,
+                  g_cclosure_marshal_generic,
+                  G_TYPE_NONE,
+                  3,
+                  GB_TYPE_SEARCH_PROVIDER,
+                  G_TYPE_POINTER,
+                  G_TYPE_BOOLEAN);
+}
+
+static void
+gb_search_context_init (GbSearchContext *self)
+{
+  ENTRY;
+  self->priv = gb_search_context_get_instance_private (self);
+  EXIT;
+}
diff --git a/src/search/gb-search-context.h b/src/search/gb-search-context.h
new file mode 100644
index 0000000..94bb03b
--- /dev/null
+++ b/src/search/gb-search-context.h
@@ -0,0 +1,66 @@
+/* gb-search-context.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef GB_SEARCH_CONTEXT_H
+#define GB_SEARCH_CONTEXT_H
+
+#include <gio/gio.h>
+
+#include "gb-search-types.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_SEARCH_CONTEXT            (gb_search_context_get_type())
+#define GB_SEARCH_CONTEXT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_CONTEXT, 
GbSearchContext))
+#define GB_SEARCH_CONTEXT_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_CONTEXT, 
GbSearchContext const))
+#define GB_SEARCH_CONTEXT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GB_TYPE_SEARCH_CONTEXT, 
GbSearchContextClass))
+#define GB_IS_SEARCH_CONTEXT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_SEARCH_CONTEXT))
+#define GB_IS_SEARCH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GB_TYPE_SEARCH_CONTEXT))
+#define GB_SEARCH_CONTEXT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GB_TYPE_SEARCH_CONTEXT, 
GbSearchContextClass))
+
+struct _GbSearchContext
+{
+  GObject parent;
+
+  /*< private >*/
+  GbSearchContextPrivate *priv;
+};
+
+struct _GbSearchContextClass
+{
+  GObjectClass parent;
+
+  void (*results_added) (GbSearchContext  *context,
+                         GbSearchProvider *provider,
+                         GList            *results,
+                         gboolean          finished);
+};
+
+GType            gb_search_context_get_type    (void);
+GbSearchContext *gb_search_context_new         (const GList      *providers,
+                                                const gchar      *search_text);
+void             gb_search_context_cancel      (GbSearchContext  *context);
+void             gb_search_context_add_results (GbSearchContext  *context,
+                                                GbSearchProvider *provider,
+                                                GList            *results,
+                                                gboolean          finished);
+void             gb_search_context_execute     (GbSearchContext  *context);
+
+G_END_DECLS
+
+#endif /* GB_SEARCH_CONTEXT_H */
diff --git a/src/search/gb-search-display.c b/src/search/gb-search-display.c
new file mode 100644
index 0000000..535f39a
--- /dev/null
+++ b/src/search/gb-search-display.c
@@ -0,0 +1,187 @@
+/* gb-search-display.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "gb-search-display.h"
+#include "gb-search-provider.h"
+
+struct _GbSearchDisplayPrivate
+{
+  /* References owned by widget */
+  GbSearchContext *context;
+
+  /* References owned by Gtk template */
+  GtkListBox      *list_box;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GbSearchDisplay, gb_search_display, GTK_TYPE_BIN)
+
+enum {
+  PROP_0,
+  PROP_CONTEXT,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+GtkWidget *
+gb_search_display_new (void)
+{
+  return g_object_new (GB_TYPE_SEARCH_DISPLAY, NULL);
+}
+
+static void
+gb_search_display_results_added (GbSearchDisplay  *display,
+                                 GbSearchProvider *provider,
+                                 GList            *results,
+                                 gboolean          finished)
+{
+  GList *iter;
+
+  g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
+  g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
+
+  for (iter = results; iter; iter = iter->next)
+    gtk_list_box_insert (display->priv->list_box, iter->data, -1);
+
+  gtk_list_box_invalidate_sort (display->priv->list_box);
+}
+
+static void
+gb_search_display_connect (GbSearchDisplay *display,
+                           GbSearchContext *context)
+{
+  g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+
+  g_signal_connect_object (context,
+                           "results-added",
+                           G_CALLBACK (gb_search_display_results_added),
+                           display,
+                           G_CONNECT_SWAPPED);
+}
+
+static void
+gb_search_display_disconnect (GbSearchDisplay *display,
+                              GbSearchContext *context)
+{
+  g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+
+  g_signal_handlers_disconnect_by_func (context,
+                                        G_CALLBACK (gb_search_display_results_added),
+                                        display);
+}
+
+void
+gb_search_display_set_context (GbSearchDisplay *display,
+                               GbSearchContext *context)
+{
+  g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
+  g_return_if_fail (!context || GB_IS_SEARCH_CONTEXT (context));
+
+  if (display->priv->context != context)
+    {
+      if (display->priv->context)
+        {
+          gb_search_display_disconnect (display, context);
+          g_clear_object (&display->priv->context);
+        }
+
+      if (context)
+        {
+          display->priv->context = g_object_ref (context);
+          gb_search_display_connect (display, context);
+        }
+
+      g_object_notify_by_pspec (G_OBJECT (display),
+                                gParamSpecs [PROP_CONTEXT]);
+    }
+}
+
+static void
+gb_search_display_finalize (GObject *object)
+{
+  GbSearchDisplayPrivate *priv = GB_SEARCH_DISPLAY (object)->priv;
+
+  g_clear_object (&priv->context);
+
+  G_OBJECT_CLASS (gb_search_display_parent_class)->finalize (object);
+}
+
+static void
+gb_search_display_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  GbSearchDisplay *self = GB_SEARCH_DISPLAY (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      g_value_set_object (value, self->priv->context);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_search_display_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  GbSearchDisplay *self = GB_SEARCH_DISPLAY (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      gb_search_display_set_context (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_search_display_class_init (GbSearchDisplayClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = gb_search_display_finalize;
+  object_class->get_property = gb_search_display_get_property;
+  object_class->set_property = gb_search_display_set_property;
+
+  gtk_widget_class_set_template_from_resource (widget_class,
+                                               "/org/gnome/builder/ui/gb-search-display.ui");
+  gtk_widget_class_bind_template_child_private (widget_class, GbSearchDisplay, list_box);
+}
+
+static void
+gb_search_display_init (GbSearchDisplay *self)
+{
+  self->priv = gb_search_display_get_instance_private (self);
+
+  gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/src/search/gb-search-display.h b/src/search/gb-search-display.h
new file mode 100644
index 0000000..7bd9675
--- /dev/null
+++ b/src/search/gb-search-display.h
@@ -0,0 +1,61 @@
+/* gb-search-display.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef GB_SEARCH_DISPLAY_H
+#define GB_SEARCH_DISPLAY_H
+
+#include <gtk/gtk.h>
+
+#include "gb-search-types.h"
+#include "gb-search-context.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_SEARCH_DISPLAY            (gb_search_display_get_type())
+#define GB_SEARCH_DISPLAY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_DISPLAY, 
GbSearchDisplay))
+#define GB_SEARCH_DISPLAY_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_DISPLAY, 
GbSearchDisplay const))
+#define GB_SEARCH_DISPLAY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GB_TYPE_SEARCH_DISPLAY, 
GbSearchDisplayClass))
+#define GB_IS_SEARCH_DISPLAY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_SEARCH_DISPLAY))
+#define GB_IS_SEARCH_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GB_TYPE_SEARCH_DISPLAY))
+#define GB_SEARCH_DISPLAY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GB_TYPE_SEARCH_DISPLAY, 
GbSearchDisplayClass))
+
+typedef struct _GbSearchDisplay        GbSearchDisplay;
+typedef struct _GbSearchDisplayClass   GbSearchDisplayClass;
+typedef struct _GbSearchDisplayPrivate GbSearchDisplayPrivate;
+
+struct _GbSearchDisplay
+{
+  GtkBin parent;
+
+  /*< private >*/
+  GbSearchDisplayPrivate *priv;
+};
+
+struct _GbSearchDisplayClass
+{
+  GtkBinClass parent;
+};
+
+GType      gb_search_display_get_type    (void);
+GtkWidget *gb_search_display_new         (void);
+void       gb_search_display_set_context (GbSearchDisplay *display,
+                                          GbSearchContext *context);
+
+G_END_DECLS
+
+#endif /* GB_SEARCH_DISPLAY_H */
diff --git a/src/search/gb-search-manager.c b/src/search/gb-search-manager.c
new file mode 100644
index 0000000..ec2e093
--- /dev/null
+++ b/src/search/gb-search-manager.c
@@ -0,0 +1,144 @@
+/* gb-search-manager.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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 "search-manager"
+
+#include <glib/gi18n.h>
+
+#include "gb-search-context.h"
+#include "gb-search-manager.h"
+#include "gb-search-provider.h"
+
+struct _GbSearchManagerPrivate
+{
+  GList *providers;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GbSearchManager, gb_search_manager, G_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  LAST_PROP
+};
+
+//static GParamSpec *gParamSpecs [LAST_PROP];
+
+GbSearchManager *
+gb_search_manager_new (void)
+{
+  return g_object_new (GB_TYPE_SEARCH_MANAGER, NULL);
+}
+
+static gint
+sort_provider (gconstpointer a,
+               gconstpointer b)
+{
+  gint prio1;
+  gint prio2;
+
+  prio1 = gb_search_provider_get_priority ((GbSearchProvider *)a);
+  prio2 = gb_search_provider_get_priority ((GbSearchProvider *)b);
+
+  return prio1 - prio2;
+}
+
+void
+gb_search_manager_add_provider (GbSearchManager  *manager,
+                                GbSearchProvider *provider)
+{
+  g_return_if_fail (GB_IS_SEARCH_MANAGER (manager));
+  g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
+
+  manager->priv->providers =
+    g_list_sort (g_list_prepend (manager->priv->providers,
+                                 g_object_ref (provider)),
+                 sort_provider);
+}
+
+GbSearchContext *
+gb_search_manager_search (GbSearchManager *manager,
+                          const gchar     *search_text)
+{
+  GbSearchContext *context;
+
+  g_return_val_if_fail (GB_IS_SEARCH_MANAGER (manager), NULL);
+  g_return_val_if_fail (search_text, NULL);
+
+  context = gb_search_context_new (manager->priv->providers, search_text);
+
+  gb_search_context_execute (context);
+
+  return context;
+}
+
+static void
+gb_search_manager_finalize (GObject *object)
+{
+  GbSearchManagerPrivate *priv = GB_SEARCH_MANAGER (object)->priv;
+
+  g_list_foreach (priv->providers, (GFunc)g_object_unref, NULL);
+  g_clear_pointer (&priv->providers, g_list_free);
+
+  G_OBJECT_CLASS (gb_search_manager_parent_class)->finalize (object);
+}
+
+static void
+gb_search_manager_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  //GbSearchManager *self = GB_SEARCH_MANAGER (object);
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_search_manager_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  //GbSearchManager *self = GB_SEARCH_MANAGER (object);
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_search_manager_class_init (GbSearchManagerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gb_search_manager_finalize;
+  object_class->get_property = gb_search_manager_get_property;
+  object_class->set_property = gb_search_manager_set_property;
+}
+
+static void
+gb_search_manager_init (GbSearchManager *self)
+{
+  self->priv = gb_search_manager_get_instance_private (self);
+}
diff --git a/src/search/gb-search-manager.h b/src/search/gb-search-manager.h
new file mode 100644
index 0000000..5c862fe
--- /dev/null
+++ b/src/search/gb-search-manager.h
@@ -0,0 +1,63 @@
+/* gb-search-manager.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef GB_SEARCH_MANAGER_H
+#define GB_SEARCH_MANAGER_H
+
+#include <gio/gio.h>
+
+#include "gb-search-types.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_SEARCH_MANAGER            (gb_search_manager_get_type())
+#define GB_SEARCH_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_MANAGER, 
GbSearchManager))
+#define GB_SEARCH_MANAGER_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_MANAGER, 
GbSearchManager const))
+#define GB_SEARCH_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GB_TYPE_SEARCH_MANAGER, 
GbSearchManagerClass))
+#define GB_IS_SEARCH_MANAGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_SEARCH_MANAGER))
+#define GB_IS_SEARCH_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GB_TYPE_SEARCH_MANAGER))
+#define GB_SEARCH_MANAGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GB_TYPE_SEARCH_MANAGER, 
GbSearchManagerClass))
+
+typedef struct _GbSearchManager        GbSearchManager;
+typedef struct _GbSearchManagerClass   GbSearchManagerClass;
+typedef struct _GbSearchManagerPrivate GbSearchManagerPrivate;
+
+struct _GbSearchManager
+{
+  GObject parent;
+
+  /*< private >*/
+  GbSearchManagerPrivate *priv;
+};
+
+struct _GbSearchManagerClass
+{
+  GObjectClass parent;
+};
+
+GType            gb_search_manager_get_type     (void);
+GbSearchManager *gb_search_manager_new          (void);
+GbSearchManager *gb_search_manager_get_default  (void);
+void             gb_search_manager_add_provider (GbSearchManager  *manager,
+                                                 GbSearchProvider *provider);
+GbSearchContext *gb_search_manager_search       (GbSearchManager  *manager,
+                                                 const gchar      *search_text);
+
+G_END_DECLS
+
+#endif /* GB_SEARCH_MANAGER_H */
diff --git a/src/search/gb-search-provider.c b/src/search/gb-search-provider.c
new file mode 100644
index 0000000..d43cab8
--- /dev/null
+++ b/src/search/gb-search-provider.c
@@ -0,0 +1,69 @@
+/* gb-search-provider.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#include "gb-search-context.h"
+#include "gb-search-provider.h"
+
+G_DEFINE_INTERFACE (GbSearchProvider, gb_search_provider, G_TYPE_OBJECT)
+
+static void
+gb_search_provider_default_init (GbSearchProviderInterface *iface)
+{
+}
+
+/**
+ * gb_search_provider_get_priority:
+ * @provider: A #GbSearchProvider
+ *
+ * Retrieves the priority of the search provider. Lower integral values are
+ * of higher priority.
+ *
+ * Returns: An integer.
+ */
+gint
+gb_search_provider_get_priority (GbSearchProvider *provider)
+{
+  g_return_val_if_fail (GB_IS_SEARCH_PROVIDER (provider), 0);
+
+  if (GB_SEARCH_PROVIDER_GET_INTERFACE (provider)->get_priority)
+    return GB_SEARCH_PROVIDER_GET_INTERFACE (provider)->get_priority (provider);
+  return 0;
+}
+
+/**
+ * gb_search_provider_populate:
+ * @provider: A #GbSearchProvider
+ * @context: A #GbSearchContext
+ * @cancelalble: An optional #GCancellable to cancel the request.
+ *
+ * Requests that a search provider start populating @context with results.
+ * If @cancellable is not %NULL, then it may be used to cancel the request.
+ */
+void
+gb_search_provider_populate (GbSearchProvider *provider,
+                             GbSearchContext  *context,
+                             GCancellable     *cancellable)
+{
+  g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
+  g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  if (GB_SEARCH_PROVIDER_GET_INTERFACE (provider)->populate)
+    GB_SEARCH_PROVIDER_GET_INTERFACE (provider)->populate (provider, context,
+                                                           cancellable);
+}
diff --git a/src/search/gb-search-provider.h b/src/search/gb-search-provider.h
new file mode 100644
index 0000000..f209d52
--- /dev/null
+++ b/src/search/gb-search-provider.h
@@ -0,0 +1,51 @@
+/* gb-search-provider.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef GB_SEARCH_PROVIDER_H
+#define GB_SEARCH_PROVIDER_H
+
+#include <gio/gio.h>
+
+#include "gb-search-types.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_SEARCH_PROVIDER               (gb_search_provider_get_type ())
+#define GB_SEARCH_PROVIDER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj),    
GB_TYPE_SEARCH_PROVIDER, GbSearchProvider))
+#define GB_IS_SEARCH_PROVIDER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj),    
GB_TYPE_SEARCH_PROVIDER))
+#define GB_SEARCH_PROVIDER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), 
GB_TYPE_SEARCH_PROVIDER, GbSearchProviderInterface))
+
+struct _GbSearchProviderInterface
+{
+  GTypeInterface parent;
+
+  gint  (*get_priority) (GbSearchProvider *provider);
+  void  (*populate)     (GbSearchProvider *provider,
+                         GbSearchContext  *context,
+                         GCancellable     *cancellable);
+};
+
+GType gb_search_provider_get_type     (void);
+gint  gb_search_provider_get_priority (GbSearchProvider *provider);
+void  gb_search_provider_populate     (GbSearchProvider *provider,
+                                       GbSearchContext  *context,
+                                       GCancellable     *cancellable);
+
+G_END_DECLS
+
+#endif /* GB_SEARCH_PROVIDER_H */
diff --git a/src/search/gb-search-result.c b/src/search/gb-search-result.c
new file mode 100644
index 0000000..948fc28
--- /dev/null
+++ b/src/search/gb-search-result.c
@@ -0,0 +1,113 @@
+/* gb-search-result.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#include "gb-search-result.h"
+
+struct _GbSearchResultPrivate
+{
+  gint   priority;
+  gfloat score;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GbSearchResult, gb_search_result, GTK_TYPE_BIN)
+
+enum {
+  PROP_0,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+GtkWidget *
+gb_search_result_new (void)
+{
+  return g_object_new (GB_TYPE_SEARCH_RESULT, NULL);
+}
+
+gint
+gb_search_result_compare_func (gconstpointer result1,
+                               gconstpointer result2)
+{
+  const GbSearchResult *r1 = result1;
+  const GbSearchResult *r2 = result2;
+  gint ret;
+
+  ret = r1->priv->priority - r2->priv->priority;
+
+  if (ret == 0)
+    {
+      if (r1->priv->score > r2->priv->score)
+        return 1;
+      else if (r1->priv->score < r2->priv->score)
+        return -1;
+    }
+
+  return ret;
+}
+
+static void
+gb_search_result_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (gb_search_result_parent_class)->finalize (object);
+}
+
+static void
+gb_search_result_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  //GbSearchResult *self = GB_SEARCH_RESULT (object);
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_search_result_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  //GbSearchResult *self = GB_SEARCH_RESULT (object);
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_search_result_class_init (GbSearchResultClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gb_search_result_finalize;
+  object_class->get_property = gb_search_result_get_property;
+  object_class->set_property = gb_search_result_set_property;
+}
+
+static void
+gb_search_result_init (GbSearchResult *self)
+{
+  self->priv = gb_search_result_get_instance_private (self);
+}
diff --git a/src/search/gb-search-result.h b/src/search/gb-search-result.h
new file mode 100644
index 0000000..44e66bf
--- /dev/null
+++ b/src/search/gb-search-result.h
@@ -0,0 +1,56 @@
+/* gb-search-result.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef GB_SEARCH_RESULT_H
+#define GB_SEARCH_RESULT_H
+
+#include <gtk/gtk.h>
+
+#include "gb-search-types.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_SEARCH_RESULT            (gb_search_result_get_type())
+#define GB_SEARCH_RESULT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_RESULT, 
GbSearchResult))
+#define GB_SEARCH_RESULT_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_RESULT, 
GbSearchResult const))
+#define GB_SEARCH_RESULT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GB_TYPE_SEARCH_RESULT, 
GbSearchResultClass))
+#define GB_IS_SEARCH_RESULT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_SEARCH_RESULT))
+#define GB_IS_SEARCH_RESULT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GB_TYPE_SEARCH_RESULT))
+#define GB_SEARCH_RESULT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GB_TYPE_SEARCH_RESULT, 
GbSearchResultClass))
+
+struct _GbSearchResult
+{
+  GtkBin parent;
+
+  /*< private >*/
+  GbSearchResultPrivate *priv;
+};
+
+struct _GbSearchResultClass
+{
+  GtkBinClass parent;
+};
+
+GType      gb_search_result_get_type     (void);
+GtkWidget *gb_search_result_new          (void);
+gint       gb_search_result_compare_func (gconstpointer result1,
+                                          gconstpointer result2);
+
+G_END_DECLS
+
+#endif /* GB_SEARCH_RESULT_H */
diff --git a/src/search/gb-search-types.h b/src/search/gb-search-types.h
new file mode 100644
index 0000000..d6f8cd2
--- /dev/null
+++ b/src/search/gb-search-types.h
@@ -0,0 +1,39 @@
+/* gb-search-types.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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/>.
+ */
+
+#ifndef GB_SEARCH_TYPES_H
+#define GB_SEARCH_TYPES_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GbSearchContext           GbSearchContext;
+typedef struct _GbSearchContextClass      GbSearchContextClass;
+typedef struct _GbSearchContextPrivate    GbSearchContextPrivate;
+
+typedef struct _GbSearchProvider          GbSearchProvider;
+typedef struct _GbSearchProviderInterface GbSearchProviderInterface;
+
+typedef struct _GbSearchResult            GbSearchResult;
+typedef struct _GbSearchResultClass       GbSearchResultClass;
+typedef struct _GbSearchResultPrivate     GbSearchResultPrivate;
+
+G_END_DECLS
+
+#endif /* GB_SEARCH_TYPES_H */



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