Add support for asynchronous search providers
https://bugzilla.gnome.org/show_bug.cgi?id=640659
This commit is contained in:
parent
04afea76e3
commit
4b015903bc
@ -117,6 +117,43 @@ function SearchProvider(title) {
|
|||||||
SearchProvider.prototype = {
|
SearchProvider.prototype = {
|
||||||
_init: function(title) {
|
_init: function(title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
this.searchSystem = null;
|
||||||
|
this.searchAsync = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_asyncCancelled: function() {
|
||||||
|
},
|
||||||
|
|
||||||
|
startAsync: function() {
|
||||||
|
this.searchAsync = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
tryCancelAsync: function() {
|
||||||
|
if (!this.searchAsync)
|
||||||
|
return;
|
||||||
|
this._asyncCancelled();
|
||||||
|
this.searchAsync = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addItems:
|
||||||
|
* @items: an array of result identifier strings representing
|
||||||
|
* items which match the last given search terms.
|
||||||
|
*
|
||||||
|
* This should be used for something that requires a bit more
|
||||||
|
* logic; it's designed to be an asyncronous way to add a result
|
||||||
|
* to the current search.
|
||||||
|
*/
|
||||||
|
addItems: function( items) {
|
||||||
|
if (!this.searchSystem)
|
||||||
|
throw new Error('Search provider not registered');
|
||||||
|
|
||||||
|
if (!items.length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.tryCancelAsync();
|
||||||
|
|
||||||
|
this.searchSystem.addProviderItems(this, items);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,6 +261,7 @@ SearchProvider.prototype = {
|
|||||||
};
|
};
|
||||||
Signals.addSignalMethods(SearchProvider.prototype);
|
Signals.addSignalMethods(SearchProvider.prototype);
|
||||||
|
|
||||||
|
|
||||||
function OpenSearchSystem() {
|
function OpenSearchSystem() {
|
||||||
this._init();
|
this._init();
|
||||||
}
|
}
|
||||||
@ -336,6 +374,7 @@ SearchSystem.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
registerProvider: function (provider) {
|
registerProvider: function (provider) {
|
||||||
|
provider.searchSystem = this;
|
||||||
this._providers.push(provider);
|
this._providers.push(provider);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -352,13 +391,30 @@ SearchSystem.prototype = {
|
|||||||
this._previousResults = [];
|
this._previousResults = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addProviderItems: function(provider, items) {
|
||||||
|
let index = this._providers.indexOf(provider);
|
||||||
|
let [provider2, results] = this._previousResults[index];
|
||||||
|
if (provider !== provider2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
results.push.apply(results, items);
|
||||||
|
this.emit('results-updated', this._previousResults);
|
||||||
|
},
|
||||||
|
|
||||||
updateSearch: function(searchString) {
|
updateSearch: function(searchString) {
|
||||||
searchString = searchString.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
searchString = searchString.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||||
if (searchString == '')
|
if (searchString == '')
|
||||||
return [];
|
return;
|
||||||
|
|
||||||
let terms = searchString.split(/\s+/);
|
let terms = searchString.split(/\s+/);
|
||||||
let isSubSearch = terms.length == this._previousTerms.length;
|
this.updateSearchResults(terms);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSearchResults: function(terms) {
|
||||||
|
let isSubSearch = false;
|
||||||
|
|
||||||
|
if (terms) {
|
||||||
|
isSubSearch = terms.length == this._previousTerms.length;
|
||||||
if (isSubSearch) {
|
if (isSubSearch) {
|
||||||
for (let i = 0; i < terms.length; i++) {
|
for (let i = 0; i < terms.length; i++) {
|
||||||
if (terms[i].indexOf(this._previousTerms[i]) != 0) {
|
if (terms[i].indexOf(this._previousTerms[i]) != 0) {
|
||||||
@ -367,14 +423,17 @@ SearchSystem.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
terms = this._previousTerms;
|
||||||
|
}
|
||||||
|
|
||||||
let results = [];
|
let results = [];
|
||||||
if (isSubSearch) {
|
if (isSubSearch) {
|
||||||
for (let i = 0; i < this._previousResults.length; i++) {
|
for (let i = 0; i < this._providers.length; i++) {
|
||||||
let [provider, previousResults] = this._previousResults[i];
|
let [provider, previousResults] = this._previousResults[i];
|
||||||
|
provider.tryCancelAsync();
|
||||||
try {
|
try {
|
||||||
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
|
let providerResults = provider.getSubsearchResultSet(previousResults, terms);
|
||||||
if (providerResults.length > 0)
|
|
||||||
results.push([provider, providerResults]);
|
results.push([provider, providerResults]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
||||||
@ -383,9 +442,9 @@ SearchSystem.prototype = {
|
|||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < this._providers.length; i++) {
|
for (let i = 0; i < this._providers.length; i++) {
|
||||||
let provider = this._providers[i];
|
let provider = this._providers[i];
|
||||||
|
provider.tryCancelAsync();
|
||||||
try {
|
try {
|
||||||
let providerResults = provider.getInitialResultSet(terms);
|
let providerResults = provider.getInitialResultSet(terms);
|
||||||
if (providerResults.length > 0)
|
|
||||||
results.push([provider, providerResults]);
|
results.push([provider, providerResults]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
global.log ('A ' + error.name + ' has occured in ' + provider.title + ': ' + error.message);
|
||||||
@ -395,8 +454,7 @@ SearchSystem.prototype = {
|
|||||||
|
|
||||||
this._previousTerms = terms;
|
this._previousTerms = terms;
|
||||||
this._previousResults = results;
|
this._previousResults = results;
|
||||||
|
this.emit('results-updated', results);
|
||||||
return results;
|
},
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(SearchSystem.prototype);
|
Signals.addSignalMethods(SearchSystem.prototype);
|
||||||
|
@ -157,6 +157,7 @@ function SearchResults(searchSystem, openSearchSystem) {
|
|||||||
SearchResults.prototype = {
|
SearchResults.prototype = {
|
||||||
_init: function(searchSystem, openSearchSystem) {
|
_init: function(searchSystem, openSearchSystem) {
|
||||||
this._searchSystem = searchSystem;
|
this._searchSystem = searchSystem;
|
||||||
|
this._searchSystem.connect('results-updated', Lang.bind(this, this._updateResults));
|
||||||
this._openSearchSystem = openSearchSystem;
|
this._openSearchSystem = openSearchSystem;
|
||||||
|
|
||||||
this.actor = new St.BoxLayout({ name: 'searchResults',
|
this.actor = new St.BoxLayout({ name: 'searchResults',
|
||||||
@ -296,15 +297,16 @@ SearchResults.prototype = {
|
|||||||
this._statusText.show();
|
this._statusText.show();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
doSearch: function (searchString) {
|
||||||
|
this._searchSystem.updateSearch(searchString);
|
||||||
|
},
|
||||||
|
|
||||||
_metaForProvider: function(provider) {
|
_metaForProvider: function(provider) {
|
||||||
return this._providerMeta[this._providers.indexOf(provider)];
|
return this._providerMeta[this._providers.indexOf(provider)];
|
||||||
},
|
},
|
||||||
|
|
||||||
updateSearch: function (searchString) {
|
_updateResults: function(searchSystem, results) {
|
||||||
let results = this._searchSystem.updateSearch(searchString);
|
|
||||||
|
|
||||||
this._clearDisplay();
|
this._clearDisplay();
|
||||||
|
|
||||||
if (results.length == 0) {
|
if (results.length == 0) {
|
||||||
this._statusText.set_text(_("No matching results."));
|
this._statusText.set_text(_("No matching results."));
|
||||||
this._statusText.show();
|
this._statusText.show();
|
||||||
@ -314,11 +316,13 @@ SearchResults.prototype = {
|
|||||||
this._statusText.hide();
|
this._statusText.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
let terms = this._searchSystem.getTerms();
|
let terms = searchSystem.getTerms();
|
||||||
this._openSearchSystem.setSearchTerms(terms);
|
this._openSearchSystem.setSearchTerms(terms);
|
||||||
|
|
||||||
for (let i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
let [provider, providerResults] = results[i];
|
let [provider, providerResults] = results[i];
|
||||||
|
if (providerResults.length == 0)
|
||||||
|
continue;
|
||||||
let meta = this._metaForProvider(provider);
|
let meta = this._metaForProvider(provider);
|
||||||
meta.actor.show();
|
meta.actor.show();
|
||||||
meta.resultDisplay.renderResults(providerResults, terms);
|
meta.resultDisplay.renderResults(providerResults, terms);
|
||||||
|
@ -268,7 +268,7 @@ SearchTab.prototype = {
|
|||||||
_doSearch: function () {
|
_doSearch: function () {
|
||||||
this._searchTimeoutId = 0;
|
this._searchTimeoutId = 0;
|
||||||
let text = this._text.get_text().replace(/^\s+/g, '').replace(/\s+$/g, '');
|
let text = this._text.get_text().replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||||
this._searchResults.updateSearch(text);
|
this._searchResults.doSearch(text);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user