Get categories from the desktop files for all applications
and use them when finding matching applications for the search in the overlay mode. svn path=/trunk/; revision=159
This commit is contained in:
parent
0d612b7954
commit
9949d75fcc
@ -110,6 +110,10 @@ AppDisplay.prototype = {
|
|||||||
|
|
||||||
_init : function(width, height) {
|
_init : function(width, height) {
|
||||||
GenericDisplay.GenericDisplay.prototype._init.call(this, width, height);
|
GenericDisplay.GenericDisplay.prototype._init.call(this, width, height);
|
||||||
|
|
||||||
|
// map<itemId, array of category names>
|
||||||
|
this._categories = {};
|
||||||
|
|
||||||
let me = this;
|
let me = this;
|
||||||
this._appMonitor = new Shell.AppMonitor();
|
this._appMonitor = new Shell.AppMonitor();
|
||||||
this._appsStale = true;
|
this._appsStale = true;
|
||||||
@ -134,11 +138,15 @@ AppDisplay.prototype = {
|
|||||||
if (!this._appsStale)
|
if (!this._appsStale)
|
||||||
return;
|
return;
|
||||||
this._allItems = {};
|
this._allItems = {};
|
||||||
|
this._categories = {};
|
||||||
let apps = Gio.app_info_get_all();
|
let apps = Gio.app_info_get_all();
|
||||||
for (let i = 0; i < apps.length; i++) {
|
for (let i = 0; i < apps.length; i++) {
|
||||||
let appInfo = apps[i];
|
let appInfo = apps[i];
|
||||||
let appId = appInfo.get_id();
|
let appId = appInfo.get_id();
|
||||||
this._allItems[appId] = appInfo;
|
this._allItems[appId] = appInfo;
|
||||||
|
// [] is returned if we could not get the categories or the list of categories was empty
|
||||||
|
let categories = Shell.get_categories_for_desktop_file(appId);
|
||||||
|
this._categories[appId] = categories;
|
||||||
}
|
}
|
||||||
this._appsStale = false;
|
this._appsStale = false;
|
||||||
},
|
},
|
||||||
@ -169,24 +177,36 @@ AppDisplay.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Checks if the item info can be a match for the search string by checking
|
// Checks if the item info can be a match for the search string by checking
|
||||||
// the name, description, and execution command for the application.
|
// the name, description, execution command, and categories for the application.
|
||||||
// Item info is expected to be GAppInfo.
|
// Item info is expected to be GAppInfo.
|
||||||
// Returns a boolean flag indicating if itemInfo is a match.
|
// Returns a boolean flag indicating if itemInfo is a match.
|
||||||
_isInfoMatching : function(itemInfo, search) {
|
_isInfoMatching : function(itemInfo, search) {
|
||||||
if (search == null || search == '')
|
if (search == null || search == '')
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
let name = itemInfo.get_name().toLowerCase();
|
let name = itemInfo.get_name().toLowerCase();
|
||||||
if (name.indexOf(search) >= 0)
|
if (name.indexOf(search) >= 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
let description = itemInfo.get_description();
|
let description = itemInfo.get_description();
|
||||||
if (description) {
|
if (description) {
|
||||||
description = description.toLowerCase();
|
description = description.toLowerCase();
|
||||||
if (description.indexOf(search) >= 0)
|
if (description.indexOf(search) >= 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let exec = itemInfo.get_executable().toLowerCase();
|
let exec = itemInfo.get_executable().toLowerCase();
|
||||||
if (exec.indexOf(search) >= 0)
|
if (exec.indexOf(search) >= 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// we expect this._categories.hasOwnProperty(itemInfo.get_id()) to always be true here
|
||||||
|
let categories = this._categories[itemInfo.get_id()];
|
||||||
|
for (let i = 0; i < categories.length; i++) {
|
||||||
|
let category = categories[i].toLowerCase();
|
||||||
|
if (category.indexOf(search) >= 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
|
||||||
#include <libgnomeui-2.0/libgnomeui/gnome-thumbnail.h>
|
|
||||||
#include <dbus/dbus-glib.h>
|
#include <dbus/dbus-glib.h>
|
||||||
#include <libgnomeui/gnome-thumbnail.h>
|
#include <libgnomeui/gnome-thumbnail.h>
|
||||||
|
|
||||||
@ -222,6 +220,49 @@ shell_global_class_init (ShellGlobalClass *klass)
|
|||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search_path_init:
|
||||||
|
*
|
||||||
|
* search_path_init and get_applications_search_path below were copied from glib/gio/gdesktopappinfo.c
|
||||||
|
* copyright Red Hat, Inc., written by Alex Larsson, licensed under the LGPL
|
||||||
|
*
|
||||||
|
* Return value: location of an array with user and system application directories.
|
||||||
|
*/
|
||||||
|
static gpointer
|
||||||
|
search_path_init (gpointer data)
|
||||||
|
{
|
||||||
|
char **args = NULL;
|
||||||
|
const char * const *data_dirs;
|
||||||
|
const char *user_data_dir;
|
||||||
|
int i, length, j;
|
||||||
|
|
||||||
|
data_dirs = g_get_system_data_dirs ();
|
||||||
|
length = g_strv_length ((char **)data_dirs);
|
||||||
|
|
||||||
|
args = g_new (char *, length + 2);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
user_data_dir = g_get_user_data_dir ();
|
||||||
|
args[j++] = g_build_filename (user_data_dir, "applications", NULL);
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
args[j++] = g_build_filename (data_dirs[i],
|
||||||
|
"applications", NULL);
|
||||||
|
args[j++] = NULL;
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* get_applications_search_path:
|
||||||
|
*
|
||||||
|
* Return value: location of an array with user and system application directories.
|
||||||
|
*/
|
||||||
|
static const char * const *
|
||||||
|
get_applications_search_path (void)
|
||||||
|
{
|
||||||
|
static GOnce once_init = G_ONCE_INIT;
|
||||||
|
return g_once (&once_init, search_path_init, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_clutter_texture_set_from_pixbuf:
|
* shell_clutter_texture_set_from_pixbuf:
|
||||||
* texture: #ClutterTexture to be modified
|
* texture: #ClutterTexture to be modified
|
||||||
@ -298,6 +339,68 @@ shell_get_thumbnail_for_recent_info(GtkRecentInfo *recent_info)
|
|||||||
return pixbuf;
|
return pixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_get_categories_for_desktop_file:
|
||||||
|
*
|
||||||
|
* @desktop_file_name: name of the desktop file for which to retrieve categories
|
||||||
|
*
|
||||||
|
* Return value: (element-type char*) (transfer full): List of categories
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
GSList *
|
||||||
|
shell_get_categories_for_desktop_file(const char *desktop_file_name)
|
||||||
|
{
|
||||||
|
GKeyFile *key_file;
|
||||||
|
const char * const *search_dirs;
|
||||||
|
char **categories = NULL;
|
||||||
|
GSList *categories_list = NULL;
|
||||||
|
char *full_path = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
gsize len;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
key_file = g_key_file_new ();
|
||||||
|
search_dirs = get_applications_search_path();
|
||||||
|
|
||||||
|
g_key_file_load_from_dirs (key_file, desktop_file_name, (const char **)search_dirs, &full_path, 0, &error);
|
||||||
|
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Error when loading a key file for %s: %s", desktop_file_name, error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
categories = g_key_file_get_string_list (key_file,
|
||||||
|
"Desktop Entry",
|
||||||
|
"Categories",
|
||||||
|
&len,
|
||||||
|
&error);
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
g_warning ("Error when getting 'Categories' from a key file %s: %s", desktop_file_name, error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_key_file_free (key_file);
|
||||||
|
|
||||||
|
if (categories == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// gjs currently does not support returning arrays (other than a NULL value for an array), so we need
|
||||||
|
// to convert the array we are returning to GSList, returning which gjs supports.
|
||||||
|
// See http://bugzilla.gnome.org/show_bug.cgi?id=560567 for more info on gjs array support.
|
||||||
|
for (i = 0; categories[i]; i++)
|
||||||
|
{
|
||||||
|
categories_list = g_slist_prepend (categories_list, g_strdup (categories[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev (categories);
|
||||||
|
|
||||||
|
return categories_list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_global_get:
|
* shell_global_get:
|
||||||
*
|
*
|
||||||
@ -500,7 +603,7 @@ shell_global_start_task_panel (ShellGlobal *global)
|
|||||||
const char* panel_args[] = {"gnomeshell-taskpanel", SHELL_DBUS_SERVICE, NULL};
|
const char* panel_args[] = {"gnomeshell-taskpanel", SHELL_DBUS_SERVICE, NULL};
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (!g_spawn_async (NULL, (char**) panel_args, NULL, G_SPAWN_SEARCH_PATH, NULL,
|
if (!g_spawn_async (NULL, (char**)panel_args, NULL, G_SPAWN_SEARCH_PATH, NULL,
|
||||||
NULL, NULL, &error))
|
NULL, NULL, &error))
|
||||||
{
|
{
|
||||||
g_critical ("failed to execute %s: %s", panel_args[0], error->message);
|
g_critical ("failed to execute %s: %s", panel_args[0], error->message);
|
||||||
|
@ -36,6 +36,8 @@ gboolean shell_clutter_texture_set_from_pixbuf (ClutterTexture *texture,
|
|||||||
|
|
||||||
GdkPixbuf *shell_get_thumbnail_for_recent_info(GtkRecentInfo *recent_info);
|
GdkPixbuf *shell_get_thumbnail_for_recent_info(GtkRecentInfo *recent_info);
|
||||||
|
|
||||||
|
GSList *shell_get_categories_for_desktop_file(const char *desktop_file_name);
|
||||||
|
|
||||||
ShellGlobal *shell_global_get (void);
|
ShellGlobal *shell_global_get (void);
|
||||||
|
|
||||||
void shell_global_grab_dbus_service (ShellGlobal *global);
|
void shell_global_grab_dbus_service (ShellGlobal *global);
|
||||||
|
Loading…
Reference in New Issue
Block a user