[gnome-calculator] Add a search provider



commit 1b4180551b4cc9100b5f7408ab692a9cc43d4ac7
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Sat May 10 21:15:46 2014 -0500

    Add a search provider
    
    The search provider will display exactly one result if and only if the
    search term can be converted to an equation of the form recognized by
    GNOME Calculator. If a result is activated, Calculator will be launched
    displaying the equation.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=729518

 Makefile.am                                        |    2 +-
 configure.ac                                       |   13 ++-
 search-provider/Makefile.am                        |   34 +++++
 .../gnome-calculator-search-provider.ini           |    5 +
 .../org.gnome.Calculator.SearchProvider.service.in |    3 +
 search-provider/search-provider.vala               |  152 ++++++++++++++++++++
 6 files changed, 204 insertions(+), 5 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 582f28d..401faf0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = po src data help
+SUBDIRS = po src search-provider data help
 
 # Temporary fix for JHBuild, see https://bugzilla.gnome.org/show_bug.cgi?id=641652
 ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
diff --git a/configure.ac b/configure.ac
index 1557e27..eca6ac5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,15 +18,14 @@ dnl ###########################################################################
 dnl Dependencies
 dnl ###########################################################################
 
-GLIB_REQUIRED=2.31
-GIO_REQUIRED=2.25.10
+GLIB_REQUIRED=2.40.0
 GTK_REQUIRED=3.11.6
 GTKSOURCEVIEW_REQUIRED=3.0.0
 
 PKG_CHECK_MODULES(GNOME_CALCULATOR, [
     gtk+-3.0 >= $GTK_REQUIRED
     glib-2.0 >= $GLIB_REQUIRED
-    gio-2.0 >= $GIO_REQUIRED
+    gio-2.0 >= $GLIB_REQUIRED
     gtksourceview-3.0 >= $GTKSOURCEVIEW_REQUIRED
     libxml-2.0
     gmodule-export-2.0
@@ -34,10 +33,15 @@ PKG_CHECK_MODULES(GNOME_CALCULATOR, [
 
 PKG_CHECK_MODULES(GCALCCMD, [
     glib-2.0 >= $GLIB_REQUIRED
-    gio-2.0 >= $GIO_REQUIRED
+    gio-2.0 >= $GLIB_REQUIRED
     libxml-2.0
 ])
 
+PKG_CHECK_MODULES(SEARCH_PROVIDER, [
+    glib-2.0 >= $GLIB_REQUIRED
+    gio-2.0 >= $GLIB_REQUIRED
+])
+
 dnl ###########################################################################
 dnl Internationalization
 dnl ###########################################################################
@@ -62,6 +66,7 @@ dnl ###########################################################################
 
 AC_OUTPUT([
 Makefile
+search-provider/Makefile
 src/Makefile
 po/Makefile.in
 data/Makefile
diff --git a/search-provider/Makefile.am b/search-provider/Makefile.am
new file mode 100644
index 0000000..45cb4d4
--- /dev/null
+++ b/search-provider/Makefile.am
@@ -0,0 +1,34 @@
+libexec_PROGRAMS = gnome-calculator-search-provider
+
+gnome_calculator_search_provider_SOURCES = \
+       search-provider.vala
+
+gnome_calculator_search_provider_VALAFLAGS = \
+       --pkg posix \
+       --pkg gio-2.0
+
+gnome_calculator_search_provider_CPPFLAGS = \
+       -w \
+       $(SEARCH_PROVIDER_CFLAGS)
+
+gnome_calculator_search_provider_LDADD = \
+       $(SEARCH_PROVIDER_LIBS)
+
+searchproviderdir = $(datadir)/gnome-shell/search-providers
+searchprovider_DATA = gnome-calculator-search-provider.ini
+
+servicedir = $(datadir)/dbus-1/services
+service_DATA = $(service_in_files:.service.in=.service)
+service_in_files = org.gnome.Calculator.SearchProvider.service.in
+
+org.gnome.Calculator.SearchProvider.service: org.gnome.Calculator.SearchProvider.service.in Makefile
+       $(AM_V_GEN) sed -e "s|\ libexecdir\@|$(libexecdir)|" $< > $  tmp && mv $  tmp $@
+
+EXTRA_DIST = \
+       $(searchprovider_DATA) \
+       $(service_in_files)
+
+CLEANFILES = \
+       $(service_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/search-provider/gnome-calculator-search-provider.ini 
b/search-provider/gnome-calculator-search-provider.ini
new file mode 100644
index 0000000..d9c65ee
--- /dev/null
+++ b/search-provider/gnome-calculator-search-provider.ini
@@ -0,0 +1,5 @@
+[Shell Search Provider]
+DesktopId=gnome-calculator.desktop
+BusName=org.gnome.Calculator.SearchProvider
+ObjectPath=/org/gnome/Calculator/SearchProvider
+Version=2
diff --git a/search-provider/org.gnome.Calculator.SearchProvider.service.in 
b/search-provider/org.gnome.Calculator.SearchProvider.service.in
new file mode 100644
index 0000000..8d7c02a
--- /dev/null
+++ b/search-provider/org.gnome.Calculator.SearchProvider.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.gnome.Calculator.SearchProvider
+Exec= libexecdir@/gnome-calculator-search-provider
diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala
new file mode 100644
index 0000000..d88afca
--- /dev/null
+++ b/search-provider/search-provider.vala
@@ -0,0 +1,152 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright (C) 2014 Michael Catanzaro
+ *
+ * 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 2 of the License, or (at your option) any later
+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+[DBus (name = "org.gnome.Shell.SearchProvider2")]
+public class SearchProvider : Object
+{
+    private static string terms_to_equation (string[] terms)
+    {
+        return string.joinv (" ", terms);
+    }
+
+    private static bool can_parse (string[] terms)
+    {
+        try
+        {
+            int exit_status;
+            Process.spawn_command_line_sync (
+                "gnome-calculator --solve " + Shell.quote (terms_to_equation (terms)),
+                null, null, out exit_status);
+            Process.check_exit_status (exit_status);
+        }
+        catch (SpawnError e)
+        {
+            error ("Failed to spawn Calculator: %s", e.message);
+        }
+        catch (Error e)
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    private static string[] get_result_identifier (string[] terms)
+        ensures (result.length == 0 || result.length == 1)
+    {
+        /* We have at most one result: the search terms as one string */
+        if (can_parse (terms))
+            return { terms_to_equation (terms) };
+        else
+            return new string[0];
+    }
+
+    public string[] get_initial_result_set (string[] terms)
+    {
+        return get_result_identifier (terms);
+    }
+
+    public string[] get_subsearch_result_set (string[] previous_results, string[] terms)
+    {
+        return get_result_identifier (terms);
+    }
+
+    public HashTable<string, Variant>[] get_result_metas (string[] results)
+        requires (results.length == 1)
+        ensures (result.length == 1)
+    {
+        Subprocess subprocess;
+        string stdout_buf;
+
+        string[] argv = {"gnome-calculator", "--solve"};
+        argv += results[0];
+        argv += null;
+
+        try
+        {
+            subprocess = new Subprocess.newv (argv, SubprocessFlags.STDOUT_PIPE);
+        }
+        catch (Error e)
+        {
+            error ("Failed to spawn Calculator: %s", e.message);
+        }
+
+        try
+        {
+            subprocess.communicate_utf8 (null, null, out stdout_buf, null);
+        }
+        catch (Error e)
+        {
+            error ("Failed reading result: %s", e.message);
+        }
+
+        var metadata = new HashTable<string, Variant>[1];
+        metadata[0] = new HashTable<string, Variant>(str_hash, str_equal);
+        metadata[0].insert ("id", results[0]);
+        metadata[0].insert ("name", results[0] + " = " + stdout_buf);
+
+        return metadata;
+    }
+
+    private static void spawn_and_display_equation (string[] terms)
+    {
+        try
+        {
+            Process.spawn_command_line_async (
+                "gnome-calculator --equation " + Shell.quote (terms_to_equation (terms)));
+        }
+        catch (SpawnError e)
+        {
+            error ("Failed to spawn Calculator: %s", e.message);
+        }
+    }
+
+    public void activate_result (string result, string[] terms, uint32 timestamp)
+    {
+        spawn_and_display_equation (terms);
+    }
+
+    public void launch_search (string[] terms, uint32 timestamp)
+    {
+        spawn_and_display_equation (terms);
+    }
+}
+
+/* Based on GPLv2+ code from GNOME Contacts */
+public class SearchProviderApp : Application
+{
+    public SearchProviderApp ()
+    {
+        Object (application_id: "org.gnome.Calculator.SearchProvider",
+                flags: ApplicationFlags.IS_SERVICE,
+                inactivity_timeout: 10000);
+    }
+
+    public override bool dbus_register (DBusConnection connection, string object_path)
+    {
+        try
+        {
+            connection.register_object (object_path, new SearchProvider ());
+        }
+        catch (IOError error)
+        {
+            stderr.printf ("Could not register service: %s\n", error.message);
+            quit ();
+        }
+
+        return true;
+    }
+}
+
+int main ()
+{
+    return new SearchProviderApp ().run ();
+}


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