/**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** BSD License Usage ** Alternatively, you may use this file under the terms of the BSD license ** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of The Qt Company Ltd nor the names of its ** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include class RequestHandler : public QObject { public: void initializeManager() { //! [Initialize Manager] //The "provider name" is used to select a particular provider QGeoServiceProvider *provider = new QGeoServiceProvider("provider name"); QPlaceManager *manager = provider->placeManager(); //! [Initialize Manager] Q_UNUSED(provider); Q_UNUSED(manager); } void simpleSearch() { //! [Simple search] //1) Make an appropriate request QPlaceSearchRequest searchRequest; searchRequest.setSearchTerm("ice cream"); searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(12.34, 56.78))); //2) Use the manager to initiate a request and retrieve a reply object QPlaceSearchReply * searchReply = manager->search(searchRequest); //3) Connect the reply object to a slot which is invoked upon operation completion connect(searchReply, SIGNAL(finished()), this, SLOT(processSearchReply())); //! [Simple search] } void search() { //! [Search for places cpp] //instantiate request and set parameters QPlaceSearchRequest searchRequest; searchRequest.setSearchTerm("ice cream"); searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(12.34, 56.78))); //send off a search request /*QPlaceSearchReply * */ searchReply = manager->search(searchRequest); //connect a slot to handle the reply connect(searchReply, SIGNAL(finished()), this, SLOT(handleSearchReply())); //! [Search for places cpp] } void searchPaging() { //! [Search paging] QPlaceSearchRequest searchRequest; searchRequest.setLimit(15); //specify how many results are to be retrieved. //! [Search paging] } void details() { QPlace place; //! [Details check] if (!place.detailsFetched()) { /*QPlaceDetailsReply * */ detailsReply = manager->getPlaceDetails(place.placeId()); connect(detailsReply, SIGNAL(finished()), this, SLOT(handleDetailsReply())); } //! [Details check] } void images() { QPlace place; //! [Image request] QPlaceContentRequest request; request.setContentType(QPlaceContent::ImageType); request.setPlaceId(place.placeId()); request.setLimit(5); /*QPlaceContentReply * */ contentReply = manager->getPlaceContent(request); connect(contentReply, SIGNAL(finished()), this, SLOT(handleImagesReply())); //! [Image request] } void suggestion() { //! [Suggestion request] QPlaceSearchRequest request; request.setSearchTerm("piz"); request.setSearchArea(QGeoCircle(QGeoCoordinate(12.34, 56.78))); /* QPlaceSearchSuggestion * */suggestionReply = manager->searchSuggestions(request); connect(suggestionReply, SIGNAL(finished()), this, SLOT(handleSuggestionReply())); //! [Suggestion request] } void savePlace() { //! [Save place pt1] QPlace place; place.setName( "Fred's Ice Cream Parlor" ); QGeoLocation location; location.setCoordinate(QGeoCoordinate(12.34, 56.78)); QGeoAddress address; address.setStreet("111 Nother Street"); //! [Save place pt1] //! [Save place pt2] location.setAddress(address); place.setLocation(location); /* QPlaceIdReply * */savePlaceReply = manager->savePlace(place); connect(savePlaceReply, SIGNAL(finished()), this, SLOT(handleSavePlaceReply())); //! [Save place pt2] } void removePlace() { QPlace place; //! [Remove place] /* QPlaceIdReply * */removePlaceReply = manager->removePlace(place.placeId()); connect(removePlaceReply, SIGNAL(finished()), this, SLOT(handleRemovePlaceReply())); //! [Remove place] } void initializeCategories() { //! [Initialize categories] /* QPlaceReply * */initCatReply = manager->initializeCategories(); connect(initCatReply, SIGNAL(finished()), this, SLOT(handleInitCatReply())); //! [Initialize categories] } void saveCategory() { //! [Save category] QPlaceCategory fastFood; QPlaceCategory category; category.setName("pizza"); /*QPlaceIdReply */ saveCategoryReply = manager->saveCategory(category); connect(saveCategoryReply, SIGNAL(finished()), this, SLOT(handleSaveCategoryReply())); //we could have saved a category as a child by supplying a parent identifier. saveCategoryReply = manager->saveCategory(category, fastFood.categoryId()); //! [Save category] } void removeCategory() { QPlaceCategory category; //! [Remove category] /* QPlaceIdReply * */removeCategoryReply = manager->removeCategory(place.placeId()); connect(removeCategoryReply, SIGNAL(finished()), this, SLOT(handleRemoveCategoryReply())); //! [Remove category] } void searchRequest() { QPlaceCategory diner; QPlaceCategory restaurant; //! [Search request] QPlaceSearchRequest searchRequest; searchRequest.setSearchTerm("Fast food"); //search term for what we are interested in //set a search center searchRequest.setSearchArea(QGeoCircle(QGeoCoordinate(2.3, 48.87))); //set a distance hint as a relevancy hint. //closer places have greater weighting in the ranking of results. searchRequest.setRelevanceHint(QPlaceSearchRequest::DistanceHint); //use limit to adjust pagination. //this limits the number of place results to 5 per page. searchRequest.setLimit(5); //provide some categories to narrow down search QList categories; categories << diner << restaurant; searchRequest.setCategories(categories); //! [Search request] } void content() { QPlace place; //! [Content request] QPlaceContentRequest request; request.setContentType(QPlaceContent::ImageType); request.setPlaceId(place.placeId()); request.setLimit(5); QPlaceContentReply *contentReply = manager->getPlaceContent(request); //..connect signals..// //! [Content request] Q_UNUSED(contentReply); } void contentConversion() { //! [Content conversion] QPlaceImage image; image.setUrl(QUrl("www.example.com")); QPlaceContent content = image; QPlaceImage image2; image2 = content; qDebug() << image2.url(); //image2.url() == "www.example.com" //! [Content conversion] } void icon() { QPlace place; //! [icon] QUrl iconSourceUrl = place.icon().url(QSize(32,32)); //A default icon may also be requested like so iconSourceUrl = place.icon().url(); //! [icon] } void saveBetweenManagers() { QPlaceResult result; QPlaceIdReply *saveReply; //! [ Save to different manager] //result retrieved from a different manager) QPlace place = manager->compatiblePlace(result.place()); saveReply = manager->savePlace(place); //! [ Save to different manager] saveReply->abort();//needed to avoid warnings } void ratings() { //! [Ratings] qDebug() << QString("This place rated ") + place.ratings().average() + "out of " + place.ratings().maximum() + "stars"; //! [Ratings] } void matchPlaces() { QList results; //! [Match places] QPlaceMatchRequest request; request.setResults(results); QVariantMap parameters; parameters.insert(QPlaceMatchRequest::AlternativeId, "x_id_here"); request.setParameters(parameters); matchReply = manager->matchingPlaces(request); //! [Match places] } public slots: // ![Simple search handler] //4) Have the slot appropriately process the results of the operation void processSearchReply() { if (searchReply->error() == QPlaceReply::NoError) { foreach (const QPlaceSearchResult &result, searchReply->results()) { if (result.type() == QPlaceSearchResult::PlaceResult) qDebug() << "Title:" << result.title(); } } //5) Discard the rely object when done. searchReply->deleteLater(); searchReply = 0; } // ![Simple search handler] //! [Search for places handler cpp] void handleSearchReply() { if (searchReply->error() == QPlaceReply::NoError) { foreach (const QPlaceSearchResult &result, searchReply->results()) { if (result.type() == QPlaceSearchResult::PlaceResult) { QPlaceResult placeResult = result; qDebug() << "Name: " << placeResult.place().name(); qDebug() << "Coordinate " << placeResult.place().location().coordinate().toString(); qDebug() << "Street: " << placeResult.place().location().address().street(); qDebug() << "Distance: " << placeResult.distance(); } } } searchReply->deleteLater(); //discard reply searchReply = 0; } //! [Search for places handler cpp] //! [Details handler cpp] void handleDetailsReply() { QPlace place; if (detailsReply->error() == QPlaceReply::NoError) place = detailsReply->place(); detailsReply->deleteLater(); //discard reply detailsReply = 0; } //! [Details handler cpp] //! [Image handler] void handleImagesReply() { if (contentReply->error() == QPlaceReply::NoError) { const auto content = contentReply->content(); for (auto iter = content.cbegin(), end = content.cend(); iter != end; ++iter) { qDebug() << "Index: " << iter.key(); QPlaceImage image = iter.value(); qDebug() << image.url(); qDebug() << image.mimeType(); } //alternatively if indexes are irrelevant foreach (const QPlaceImage &image, contentReply->content()) { qDebug() << image.url(); qDebug() << image.mimeType(); } //we can assign content to the place that it belongs to. //the place object serves as a container where we can retrieve //content that has already been fetched place.insertContent(contentReply->request().contentType(), contentReply->content()); place.setTotalContentCount(contentReply->request().contentType(), contentReply->totalCount()); } contentReply->deleteLater(); contentReply = 0; } //! [Image handler] //! [Suggestion handler] void handleSuggestionReply() { if (suggestionReply->error() == QPlaceReply::NoError) { foreach (const QString &suggestion, suggestionReply->suggestions()) qDebug() << suggestion; } suggestionReply->deleteLater(); //discard reply suggestionReply = 0; } //! [Suggestion handler] //! [Save place handler] void handleSavePlaceReply() { if (savePlaceReply->error() == QPlaceReply::NoError) qDebug() << savePlaceReply->id(); savePlaceReply->deleteLater(); //discard reply savePlaceReply = 0; } //! [Save place handler] //! [Remove place handler] void handleRemovePlaceReply() { if (removePlaceReply->error() == QPlaceReply::NoError) qDebug() << "Removal of place identified by" << removePlaceReply->id() << "was successful"; removePlaceReply->deleteLater(); //discard reply removePlaceReply = 0; } //! [Remove place handler] //! [Initialize categories reply] void handleInitCatReply() { if (initCatReply->error() == QPlaceReply::NoError) qDebug() << "Categories initialized"; else qDebug() << "Failed to initialize categories"; initCatReply->deleteLater(); initCatReply = 0; } //! [Initialize categories reply] void categories() { QPlaceCategory pizza; //! [Top level categories] QList topLevelCategories = manager->childCategories(); foreach (const QPlaceCategory &category, topLevelCategories) qDebug() << category.name(); //! [Top level categories] //! [Child categories] QList childCategories = manager->childCategories(pizza.categoryId()); //! [Child categories] } //! [Save category handler] void handleSaveCategoryReply() { if (saveCategoryReply->error() == QPlaceReply::NoError) { qDebug() << "Saved category id =" << saveCategoryReply->id(); } saveCategoryReply->deleteLater(); saveCategoryReply = 0; } //! [Save category handler] //! [Remove category handler] void handleRemoveCategoryReply() { if (removeCategoryReply->error() == QPlaceReply::NoError) qDebug() << "Removal of category identified by" << removeCategoryReply->id() << "was successful"; removeCategoryReply->deleteLater(); //discard reply removeCategoryReply = 0; } //! [Remove category handler] //! [Content handler] void contentHandler() { if (contentReply->error() == QPlaceReply::NoError) { place.insertContent(contentReply->request().contentType(), contentReply->content()); } } //! [Content handler] void phoneNumbers() { //! [Phone numbers] if (place.contactTypes().contains(QPlaceContactDetail::Phone)) { foreach (const QPlaceContactDetail &number, place.contactDetails(QPlaceContactDetail::Phone)) qDebug() << number.label() << ":" << number.value(); } //! [Phone numbers] } void openingHours() { //! [Opening hours] if (place.extendedAttributeTypes().contains(QPlaceAttribute::OpeningHours)) qDebug() << place.extendedAttribute(QPlaceAttribute::OpeningHours).text(); //! [Opening hours] } //! [Match places handler] void matchHandler() { if (matchReply->error() == QPlaceReply::NoError) { foreach (const QPlace place, matchReply->places()) { if (place != QPlace()) qDebug() << "Place is a favorite with name" << place.name(); else qDebug() << "Place is not a favorite"; } } matchReply->deleteLater(); matchReply = 0; } //! [Match places handler] void convertSearchResult() { QPlaceSearchResult result; //! [Convert search result] if (result.type() == QPlaceSearchResult::PlaceResult) { QPlaceResult placeResult = result; qDebug() << placeResult.place().name(); qDebug() << placeResult.place().location().coordinate(); qDebug() << placeResult.distance(); } //! [Convert search result] } QPlaceSearchReply *searchReply; QPlaceManager *manager; QPlaceDetailsReply *detailsReply; QPlaceContentReply *contentReply; QPlaceSearchSuggestionReply *suggestionReply; QPlaceIdReply *savePlaceReply; QPlaceIdReply *removePlaceReply; QPlaceIdReply *saveCategoryReply; QPlaceIdReply *removeCategoryReply; QPlaceReply *initCatReply; QPlaceMatchReply *matchReply; QPlace place; }; class ManagerEngine : public QObject { }; //! [Implement reply pt1] class SearchReply : public QPlaceSearchReply { public: explicit SearchReply(ManagerEngine *engine) : QPlaceSearchReply(engine), m_engine(engine){} ~SearchReply(); void setResults(const QList &results); void setRequest(const QPlaceSearchRequest &request); //! [Implement reply pt1] //! [Implement reply pt2] void triggerDone(QPlaceReply::Error error = QPlaceReply::NoError, const QString &errorString = QString()); ManagerEngine *m_engine; }; //! [Implement reply pt2] class SearchSuggestionReply : public QPlaceSearchSuggestionReply { public: void triggerDone(QPlaceReply::Error error = QPlaceReply::NoError, const QString &errorString = QString()); ManagerEngine *m_engine; }; //! [Trigger done] void SearchSuggestionReply::triggerDone(QPlaceReply::Error error, const QString &errorString) { if (error != QPlaceReply::NoError) { this->setError(error,errorString); QMetaObject::invokeMethod(m_engine, "error", Qt::QueuedConnection, Q_ARG(QPlaceReply *,this), Q_ARG(QPlaceReply::Error, error), Q_ARG(QString, errorString)); QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QPlaceReply::Error, error), Q_ARG(QString, errorString)); } this->setFinished(true); QMetaObject::invokeMethod(m_engine, "finished", Qt::QueuedConnection, Q_ARG(QPlaceReply *,this)); QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); } //! [Trigger done]