[glib] Add g_desktop_app_info_get_implementations()



commit 9aaf990960c5182602de01fe046379af7bd9627a
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Nov 15 14:40:37 2013 -0500

    Add g_desktop_app_info_get_implementations()
    
    This provides support for the draft addition of 'Implements=' to the Desktop
    Entry specification.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=712391

 gio/gdesktopappinfo.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++++
 gio/gdesktopappinfo.h |    3 ++
 2 files changed, 86 insertions(+), 0 deletions(-)
---
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 0b72803..913c872 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -146,6 +146,7 @@ typedef struct
   GHashTable                 *app_names;
   GHashTable                 *mime_tweaks;
   GHashTable                 *memory_index;
+  GHashTable                 *memory_implementations;
 } DesktopFileDir;
 
 static DesktopFileDir *desktop_file_dirs;
@@ -954,6 +955,7 @@ desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir)
   gpointer app, path;
 
   dir->memory_index = memory_index_new ();
+  dir->memory_implementations = memory_index_new ();
 
   /* Nothing to search? */
   if (dir->app_names == NULL)
@@ -973,6 +975,7 @@ desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir)
           !g_key_file_get_boolean (key_file, "Desktop Entry", "Hidden", NULL))
         {
           /* Index the interesting keys... */
+          gchar **implements;
           gint i;
 
           for (i = 0; i < G_N_ELEMENTS (desktop_key_match_category); i++)
@@ -1006,6 +1009,12 @@ desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir)
 
               g_free (raw);
             }
+
+          /* Make note of the Implements= line */
+          implements = g_key_file_get_string_list (key_file, "Desktop Entry", "Implements", NULL, NULL);
+          for (i = 0; implements && implements[i]; i++)
+            memory_index_add_token (dir->memory_implementations, implements[i], 0, app);
+          g_strfreev (implements);
         }
 
       g_key_file_free (key_file);
@@ -1112,6 +1121,20 @@ desktop_file_dir_unindexed_default_lookup (DesktopFileDir *dir,
     }
 }
 
+static void
+desktop_file_dir_unindexed_get_implementations (DesktopFileDir  *dir,
+                                                GList          **results,
+                                                const gchar     *interface)
+{
+  MemoryIndexEntry *mie;
+
+  if (!dir->memory_index)
+    desktop_file_dir_unindexed_setup_search (dir);
+
+  for (mie = g_hash_table_lookup (dir->memory_implementations, interface); mie; mie = mie->next)
+    *results = g_list_prepend (*results, g_strdup (mie->app_name));
+}
+
 /* DesktopFileDir "API" {{{2 */
 
 /*< internal >
@@ -1189,6 +1212,12 @@ desktop_file_dir_reset (DesktopFileDir *dir)
       dir->mime_tweaks = NULL;
     }
 
+  if (dir->memory_implementations)
+    {
+      g_hash_table_unref (dir->memory_implementations);
+      dir->memory_implementations = NULL;
+    }
+
   dir->is_setup = FALSE;
 }
 
@@ -1311,6 +1340,14 @@ desktop_file_dir_search (DesktopFileDir *dir,
   desktop_file_dir_unindexed_search (dir, search_token);
 }
 
+static void
+desktop_file_dir_get_implementations (DesktopFileDir  *dir,
+                                      GList          **results,
+                                      const gchar     *interface)
+{
+  desktop_file_dir_unindexed_get_implementations (dir, results, interface);
+}
+
 /* Lock/unlock and global setup API {{{2 */
 
 static void
@@ -4012,6 +4049,52 @@ g_app_info_get_default_for_uri_scheme (const char *uri_scheme)
 /* "Get all" API {{{2 */
 
 /**
+ * g_desktop_app_info_get_implementations:
+ * @interface: the name of the interface
+ *
+ * Gets all applications that implement @interface.
+ *
+ * An application implements an interface if that interface is listed in
+ * the Implements= line of the desktop file of the application.
+ *
+ * Since: 2.42
+ **/
+GList *
+g_desktop_app_info_get_implementations (const gchar *interface)
+{
+  GList *result = NULL;
+  GList **ptr;
+  gint i;
+
+  desktop_file_dirs_lock ();
+
+  for (i = 0; i < n_desktop_file_dirs; i++)
+    desktop_file_dir_get_implementations (&desktop_file_dirs[i], &result, interface);
+
+  desktop_file_dirs_unlock ();
+
+  ptr = &result;
+  while (*ptr)
+    {
+      gchar *name = (*ptr)->data;
+      GDesktopAppInfo *app;
+
+      app = g_desktop_app_info_new (name);
+      g_free (name);
+
+      if (app)
+        {
+          (*ptr)->data = app;
+          ptr = &(*ptr)->next;
+        }
+      else
+        *ptr = g_list_delete_link (*ptr, *ptr);
+    }
+
+  return result;
+}
+
+/**
  * g_desktop_app_info_search:
  * @search_string: the search string to use
  *
diff --git a/gio/gdesktopappinfo.h b/gio/gdesktopappinfo.h
index b9bb699..877ce5d 100644
--- a/gio/gdesktopappinfo.h
+++ b/gio/gdesktopappinfo.h
@@ -165,6 +165,9 @@ gboolean    g_desktop_app_info_launch_uris_as_manager (GDesktopAppInfo
 GLIB_AVAILABLE_IN_2_40
 gchar *** g_desktop_app_info_search (const gchar *search_string);
 
+GLIB_AVAILABLE_IN_2_42
+GList *g_desktop_app_info_get_implementations (const gchar *interface);
+
 G_END_DECLS
 
 #endif /* __G_DESKTOP_APP_INFO_H__ */


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