/****************************************************************************
**
** 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

*/
