aboutsummaryrefslogtreecommitdiffstats
path: root/src/ivicore/doc/src/models.qdoc
blob: f55849a27d50e9be210da369c0f7fa81a9b8ea9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** 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 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$
**
****************************************************************************/
/*!
\page models.html
\title Models
\previouspage Dynamic Backend System
\nextpage Qt IVI Query Language
\contentspage Concepts

To interact with lists in Qt applications, typically, you would use Qt's ListView classes, which
are based on the Model-View-Controller (MVC) pattern. Similarly, QtIvi has the following classes
that support this use case, for you to provide your own models:

\list
   \li \l{ivi-abstract-feature-list-model}{QIviAbstractFeatureListModel}
   \li \l{ivi-paging-model}{QIviPagingModel}
   \li \l{ivi-search-and-browse-model}{QIviSearchAndBrowseModel}
\endlist

Apart from creating standalone models using one of classes mentioned above, you can also provide
\l{Models as properties of a QtIvi Feature}{models that are properties of an existing feature}.

\target ivi-abstract-feature-list-model
\section1 QIviAbstractFeatureListModel

Suppose you have to design a feature like a Contact List in a connected Mobile Phone, you can use
QtIvi's frontend/backend separation by deriving from QIviAbstractFeature. Then, you use your
subclass with a QAbstractItemView derived class to show your contacts in a list form.

QtIviCore provides \l{QIviAbstractFeatureListModel::QIviAbstractFeatureListModel}{QIviAbstractFeatureListModel}
for this use case. The class is derived from QAbstractListModel, but also provides all the
functionality from QIviAbstractFeature.

\target ivi-paging-model
\section1 QIviPagingModel

The \l{QIviPagingModel::QIviPagingModel}{QIviPagingModel} is a list model that uses the well-known
Pagination concept to only load content from the backend, when it is needed. This model provides
two different modes that determine when and how data should be retrieved and the number of items
to fetch in each stage.

\section2 Fetch Modes

Since we don't have control on the data providers' interfaces, the
\l{QIviPagingModel::QIviPagingModel}{QIviPagingModel} supports two fetch modes:

\list 1
\li If the number of items in the model is \b not known from the beginning, use the
    \l{QIviPagingModel::FetchMore}{FetchMore} mode. This mode fetches a number of items from the
    backend when they are needed; the backend tells the frontend whether there is more data to be
    fetched.

\li If the number of items in the model is \b known from the beginning, use the
    \l{QIviPagingModel::DataChanged}{DataChanged} mode. This mode fills the complete model with
    empty data and then uses the \l{QAbstractItemModel::dataChanged()} signal to tell the view
    about the actual content.
\endlist

For more details on fetch modes, see \l{QIviPagingModel::QIviPagingModel}{QIviPagingModel}.

\section2 Model Data

\l{QIviPagingModel::QIviPagingModel}{QIviPagingModel} provides a classic item-based approach to
working with the model; the items are provided by QIviStandardItem or classes derived from it. The
best way to provide data to the QIviPagingModel is to create a new class derived from
QIviStandardItem. Then, override the \c name() and \c type() accessor functions. The \c name and
\c type properties for each QIviStandardItem can be retrieved directly from the model's \c data()
function. This function also exposes those properties to delegates in item views, such as ListView.
In addition, the \l{QIviPagingModel::}{ItemRole} provides a const pointer to the QIviStandardItem
stored. Using \l{The Meta-Object System}, all the properties from the derived type are also
available in QML, directly, with this pointer. From C++, you can use the \c at() template function
to cast this const pointer directly to the type you need.

\target ivi-search-and-browse-model
\section1 QIviSearchAndBrowseModel

The \l{QIviSearchAndBrowseModel::QIviSearchAndBrowseModel}{QIviSearchAndBrowseModel} is derived
from the \l{QIviPagingModel::QIviPagingModel}{QIviPagingModel} to extends its functionality. This
class provides a model that supports searching through its content and browsing through a set of
model data.

\section2 Search: Filter and Sort

To filter and sort,
\l{QIviSearchAndBrowseModel::QIviSearchAndBrowseModel}{QIviSearchAndBrowseModel} uses the
\l{Qt IVI Query Language}; this makes the system both flexible and powerful.

\section2 Browse

Although the Qt IVI Query Language supports very complex queries, enabling you to filter content
in a list, it may not suit all use cases. With the query language, the frontend developer defines
which data is needed next. Sometimes, this is not possible, if the backend already has a fixed
browsing order. For example, a DLNA backend already specifies that an artist needs to be selected
first, only then is a list of all albums for that artist presented.

For this scenario, the {QIviSearchAndBrowseModel::QIviSearchAndBrowseModel}{QIviSearchAndBrowseModel}
provides some methods to navigate through the models:

\list
  \li \l{QIviSearchAndBrowseModel::canGoForward}{canGoForward(index)}
  \li \l{QIviSearchAndBrowseModel::goForward}{goForward(index)}
  \li \l{QIviSearchAndBrowseModel::canGoBack}{canGoBack()}
  \li \l{QIviSearchAndBrowseModel::goBack}{goBack()}
\endlist

\section2 Capabilities

You might not need all of the features above simultaneously; or your backend may not support all of
them. In this case, the QIviSearchAndBrowseModel has a capabilities feature where the backend
reports which capabilities it can support. Based on that information, only the supported
functionalities are enabled in the frontend API.

\section2 Modify the Content

{QIviSearchAndBrowseModel::QIviSearchAndBrowseModel}{QIviSearchAndBrowseModel} provides some
generic methods to modify the contents of the model:

\list
  \li \l{QIviSearchAndBrowseModel::insert}{insert()}
  \li \l{QIviSearchAndBrowseModel::remove}{remove()}
  \li \l{QIviSearchAndBrowseModel::move}{move()}
\endlist

\target models-as-properties
\section1 Models as Properties of a QtIvi Feature

In some cases, you might need a model as a property of a specific QtIvi Feature. A good example
is a MediaPlayer feature, where you provide the basic player functionality like the play state. In
addition you also want to provide the current play queue as a model to display it nicely inside a
ListView.

This play queue might be long, a vector or list is not a suitable container for it. Using the
{QIviPagingModel::QIviPagingModel}{QIviPagingModel} to only load the items, is a logical
conclusion.

As the {QIviPagingModel::QIviPagingModel}{QIviPagingModel} is a also a QtIvi Feature, it has its
own backend interface which the backend plugin needs to implement.

\image models-as-properties.png

Each model property needs to map to a unique model interface implementation in the backend, as
each model is filled with different data and the data is requested at a different time.
Ultimately, every model instance needs to maintain its own state.

To implement this concept, we use the QIviProxyServiceObject to connect the
{QIviPagingModel::QIviPagingModel}{QIviPagingModel} instance provided with the correct backend
interface instance.

\image models-as-properties-details.png

For the MediaPlayer play queue example, we would implement the following:

\list a
    \li For the Backend
    \list 1
        \li Implement the QIviPagingModelInterface to retrieve the play queue items
        \li Implement the MediaPlayer feature interface and return a pointer to the
            QIviPagingModelInterface implementation for the play queue property
    \endlist

    \li For the Frontend
    \list 1
        \li Retrieve the QIviPagingModelInterface pointer from the backend
        \li Create a QIviProxyServiceObject that holds the QIviPagingModelInterface
        \li Create a \l{QIviPagingModel::QIviPagingModel}{QIviPagingModel} instance and set the
            QIviProxyServiceObject on it
        \li Return the \l{QIviPagingModel::QIviPagingModel}{QIviPagingModel} instance to the
            developer
    \endlist
\endlist

All these steps are already implemented in the IVIGenerator, via \c model type for a
property in an \c interface.

*/