/**************************************************************************** ** ** Copyright (C) 2019 Luxoft Sweden AB ** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the QtIvi module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL-QTAS$ ** Commercial License Usage ** Licensees holding valid commercial Qt Automotive Suite 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 ivicore/qface-ivi-addressbook \brief This example shows how to generate models using the Qt IVI Generator. \ingroup qtivicore-examples \title Qt IVI Generator Addressbook Example \image examples_qface_ivi_addressbook.png \section1 Introduction This example shows how to generate a model using the \e model type in a qface file with the Qt IVI Generator. It will only explain the details on how to use the \e model type and how it works internally. For a general introduction to the Qt IVI Generator, please have a look at the \l {ivicore/qface-ivi-climate} {Qt IVI Generator Climate Example}. \section2 Walkthrough The IDL file used in the example represents an addressbook API. It contains a single interface providing the contacts as a model and a struct definition for the actual contact. \snippet ../../../../examples/ivicore/qface-ivi-addressbook/example-ivi-addressbook.qface 0 The \e contact property is defined to be of type \e model. The \l frontend template will create a C++ property of type \l {QIviPagingModel}{QIviPagingModel*}. The getter function of this property returns a valid instance once a backend is connected and the properties are initialized. This QIviPagingModel instance can be used from C++, as well as from QML and already provides the basic functionality for retrieving its data in an optimized fashion using the so called \e Pagination concept. For the backend interface the property type is different and will be a \l QIviPagingModelInterface pointer. This is needed as the QIviPagingModel is also a QtIvi feature and, like all features, it uses a backend interface for the frontend-backend separation. For more information, see \l{Concepts and Architecture}. The backend plugin needs to implement the \l QIviPagingModelInterface class for every exposed property. The \l backend_simulator template already takes care of this and generates all the needed code. \section1 Configuring the Simulation Backend Plugin By default the generated simulation backend does not populate any data for the model, as the template doesn't know what content it should provide. For this use-case the \l {config_simulator_default}{default} annotation can be used to configure the simulator to provide static simulation data. This is done in the example-ivi-addressbook.yaml file: \quotefile ../../../../examples/ivicore/qface-ivi-addressbook/example-ivi-addressbook.yaml The JSON fragment assigned to the \l {config_simulator_default}{default} variable is parsed by the Qt IVI Generator and will be used to generate a simulation backend which creates two Contact instances and returns them as content for the contacts model. \section1 Demo Application The demo application is not autogenerated, but a standard QQmlEngine setup for an application similar to other examples. \snippet ../../../../examples/ivicore/qface-ivi-addressbook/demo/main.qml 0 The model is retrieved from the \e addressbook object using the \e contacts property and passed to the ListView. The delegate can access the actual contact using the \l {QIviPagingModel::}{ItemRole} of the QIviPagingModel, which is exposed to QML through \e model.item. \section1 Extended Simulation Behavior Because the \l backend_simulator template can only generated a stub, it doesn't know what behavior it should implement for the insertContact function of the qface file. The ivigenerator will simply generate a stub implementation printing a message that this function is not implemented. This limitation is fixed by using the \l {config_simulator_simulationFile}{simulationFile} annotation to tell the autogenerator we want to provide our own simulation QML file. In the example the \e simulationFile annotation points to a QML file in a resource file. The resource file is added to the project file as usual like this: \snippet ../../../../examples/ivicore/qface-ivi-addressbook/backend_simulator/backend_simulator.pro 0 \section2 Providing the simulation behavior in QML The autogenerated simulation backend code loads the simulation behavior from a QML file using a QIviSimulationEngine. This special engine makes sure the autogenerated backend interfaces are provided to the QML file and they can be extended from there. It also makes sure that the interfaces are available only to this engine instance and to no other engine running in the same process (e.g. in the frontend). See the QIviSimulationEngine documentation for more information about how the engine works. Using the ivigenerator for the simulation backend, the simulation interfaces are provided in the \e example.ivi.addressbook.simulation uri. The provided types are named after the backend interfaces implemented by the simulation backend. For our example two types are registered: \list \li AddressBookBackend \li ContactsModelBackend \endlist Our simulation QML file looks like this: \snippet ../../../../examples/ivicore/qface-ivi-addressbook/backend_simulator/simulation.qml 0 It creates an AddressBookBackend instance and prints a message once the QML code is loaded by using the Component.onCompleted handler. To implement the behavior for the insertContact function, a JS function is added to the AddressBookBackend object in QML. This function takes three arguments, the first one is an PendingReply object used to notify the frontend once the request was successful or failed. The other arguments are as defined in the IDL file. To insert the provided contact to our list we use the \e contacts property which hold the implementation of the QIviPagingModelInterface for the contacts property. This implementation provides some extra convenience functions which can be used by the simulation to modify the model in an easy way. In our case we just call the \c insert() function and let the autogenerated implementation do the rest. */