| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** 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. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \example googlesuggest |
| \title Google Suggest Example |
| \ingroup examples-network |
| \brief Obtains the list of search recommendations by the Google search engine. |
| |
| The example uses the QNetworkAccessManager to obtain the list of search |
| recommendations by Google as the user types into a QLineEdit. |
| |
| \image googlesuggest-example.png |
| |
| The application makes use of the \c get function in |
| QNetworkAccessManager to post a request and obtain the result of the search |
| query sent to the Google search engine. The results returned are listed as |
| clickable links appearing below the search box as a drop-down menu. |
| |
| The widget is built up by a QLineEdit as the search box, and a QTreeView |
| used as a popup menu below the search box. |
| |
| \section1 GSuggestCompletion Class Declaration |
| |
| This class implements an event filter and a number of functions to display |
| the search results and to determent when and how to perform the search. |
| |
| \snippet googlesuggest/googlesuggest.h 1 |
| |
| The class connects to a QLineEdit and uses a QTreeWidget to display the |
| results. A QTimer controls the start of the network requests that are |
| executed using a QNetworkAccessManager. |
| |
| \section1 GSuggestCompletion Class Implementation |
| |
| We start by defining a constant containing the URL to be used in the Google |
| queries. This is the basis for the query. The letters typed into the search |
| box will be added to the query to perform the search itself. |
| |
| \snippet googlesuggest/googlesuggest.cpp 1 |
| |
| In the constructor, we set the parent of this GSuggestCompletion instance |
| to be the QLineEdit passed in. For simplicity, the QLineEdit is also stored |
| in the explicit \c editor member variable. |
| |
| We then create a QTreeWidget as a toplevel widget and configure the various |
| properties to give it the look of a popup widget. The widget is populated |
| with the results by Google Suggest API request. |
| |
| Furthermore, we install the GSuggestCompletion instance as an event filter |
| on the QTreeWidget, and connect the \c itemClicked() signal with the \c |
| doneCompletion() slot. |
| |
| A single-shot QTimer is used to start the request when the user has stopped |
| typing for 500 ms. |
| |
| Finally, we connect the networkManagers \c finished() signal with the \c |
| handleNetworkData() slot to handle the incoming data. |
| |
| \snippet googlesuggest/googlesuggest.cpp 2 |
| |
| Since the QTreeWidget popup has been instantiated as a toplevel widget, the |
| destructor has to delete it explicitly from memory to avoid a memory leak. |
| |
| \snippet googlesuggest/googlesuggest.cpp 3 |
| |
| The event filter handles mouse press and key press events that are |
| delivered to the popup. For mouse press events we just hide the popup and |
| return focus to the editor widget, and then return true to prevent further |
| event processing. |
| |
| Key event handling is implemented so that Enter and Return execute the |
| selected link, while the Escape key hides the popup. Since we want to be |
| able to navigate the list of suggestions using the different navigation |
| keys on the keyboard we let Qt continue regular event processing for those |
| by returning false from the eventFilter reimplementation. |
| |
| For all other keys, the event will be passed on to the editor widget and the |
| popup is hidden. This way the user's typing will not be interrupted by the |
| popping up of the completion list. |
| |
| \snippet googlesuggest/googlesuggest.cpp 4 |
| |
| The \c showCompletion() function populates the QTreeWidget with the results |
| returned from the query. It takes a QStringList of the suggested search |
| terms. |
| |
| \snippet googlesuggest/googlesuggest.cpp 5 |
| |
| A QTreeWidgetItem is created for each index in the list and inserted into |
| the QTreeWidget. Finally, we adjust position and size of the popup to make |
| sure that it pops up in the correct position below the editor, and show it. |
| |
| The \c doneCompletion() function, which is called by the event filter when |
| either Enter or Return keys are pressed, stops the timer to prevent further |
| requests and passes the text of the selected item to the editor. We then |
| make the \c editor QLineEdit emit the returnPressed() signal, to which the |
| application can connect to open the respective web page. |
| |
| \snippet googlesuggest/googlesuggest.cpp 6 |
| |
| The \c autoSuggest() slot is called when the timer times out, and uses the |
| text in the editor to build the complete search query. The query is then |
| passed to the QNetworkAccessManager's \c get() function to start the |
| request. |
| |
| \snippet googlesuggest/googlesuggest.cpp 7 |
| |
| The function \c preventSuggest() stops the timer to prevent further |
| requests from being started. |
| |
| \snippet googlesuggest/googlesuggest.cpp 8 |
| |
| When the network request is finished, the QNetworkAccessManager delivers the |
| data received from the server through the networkReply object. |
| |
| \snippet googlesuggest/googlesuggest.cpp 9 |
| |
| To extract the data from the reply we use the \c readAll() function, which |
| is inherited from QIODevice and returns a QByteArray. Since this data is |
| encoded in XML we can use a QXmlStreamReader to traverse the data and |
| extract the search result as QStrings, which we can stream into two |
| QStringLists used to populate the popup. |
| |
| Finally, we schedule the QNetworkReply object for deletion using the \c |
| deleteLater function. |
| |
| \section1 SearchBox Class Declaration |
| |
| The SearchBox class inherits QLineEdit and adds the protected slot \c |
| doSearch(). |
| |
| A \c GSuggestCompletion member provides the SearchBox with the request |
| functionality and the suggestions returned from the Google search engine. |
| |
| \snippet googlesuggest/searchbox.h 1 |
| |
| \section1 SearchBox Class Implementation |
| |
| The search box constructor instantiates the GSuggestCompletion object and |
| connects the returnPressed() signal to the doSearch() slot. |
| |
| \snippet googlesuggest/searchbox.cpp 1 |
| |
| The function \c doSearch() stops the completer from sending any further |
| queries to the search engine. |
| |
| Further, the function extracts the selected search phrase and opens it |
| in the default web browser using QDesktopServices. |
| |
| \snippet googlesuggest/searchbox.cpp 2 |
| |
| */ |