/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** 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 Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/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: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
    \title Enginio C++ Examples - Todos
    \example todos-cpp
    \brief The Todo example shows the \l {EnginioModelCpp}{EnginioModel} usage together with QtWigets.
    \ingroup enginio-examples
    \inmodule enginio-qt

    In this example, a simple list of objects is displayed in a \l QListView.
    Each item in the list is a "To Do" object which can be "done" or "not yet done".
    Todos can be added, removed, or altered.
    \image todo-example.png

    In this simple schema the objects will have two properties that are added
    to the default properties (such as creation date which always exists):
    a string "title" and a bool "completed". The object type will be created
    when a call to create, or in this case EnginoModel::append(), is made.

    A todo object will look like this (in JSON):
    \code
{
  "title": "Buy Milk",
  "completed": false
}
    \endcode

    The first step is to create a TodosModel which inherits \l {EnginioModelCpp}{EnginioModel}
    and defines the main roles which will be used. As we are interested in the To Do \c title
    and the \c completed information we need to define these two roles.
    \snippet todos-cpp/todosmodel.h definition

    By default views (for example \l QListView) use the \l{Qt::ItemDataRole} role to display or edit the content.
    The newly created \l{EnginioModelCpp}{EnginioModel} is empty and defines basic roles. Most roles are created
    dynamically, based on the json data-structure.  They have no predefined value in the \l Qt::ItemDataRole enum.
    \l{EnginioModelCpp}{EnginioModel} automatically populates itself as soon as the
    \l{EnginioModel::query}{query} and \l{EnginioModel::client}{client} properties have been set.
    When the data is downloaded, the model resets itself, and sets up the internal data cache and roles names.
    \l{EnginioModelCpp}{EnginioModel} guesses the role names based on heuristics and it may be wrong if not all
    objects received from the backend have exactly the same structure, for example a property can be missing
    in certain objects. To protect against such cases we overload \l{EnginioModel::roleNames()}{roleNames()}.
    Overriding \l{EnginioModel::roleNames()}{roleNames()} can also be used to match default Qt roles to the named
    ones.

    \snippet todos-cpp/todosmodel.cpp roleNames

    In this example we map the \l Qt::DisplayRole and \l Qt::EditRole to the "title" property in the JSON.
    This way the right string is shown by default and editing works as expected.

    Remember to always call the base class implementation to avoid situations in which the internal cache is not in sync.

    By default \l {EnginioModelCpp}{EnginioModel} operates on \l{QJsonValue}, and that is
    what the \l{EnginioModel::data()}{data()} function returns inside the \l QVariant, but standard
    views, such as \l QListView, use predefined roles which do not map directly to our roles.
    That is why we need to write a mapping between them:

    \snippet todos-cpp/todosmodel.cpp data

    As we have our model defined, we need to create an instance of \l EnginioClient:

    \snippet todos-cpp/mainwindow.cpp client

    It is used by model to connect to the Enginio backend. Next we need to construct
    and configure our model too. The configuration is based on two steps, assigning
    an \l EnginioClient instance and by creating a query.

    \snippet todos-cpp/mainwindow.cpp model

    The model has to be assigned to a view, in our case it is a \l QListView.

    \snippet todos-cpp/mainwindow.cpp assignModel

    To make the application fully functional, a way to add and remove "To Dos" is needed.
    To do so, we need to connect correct buttons to slots for adding a new item:

    \snippet todos-cpp/mainwindow.cpp appendItem

    and for removing it:

    \snippet todos-cpp/mainwindow.cpp removeItem
*/
