From 1dd50951f6e0d487ec5b160c11d952ec1d4207fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erick=20P=C3=A9rez=20Castellanos?= Date: Sun, 1 Feb 2015 10:08:41 -0500 Subject: [PATCH] app: add shell provider implementation skeleton --- .gitignore | 2 + data/Makefile.am | 1 + .../shell-search-provider-dbus-interfaces.xml | 44 +++++ src/Makefile.am | 14 ++ src/gcal-application.c | 149 ++++++++++---- src/gcal-manager.c | 35 ++++ src/gcal-manager.h | 5 + src/gcal-shell-search-provider.c | 185 ++++++++++++++++++ src/gcal-shell-search-provider.h | 47 +++++ 9 files changed, 445 insertions(+), 37 deletions(-) create mode 100644 data/shell-search-provider-dbus-interfaces.xml create mode 100644 src/gcal-shell-search-provider.c create mode 100644 src/gcal-shell-search-provider.h diff --git a/.gitignore b/.gitignore index 1b8dea9d..727b25ec 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,8 @@ src/gcal-enum-types.c src/gcal-enum-types.h src/gcal-resources.c src/gcal-resources.h +src/gcal-shell-search-provider-generated.c +src/gcal-shell-search-provider-generated.h AUTHORS build-aux data/org.gnome.Calendar.desktop diff --git a/data/Makefile.am b/data/Makefile.am index 81e19f37..358c43ff 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -45,6 +45,7 @@ EXTRA_DIST= \ org.gnome.Calendar.search-provider.ini.in.in \ org.gnome.Calendar.desktop \ calendar.gresource.xml \ + shell-search-provider-dbus-interfaces.xml \ ui/date-selector.ui \ ui/edit-dialog.ui \ ui/menus.ui \ diff --git a/data/shell-search-provider-dbus-interfaces.xml b/data/shell-search-provider-dbus-interfaces.xml new file mode 100644 index 00000000..f6840e2c --- /dev/null +++ b/data/shell-search-provider-dbus-interfaces.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 3400e11d..61c68a4a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,7 @@ AM_CPPFLAGS = \ bin_PROGRAMS = gnome-calendar BUILT_SOURCES = \ + $(dbus_shell_search_provider_built_sources) \ gcal-resources.c \ gcal-resources.h \ gcal-enum-types.c \ @@ -26,6 +27,8 @@ gnome_calendar_SOURCES = \ css-code.h \ gcal-application.h \ gcal-application.c \ + gcal-shell-search-provider.h \ + gcal-shell-search-provider.c \ gcal-window.h \ gcal-window.c \ gcal-view.c \ @@ -76,6 +79,17 @@ gcal-enum-types.h: gcal-enum-types.h.template $(ENUM_TYPES) $(GLIB_MKENUMS) gcal-enum-types.c: gcal-enum-types.c.template $(ENUM_TYPES) $(GLIB_MKENUMS) $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template gcal-enum-types.c.template $(ENUM_TYPES)) > $@ +dbus_shell_search_provider_built_sources = \ + gcal-shell-search-provider-generated.c \ + gcal-shell-search-provider-generated.h + +$(dbus_shell_search_provider_built_sources) : Makefile.am $(top_srcdir)/data/shell-search-provider-dbus-interfaces.xml + gdbus-codegen \ + --interface-prefix org.gnome. \ + --c-namespace Gcal \ + --generate-c-code gcal-shell-search-provider-generated \ + $(top_srcdir)/data/shell-search-provider-dbus-interfaces.xml + CLEANFILES = \ $(BUILT_SOURCES) \ $(NULL) diff --git a/src/gcal-application.c b/src/gcal-application.c index 5ef6cfc0..c42628e2 100644 --- a/src/gcal-application.c +++ b/src/gcal-application.c @@ -24,6 +24,7 @@ #include "gcal-application.h" #include "css-code.h" #include "gcal-window.h" +#include "gcal-shell-search-provider.h" #include #include @@ -39,6 +40,8 @@ struct _GcalApplicationPrivate GSettings *settings; GcalManager *manager; + GcalShellSearchProvider *search_provider; + GtkCssProvider *provider; gchar **css_code_snippets; @@ -83,6 +86,15 @@ static void gcal_application_quit (GSimpleAction * GVariant *parameter, gpointer user_data); +static gboolean gcal_application_dbus_register (GApplication *application, + GDBusConnection *connection, + const gchar *object_path, + GError **error); + +static void gcal_application_dbus_unregister (GApplication *application, + GDBusConnection *connection, + const gchar *object_path); + G_DEFINE_TYPE_WITH_PRIVATE (GcalApplication, gcal_application, GTK_TYPE_APPLICATION); static gboolean show_version = FALSE; @@ -203,6 +215,9 @@ gcal_application_class_init (GcalApplicationClass *klass) application_class->activate = gcal_application_activate; application_class->startup = gcal_application_startup; application_class->command_line = gcal_application_command_line; + + application_class->dbus_register = gcal_application_dbus_register; + application_class->dbus_unregister = gcal_application_dbus_unregister; } static void @@ -212,6 +227,7 @@ gcal_application_init (GcalApplication *self) priv->settings = g_settings_new ("org.gnome.calendar"); priv->colors_provider = gtk_css_provider_new (); + priv->search_provider = gcal_shell_search_provider_new (); self->priv = priv; } @@ -221,27 +237,64 @@ gcal_application_finalize (GObject *object) { GcalApplicationPrivate *priv = GCAL_APPLICATION (object)->priv; - gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (priv->colors_provider)); - gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (priv->provider)); - - g_clear_object (&(priv->settings)); - g_clear_object (&(priv->colors_provider)); - g_clear_object (&(priv->provider)); - g_clear_object (&(priv->manager)); - if (priv->initial_date != NULL) g_free (priv->initial_date); if (priv->css_code_snippets != NULL) g_strfreev (priv->css_code_snippets); + if (priv->provider != NULL) + { + gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (priv->colors_provider)); + + gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (priv->provider)); + g_clear_object (&(priv->provider)); + } + + g_clear_object (&(priv->colors_provider)); + g_clear_object (&(priv->settings)); + + g_clear_object (&(priv->manager)); + G_OBJECT_CLASS (gcal_application_parent_class)->finalize (object); + g_clear_object (&(priv->search_provider)); } static void gcal_application_activate (GApplication *application) { - GcalApplicationPrivate *priv = GCAL_APPLICATION (application)->priv; + GcalApplicationPrivate *priv; + GFile* css_file; + GError *error; + + priv = GCAL_APPLICATION (application)->priv; + + if (priv->provider == NULL) + { + priv->provider = gtk_css_provider_new (); + gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), + GTK_STYLE_PROVIDER (priv->provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1); + + error = NULL; + css_file = g_file_new_for_uri (CSS_FILE); + gtk_css_provider_load_from_file (priv->provider, css_file, &error); + if (error != NULL) + g_warning ("Error loading stylesheet from file %s. %s", CSS_FILE, error->message); + + g_object_set (gtk_settings_get_default (), "gtk-application-prefer-dark-theme", FALSE, NULL); + + g_object_unref (css_file); + } + + if (priv->colors_provider != NULL) + { + gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), + GTK_STYLE_PROVIDER (priv->colors_provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 2); + } + + gcal_application_set_app_menu (application); if (priv->window != NULL) { @@ -273,42 +326,20 @@ static void gcal_application_startup (GApplication *app) { GcalApplicationPrivate *priv; - GFile* css_file; - GError *error; priv = GCAL_APPLICATION (app)->priv; G_APPLICATION_CLASS (gcal_application_parent_class)->startup (app); - if (priv->provider == NULL) - { - priv->provider = gtk_css_provider_new (); - gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), - GTK_STYLE_PROVIDER (priv->provider), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1); - - error = NULL; - css_file = g_file_new_for_uri (CSS_FILE); - gtk_css_provider_load_from_file (priv->provider, css_file, &error); - if (error != NULL) - g_warning ("Error loading stylesheet from file %s. %s", CSS_FILE, error->message); - - g_object_set (gtk_settings_get_default (), "gtk-application-prefer-dark-theme", FALSE, NULL); - - g_object_unref (css_file); - } - - if (priv->colors_provider != NULL) - { - gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), - GTK_STYLE_PROVIDER (priv->colors_provider), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 2); - } - priv->manager = gcal_manager_new_with_settings (priv->settings); g_signal_connect (priv->manager, "source-added", G_CALLBACK (source_added_cb), app); - gcal_application_set_app_menu (app); + /* We're assuming the application is called as a service only by the shell search system */ + if ((g_application_get_flags (app) & G_APPLICATION_IS_SERVICE) != 0) + { + g_application_set_inactivity_timeout (app, 600 * 1000); + gcal_manager_set_shell_search (priv->manager); + } } static gint @@ -368,6 +399,50 @@ gcal_application_command_line (GApplication *app, return 0; } +static gboolean +gcal_application_dbus_register (GApplication *application, + GDBusConnection *connection, + const gchar *object_path, + GError **error) +{ + GcalApplicationPrivate *priv; + gchar *search_provider_path = NULL; + gboolean ret_val = FALSE; + + priv = GCAL_APPLICATION (application)->priv; + + if (!G_APPLICATION_CLASS (gcal_application_parent_class)->dbus_register (application, connection, object_path, error)) + goto out; + + search_provider_path = g_strconcat (object_path, "/SearchProvider", NULL); + if (!gcal_shell_search_provider_dbus_export (priv->search_provider, connection, search_provider_path, error)) + goto out; + + ret_val = TRUE; + +out: + g_free (search_provider_path); + return ret_val; +} + +static void +gcal_application_dbus_unregister (GApplication *application, + GDBusConnection *connection, + const gchar *object_path) +{ + GcalApplicationPrivate *priv; + gchar *search_provider_path = NULL; + + priv = GCAL_APPLICATION (application)->priv; + + search_provider_path = g_strconcat (object_path, "/SearchProvider", NULL); + gcal_shell_search_provider_dbus_unexport (priv->search_provider, connection, search_provider_path); + + G_APPLICATION_CLASS (gcal_application_parent_class)->dbus_unregister (application, connection, object_path); + + g_free (search_provider_path); +} + static void gcal_application_set_app_menu (GApplication *app) { diff --git a/src/gcal-manager.c b/src/gcal-manager.c index 03d985e2..4cb5d5b3 100644 --- a/src/gcal-manager.c +++ b/src/gcal-manager.c @@ -48,6 +48,7 @@ typedef struct ECalDataModel *e_data_model; ECalDataModel *search_data_model; + ECalDataModel *shell_search_data_model; GCancellable *async_ops; @@ -730,6 +731,40 @@ gcal_manager_get_system_timezone (GcalManager *manager) return priv->system_timezone; } +void +gcal_manager_set_shell_search (GcalManager *manager) +{ + GcalManagerPrivate *priv; + priv = gcal_manager_get_instance_private (manager); + + if (priv->shell_search_data_model == NULL) + { + priv->shell_search_data_model = e_cal_data_model_new (submit_thread_job); + + e_cal_data_model_set_expand_recurrences (priv->shell_search_data_model, TRUE); + e_cal_data_model_set_timezone (priv->shell_search_data_model, priv->system_timezone); + } +} + +/** + * gcal_manager_set_shell_query: + * @manager: A #GcalManager instance + * @query: (nullable): query terms or %NULL + * + * Set the query terms of the #ECalDataModel or clear it if %NULL is + * passed + * + **/ +void +gcal_manager_set_shell_query (GcalManager *manager, + const gchar *query) +{ + GcalManagerPrivate *priv; + + priv = gcal_manager_get_instance_private (manager); + e_cal_data_model_set_filter (priv->shell_search_data_model, query); +} + void gcal_manager_set_subscriber (GcalManager *manager, ECalDataModelSubscriber *subscriber, diff --git a/src/gcal-manager.h b/src/gcal-manager.h index 1ecd3c6b..b0d7b225 100644 --- a/src/gcal-manager.h +++ b/src/gcal-manager.h @@ -69,6 +69,11 @@ ESource* gcal_manager_get_default_source (GcalManager *manager icaltimezone* gcal_manager_get_system_timezone (GcalManager *manager); +void gcal_manager_set_shell_search (GcalManager *manager); + +void gcal_manager_set_shell_query (GcalManager *manager, + const gchar *query); + void gcal_manager_set_subscriber (GcalManager *manager, ECalDataModelSubscriber *subscriber, time_t range_start, diff --git a/src/gcal-shell-search-provider.c b/src/gcal-shell-search-provider.c new file mode 100644 index 00000000..8185758e --- /dev/null +++ b/src/gcal-shell-search-provider.c @@ -0,0 +1,185 @@ +/* gcal-shell-search-provider.c + * + * Copyright (C) 2015 Erick Pérez Castellanos + * + * 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 . + */ + +#include "gcal-shell-search-provider.h" +#include "gcal-shell-search-provider-generated.h" +#include "gcal-manager.h" + +typedef struct +{ + GcalShellSearchProvider2 *skeleton; + + gboolean searching; +} GcalShellSearchProviderPrivate; + +struct _GcalShellSearchProvider +{ + GObject parent; + + /*< private >*/ + GcalShellSearchProviderPrivate *priv; +}; + +static void gcal_subscriber_interface_init (ECalDataModelSubscriberInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GcalShellSearchProvider, gcal_shell_search_provider, G_TYPE_OBJECT, + G_ADD_PRIVATE (GcalShellSearchProvider) + G_IMPLEMENT_INTERFACE (E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, gcal_subscriber_interface_init)); + +static gboolean +get_initial_result_set_cb (GcalShellSearchProvider2 *skeleton, + GDBusMethodInvocation *invocation, + gchar **terms, + gpointer user_data) +{ + gchar *strv; + + strv = g_strjoinv (", ", terms); + g_debug ("will search: %s", strv); + + g_free (strv); + return TRUE; +} + +static gboolean +get_subsearch_result_set_cb (GcalShellSearchProvider2 *skeleton, + GDBusMethodInvocation *invocation, + gchar **previous_results, + gchar **terms, + gpointer user_data) +{ + gchar *strv; + + strv = g_strjoinv (", ", terms); + g_debug ("will subsearch: %s", strv); + + g_free (strv); + return TRUE; +} + +static gboolean +get_result_metas_cb (GcalShellSearchProvider2 *skeleton, + GDBusMethodInvocation *invocation, + gchar **results, + gpointer user_data) +{ + gchar *strv; + + strv = g_strjoinv (", ", results); + g_debug ("Get result metas: %s", strv); + + g_free (strv); + return TRUE; +} + +static gboolean +activate_result_cb (GcalShellSearchProvider2 *skeleton, + GDBusMethodInvocation *invocation, + gchar *result, + gchar **terms, + guint32 timestamp, + gpointer user_data) +{ + return TRUE; +} + +static gboolean +launch_search_cb (GcalShellSearchProvider2 *skeleton, + GDBusMethodInvocation *invocation, + gchar **terms, + guint32 timestamp, + gpointer user_data) +{ + return TRUE; +} + +static void +gcal_shell_search_provider_finalize (GObject *object) +{ + GcalShellSearchProviderPrivate *priv = GCAL_SHELL_SEARCH_PROVIDER (object)->priv; + + g_clear_object (&priv->skeleton); + 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; +} + +static void +gcal_shell_search_provider_class_init (GcalShellSearchProviderClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gcal_shell_search_provider_finalize; +} + +static void +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 (); + + 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); + + self->priv = priv; +} + +GcalShellSearchProvider* +gcal_shell_search_provider_new (void) +{ + return g_object_new (GCAL_TYPE_SHELL_SEARCH_PROVIDER, NULL); +} + +gboolean +gcal_shell_search_provider_dbus_export (GcalShellSearchProvider *search_provider, + GDBusConnection *connection, + const gchar *object_path, + GError **error) +{ + 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); +} + +void +gcal_shell_search_provider_dbus_unexport (GcalShellSearchProvider *search_provider, + GDBusConnection *connection, + const gchar *object_path) +{ + 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); + } +} + diff --git a/src/gcal-shell-search-provider.h b/src/gcal-shell-search-provider.h new file mode 100644 index 00000000..e6f7fad2 --- /dev/null +++ b/src/gcal-shell-search-provider.h @@ -0,0 +1,47 @@ +/* gcal-shell-search-provider.h + * + * Copyright (C) 2015 Erick Pérez Castellanos + * + * 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 . + */ + +#ifndef GCAL_SHELL_SEARCH_PROVIDER_H +#define GCAL_SHELL_SEARCH_PROVIDER_H + +#include +#include + +G_BEGIN_DECLS + +#define GCAL_TYPE_SHELL_SEARCH_PROVIDER (gcal_shell_search_provider_get_type()) + +G_DECLARE_FINAL_TYPE (GcalShellSearchProvider, gcal_shell_search_provider, GCAL, SHELL_SEARCH_PROVIDER, GObject) + +struct _GcalShellSearchProviderClass +{ + GObjectClass parent; +}; + +GcalShellSearchProvider *gcal_shell_search_provider_new (void); +gboolean gcal_shell_search_provider_dbus_export (GcalShellSearchProvider *search_provider, + GDBusConnection *connection, + const gchar *object_path, + GError **error); +void gcal_shell_search_provider_dbus_unexport (GcalShellSearchProvider *search_provider, + GDBusConnection *connection, + const gchar *object_path); + +G_END_DECLS + +#endif /* GCAL_SHELL_SEARCH_PROVIDER_H */