mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 08:04:01 +02:00
Removed GPL code. Added own implementation of suggestions engine. Fixed Google maps different issues
This commit is contained in:
parent
c735809e32
commit
586dde7dd7
8 changed files with 147 additions and 853 deletions
|
@ -36,13 +36,11 @@ Rectangle {
|
|||
property bool keyboardRaised: false
|
||||
property bool punctuationMode: false
|
||||
property var suggestionsList: []
|
||||
readonly property string searchUrlTemplate: "https://www.google.com/search?client=hifibrowser&q=";
|
||||
|
||||
OpenSearchEngine {
|
||||
|
||||
WebBrowserSuggestionsEngine {
|
||||
id: searchEngine
|
||||
name: "Google";
|
||||
searchUrlTemplate: "https://www.google.com/search?client=hifibrowser&q={searchTerms}";
|
||||
suggestionsUrlTemplate: "https://suggestqueries.google.com/complete/search?output=firefox&q=%s";
|
||||
suggestionsUrl: "https://suggestqueries.google.com/complete/search?output=firefox&q=%s";
|
||||
|
||||
onSuggestions: {
|
||||
if (suggestions.length > 0) {
|
||||
|
@ -65,7 +63,7 @@ Rectangle {
|
|||
repeat: false
|
||||
onTriggered: {
|
||||
if (addressBar.editText !== "") {
|
||||
searchEngine.requestSuggestions(addressBarInput.text);
|
||||
searchEngine.querySuggestions(addressBarInput.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,18 +72,19 @@ Rectangle {
|
|||
|
||||
function goTo(url) {
|
||||
//must be valid attempt to open an site with dot
|
||||
|
||||
var urlNew = url
|
||||
if (url.indexOf(".") > 0) {
|
||||
if (url.indexOf("http") < 0) {
|
||||
url = "http://" + url;
|
||||
urlNew = "http://" + url;
|
||||
}
|
||||
} else {
|
||||
url = searchEngine.searchUrl(url)
|
||||
urlNew = searchUrlTemplate + url
|
||||
}
|
||||
|
||||
addressBar.model = []
|
||||
webStack.currentItem.webEngineView.url = url
|
||||
addressBar.editText = webStack.currentItem.webEngineView.url
|
||||
//need to rebind if binfing was broken by selecting from suggestions
|
||||
addressBar.editText = Qt.binding( function() { return webStack.currentItem.webEngineView.url; });
|
||||
webStack.currentItem.webEngineView.url = urlNew
|
||||
suggestionRequestTimer.stop();
|
||||
addressBar.popup.close();
|
||||
}
|
||||
|
@ -305,11 +304,13 @@ Rectangle {
|
|||
objectName: "tabletWebEngineView"
|
||||
|
||||
//profile: HFWebEngineProfile;
|
||||
profile.httpUserAgent: "Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0"
|
||||
|
||||
property string userScriptUrl: ""
|
||||
|
||||
onLoadingChanged: {
|
||||
if (!loading) {
|
||||
addressBarInput.cursorPosition = 0 //set input field cursot to beginning
|
||||
suggestionRequestTimer.stop();
|
||||
addressBar.popup.close();
|
||||
}
|
||||
|
@ -360,7 +361,6 @@ Rectangle {
|
|||
Component.onCompleted: {
|
||||
webChannel.registerObject("eventBridge", eventBridge);
|
||||
webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper);
|
||||
//webEngineView.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface)";
|
||||
}
|
||||
|
||||
onFeaturePermissionRequested: {
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
#include "commerce/Wallet.h"
|
||||
#include "commerce/QmlCommerce.h"
|
||||
|
||||
#include "opensearch/opensearchengine.h"
|
||||
#include "webbrowser/webbrowsersuggestionsengine.h"
|
||||
|
||||
// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||
// FIXME seems to be broken.
|
||||
|
@ -2225,7 +2225,7 @@ void Application::initializeUi() {
|
|||
QmlCommerce::registerType();
|
||||
qmlRegisterType<ResourceImageItem>("Hifi", 1, 0, "ResourceImageItem");
|
||||
qmlRegisterType<Preference>("Hifi", 1, 0, "Preference");
|
||||
qmlRegisterType<OpenSearchEngine>("HifiWeb", 1, 0, "OpenSearchEngine");
|
||||
qmlRegisterType<WebBrowserSuggestionsEngine>("HifiWeb", 1, 0, "WebBrowserSuggestionsEngine");
|
||||
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
offscreenUi->create();
|
||||
|
|
|
@ -1,650 +0,0 @@
|
|||
#include "opensearchengine.h"
|
||||
#include "qregexp.h"
|
||||
#include "opensearchenginedelegate.h"
|
||||
|
||||
#include <qbuffer.h>
|
||||
#include <qcoreapplication.h>
|
||||
#include <qlocale.h>
|
||||
#include <qnetworkrequest.h>
|
||||
#include <qnetworkreply.h>
|
||||
#include <qregexp.h>
|
||||
#include <qstringlist.h>
|
||||
|
||||
#include <QUrlQuery>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <NetworkAccessManager.h>
|
||||
|
||||
|
||||
/*!
|
||||
\class OpenSearchEngine
|
||||
\brief A class representing a single search engine described in OpenSearch format
|
||||
|
||||
OpenSearchEngine is a class that represents a single search engine based on
|
||||
the OpenSearch format.
|
||||
For more information about the format, see http://www.opensearch.org/.
|
||||
|
||||
Instances of the class hold all the data associated with the corresponding search
|
||||
engines, such as name(), description() and also URL templates that are used
|
||||
to construct URLs, which can be used later to perform search queries. Search engine
|
||||
can also have an image, even an external one, in this case it will be downloaded
|
||||
automatically from the network.
|
||||
|
||||
OpenSearchEngine instances can be constructed from scratch but also read from
|
||||
external sources and written back to them. OpenSearchReader and OpenSearchWriter
|
||||
are the classes provided for reading and writing OpenSearch descriptions.
|
||||
|
||||
Default constructed engines need to be filled with the necessary information before
|
||||
they can be used to peform search requests. First of all, a search engine should have
|
||||
the metadata including the name and the description.
|
||||
However, the most important are URL templates, which are the construction of URLs
|
||||
but can also contain template parameters, that are replaced with corresponding values
|
||||
at the time of constructing URLs.
|
||||
|
||||
There are two types of URL templates: search URL template and suggestions URL template.
|
||||
Search URL template is needed for constructing search URLs, which point directly to
|
||||
search results. Suggestions URL template is necessary to construct suggestion queries
|
||||
URLs, which are then used for requesting contextual suggestions, a popular service
|
||||
offered along with search results that provides search terms related to what has been
|
||||
supplied by the user.
|
||||
|
||||
Both types of URLs are constructed by the class, by searchUrl() and suggestionsUrl()
|
||||
functions respectively. However, search requests are supposed to be performed outside
|
||||
the class, while suggestion queries can be executed using the requestSuggestions()
|
||||
method. The class will take care of peforming the network request and parsing the
|
||||
JSON response.
|
||||
|
||||
Both the image request and suggestion queries need network access. The class can
|
||||
perform network requests on its own, though the client application needs to provide
|
||||
a network access manager, which then will to be used for network operations.
|
||||
Without that, both images delivered from remote locations and contextual suggestions
|
||||
will be disabled.
|
||||
|
||||
\sa OpenSearchReader, OpenSearchWriter
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an engine with a given \a parent.
|
||||
*/
|
||||
OpenSearchEngine::OpenSearchEngine(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_searchMethod(QLatin1String("get"))
|
||||
, m_suggestionsMethod(QLatin1String("get"))
|
||||
, m_suggestionsReply(0)
|
||||
, m_delegate(0)
|
||||
{
|
||||
m_requestMethods.insert(QLatin1String("get"), QNetworkAccessManager::GetOperation);
|
||||
m_requestMethods.insert(QLatin1String("post"), QNetworkAccessManager::PostOperation);
|
||||
}
|
||||
|
||||
/*!
|
||||
A destructor.
|
||||
*/
|
||||
OpenSearchEngine::~OpenSearchEngine()
|
||||
{
|
||||
}
|
||||
|
||||
QString OpenSearchEngine::parseTemplate(const QString &searchTerm, const QString &searchTemplate)
|
||||
{
|
||||
QString language = QLocale().name();
|
||||
// Simple conversion to RFC 3066.
|
||||
language = language.replace(QLatin1Char('_'), QLatin1Char('-'));
|
||||
|
||||
QString result = searchTemplate;
|
||||
result.replace(QLatin1String("{count}"), QLatin1String("20"));
|
||||
result.replace(QLatin1String("{startIndex}"), QLatin1String("0"));
|
||||
result.replace(QLatin1String("{startPage}"), QLatin1String("0"));
|
||||
result.replace(QLatin1String("{language}"), language);
|
||||
result.replace(QLatin1String("{inputEncoding}"), QLatin1String("UTF-8"));
|
||||
result.replace(QLatin1String("{outputEncoding}"), QLatin1String("UTF-8"));
|
||||
result.replace(QRegExp(QLatin1String("\\{([^\\}]*:|)source\\??\\}")), QCoreApplication::applicationName());
|
||||
result.replace(QLatin1String("{searchTerms}"), QLatin1String(QUrl::toPercentEncoding(searchTerm)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property OpenSearchEngine::name
|
||||
\brief the name of the engine
|
||||
|
||||
\sa description()
|
||||
*/
|
||||
QString OpenSearchEngine::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setName(const QString &name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property OpenSearchEngine::description
|
||||
\brief the description of the engine
|
||||
|
||||
\sa name()
|
||||
*/
|
||||
QString OpenSearchEngine::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setDescription(const QString &description)
|
||||
{
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property OpenSearchEngine::searchUrlTemplate
|
||||
\brief the template of the search URL
|
||||
|
||||
\sa searchUrl(), searchParameters(), suggestionsUrlTemplate()
|
||||
*/
|
||||
QString OpenSearchEngine::searchUrlTemplate() const
|
||||
{
|
||||
return m_searchUrlTemplate;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setSearchUrlTemplate(const QString &searchUrlTemplate)
|
||||
{
|
||||
if (!searchUrlTemplate.startsWith(QLatin1String("http://")) && !searchUrlTemplate.startsWith(QLatin1String("https://"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_searchUrlTemplate = searchUrlTemplate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs and returns a search URL with a given \a searchTerm.
|
||||
|
||||
The URL template is processed according to the specification:
|
||||
http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_URL_template_syntax
|
||||
|
||||
A list of template parameters currently supported and what they are replaced with:
|
||||
\table
|
||||
\header \o parameter
|
||||
\o value
|
||||
\row \o "{count}"
|
||||
\o "20"
|
||||
\row \o "{startIndex}"
|
||||
\o "0"
|
||||
\row \o "{startPage}"
|
||||
\o "0"
|
||||
\row \o "{language}"
|
||||
\o "the default language code (RFC 3066)"
|
||||
\row \o "{inputEncoding}"
|
||||
\o "UTF-8"
|
||||
\row \o "{outputEncoding}"
|
||||
\o "UTF-8"
|
||||
\row \o "{*:source}"
|
||||
\o "application name, QCoreApplication::applicationName()"
|
||||
\row \o "{searchTerms}"
|
||||
\o "the string supplied by the user"
|
||||
\endtable
|
||||
|
||||
\sa searchUrlTemplate(), searchParameters(), suggestionsUrl()
|
||||
*/
|
||||
QUrl OpenSearchEngine::searchUrl(const QString &searchTerm) const
|
||||
{
|
||||
if (m_searchUrlTemplate.isEmpty()) {
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
QUrl retVal = QUrl::fromEncoded(parseTemplate(searchTerm, m_searchUrlTemplate).toUtf8());
|
||||
|
||||
QUrlQuery query(retVal);
|
||||
if (m_searchMethod != QLatin1String("post")) {
|
||||
Parameters::const_iterator end = m_searchParameters.constEnd();
|
||||
Parameters::const_iterator i = m_searchParameters.constBegin();
|
||||
for (; i != end; ++i) {
|
||||
query.addQueryItem(i->first, parseTemplate(searchTerm, i->second));
|
||||
}
|
||||
retVal.setQuery(query);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
QByteArray OpenSearchEngine::getPostData(const QString &searchTerm) const
|
||||
{
|
||||
if (m_searchMethod != QLatin1String("post")) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QUrl retVal = QUrl("http://foo.bar");
|
||||
|
||||
QUrlQuery query(retVal);
|
||||
Parameters::const_iterator end = m_searchParameters.constEnd();
|
||||
Parameters::const_iterator i = m_searchParameters.constBegin();
|
||||
for (; i != end; ++i) {
|
||||
query.addQueryItem(i->first, parseTemplate(searchTerm, i->second));
|
||||
}
|
||||
retVal.setQuery(query);
|
||||
|
||||
QByteArray data = retVal.toEncoded(QUrl::RemoveScheme);
|
||||
return data.contains('?') ? data.mid(data.lastIndexOf('?') + 1) : QByteArray();
|
||||
}
|
||||
|
||||
/*!
|
||||
\property providesSuggestions
|
||||
\brief indicates whether the engine supports contextual suggestions
|
||||
*/
|
||||
bool OpenSearchEngine::providesSuggestions() const
|
||||
{
|
||||
return (!m_suggestionsUrlTemplate.isEmpty() || !m_preparedSuggestionsUrl.isEmpty());
|
||||
}
|
||||
|
||||
/*!
|
||||
\property OpenSearchEngine::suggestionsUrlTemplate
|
||||
\brief the template of the suggestions URL
|
||||
|
||||
\sa suggestionsUrl(), suggestionsParameters(), searchUrlTemplate()
|
||||
*/
|
||||
QString OpenSearchEngine::suggestionsUrlTemplate() const
|
||||
{
|
||||
return m_suggestionsUrlTemplate;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setSuggestionsUrlTemplate(const QString &suggestionsUrlTemplate)
|
||||
{
|
||||
if (!suggestionsUrlTemplate.startsWith(QLatin1String("http://")) && !suggestionsUrlTemplate.startsWith(QLatin1String("https://"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_suggestionsUrlTemplate = suggestionsUrlTemplate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a suggestions URL with a given \a searchTerm.
|
||||
|
||||
The URL template is processed according to the specification:
|
||||
http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_URL_template_syntax
|
||||
|
||||
See searchUrl() for more information about processing template parameters.
|
||||
|
||||
\sa suggestionsUrlTemplate(), suggestionsParameters(), searchUrl()
|
||||
*/
|
||||
QUrl OpenSearchEngine::suggestionsUrl(const QString &searchTerm) const
|
||||
{
|
||||
if (!m_preparedSuggestionsUrl.isEmpty()) {
|
||||
QString s = m_preparedSuggestionsUrl;
|
||||
s.replace(QLatin1String("%s"), searchTerm);
|
||||
return QUrl(s);
|
||||
}
|
||||
|
||||
if (m_suggestionsUrlTemplate.isEmpty()) {
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
QUrl retVal = QUrl::fromEncoded(parseTemplate(searchTerm, m_suggestionsUrlTemplate).toUtf8());
|
||||
|
||||
QUrlQuery query(retVal);
|
||||
if (m_suggestionsMethod != QLatin1String("post")) {
|
||||
Parameters::const_iterator end = m_suggestionsParameters.constEnd();
|
||||
Parameters::const_iterator i = m_suggestionsParameters.constBegin();
|
||||
for (; i != end; ++i) {
|
||||
query.addQueryItem(i->first, parseTemplate(searchTerm, i->second));
|
||||
}
|
||||
retVal.setQuery(query);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property searchParameters
|
||||
\brief additional parameters that will be included in the search URL
|
||||
|
||||
For more information see:
|
||||
http://www.opensearch.org/Specifications/OpenSearch/Extensions/Parameter/1.0
|
||||
*/
|
||||
OpenSearchEngine::Parameters OpenSearchEngine::searchParameters() const
|
||||
{
|
||||
return m_searchParameters;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setSearchParameters(const Parameters &searchParameters)
|
||||
{
|
||||
m_searchParameters = searchParameters;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property suggestionsParameters
|
||||
\brief additional parameters that will be included in the suggestions URL
|
||||
|
||||
For more information see:
|
||||
http://www.opensearch.org/Specifications/OpenSearch/Extensions/Parameter/1.0
|
||||
*/
|
||||
OpenSearchEngine::Parameters OpenSearchEngine::suggestionsParameters() const
|
||||
{
|
||||
return m_suggestionsParameters;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setSuggestionsParameters(const Parameters &suggestionsParameters)
|
||||
{
|
||||
m_suggestionsParameters = suggestionsParameters;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property searchMethod
|
||||
\brief HTTP request method that will be used to perform search requests
|
||||
*/
|
||||
QString OpenSearchEngine::searchMethod() const
|
||||
{
|
||||
return m_searchMethod;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setSearchMethod(const QString &method)
|
||||
{
|
||||
QString requestMethod = method.toLower();
|
||||
if (!m_requestMethods.contains(requestMethod)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_searchMethod = requestMethod;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property suggestionsMethod
|
||||
\brief HTTP request method that will be used to perform suggestions requests
|
||||
*/
|
||||
QString OpenSearchEngine::suggestionsMethod() const
|
||||
{
|
||||
return m_suggestionsMethod;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setSuggestionsMethod(const QString &method)
|
||||
{
|
||||
QString requestMethod = method.toLower();
|
||||
if (!m_requestMethods.contains(requestMethod)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_suggestionsMethod = requestMethod;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property imageUrl
|
||||
\brief the image URL of the engine
|
||||
|
||||
When setting a new image URL, it won't be loaded immediately. The first request will be
|
||||
deferred until image() is called for the first time.
|
||||
|
||||
\note To be able to request external images, you need to provide a network access manager,
|
||||
which will be used for network operations.
|
||||
|
||||
\sa image(), networkAccessManager()
|
||||
*/
|
||||
QString OpenSearchEngine::imageUrl() const
|
||||
{
|
||||
return m_imageUrl;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setImageUrl(const QString &imageUrl)
|
||||
{
|
||||
m_imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::loadImage() const
|
||||
{
|
||||
if (m_imageUrl.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
|
||||
QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(QUrl::fromEncoded(m_imageUrl.toUtf8())));
|
||||
connect(reply, SIGNAL(finished()), this, SLOT(imageObtained()));
|
||||
}
|
||||
|
||||
void OpenSearchEngine::imageObtained()
|
||||
{
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
||||
|
||||
if (!reply) {
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray response = reply->readAll();
|
||||
|
||||
reply->close();
|
||||
reply->deleteLater();
|
||||
|
||||
if (response.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_image.loadFromData(response);
|
||||
emit imageChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\property image
|
||||
\brief the image of the engine
|
||||
|
||||
When no image URL has been set and an image will be set explicitly, a new data URL
|
||||
will be constructed, holding the image data encoded with Base64.
|
||||
|
||||
\sa imageUrl()
|
||||
*/
|
||||
QImage OpenSearchEngine::image() const
|
||||
{
|
||||
if (m_image.isNull()) {
|
||||
loadImage();
|
||||
}
|
||||
return m_image;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setImage(const QImage &image)
|
||||
{
|
||||
if (m_imageUrl.isEmpty()) {
|
||||
QBuffer imageBuffer;
|
||||
imageBuffer.open(QBuffer::ReadWrite);
|
||||
if (image.save(&imageBuffer, "PNG")) {
|
||||
m_imageUrl = QString(QLatin1String("data:image/png;base64,%1"))
|
||||
.arg(QLatin1String(imageBuffer.buffer().toBase64()));
|
||||
}
|
||||
}
|
||||
|
||||
m_image = image;
|
||||
emit imageChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\property valid
|
||||
\brief indicates whether the engine is valid i.e. the description was properly formed and included all necessary information
|
||||
*/
|
||||
bool OpenSearchEngine::isValid() const
|
||||
{
|
||||
return (!m_name.isEmpty() && !m_searchUrlTemplate.isEmpty());
|
||||
}
|
||||
|
||||
bool OpenSearchEngine::operator==(const OpenSearchEngine &other) const
|
||||
{
|
||||
return (m_name == other.m_name
|
||||
&& m_description == other.m_description
|
||||
&& m_imageUrl == other.m_imageUrl
|
||||
&& m_searchUrlTemplate == other.m_searchUrlTemplate
|
||||
&& m_suggestionsUrlTemplate == other.m_suggestionsUrlTemplate
|
||||
&& m_searchParameters == other.m_searchParameters
|
||||
&& m_suggestionsParameters == other.m_suggestionsParameters);
|
||||
}
|
||||
|
||||
bool OpenSearchEngine::operator<(const OpenSearchEngine &other) const
|
||||
{
|
||||
return (m_name < other.m_name);
|
||||
}
|
||||
|
||||
/*!
|
||||
Requests contextual suggestions on the search engine, for a given \a searchTerm.
|
||||
|
||||
If succeeded, suggestions() signal will be emitted once the suggestions are received.
|
||||
|
||||
\note To be able to request suggestions, you need to provide a network access manager,
|
||||
which will be used for network operations.
|
||||
|
||||
\sa requestSearchResults()
|
||||
*/
|
||||
|
||||
void OpenSearchEngine::setSuggestionsParameters(const QByteArray ¶meters)
|
||||
{
|
||||
m_preparedSuggestionsParameters = parameters;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setSuggestionsUrl(const QString &string)
|
||||
{
|
||||
m_preparedSuggestionsUrl = string;
|
||||
}
|
||||
|
||||
QString OpenSearchEngine::getSuggestionsUrl()
|
||||
{
|
||||
return suggestionsUrl("searchstring").toString().replace(QLatin1String("searchstring"), QLatin1String("%s"));
|
||||
}
|
||||
|
||||
QByteArray OpenSearchEngine::getSuggestionsParameters()
|
||||
{
|
||||
QStringList parameters;
|
||||
Parameters::const_iterator end = m_suggestionsParameters.constEnd();
|
||||
Parameters::const_iterator i = m_suggestionsParameters.constBegin();
|
||||
for (; i != end; ++i) {
|
||||
parameters.append(i->first + QLatin1String("=") + i->second);
|
||||
}
|
||||
|
||||
QByteArray data = parameters.join(QLatin1String("&")).toUtf8();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::requestSuggestions(const QString &searchTerm)
|
||||
{
|
||||
if (searchTerm.isEmpty() || !providesSuggestions()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||
|
||||
if (m_suggestionsReply) {
|
||||
m_suggestionsReply->disconnect(this);
|
||||
m_suggestionsReply->abort();
|
||||
m_suggestionsReply->deleteLater();
|
||||
m_suggestionsReply = 0;
|
||||
}
|
||||
|
||||
Q_ASSERT(m_requestMethods.contains(m_suggestionsMethod));
|
||||
if (m_suggestionsMethod == QLatin1String("get")) {
|
||||
m_suggestionsReply = networkAccessManager.get(QNetworkRequest(suggestionsUrl(searchTerm)));
|
||||
}
|
||||
else {
|
||||
QStringList parameters;
|
||||
Parameters::const_iterator end = m_suggestionsParameters.constEnd();
|
||||
Parameters::const_iterator i = m_suggestionsParameters.constBegin();
|
||||
for (; i != end; ++i) {
|
||||
parameters.append(i->first + QLatin1String("=") + i->second);
|
||||
}
|
||||
|
||||
QByteArray data = parameters.join(QLatin1String("&")).toUtf8();
|
||||
m_suggestionsReply = networkAccessManager.post(QNetworkRequest(suggestionsUrl(searchTerm)), data);
|
||||
}
|
||||
|
||||
connect(m_suggestionsReply, SIGNAL(finished()), this, SLOT(suggestionsObtained()));
|
||||
}
|
||||
|
||||
/*!
|
||||
Requests search results on the search engine, for a given \a searchTerm.
|
||||
|
||||
The default implementation does nothing, to supply your own you need to create your own
|
||||
OpenSearchEngineDelegate subclass and supply it to the engine. Then the function will call
|
||||
the performSearchRequest() method of the delegate, which can then handle the request
|
||||
in a custom way.
|
||||
|
||||
\sa requestSuggestions(), delegate()
|
||||
*/
|
||||
void OpenSearchEngine::requestSearchResults(const QString &searchTerm)
|
||||
{
|
||||
if (!m_delegate || searchTerm.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Q_ASSERT(m_requestMethods.contains(m_searchMethod));
|
||||
|
||||
QNetworkRequest request(QUrl(searchUrl(searchTerm)));
|
||||
QByteArray data;
|
||||
QNetworkAccessManager::Operation operation = m_requestMethods.value(m_searchMethod);
|
||||
|
||||
if (operation == QNetworkAccessManager::PostOperation) {
|
||||
QStringList parameters;
|
||||
Parameters::const_iterator end = m_searchParameters.constEnd();
|
||||
Parameters::const_iterator i = m_searchParameters.constBegin();
|
||||
for (; i != end; ++i) {
|
||||
parameters.append(i->first + QLatin1String("=") + i->second);
|
||||
}
|
||||
|
||||
data = parameters.join(QLatin1String("&")).toUtf8();
|
||||
}
|
||||
|
||||
m_delegate->performSearchRequest(request, operation, data);
|
||||
}
|
||||
|
||||
void OpenSearchEngine::suggestionsObtained()
|
||||
{
|
||||
const QByteArray response = m_suggestionsReply->readAll();
|
||||
|
||||
m_suggestionsReply->close();
|
||||
m_suggestionsReply->deleteLater();
|
||||
m_suggestionsReply = 0;
|
||||
|
||||
QJsonParseError err;
|
||||
QJsonDocument json = QJsonDocument::fromJson(response, &err);
|
||||
const QVariant res = json.toVariant();
|
||||
|
||||
if (err.error != QJsonParseError::NoError || res.type() != QVariant::List)
|
||||
return;
|
||||
|
||||
const QVariantList list = res.toList();
|
||||
|
||||
if (list.size() < 2)
|
||||
return;
|
||||
|
||||
QStringList out;
|
||||
|
||||
foreach (const QVariant &v, list.at(1).toList())
|
||||
out.append(v.toString());
|
||||
|
||||
emit suggestions(out);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\property delegate
|
||||
\brief the delegate that is used to perform specific tasks.
|
||||
|
||||
It can be currently supplied to provide a custom behaviour ofthe requetSearchResults() method.
|
||||
The default implementation does nothing.
|
||||
*/
|
||||
OpenSearchEngineDelegate* OpenSearchEngine::delegate() const
|
||||
{
|
||||
return m_delegate;
|
||||
}
|
||||
|
||||
void OpenSearchEngine::setDelegate(OpenSearchEngineDelegate* delegate)
|
||||
{
|
||||
m_delegate = delegate;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void OpenSearchEngine::imageChanged()
|
||||
|
||||
This signal is emitted whenever the image of the engine changes.
|
||||
|
||||
\sa image(), imageUrl()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void OpenSearchEngine::suggestions(const QStringList &suggestions)
|
||||
|
||||
This signal is emitted whenever new contextual suggestions have been provided
|
||||
by the search engine. To request suggestions, use requestSuggestions().
|
||||
The suggestion set is specified by \a suggestions.
|
||||
|
||||
\sa requestSuggestions()
|
||||
*/
|
|
@ -1,128 +0,0 @@
|
|||
#ifndef OPENSEARCHENGINE_H
|
||||
#define OPENSEARCHENGINE_H
|
||||
|
||||
#include <qpair.h>
|
||||
#include <qimage.h>
|
||||
#include <qmap.h>
|
||||
#include <qnetworkaccessmanager.h>
|
||||
#include <qstring.h>
|
||||
#include <qurl.h>
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
class OpenSearchEngineDelegate;
|
||||
class OpenSearchEngine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void imageChanged();
|
||||
void suggestions(const QStringList &suggestions);
|
||||
|
||||
public:
|
||||
typedef QPair<QString, QString> Parameter;
|
||||
typedef QList<Parameter> Parameters;
|
||||
|
||||
Q_PROPERTY(QString name READ name WRITE setName)
|
||||
Q_PROPERTY(QString description READ description WRITE setDescription)
|
||||
Q_PROPERTY(QString searchUrlTemplate READ searchUrlTemplate WRITE setSearchUrlTemplate)
|
||||
Q_PROPERTY(Parameters searchParameters READ searchParameters WRITE setSearchParameters)
|
||||
Q_PROPERTY(QString searchMethod READ searchMethod WRITE setSearchMethod)
|
||||
Q_PROPERTY(QString suggestionsUrlTemplate READ suggestionsUrlTemplate WRITE setSuggestionsUrlTemplate)
|
||||
Q_PROPERTY(QString suggestionsUrl READ getSuggestionsUrl WRITE setSuggestionsUrl)
|
||||
Q_PROPERTY(Parameters suggestionsParameters READ suggestionsParameters WRITE setSuggestionsParameters)
|
||||
Q_PROPERTY(QString suggestionsMethod READ suggestionsMethod WRITE setSuggestionsMethod)
|
||||
Q_PROPERTY(bool providesSuggestions READ providesSuggestions)
|
||||
Q_PROPERTY(QString imageUrl READ imageUrl WRITE setImageUrl)
|
||||
Q_PROPERTY(bool valid READ isValid)
|
||||
|
||||
OpenSearchEngine(QObject* parent = 0);
|
||||
~OpenSearchEngine();
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
QString description() const;
|
||||
void setDescription(const QString &description);
|
||||
|
||||
QString searchUrlTemplate() const;
|
||||
void setSearchUrlTemplate(const QString &searchUrl);
|
||||
|
||||
QByteArray getPostData(const QString &searchTerm) const;
|
||||
|
||||
bool providesSuggestions() const;
|
||||
|
||||
QString suggestionsUrlTemplate() const;
|
||||
void setSuggestionsUrlTemplate(const QString &suggestionsUrl);
|
||||
QUrl suggestionsUrl(const QString &searchTerm) const;
|
||||
|
||||
Parameters searchParameters() const;
|
||||
void setSearchParameters(const Parameters &searchParameters);
|
||||
|
||||
Parameters suggestionsParameters() const;
|
||||
void setSuggestionsParameters(const Parameters &suggestionsParameters);
|
||||
|
||||
QString searchMethod() const;
|
||||
void setSearchMethod(const QString &method);
|
||||
|
||||
QString suggestionsMethod() const;
|
||||
void setSuggestionsMethod(const QString &method);
|
||||
|
||||
QString imageUrl() const;
|
||||
void setImageUrl(const QString &url);
|
||||
|
||||
QImage image() const;
|
||||
void setImage(const QImage &image);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void setSuggestionsUrl(const QString &string);
|
||||
void setSuggestionsParameters(const QByteArray ¶meters);
|
||||
QString getSuggestionsUrl();
|
||||
QByteArray getSuggestionsParameters();
|
||||
|
||||
OpenSearchEngineDelegate* delegate() const;
|
||||
void setDelegate(OpenSearchEngineDelegate* delegate);
|
||||
|
||||
bool operator==(const OpenSearchEngine &other) const;
|
||||
bool operator<(const OpenSearchEngine &other) const;
|
||||
|
||||
public slots:
|
||||
QUrl searchUrl(const QString &searchTerm) const;
|
||||
void requestSuggestions(const QString &searchTerm);
|
||||
void requestSearchResults(const QString &searchTerm);
|
||||
|
||||
protected:
|
||||
static QString parseTemplate(const QString &searchTerm, const QString &searchTemplate);
|
||||
void loadImage() const;
|
||||
|
||||
private slots:
|
||||
void imageObtained();
|
||||
void suggestionsObtained();
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_description;
|
||||
|
||||
QString m_imageUrl;
|
||||
QImage m_image;
|
||||
|
||||
QString m_searchUrlTemplate;
|
||||
QString m_suggestionsUrlTemplate;
|
||||
Parameters m_searchParameters;
|
||||
Parameters m_suggestionsParameters;
|
||||
QString m_searchMethod;
|
||||
QString m_suggestionsMethod;
|
||||
|
||||
QByteArray m_preparedSuggestionsParameters;
|
||||
QString m_preparedSuggestionsUrl;
|
||||
|
||||
QMap<QString, QNetworkAccessManager::Operation> m_requestMethods;
|
||||
|
||||
QNetworkReply* m_suggestionsReply;
|
||||
|
||||
OpenSearchEngineDelegate* m_delegate;
|
||||
};
|
||||
|
||||
#endif // OPENSEARCHENGINE_H
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
#include "opensearchenginedelegate.h"
|
||||
|
||||
/*!
|
||||
\class OpenSearchEngineDelegate
|
||||
\brief An abstract class providing custom processing of specific activities.
|
||||
|
||||
OpenSearchEngineDelegate is an abstract class that can be subclassed and set on
|
||||
an OpenSearchEngine. It allows to customize some parts of the default implementation
|
||||
or even extend it with missing bits.
|
||||
|
||||
Currently subclasses can only provide a custom way of handling search requests by
|
||||
reimplementing the performSearchRequest() method.
|
||||
|
||||
\sa OpenSearchEngine
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs the delegate.
|
||||
*/
|
||||
OpenSearchEngineDelegate::OpenSearchEngineDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Destructs the delegate.
|
||||
*/
|
||||
OpenSearchEngineDelegate::~OpenSearchEngineDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void performSearchRequest(const QNetworkRequest &request,
|
||||
QNetworkAccessManager::Operation operation, const QByteArray &data) = 0
|
||||
|
||||
This method will be used after OpenSearchEngine::requestResults() is called.
|
||||
|
||||
For example, a console application that uses the OpenSearchEngine class to generate
|
||||
a search URL for a search term supplied by the user would reimplement the function
|
||||
and forward the request to e.g. a web browser.
|
||||
|
||||
Likewise, a web browser that uses the OpenSearchEngine class to support multiple search
|
||||
engines e.g. in a toolbar would perform the request and navigate to the search results site.
|
||||
*/
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef OPENSEARCHENGINEDELEGATE_H
|
||||
#define OPENSEARCHENGINEDELEGATE_H
|
||||
|
||||
#include <qnetworkaccessmanager.h>
|
||||
#include <qnetworkrequest.h>
|
||||
|
||||
class OpenSearchEngineDelegate
|
||||
{
|
||||
public:
|
||||
OpenSearchEngineDelegate();
|
||||
virtual ~OpenSearchEngineDelegate();
|
||||
|
||||
virtual void performSearchRequest(const QNetworkRequest &request,
|
||||
QNetworkAccessManager::Operation operation,
|
||||
const QByteArray &data) = 0;
|
||||
};
|
||||
|
||||
#endif // OPENSEARCHENGINEDELEGATE_H
|
87
interface/src/webbrowser/webbrowsersuggestionsengine.cpp
Normal file
87
interface/src/webbrowser/webbrowsersuggestionsengine.cpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// webbrowsersuggestionsengine.cpp
|
||||
// interface/src/webbrowser
|
||||
//
|
||||
// Created by Vlad Stelmahovsky Kapolka on 30/10/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "webbrowsersuggestionsengine.h"
|
||||
#include "qregexp.h"
|
||||
|
||||
#include <qbuffer.h>
|
||||
#include <qcoreapplication.h>
|
||||
#include <qlocale.h>
|
||||
#include <qnetworkrequest.h>
|
||||
#include <qnetworkreply.h>
|
||||
#include <qregexp.h>
|
||||
#include <qstringlist.h>
|
||||
|
||||
#include <QUrlQuery>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <NetworkAccessManager.h>
|
||||
|
||||
const QString GoogleSuggestionsUrl = "https://suggestqueries.google.com/complete/search?output=firefox&q=%1";
|
||||
|
||||
WebBrowserSuggestionsEngine::WebBrowserSuggestionsEngine(QObject* parent)
|
||||
: QObject(parent)
|
||||
, _suggestionsReply(0) {
|
||||
_currentNAM = &NetworkAccessManager::getInstance();
|
||||
connect(_currentNAM, &QNetworkAccessManager::finished, this, &WebBrowserSuggestionsEngine::suggestionsFinished);
|
||||
}
|
||||
|
||||
|
||||
WebBrowserSuggestionsEngine::~WebBrowserSuggestionsEngine() {
|
||||
disconnect(_currentNAM, &QNetworkAccessManager::finished, this, &WebBrowserSuggestionsEngine::suggestionsFinished);
|
||||
}
|
||||
|
||||
void WebBrowserSuggestionsEngine::querySuggestions(const QString &searchString) {
|
||||
if (_suggestionsReply) {
|
||||
_suggestionsReply->disconnect(this);
|
||||
_suggestionsReply->abort();
|
||||
_suggestionsReply->deleteLater();
|
||||
_suggestionsReply = 0;
|
||||
}
|
||||
QString url = QString(GoogleSuggestionsUrl).arg(searchString);
|
||||
_suggestionsReply = _currentNAM->get(QNetworkRequest(url));
|
||||
}
|
||||
|
||||
void WebBrowserSuggestionsEngine::suggestionsFinished(QNetworkReply *reply) {
|
||||
|
||||
if (reply != _suggestionsReply) {
|
||||
return; //invalid reply. ignore
|
||||
}
|
||||
|
||||
const QByteArray response = _suggestionsReply->readAll();
|
||||
|
||||
_suggestionsReply->close();
|
||||
_suggestionsReply->deleteLater();
|
||||
_suggestionsReply = 0;
|
||||
|
||||
QJsonParseError err;
|
||||
QJsonDocument json = QJsonDocument::fromJson(response, &err);
|
||||
const QVariant res = json.toVariant();
|
||||
|
||||
if (err.error != QJsonParseError::NoError || res.type() != QVariant::List) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QVariantList list = res.toList();
|
||||
|
||||
if (list.size() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList out;
|
||||
const QVariantList& suggList = list.at(1).toList();
|
||||
|
||||
foreach (const QVariant &v, suggList) {
|
||||
out.append(v.toString());
|
||||
}
|
||||
|
||||
emit suggestions(out);
|
||||
}
|
46
interface/src/webbrowser/webbrowsersuggestionsengine.h
Normal file
46
interface/src/webbrowser/webbrowsersuggestionsengine.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef WEBBROWSERSUGGESTIONSENGINE_H
|
||||
#define WEBBROWSERSUGGESTIONSENGINE_H
|
||||
|
||||
#include <qpair.h>
|
||||
#include <qimage.h>
|
||||
#include <qmap.h>
|
||||
//
|
||||
// webbrowsersuggestionsengine.h
|
||||
// interface/src/webbrowser
|
||||
//
|
||||
// Created by Vlad Stelmahovsky Kapolka on 30/10/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <qnetworkaccessmanager.h>
|
||||
#include <qstring.h>
|
||||
#include <qurl.h>
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
class WebBrowserSuggestionsEngine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WebBrowserSuggestionsEngine(QObject* parent = 0);
|
||||
virtual ~WebBrowserSuggestionsEngine();
|
||||
|
||||
public slots:
|
||||
void querySuggestions(const QString& searchString);
|
||||
|
||||
signals:
|
||||
void suggestions(const QStringList& suggestions);
|
||||
|
||||
private slots:
|
||||
void suggestionsFinished(QNetworkReply *reply);
|
||||
private:
|
||||
QNetworkReply* _suggestionsReply;
|
||||
QNetworkAccessManager* _currentNAM;
|
||||
};
|
||||
|
||||
#endif // WEBBROWSERSUGGESTIONSENGINE_H
|
||||
|
Loading…
Reference in a new issue