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
This commit is contained in:
Ryan Lortie 2013-11-15 14:40:37 -05:00
parent 49f5737f00
commit 9aaf990960
2 changed files with 86 additions and 0 deletions

View File

@ -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
@ -4011,6 +4048,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

View File

@ -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__ */