docDisplay: Remove "Recent Items" search provider

Although not all "Finding and reminding" applications are ready
yet, the integration with gnome-documents' search results overlaps
enough with the "Recent Items" provider to justify its removal.

https://bugzilla.gnome.org/show_bug.cgi?id=670150
This commit is contained in:
Florian Müllner 2012-02-15 17:59:50 +01:00
parent 34c6ff9645
commit ac78a1e1c0
7 changed files with 0 additions and 606 deletions

View File

@ -24,7 +24,6 @@ nobase_dist_js_DATA = \
gdm/systemd.js \ gdm/systemd.js \
extensionPrefs/main.js \ extensionPrefs/main.js \
misc/config.js \ misc/config.js \
misc/docInfo.js \
misc/extensionUtils.js \ misc/extensionUtils.js \
misc/fileUtils.js \ misc/fileUtils.js \
misc/format.js \ misc/format.js \
@ -49,7 +48,6 @@ nobase_dist_js_DATA = \
ui/dash.js \ ui/dash.js \
ui/dateMenu.js \ ui/dateMenu.js \
ui/dnd.js \ ui/dnd.js \
ui/docDisplay.js \
ui/endSessionDialog.js \ ui/endSessionDialog.js \
ui/environment.js \ ui/environment.js \
ui/extensionSystem.js \ ui/extensionSystem.js \

View File

@ -1,136 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Lang = imports.lang;
const Signals = imports.signals;
const Search = imports.ui.search;
const THUMBNAIL_ICON_MARGIN = 2;
const DocInfo = new Lang.Class({
Name: 'DocInfo',
_init : function(recentInfo) {
this.recentInfo = recentInfo;
// We actually used get_modified() instead of get_visited()
// here, as GtkRecentInfo doesn't updated get_visited()
// correctly. See http://bugzilla.gnome.org/show_bug.cgi?id=567094
this.timestamp = recentInfo.get_modified();
this.name = recentInfo.get_display_name();
this._lowerName = this.name.toLowerCase();
this.uri = recentInfo.get_uri();
this.mimeType = recentInfo.get_mime_type();
},
createIcon : function(size) {
return St.TextureCache.get_default().load_recent_thumbnail(size, this.recentInfo);
},
launch : function(workspaceIndex) {
Shell.DocSystem.get_default().open(this.recentInfo, workspaceIndex);
},
matchTerms: function(terms) {
let mtype = Search.MatchType.NONE;
for (let i = 0; i < terms.length; i++) {
let term = terms[i];
let idx = this._lowerName.indexOf(term);
if (idx == 0) {
mtype = Search.MatchType.PREFIX;
} else if (idx > 0) {
if (mtype == Search.MatchType.NONE)
mtype = Search.MatchType.SUBSTRING;
} else {
return Search.MatchType.NONE;
}
}
return mtype;
}
});
var docManagerInstance = null;
function getDocManager() {
if (docManagerInstance == null)
docManagerInstance = new DocManager();
return docManagerInstance;
}
/**
* DocManager wraps the DocSystem, primarily to expose DocInfo objects.
*/
const DocManager = new Lang.Class({
Name: 'DocManager',
_init: function() {
this._docSystem = Shell.DocSystem.get_default();
this._infosByTimestamp = [];
this._infosByUri = {};
this._docSystem.connect('changed', Lang.bind(this, this._reload));
this._reload();
},
_reload: function() {
let docs = this._docSystem.get_all();
this._infosByTimestamp = [];
this._infosByUri = {};
for (let i = 0; i < docs.length; i++) {
let recentInfo = docs[i];
let docInfo = new DocInfo(recentInfo);
this._infosByTimestamp.push(docInfo);
this._infosByUri[docInfo.uri] = docInfo;
}
this.emit('changed');
},
getTimestampOrderedInfos: function() {
return this._infosByTimestamp;
},
getInfosByUri: function() {
return this._infosByUri;
},
lookupByUri: function(uri) {
return this._infosByUri[uri];
},
queueExistenceCheck: function(count) {
return this._docSystem.queue_existence_check(count);
},
_searchDocs: function(items, terms) {
let multiplePrefixMatches = [];
let prefixMatches = [];
let multipleSubtringMatches = [];
let substringMatches = [];
for (let i = 0; i < items.length; i++) {
let item = items[i];
let mtype = item.matchTerms(terms);
if (mtype == Search.MatchType.MULTIPLE_PREFIX)
multiplePrefixMatches.push(item.uri);
else if (mtype == Search.MatchType.PREFIX)
prefixMatches.push(item.uri);
else if (mtype == Search.MatchType.MULTIPLE_SUBSTRING)
multipleSubtringMatches.push(item.uri);
else if (mtype == Search.MatchType.SUBSTRING)
substringMatches.push(item.uri);
}
return multiplePrefixMatches.concat(prefixMatches.concat(multipleSubtringMatches.concat(substringMatches)));
},
initialSearch: function(terms) {
return this._searchDocs(this._infosByTimestamp, terms);
},
subsearch: function(previousResults, terms) {
return this._searchDocs(previousResults.map(Lang.bind(this,
function(url) {
return this._infosByUri[url];
})), terms);
}
});
Signals.addSignalMethods(DocManager.prototype);

View File

@ -1,49 +0,0 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const DocInfo = imports.misc.docInfo;
const Lang = imports.lang;
const Params = imports.misc.params;
const Search = imports.ui.search;
const DocSearchProvider = new Lang.Class({
Name: 'DocSearchProvider',
Extends: Search.SearchProvider,
_init: function(name) {
this.parent(_("RECENT ITEMS"));
this._docManager = DocInfo.getDocManager();
},
getResultMetas: function(resultIds) {
let metas = [];
for (let i = 0; i < resultIds.length; i++) {
let docInfo = this._docManager.lookupByUri(resultIds[i]);
if (!docInfo)
metas.push(null);
else
metas.push({ 'id': resultIds[i],
'name': docInfo.name,
'createIcon': function(size) {
return docInfo.createIcon(size);
}
});
}
return metas;
},
activateResult: function(id, params) {
params = Params.parse(params, { workspace: -1,
timestamp: 0 });
let docInfo = this._docManager.lookupByUri(id);
docInfo.launch(params.workspace);
},
getInitialResultSet: function(terms) {
return this._docManager.initialSearch(terms);
},
getSubsearchResultSet: function(previousResults, terms) {
return this._docManager.subsearch(previousResults, terms);
}
});

View File

@ -14,7 +14,6 @@ const AppDisplay = imports.ui.appDisplay;
const ContactDisplay = imports.ui.contactDisplay; const ContactDisplay = imports.ui.contactDisplay;
const Dash = imports.ui.dash; const Dash = imports.ui.dash;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const DocDisplay = imports.ui.docDisplay;
const Lightbox = imports.ui.lightbox; const Lightbox = imports.ui.lightbox;
const Main = imports.ui.main; const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
@ -208,7 +207,6 @@ const Overview = new Lang.Class({
this.addSearchProvider(new AppDisplay.AppSearchProvider()); this.addSearchProvider(new AppDisplay.AppSearchProvider());
this.addSearchProvider(new AppDisplay.SettingsSearchProvider()); this.addSearchProvider(new AppDisplay.SettingsSearchProvider());
this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider()); this.addSearchProvider(new PlaceDisplay.PlaceSearchProvider());
this.addSearchProvider(new DocDisplay.DocSearchProvider());
this.addSearchProvider(new ContactDisplay.ContactSearchProvider()); this.addSearchProvider(new ContactDisplay.ContactSearchProvider());
// Load remote search providers provided by applications // Load remote search providers provided by applications

View File

@ -105,7 +105,6 @@ shell_public_headers_h = \
shell-app-system.h \ shell-app-system.h \
shell-app-usage.h \ shell-app-usage.h \
shell-contact-system.h \ shell-contact-system.h \
shell-doc-system.h \
shell-embedded-window.h \ shell-embedded-window.h \
shell-generic-container.h \ shell-generic-container.h \
shell-gtk-embed.h \ shell-gtk-embed.h \
@ -152,7 +151,6 @@ libgnome_shell_la_SOURCES = \
shell-app-system.c \ shell-app-system.c \
shell-app-usage.c \ shell-app-usage.c \
shell-contact-system.c \ shell-contact-system.c \
shell-doc-system.c \
shell-embedded-window.c \ shell-embedded-window.c \
shell-generic-container.c \ shell-generic-container.c \
shell-gtk-embed.c \ shell-gtk-embed.c \

View File

@ -1,368 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include "config.h"
#include "shell-doc-system.h"
#include "shell-global.h"
/**
* SECTION:shell-doc-system
* @short_description: Track recently used documents
*
* Wraps #GtkRecentManager, caching recently used document information, and adds
* APIs for asynchronous queries.
*/
enum {
CHANGED,
DELETED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
struct _ShellDocSystemPrivate {
GtkRecentManager *manager;
GHashTable *infos_by_uri;
GSList *infos_by_timestamp;
guint idle_recent_changed_id;
GHashTable *deleted_infos;
guint idle_emit_deleted_id;
};
G_DEFINE_TYPE(ShellDocSystem, shell_doc_system, G_TYPE_OBJECT);
/**
* shell_doc_system_get_all:
* @system: A #ShellDocSystem
*
* Returns the currently cached set of recent files. Recent files are read initially
* from the underlying #GtkRecentManager, and updated when it changes.
* This function does not perform I/O.
*
* Returns: (transfer none) (element-type GtkRecentInfo): Cached recent file infos
*/
GSList *
shell_doc_system_get_all (ShellDocSystem *self)
{
return self->priv->infos_by_timestamp;
}
/**
* shell_doc_system_lookup_by_uri:
* @system: A #ShellDocSystem
* @uri: URI
*
* Returns: (transfer none): Recent file info corresponding to given @uri
*/
GtkRecentInfo *
shell_doc_system_lookup_by_uri (ShellDocSystem *system,
const char *uri)
{
return g_hash_table_lookup (system->priv->infos_by_uri, uri);
}
static gboolean
shell_doc_system_idle_emit_deleted (gpointer data)
{
ShellDocSystem *self = SHELL_DOC_SYSTEM (data);
GHashTableIter iter;
gpointer key, value;
self->priv->idle_emit_deleted_id = 0;
g_hash_table_iter_init (&iter, self->priv->deleted_infos);
while (g_hash_table_iter_next (&iter, &key, &value))
{
GtkRecentInfo *info = key;
g_signal_emit (self, signals[DELETED], 0, info);
}
g_signal_emit (self, signals[CHANGED], 0);
return FALSE;
}
typedef struct {
ShellDocSystem *self;
GtkRecentInfo *info;
} ShellDocSystemRecentQueryData;
static void
on_recent_file_query_result (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
ShellDocSystemRecentQueryData *data = user_data;
ShellDocSystem *self = data->self;
GError *error = NULL;
GFileInfo *fileinfo;
fileinfo = g_file_query_info_finish (G_FILE (source), result, &error);
if (fileinfo)
g_object_unref (fileinfo);
/* This is a strict error check; we don't want to cause recent files to
* vanish for anything potentially transient.
*/
if (error != NULL && error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_FOUND)
{
self->priv->infos_by_timestamp = g_slist_remove (self->priv->infos_by_timestamp, data->info);
g_hash_table_remove (self->priv->infos_by_uri, gtk_recent_info_get_uri (data->info));
g_hash_table_insert (self->priv->deleted_infos, gtk_recent_info_ref (data->info), NULL);
if (self->priv->idle_emit_deleted_id == 0)
self->priv->idle_emit_deleted_id = g_timeout_add (0, shell_doc_system_idle_emit_deleted, self);
}
g_clear_error (&error);
gtk_recent_info_unref (data->info);
g_free (data);
}
/**
* shell_doc_system_queue_existence_check:
* @system: A #ShellDocSystem
* @n_items: Count of items to check for existence, starting from most recent
*
* Asynchronously start a check of a number of recent file for existence;
* any deleted files will be emitted from the #ShellDocSystem::deleted
* signal. Note that this function ignores non-local files; they
* will simply always appear to exist (until they are removed from
* the recent file list manually).
*
* The intent of this function is to be called after a #ShellDocSystem::changed
* signal has been emitted, and a display has shown a subset of those files.
*/
void
shell_doc_system_queue_existence_check (ShellDocSystem *self,
guint n_items)
{
GSList *iter;
guint i;
for (i = 0, iter = self->priv->infos_by_timestamp; i < n_items && iter; i++, iter = iter->next)
{
GtkRecentInfo *info = iter->data;
const char *uri;
GFile *file;
ShellDocSystemRecentQueryData *data;
if (!gtk_recent_info_is_local (info))
continue;
data = g_new0 (ShellDocSystemRecentQueryData, 1);
data->self = self;
data->info = gtk_recent_info_ref (info);
uri = gtk_recent_info_get_uri (info);
file = g_file_new_for_uri (uri);
g_file_query_info_async (file, "standard::type", G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT, NULL, on_recent_file_query_result, data);
g_object_unref (file);
}
}
static int
sort_infos_by_timestamp_descending (gconstpointer a,
gconstpointer b)
{
GtkRecentInfo *info_a = (GtkRecentInfo*)a;
GtkRecentInfo *info_b = (GtkRecentInfo*)b;
time_t modified_a, modified_b;
modified_a = gtk_recent_info_get_modified (info_a);
modified_b = gtk_recent_info_get_modified (info_b);
return modified_b - modified_a;
}
static gboolean
idle_handle_recent_changed (gpointer data)
{
ShellDocSystem *self = SHELL_DOC_SYSTEM (data);
GList *items, *iter;
self->priv->idle_recent_changed_id = 0;
g_hash_table_remove_all (self->priv->deleted_infos);
g_hash_table_remove_all (self->priv->infos_by_uri);
g_slist_free (self->priv->infos_by_timestamp);
self->priv->infos_by_timestamp = NULL;
items = gtk_recent_manager_get_items (self->priv->manager);
for (iter = items; iter; iter = iter->next)
{
GtkRecentInfo *info = iter->data;
const char *uri = gtk_recent_info_get_uri (info);
/* uri is owned by the info */
g_hash_table_insert (self->priv->infos_by_uri, (char*) uri, info);
self->priv->infos_by_timestamp = g_slist_prepend (self->priv->infos_by_timestamp, info);
}
g_list_free (items);
self->priv->infos_by_timestamp = g_slist_sort (self->priv->infos_by_timestamp, sort_infos_by_timestamp_descending);
g_signal_emit (self, signals[CHANGED], 0);
return FALSE;
}
static void
shell_doc_system_on_recent_changed (GtkRecentManager *manager,
ShellDocSystem *self)
{
if (self->priv->idle_recent_changed_id != 0)
return;
self->priv->idle_recent_changed_id = g_timeout_add (0, idle_handle_recent_changed, self);
}
/**
* shell_doc_system_open:
* @system: A #ShellDocSystem
* @info: A #GtkRecentInfo
* @workspace: Open on this workspace, or -1 for default
*
* Launch the default application associated with the mime type of
* @info, using its uri.
*/
void
shell_doc_system_open (ShellDocSystem *system,
GtkRecentInfo *info,
int workspace)
{
GFile *file;
GAppInfo *app_info;
gboolean needs_uri;
GAppLaunchContext *context;
context = shell_global_create_app_launch_context (shell_global_get ());
if (workspace != -1)
gdk_app_launch_context_set_desktop ((GdkAppLaunchContext *)context, workspace);
file = g_file_new_for_uri (gtk_recent_info_get_uri (info));
needs_uri = g_file_get_path (file) == NULL;
g_object_unref (file);
app_info = g_app_info_get_default_for_type (gtk_recent_info_get_mime_type (info), needs_uri);
if (app_info != NULL)
{
GList *uris;
uris = g_list_prepend (NULL, (gpointer)gtk_recent_info_get_uri (info));
g_app_info_launch_uris (app_info, uris, context, NULL);
g_list_free (uris);
}
else
{
char *app_name;
const char *app_exec;
char *app_exec_quoted;
guint count;
time_t time;
app_name = gtk_recent_info_last_application (info);
if (gtk_recent_info_get_application_info (info, app_name, &app_exec, &count, &time))
{
GRegex *regex;
/* TODO: Change this once better support for creating
GAppInfo is added to GtkRecentInfo, as right now
this relies on the fact that the file uri is
already a part of appExec, so we don't supply any
files to app_info.launch().
The 'command line' passed to
create_from_command_line is allowed to contain
'%<something>' macros that are expanded to file
name / icon name, etc, so we need to escape % as %%
*/
regex = g_regex_new ("%", 0, 0, NULL);
app_exec_quoted = g_regex_replace (regex, app_exec, -1, 0, "%%", 0, NULL);
g_regex_unref (regex);
app_info = g_app_info_create_from_commandline (app_exec_quoted, NULL, 0, NULL);
g_free (app_exec_quoted);
/* The point of passing an app launch context to
launch() is mostly to get startup notification and
associated benefits like the app appearing on the
right desktop; but it doesn't really work for now
because with the way we create the appInfo we
aren't reading the application's desktop file, and
thus don't find the StartupNotify=true in it. So,
despite passing the app launch context, no startup
notification occurs.
*/
g_app_info_launch (app_info, NULL, context, NULL);
}
g_free (app_name);
}
g_object_unref (context);
}
static void
shell_doc_system_class_init(ShellDocSystemClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *)klass;
signals[CHANGED] =
g_signal_new ("changed",
SHELL_TYPE_DOC_SYSTEM,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[DELETED] =
g_signal_new ("deleted",
SHELL_TYPE_DOC_SYSTEM,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, GTK_TYPE_RECENT_INFO);
g_type_class_add_private (gobject_class, sizeof (ShellDocSystemPrivate));
}
static void
shell_doc_system_init (ShellDocSystem *self)
{
ShellDocSystemPrivate *priv;
self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
SHELL_TYPE_DOC_SYSTEM,
ShellDocSystemPrivate);
self->priv->manager = gtk_recent_manager_get_default ();
self->priv->deleted_infos = g_hash_table_new_full (NULL, NULL, (GDestroyNotify)gtk_recent_info_unref, NULL);
self->priv->infos_by_uri = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)gtk_recent_info_unref);
g_signal_connect (self->priv->manager, "changed", G_CALLBACK(shell_doc_system_on_recent_changed), self);
shell_doc_system_on_recent_changed (self->priv->manager, self);
}
/**
* shell_doc_system_get_default:
*
* Return Value: (transfer none): The global #ShellDocSystem singleton
*/
ShellDocSystem *
shell_doc_system_get_default ()
{
static ShellDocSystem *instance = NULL;
if (instance == NULL)
instance = g_object_new (SHELL_TYPE_DOC_SYSTEM, NULL);
return instance;
}

View File

@ -1,47 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef __SHELL_DOC_SYSTEM_H__
#define __SHELL_DOC_SYSTEM_H__
#include <gio/gio.h>
#include <gtk/gtk.h>
#define SHELL_TYPE_DOC_SYSTEM (shell_doc_system_get_type ())
#define SHELL_DOC_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_DOC_SYSTEM, ShellDocSystem))
#define SHELL_DOC_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_DOC_SYSTEM, ShellDocSystemClass))
#define SHELL_IS_DOC_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_DOC_SYSTEM))
#define SHELL_IS_DOC_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_DOC_SYSTEM))
#define SHELL_DOC_SYSTEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_DOC_SYSTEM, ShellDocSystemClass))
typedef struct _ShellDocSystem ShellDocSystem;
typedef struct _ShellDocSystemClass ShellDocSystemClass;
typedef struct _ShellDocSystemPrivate ShellDocSystemPrivate;
struct _ShellDocSystem
{
GObject parent;
ShellDocSystemPrivate *priv;
};
struct _ShellDocSystemClass
{
GObjectClass parent_class;
};
GType shell_doc_system_get_type (void) G_GNUC_CONST;
ShellDocSystem* shell_doc_system_get_default (void);
GSList *shell_doc_system_get_all (ShellDocSystem *system);
GtkRecentInfo *shell_doc_system_lookup_by_uri (ShellDocSystem *system,
const char *uri);
void shell_doc_system_queue_existence_check (ShellDocSystem *system,
guint n_items);
void shell_doc_system_open (ShellDocSystem *system,
GtkRecentInfo *info,
int workspace);
#endif /* __SHELL_DOC_SYSTEM_H__ */