search: Remove the ability to add synchronous search providers

As shown in the previous commits, synchronous search is easily implemented
by the asynchronous search API. The only reason we still have a
synchronous search API is of historical reasons. Well, we're not a museum,
and git log can keep our fossils safe if need be....

https://bugzilla.gnome.org/show_bug.cgi?id=675328
This commit is contained in:
Jasper St. Pierre 2012-05-02 15:54:25 -04:00
parent 58f77a19ed
commit 333e380340
7 changed files with 47 additions and 116 deletions

View File

@ -312,12 +312,10 @@ const AppSearchProvider = new Lang.Class({
_init: function() {
this.parent(_("APPLICATIONS"));
this.async = true;
this._appSys = Shell.AppSystem.get_default();
},
getResultMetasAsync: function(apps, callback) {
getResultMetas: function(apps, callback) {
let metas = [];
for (let i = 0; i < apps.length; i++) {
let app = apps[i];
@ -331,11 +329,11 @@ const AppSearchProvider = new Lang.Class({
callback(metas);
},
getInitialResultSetAsync: function(terms) {
getInitialResultSet: function(terms) {
this.searchSystem.pushResults(this, this._appSys.initial_search(terms));
},
getSubsearchResultSetAsync: function(previousResults, terms) {
getSubsearchResultSet: function(previousResults, terms) {
this.searchSystem.pushResults(this, this._appSys.subsearch(previousResults, terms));
},
@ -375,12 +373,11 @@ const SettingsSearchProvider = new Lang.Class({
_init: function() {
this.parent(_("SETTINGS"));
this.async = true;
this._appSys = Shell.AppSystem.get_default();
this._gnomecc = this._appSys.lookup_app('gnome-control-center.desktop');
},
getResultMetasAsync: function(prefs, callback) {
getResultMetas: function(prefs, callback) {
let metas = [];
for (let i = 0; i < prefs.length; i++) {
let pref = prefs[i];
@ -394,11 +391,11 @@ const SettingsSearchProvider = new Lang.Class({
callback(metas);
},
getInitialResultSetAsync: function(terms) {
getInitialResultSet: function(terms) {
this.searchSystem.pushResults(this, this._appSys.search_settings(terms));
},
getSubsearchResultSetAsync: function(previousResults, terms) {
getSubsearchResultSet: function(previousResults, terms) {
this.searchSystem.pushResults(this, this._appSys.search_settings(terms));
},

View File

@ -151,11 +151,10 @@ const ContactSearchProvider = new Lang.Class({
_init: function() {
this.parent(_("CONTACTS"));
this.async = true;
this._contactSys = Shell.ContactSystem.get_default();
},
getResultMetasAsync: function(ids, callback) {
getResultMetas: function(ids, callback) {
let metas = [];
for (let i = 0; i < ids.length; i++) {
let contact = new Contact(ids[i]);
@ -169,11 +168,11 @@ const ContactSearchProvider = new Lang.Class({
callback(metas);
},
getInitialResultSetAsync: function(terms) {
getInitialResultSet: function(terms) {
this.searchSystem.pushResults(this, this._contactSys.initial_search(terms));
},
getSubsearchResultSetAsync: function(previousResults, terms) {
getSubsearchResultSet: function(previousResults, terms) {
this.searchSystem.pushResults(this, this._contactSys.subsearch(previousResults, terms));
},

View File

@ -365,11 +365,10 @@ const PlaceSearchProvider = new Lang.Class({
_init: function() {
this.parent(_("PLACES & DEVICES"));
this.async = true;
this.placesManager = new PlacesManager();
},
getResultMetasAsync: function(resultIds, callback) {
getResultMetas: function(resultIds, callback) {
let metas = [];
for (let i = 0; i < resultIds.length; i++) {
let placeInfo = this.placesManager.lookupPlaceById(resultIds[i]);
@ -417,12 +416,12 @@ const PlaceSearchProvider = new Lang.Class({
this.searchSystem.pushResults(this, prefixResults.concat(substringResults));
},
getInitialResultSetAsync: function(terms) {
getInitialResultSet: function(terms) {
let places = this.placesManager.getAllPlaces();
this._searchPlaces(places, terms);
},
getSubsearchResultSetAsync: function(previousResults, terms) {
getSubsearchResultSet: function(previousResults, terms) {
let places = previousResults.map(Lang.bind(this, function(id) {
return this.placesManager.lookupPlaceById(id);
}));

View File

@ -91,7 +91,6 @@ const RemoteSearchProvider = new Lang.Class({
dbusName, dbusPath);
this.parent(title.toUpperCase());
this.async = true;
this._cancellable = new Gio.Cancellable();
},
@ -120,7 +119,7 @@ const RemoteSearchProvider = new Lang.Class({
this.searchSystem.pushResults(this, results[0]);
},
getInitialResultSetAsync: function(terms) {
getInitialResultSet: function(terms) {
this._cancellable.cancel();
this._cancellable.reset();
try {
@ -133,7 +132,7 @@ const RemoteSearchProvider = new Lang.Class({
}
},
getSubsearchResultSetAsync: function(previousResults, newTerms) {
getSubsearchResultSet: function(previousResults, newTerms) {
this._cancellable.cancel();
this._cancellable.reset();
try {
@ -164,7 +163,7 @@ const RemoteSearchProvider = new Lang.Class({
callback(resultMetas);
},
getResultMetasAsync: function(ids, callback) {
getResultMetas: function(ids, callback) {
this._cancellable.cancel();
this._cancellable.reset();
try {

View File

@ -70,11 +70,8 @@ const SearchResultDisplay = new Lang.Class({
* Subclass this object to add a new result type
* to the search system, then call registerProvider()
* in SearchSystem with an instance.
* By default, search is synchronous and uses the
* Search is asynchronous and uses the
* getInitialResultSet()/getSubsearchResultSet() methods.
* For asynchronous search, set the async property to true
* and implement getInitialResultSetAsync()/getSubsearchResultSetAsync()
* instead.
*/
const SearchProvider = new Lang.Class({
Name: 'SearchProvider',
@ -82,7 +79,6 @@ const SearchProvider = new Lang.Class({
_init: function(title) {
this.title = title;
this.searchSystem = null;
this.async = false;
},
/**
@ -93,7 +89,7 @@ const SearchProvider = new Lang.Class({
* therefore a single term of length one or two), or when
* a new term is added.
*
* Should return an array of result identifier strings representing
* Should "return" an array of result identifier strings representing
* items which match the given search terms. This
* is expected to be a substring match on the metadata for a given
* item. Ordering of returned results is up to the discretion of the provider,
@ -103,6 +99,9 @@ const SearchProvider = new Lang.Class({
* description) before single matches
* * Put items which match on a prefix before non-prefix substring matches
*
* We say "return" above, but in order to make the query asynchronous, use
* this.searchSystem.pushResults();. The return value should be ignored.
*
* This function should be fast; do not perform unindexed full-text searches
* or network queries.
*/
@ -110,18 +109,6 @@ const SearchProvider = new Lang.Class({
throw new Error('Not implemented');
},
/**
* getInitialResultSetAsync:
* @terms: Array of search terms, treated as logical AND
*
* Like getInitialResultSet(), but the method should return immediately
* without a return value - use SearchSystem.pushResults() when the
* corresponding results are ready.
*/
getInitialResultSetAsync: function(terms) {
throw new Error('Not implemented');
},
/**
* getSubsearchResultSet:
* @previousResults: Array of item identifiers
@ -134,46 +121,23 @@ const SearchProvider = new Lang.Class({
*
* This allows search providers to only search through the previous
* result set, rather than possibly performing a full re-query.
*
* Similar to getInitialResultSet, the return value for this will
* be ignored; use this.searchSystem.pushResults();.
*/
getSubsearchResultSet: function(previousResults, newTerms) {
throw new Error('Not implemented');
},
/**
* getSubsearchResultSetAsync:
* @previousResults: Array of item identifiers
* @newTerms: Updated search terms
*
* Like getSubsearchResultSet(), but the method should return immediately
* without a return value - use SearchSystem.pushResults() when the
* corresponding results are ready.
*/
getSubsearchResultSetAsync: function(previousResults, newTerms) {
throw new Error('Not implemented');
},
/**
* getResultMetas:
* @ids: Result identifier strings
*
* Return an array of objects with 'id', 'name', (both strings) and
* Call callback with array of objects with 'id', 'name', (both strings) and
* 'createIcon' (function(size) returning a Clutter.Texture) properties
* with the same number of members as @ids
*/
getResultMetas: function(ids) {
throw new Error('Not implemented');
},
/**
* getResultMetasAsync:
* @ids: Result identifier strings
* @callback: callback to pass the results to when ready
*
* Like getResultMetas(), but the method should return immediately
* without a return value - pass the results to the provided @callback
* when ready.
*/
getResultMetasAsync: function(ids, callback) {
getResultMetas: function(ids, callback) {
throw new Error('Not implemented');
},
@ -387,13 +351,8 @@ const SearchSystem = new Lang.Class({
for (let i = 0; i < this._providers.length; i++) {
let [provider, previousResults] = previousResultsArr[i];
try {
if (provider.async) {
results.push([provider, []]);
provider.getSubsearchResultSetAsync(previousResults, terms);
} else {
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
results.push([provider, providerResults]);
}
results.push([provider, []]);
provider.getSubsearchResultSet(previousResults, terms);
} catch (error) {
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
}
@ -402,13 +361,8 @@ const SearchSystem = new Lang.Class({
for (let i = 0; i < this._providers.length; i++) {
let provider = this._providers[i];
try {
if (provider.async) {
results.push([provider, []]);
provider.getInitialResultSetAsync(terms);
} else {
let providerResults = provider.getInitialResultSet(terms);
results.push([provider, providerResults]);
}
results.push([provider, []]);
provider.getInitialResultSet(terms);
} catch (error) {
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
}

View File

@ -119,13 +119,7 @@ const GridSearchResults = new Lang.Class({
if (results.length == 0)
return;
if (provider.async) {
provider.getResultMetasAsync(results,
Lang.bind(this, this.renderResults));
} else {
let metas = provider.getResultMetas(results);
this.renderResults(metas);
}
provider.getResultMetas(results, Lang.bind(this, this.renderResults));
}));
}));
this._notDisplayedResult = [];
@ -390,29 +384,21 @@ const SearchResults = new Lang.Class({
meta.resultDisplay.setResults(providerResults, terms);
let results = meta.resultDisplay.getResultsForDisplay();
if (provider.async) {
provider.getResultMetasAsync(results, Lang.bind(this,
function(metas) {
this._clearDisplayForProvider(provider);
meta.actor.show();
// Hinding drops the key focus if we have it
let focus = global.stage.get_key_focus();
this._content.hide();
meta.resultDisplay.renderResults(metas);
this._maybeSetInitialSelection();
this._content.show();
if (this._content.contains(focus))
global.stage.set_key_focus(focus);
}));
} else {
let metas = provider.getResultMetas(results);
provider.getResultMetas(results, Lang.bind(this, function(metas) {
this._clearDisplayForProvider(provider);
meta.actor.show();
// Hinding drops the key focus if we have it
let focus = global.stage.get_key_focus();
this._content.hide();
meta.resultDisplay.renderResults(metas);
}
this._maybeSetInitialSelection();
this._content.show();
if (this._content.contains(focus))
global.stage.set_key_focus(focus);
}));
}
this._maybeSetInitialSelection();
},
@ -436,9 +422,7 @@ const SearchResults = new Lang.Class({
for (let i = 0; i < results.length; i++) {
let [provider, providerResults] = results[i];
let meta = this._metaForProvider(provider);
meta.hasPendingResults = provider.async;
if (!meta.hasPendingResults)
this._updateProviderResults(provider, providerResults, terms);
meta.hasPendingResults = true;
}
this._content.show();

View File

@ -166,10 +166,9 @@ const WandaSearchProvider = new Lang.Class({
_init: function() {
this.parent(_("Your favorite Easter Egg"));
this.async = true;
},
getResultMetasAsync: function(fish, callback) {
getResultMetas: function(fish, callback) {
callback([{ 'id': fish[0], // there may be many fish in the sea, but
// only one which speaks the truth!
'name': capitalize(fish[0]),
@ -188,7 +187,7 @@ const WandaSearchProvider = new Lang.Class({
}]);
},
getInitialResultSetAsync: function(terms) {
getInitialResultSet: function(terms) {
if (terms.join(' ') == MAGIC_FISH_KEY) {
this.searchSystem.pushResults(this, [ FISH_NAME ]);
} else {
@ -196,8 +195,8 @@ const WandaSearchProvider = new Lang.Class({
}
},
getSubsearchResultSetAsync: function(previousResults, terms) {
this.getInitialResultSetAsync(terms);
getSubsearchResultSet: function(previousResults, terms) {
this.getInitialResultSet(terms);
},
activateResult: function(fish, params) {