[gnome-calendar] shell-search: initial impl of get_search_result and get_result_metas



commit f3e97aa3bd155ee7f0d0e579bafad697c01dd421
Author: Erick Pérez Castellanos <erick red gmail com>
Date:   Wed Feb 4 12:55:44 2015 -0500

    shell-search: initial impl of get_search_result and get_result_metas
    
    This code is missing the handling of :activate-result and :launch-search
    We are not ranking and sorting the results yet, that need a bit more of tinkering

 src/gcal-shell-search-provider.c |  304 ++++++++++++++++++++++++++++++++------
 src/gcal-shell-search-provider.h |    4 +
 2 files changed, 259 insertions(+), 49 deletions(-)
---
diff --git a/src/gcal-shell-search-provider.c b/src/gcal-shell-search-provider.c
index 8185758..df737d6 100644
--- a/src/gcal-shell-search-provider.c
+++ b/src/gcal-shell-search-provider.c
@@ -18,13 +18,18 @@
 
 #include "gcal-shell-search-provider.h"
 #include "gcal-shell-search-provider-generated.h"
-#include "gcal-manager.h"
+
+#include "gcal-utils.h"
 
 typedef struct
 {
-  GcalShellSearchProvider2 *skeleton;
+  GcalShellSearchProvider2 *skel;
+  GcalManager              *manager;
+
+  GDBusMethodInvocation    *search_invocation; /* current */
+  gchar                    *search_query;
 
-  gboolean                  searching;
+  GHashTable               *events;
 } GcalShellSearchProviderPrivate;
 
 struct _GcalShellSearchProvider
@@ -41,90 +46,285 @@ G_DEFINE_TYPE_WITH_CODE (GcalShellSearchProvider, gcal_shell_search_provider, G_
                          G_ADD_PRIVATE (GcalShellSearchProvider)
                          G_IMPLEMENT_INTERFACE (E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, 
gcal_subscriber_interface_init));
 
+static void
+free_event_data (gpointer data)
+{
+  GcalEventData *event_data = data;
+  g_object_unref (event_data->event_component);
+  g_free (event_data);
+}
+
+static void
+execute_search (GcalShellSearchProvider *search_provider,
+                GDBusMethodInvocation   *invocation,
+                gchar                  **terms)
+{
+  GcalShellSearchProviderPrivate *priv;
+
+  guint i;
+  gchar *search_query;
+
+  icaltimetype date;
+  icaltimezone *zone;
+  time_t range_start, range_end;
+
+  priv = search_provider->priv;
+
+  /* don't attempt searches for a single character */
+  if (g_strv_length (terms) == 1 && g_utf8_strlen (terms[0], -1) == 1)
+    {
+      g_dbus_method_invocation_return_value (invocation, g_variant_new ("(as)", NULL));
+      return;
+    }
+
+  /* FIXME: handle hold/release */
+  //g_application_hold (g_application_get_default ());
+
+  priv->search_invocation = g_object_ref (invocation);
+
+  zone = gcal_manager_get_system_timezone (priv->manager);
+  date = icaltime_current_time_with_zone (zone);
+  icaltime_adjust (&date, -7, 0, 0, 0); /* -1 weeks from today */
+  range_start = icaltime_as_timet_with_zone (date, zone);
+
+  icaltime_adjust (&date, 21 * 2, 0, 0, 0); /* +3 weeks from today */
+  range_end = icaltime_as_timet_with_zone (date, zone);
+
+  gcal_manager_set_shell_search_subscriber (priv->manager, E_CAL_DATA_MODEL_SUBSCRIBER (search_provider),
+                                            range_start, range_end);
+
+  /* FIXME: terms */
+  search_query = g_strdup_printf ("(or (contains? \"summary\" \"%s\") (contains? \"description\" \"%s\"))",
+                                  terms[0], terms[0]);
+  for (i = 1; i < g_strv_length (terms); i++)
+    {
+      gchar *complete_query;
+      gchar *second_query = g_strdup_printf ("(or (contains? \"summary\" \"%s\") (contains? \"description\" 
\"%s\"))",
+                                             terms[0], terms[0]);
+      complete_query = g_strdup_printf ("(and %s %s)", search_query, second_query);
+
+      g_free (second_query);
+      g_free (search_query);
+
+      search_query = complete_query;
+    }
+
+  g_free (priv->search_query);
+  priv->search_query = search_query;
+  gcal_manager_set_shell_search_query (priv->manager,  search_query);
+}
+
 static gboolean
-get_initial_result_set_cb (GcalShellSearchProvider2 *skeleton,
+get_initial_result_set_cb (GcalShellSearchProvider  *search_provider,
                            GDBusMethodInvocation    *invocation,
                            gchar                   **terms,
-                           gpointer                  user_data)
+                           GcalShellSearchProvider2 *skel)
 {
-  gchar *strv;
-
-  strv = g_strjoinv (", ", terms);
-  g_debug ("will search: %s", strv);
-
-  g_free (strv);
+  execute_search (search_provider, invocation, terms);
   return TRUE;
 }
 
 static gboolean
-get_subsearch_result_set_cb (GcalShellSearchProvider2 *skeleton,
+get_subsearch_result_set_cb (GcalShellSearchProvider  *search_provider,
                              GDBusMethodInvocation    *invocation,
                              gchar                   **previous_results,
                              gchar                   **terms,
-                             gpointer                  user_data)
+                             GcalShellSearchProvider2 *skel)
 {
-  gchar *strv;
-
-  strv = g_strjoinv (", ", terms);
-  g_debug ("will subsearch: %s", strv);
-
-  g_free (strv);
+  execute_search (search_provider, invocation, terms);
   return TRUE;
 }
 
 static gboolean
-get_result_metas_cb (GcalShellSearchProvider2 *skeleton,
+get_result_metas_cb (GcalShellSearchProvider  *search_provider,
                      GDBusMethodInvocation    *invocation,
                      gchar                   **results,
-                     gpointer                  user_data)
+                     GcalShellSearchProvider2 *skel)
 {
-  gchar *strv;
-
-  strv = g_strjoinv (", ", results);
-  g_debug ("Get result metas: %s", strv);
+  GcalShellSearchProviderPrivate *priv;
+  gint i;
+  gchar *uuid, *desc, *str;
+  gchar start_date [64];
+  ECalComponentText summary;
+  ECalComponentDateTime dtstart;
+  struct tm tm_date;
+  GdkRGBA color;
+  GVariantBuilder abuilder, builder;
+  GcalEventData *data;
+  GdkPixbuf *gicon;
+
+  priv = search_provider->priv;
+
+  g_variant_builder_init (&abuilder, G_VARIANT_TYPE ("aa{sv}"));
+  for (i = 0; i < g_strv_length (results); i++)
+    {
+      uuid = results[i];
+      data = g_hash_table_lookup (priv->events, uuid);
+
+      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+      g_variant_builder_add (&builder, "{sv}", "id", g_variant_new_string (uuid));
+
+      e_cal_component_get_summary (data->event_component, &summary);
+      g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string (summary.value));
+
+      gdk_rgba_parse (&color, get_color_name_from_source (data->source));
+      gicon = get_circle_pixbuf_from_color (&color, 128);
+      g_variant_builder_add (&builder, "{sv}", "icon", g_icon_serialize (G_ICON (gicon)));
+      g_object_unref (gicon);
+
+      str = get_desc_from_component (data->event_component, "\n");
+      if (str != NULL)
+        {
+          gchar *end = g_utf8_strchr (g_strstrip (str), -1, '\n');
+          if (end == NULL)
+            desc = g_strdup (str);
+          else
+            desc = g_utf8_substring (str, 0, end - str);
+          g_free (str);
+        }
+      else
+        {
+          const gchar *location;
+          e_cal_component_get_location (data->event_component, &location);
+          if (location != NULL)
+            desc = g_strdup (location);
+          else
+            desc = e_source_dup_display_name (data->source);
+        }
+
+      e_cal_component_get_dtstart (data->event_component, &dtstart);
+      tm_date = icaltimetype_to_tm (dtstart.value);
+      /* FIXME: respect 24h time format */
+      e_utf8_strftime_fix_am_pm (start_date, 64, (dtstart.value->is_date == 1) ? "%x" : "%c", &tm_date);
+      e_cal_component_free_datetime (&dtstart);
+
+      str = desc;
+      desc = g_strconcat (start_date, ". ", str, NULL);
+      g_variant_builder_add (&builder, "{sv}", "description", g_variant_new_string (desc));
+      g_variant_builder_add_value (&abuilder, g_variant_builder_end (&builder));
+
+      g_free (desc);
+      g_free (str);
+    }
+  g_dbus_method_invocation_return_value (invocation, g_variant_new ("(aa{sv})", &abuilder));
 
-  g_free (strv);
   return TRUE;
 }
 
 static gboolean
-activate_result_cb (GcalShellSearchProvider2 *skeleton,
+activate_result_cb (GcalShellSearchProvider  *search_provider,
                     GDBusMethodInvocation    *invocation,
                     gchar                    *result,
                     gchar                   **terms,
                     guint32                   timestamp,
-                    gpointer                  user_data)
+                    GcalShellSearchProvider2 *skel)
 {
   return TRUE;
 }
 
 static gboolean
-launch_search_cb (GcalShellSearchProvider2 *skeleton,
+launch_search_cb (GcalShellSearchProvider  *search_provider,
                   GDBusMethodInvocation    *invocation,
                   gchar                   **terms,
                   guint32                   timestamp,
-                  gpointer                  user_data)
+                  GcalShellSearchProvider2 *skel)
 {
   return TRUE;
 }
 
 static void
+query_completed_cb (GcalShellSearchProvider *search_provider,
+                    GcalManager             *manager)
+{
+  GcalShellSearchProviderPrivate *priv = search_provider->priv;
+  GList *events, *l;
+  GVariantBuilder builder;
+
+  GcalEventData *data;
+  gchar *uuid;
+
+  if (!gcal_manager_load_completed (priv->manager))
+    return;
+
+  g_hash_table_remove_all (priv->events);
+
+  events = gcal_manager_get_shell_search_events (priv->manager);
+  if (events == NULL)
+    {
+      g_dbus_method_invocation_return_value (priv->search_invocation, g_variant_new ("(as)", NULL));
+      g_object_unref (priv->search_invocation);
+      return;
+    }
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+  /* FIXME: add sorting and ranking */
+  //events = g_list_sort (events, search_compare_func);
+  for (l = events; l != NULL; l = g_list_next (l))
+    {
+      data = l->data;
+      uuid = get_uuid_from_component (data->source, data->event_component);
+
+      g_variant_builder_add (&builder, "s", uuid);
+
+      g_hash_table_insert (priv->events, uuid, data);
+    }
+
+  /* FIXME: handle hold/release
+  if (events != NULL)
+    g_application_release (g_application_get_default ());*/
+
+  g_dbus_method_invocation_return_value (priv->search_invocation, g_variant_new ("(as)", &builder));
+
+  g_list_free (events);
+  g_object_unref (priv->search_invocation);
+}
+
+static void
+gcal_shell_search_provider_component_changed (ECalDataModelSubscriber *subscriber,
+                                              ECalClient              *client,
+                                              ECalComponent           *comp)
+{
+  ;
+}
+
+static void
+gcal_shell_search_provider_component_removed (ECalDataModelSubscriber *subscriber,
+                                              ECalClient              *client,
+                                              const gchar             *uid,
+                                              const gchar             *rid)
+{
+  ;
+}
+
+static void
+gcal_shell_search_provider_freeze (ECalDataModelSubscriber *subscriber)
+{
+  ;
+}
+
+static void
+gcal_shell_search_provider_thaw (ECalDataModelSubscriber *subscriber)
+{
+  ;
+}
+
+static void
 gcal_shell_search_provider_finalize (GObject *object)
 {
   GcalShellSearchProviderPrivate *priv = GCAL_SHELL_SEARCH_PROVIDER (object)->priv;
 
-  g_clear_object (&priv->skeleton);
+  g_clear_object (&priv->skel);
   G_OBJECT_CLASS (gcal_shell_search_provider_parent_class)->finalize (object);
 }
 
 static void
 gcal_subscriber_interface_init (ECalDataModelSubscriberInterface *iface)
 {
-  iface->component_added = NULL; //gcal_shell_search_provider_component_changed;
-  iface->component_modified = NULL; //gcal_shell_search_provider_component_changed;
-  iface->component_removed = NULL; //gcal_shell_search_provider_component_removed;
-  iface->freeze = NULL; //gcal_shell_search_provider_freeze;
-  iface->thaw = NULL; //gcal_shell_search_provider_thaw;
+  iface->component_added = gcal_shell_search_provider_component_changed;
+  iface->component_modified = gcal_shell_search_provider_component_changed;
+  iface->component_removed = gcal_shell_search_provider_component_removed;
+  iface->freeze = gcal_shell_search_provider_freeze;
+  iface->thaw = gcal_shell_search_provider_thaw;
 }
 
 static void
@@ -140,13 +340,14 @@ gcal_shell_search_provider_init (GcalShellSearchProvider *self)
 {
   GcalShellSearchProviderPrivate *priv = gcal_shell_search_provider_get_instance_private (self);
 
-  priv->skeleton = gcal_shell_search_provider2_skeleton_new ();
+  priv->events = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_event_data);
+  priv->skel = gcal_shell_search_provider2_skeleton_new ();
 
-  g_signal_connect (priv->skeleton, "handle-get-initial-result-set", G_CALLBACK (get_initial_result_set_cb), 
self);
-  g_signal_connect (priv->skeleton, "handle-get-subsearch-result-set", G_CALLBACK 
(get_subsearch_result_set_cb), self);
-  g_signal_connect (priv->skeleton, "handle-get-result-metas", G_CALLBACK (get_result_metas_cb), self);
-  g_signal_connect (priv->skeleton, "handle-activate-result", G_CALLBACK (activate_result_cb), self);
-  g_signal_connect (priv->skeleton, "handle-launch-search", G_CALLBACK (launch_search_cb), self);
+  g_signal_connect_swapped (priv->skel, "handle-get-initial-result-set", G_CALLBACK 
(get_initial_result_set_cb), self);
+  g_signal_connect_swapped (priv->skel, "handle-get-subsearch-result-set", G_CALLBACK 
(get_subsearch_result_set_cb), self);
+  g_signal_connect_swapped (priv->skel, "handle-get-result-metas", G_CALLBACK (get_result_metas_cb), self);
+  g_signal_connect_swapped (priv->skel, "handle-activate-result", G_CALLBACK (activate_result_cb), self);
+  g_signal_connect_swapped (priv->skel, "handle-launch-search", G_CALLBACK (launch_search_cb), self);
 
   self->priv = priv;
 }
@@ -165,8 +366,7 @@ gcal_shell_search_provider_dbus_export (GcalShellSearchProvider *search_provider
 {
   GcalShellSearchProviderPrivate *priv = GCAL_SHELL_SEARCH_PROVIDER (search_provider)->priv;
 
-  g_application_hold (g_application_get_default ());
-  return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->skeleton), connection, 
object_path, error);
+  return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->skel), connection, object_path, 
error);
 }
 
 void
@@ -176,10 +376,16 @@ gcal_shell_search_provider_dbus_unexport (GcalShellSearchProvider *search_provid
 {
   GcalShellSearchProviderPrivate *priv = GCAL_SHELL_SEARCH_PROVIDER (search_provider)->priv;
 
-  if (g_dbus_interface_skeleton_has_connection (G_DBUS_INTERFACE_SKELETON (priv->skeleton), connection))
-    {
-      g_application_release (g_application_get_default ());
-      g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON (priv->skeleton), 
connection);
-    }
+  if (g_dbus_interface_skeleton_has_connection (G_DBUS_INTERFACE_SKELETON (priv->skel), connection))
+    g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON (priv->skel), connection);
 }
 
+void
+gcal_shell_search_provider_connect (GcalShellSearchProvider *search_provider,
+                                    GcalManager             *manager)
+{
+  search_provider->priv->manager = manager;
+
+  gcal_manager_setup_shell_search (manager, E_CAL_DATA_MODEL_SUBSCRIBER (search_provider));
+  g_signal_connect_swapped (manager, "query-completed", G_CALLBACK (query_completed_cb), search_provider);
+}
diff --git a/src/gcal-shell-search-provider.h b/src/gcal-shell-search-provider.h
index e6f7fad..fcd6a92 100644
--- a/src/gcal-shell-search-provider.h
+++ b/src/gcal-shell-search-provider.h
@@ -22,6 +22,8 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
+#include "gcal-manager.h"
+
 G_BEGIN_DECLS
 
 #define GCAL_TYPE_SHELL_SEARCH_PROVIDER (gcal_shell_search_provider_get_type())
@@ -41,6 +43,8 @@ gboolean                 gcal_shell_search_provider_dbus_export   (GcalShellSear
 void                     gcal_shell_search_provider_dbus_unexport (GcalShellSearchProvider *search_provider,
                                                                    GDBusConnection         *connection,
                                                                    const gchar             *object_path);
+void                     gcal_shell_search_provider_connect       (GcalShellSearchProvider *search_provider,
+                                                                   GcalManager             *manager);
 
 G_END_DECLS
 


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