1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Data Visualization module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 or (at your option) any later version
20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29
30 #include "qitemmodelbardataproxy_p.h"
31 #include "baritemmodelhandler_p.h"
32
33 QT_BEGIN_NAMESPACE_DATAVISUALIZATION
34
35 /*!
36 * \class QItemModelBarDataProxy
37 * \inmodule QtDataVisualization
38 * \brief Proxy class for presenting data in item models with Q3DBars.
39 * \since QtDataVisualization 1.0
40 *
41 * QItemModelBarDataProxy allows you to use QAbstractItemModel derived models as a data source
42 * for Q3DBars. It uses the defined mappings to map data from the model to rows, columns, and
43 * values of Q3DBars graph.
44 *
45 * The data is resolved asynchronously whenever mappings or the model changes.
46 * QBarDataProxy::arrayReset() is emitted when the data has been resolved.
47 * However, when useModelCategories property is set to true, single item changes are resolved
48 * synchronously, unless the same frame also contains a change that causes the whole model to be
49 * resolved.
50 *
51 * Mappings can be used in the following ways:
52 *
53 * \list
54 * \li If useModelCategories property is set to true, this proxy will map rows and
55 * columns of QAbstractItemModel directly to rows and columns of Q3DBars, and uses the value
56 * returned for Qt::DisplayRole as bar value by default.
57 * The value role to be used can be redefined if Qt::DisplayRole is not suitable.
58 *
59 * \li For models that do not have data already neatly sorted into rows and columns, such as
60 * QAbstractListModel based models, you can define a role from the model to map for each of row,
61 * column and value.
62 *
63 * \li If you do not want to include all data contained in the model, or the autogenerated rows and
64 * columns are not ordered as you wish, you can specify which rows and columns should be included
65 * and in which order by defining an explicit list of categories for either or both of rows and
66 * columns.
67 * \endlist
68 *
69 * For example, assume that you have a custom QAbstractItemModel for storing various monthly values
70 * related to a business.
71 * Each item in the model has the roles "year", "month", "income", and "expenses".
72 * You could do the following to display the data in a bar graph:
73 *
74 * \snippet doc_src_qtdatavisualization.cpp 3
75 *
76 * If the fields of the model do not contain the data in the exact format you need, you can specify
77 * a search pattern regular expression and a replace rule for each role to get the value in a
78 * format you need. For more information how the replace using regular expressions works, see
79 * QString::replace(const QRegExp &rx, const QString &after) function documentation. Note that
80 * using regular expressions has an impact on the performance, so it's more efficient to utilize
81 * item models where doing search and replace is not necessary to get the desired values.
82 *
83 * For example about using the search patterns in conjunction with the roles, see
84 * \l{Qt Quick 2 Bars Example}.
85 *
86 * \sa {Qt Data Visualization Data Handling}
87 */
88
89 /*!
90 * \qmltype ItemModelBarDataProxy
91 * \inqmlmodule QtDataVisualization
92 * \since QtDataVisualization 1.0
93 * \ingroup datavisualization_qml
94 * \instantiates QItemModelBarDataProxy
95 * \inherits BarDataProxy
96 * \brief Proxy class for presenting data in item models with Bars3D.
97 *
98 * This type allows you to use AbstractItemModel derived models as a data source for Bars3D.
99 *
100 * Data is resolved asynchronously whenever the mapping or the model changes.
101 * QBarDataProxy::arrayReset() is emitted when the data has been resolved.
102 *
103 * For ItemModelBarDataProxy enums, see \l{QItemModelBarDataProxy::MultiMatchBehavior}.
104 *
105 * For more details, see QItemModelBarDataProxy documentation.
106 *
107 * Usage example:
108 *
109 * \snippet doc_src_qmldatavisualization.cpp 7
110 *
111 * \sa BarDataProxy, {Qt Data Visualization Data Handling}
112 */
113
114 /*!
115 * \qmlproperty model ItemModelBarDataProxy::itemModel
116 * The item model.
117 */
118
119 /*!
120 * \qmlproperty string ItemModelBarDataProxy::rowRole
121 * The item model role to map into row category.
122 */
123
124 /*!
125 * \qmlproperty string ItemModelBarDataProxy::columnRole
126 * The item model role to map into column category.
127 */
128
129 /*!
130 * \qmlproperty string ItemModelBarDataProxy::valueRole
131 * The item model role to map into bar value.
132 */
133
134 /*!
135 * \qmlproperty string ItemModelBarDataProxy::rotationRole
136 * The item model role to map into bar rotation angle.
137 */
138
139 /*!
140 * \qmlproperty list<String> ItemModelBarDataProxy::rowCategories
141 * The row categories of the mapping. Only items with row role values that are found in this list
142 * are included when the data is resolved. The rows are ordered in the same order as they are in
143 * this list.
144 */
145
146 /*!
147 * \qmlproperty list<String> ItemModelBarDataProxy::columnCategories
148 * The column categories of the mapping. Only items with column role values that are found in this
149 * list are included when the data is resolved. The columns are ordered in the same order as they
150 * are in this list.
151 */
152
153 /*!
154 * \qmlproperty bool ItemModelBarDataProxy::useModelCategories
155 * When set to \c true, the mapping ignores row and column roles and categories, and uses
156 * the rows and columns from the model instead. Row and column headers are used for row and column
157 * labels. Defaults to \c{false}.
158 */
159
160 /*!
161 * \qmlproperty bool ItemModelBarDataProxy::autoRowCategories
162 * When set to \c true, the mapping ignores any explicitly set row categories
163 * and overwrites them with automatically generated ones whenever the
164 * data from the model is resolved. Defaults to \c{true}.
165 */
166
167 /*!
168 * \qmlproperty bool ItemModelBarDataProxy::autoColumnCategories
169 * When set to \c true, the mapping ignores any explicitly set column categories
170 * and overwrites them with automatically generated ones whenever the
171 * data from model is resolved. Defaults to \c{true}.
172 */
173
174 /*!
175 * \qmlproperty regExp ItemModelBarDataProxy::rowRolePattern
176 * When set, a search and replace is done on the value mapped by row role before it is used as
177 * a row category. This property specifies the regular expression to find the portion of the
178 * mapped value to replace and rowRoleReplace property contains the replacement string.
179 * This is useful for example in parsing row and column categories from a single
180 * timestamp field in the item model.
181 *
182 * \sa rowRole, rowRoleReplace
183 */
184
185 /*!
186 * \qmlproperty regExp ItemModelBarDataProxy::columnRolePattern
187 * When set, a search and replace is done on the value mapped by column role before it is used
188 * as a column category. This property specifies the regular expression to find the portion of the
189 * mapped value to replace and columnRoleReplace property contains the replacement string.
190 * This is useful for example in parsing row and column categories from
191 * a single timestamp field in the item model.
192 *
193 * \sa columnRole, columnRoleReplace
194 */
195
196 /*!
197 * \qmlproperty regExp ItemModelBarDataProxy::valueRolePattern
198 * When set, a search and replace is done on the value mapped by value role before it is used as
199 * a bar value. This property specifies the regular expression to find the portion of the
200 * mapped value to replace and valueRoleReplace property contains the replacement string.
201 *
202 * \sa valueRole, valueRoleReplace
203 */
204
205 /*!
206 * \qmlproperty regExp ItemModelBarDataProxy::rotationRolePattern
207 * When set, a search and replace is done on the value mapped by rotation role before it is used
208 * as a bar rotation angle. This property specifies the regular expression to find the portion
209 * of the mapped value to replace and rotationRoleReplace property contains the replacement string.
210 *
211 * \sa rotationRole, rotationRoleReplace
212 */
213
214 /*!
215 * \qmlproperty string ItemModelBarDataProxy::rowRoleReplace
216 * This property defines the replace content to be used in conjunction with rowRolePattern.
217 * Defaults to empty string. For more information on how the search and replace using regular
218 * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
219 * function documentation.
220 *
221 * \sa rowRole, rowRolePattern
222 */
223
224 /*!
225 * \qmlproperty string ItemModelBarDataProxy::columnRoleReplace
226 * This property defines the replace content to be used in conjunction with columnRolePattern.
227 * Defaults to empty string. For more information on how the search and replace using regular
228 * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
229 * function documentation.
230 *
231 * \sa columnRole, columnRolePattern
232 */
233
234 /*!
235 * \qmlproperty string ItemModelBarDataProxy::valueRoleReplace
236 * This property defines the replace content to be used in conjunction with valueRolePattern.
237 * Defaults to empty string. For more information on how the search and replace using regular
238 * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
239 * function documentation.
240 *
241 * \sa valueRole, valueRolePattern
242 */
243
244 /*!
245 * \qmlproperty string ItemModelBarDataProxy::rotationRoleReplace
246 * This property defines the replace content to be used in conjunction with rotationRolePattern.
247 * Defaults to empty string. For more information on how the search and replace using regular
248 * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
249 * function documentation.
250 *
251 * \sa rotationRole, rotationRolePattern
252 */
253
254 /*!
255 * \qmlproperty ItemModelBarDataProxy.MultiMatchBehavior ItemModelBarDataProxy::multiMatchBehavior
256 * Defines how multiple matches for each row/column combination are handled.
257 * Defaults to \l{QItemModelBarDataProxy::MMBLast}{ItemModelBarDataProxy.MMBLast}. The chosen
258 * behavior affects both bar value and rotation.
259 *
260 * For example, you might have an item model with timestamped data taken at irregular intervals
261 * and you want to visualize total value of data items on each day with a bar graph.
262 * This can be done by specifying row and column categories so that each bar represents a day,
263 * and setting multiMatchBehavior to
264 * \l{QItemModelBarDataProxy::MMBCumulative}{ItemModelBarDataProxy.MMBCumulative}.
265 */
266
267 /*!
268 * \enum QItemModelBarDataProxy::MultiMatchBehavior
269 *
270 * Behavior types for QItemModelBarDataProxy::multiMatchBehavior property.
271 *
272 * \value MMBFirst
273 * The value is taken from the first item in the item model that matches
274 * each row/column combination.
275 * \value MMBLast
276 * The value is taken from the last item in the item model that matches
277 * each row/column combination.
278 * \value MMBAverage
279 * The values from all items matching each row/column combination are
280 * averaged together and the average is used as the bar value.
281 * \value MMBCumulative
282 * The values from all items matching each row/column combination are
283 * added together and the total is used as the bar value.
284 */
285
286 /*!
287 * Constructs QItemModelBarDataProxy with optional \a parent.
288 */
QItemModelBarDataProxy(QObject * parent)289 QItemModelBarDataProxy::QItemModelBarDataProxy(QObject *parent)
290 : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
291 {
292 dptr()->connectItemModelHandler();
293 }
294
295 /*!
296 * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
297 * ownership of the \a itemModel, as typically item models are owned by other controls.
298 */
QItemModelBarDataProxy(QAbstractItemModel * itemModel,QObject * parent)299 QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel, QObject *parent)
300 : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
301 {
302 setItemModel(itemModel);
303 dptr()->connectItemModelHandler();
304 }
305
306 /*!
307 * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
308 * ownership of the \a itemModel, as typically item models are owned by other controls.
309 * The value role is set to \a valueRole.
310 * This constructor is meant to be used with models that have data properly sorted
311 * in rows and columns already, so it also sets useModelCategories property to true.
312 */
QItemModelBarDataProxy(QAbstractItemModel * itemModel,const QString & valueRole,QObject * parent)313 QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
314 const QString &valueRole, QObject *parent)
315 : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
316 {
317 dptr()->m_itemModelHandler->setItemModel(itemModel);
318 dptr()->m_valueRole = valueRole;
319 dptr()->m_useModelCategories = true;
320 dptr()->connectItemModelHandler();
321 }
322
323 /*!
324 * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
325 * ownership of the \a itemModel, as typically item models are owned by other controls.
326 * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
327 */
QItemModelBarDataProxy(QAbstractItemModel * itemModel,const QString & rowRole,const QString & columnRole,const QString & valueRole,QObject * parent)328 QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
329 const QString &rowRole,
330 const QString &columnRole,
331 const QString &valueRole, QObject *parent)
332 : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
333 {
334 dptr()->m_itemModelHandler->setItemModel(itemModel);
335 dptr()->m_rowRole = rowRole;
336 dptr()->m_columnRole = columnRole;
337 dptr()->m_valueRole = valueRole;
338 dptr()->connectItemModelHandler();
339 }
340
341 /*!
342 * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
343 * ownership of the \a itemModel, as typically item models are owned by other controls.
344 * The role mappings are set with \a rowRole, \a columnRole, \a valueRole, and \a rotationRole.
345 */
QItemModelBarDataProxy(QAbstractItemModel * itemModel,const QString & rowRole,const QString & columnRole,const QString & valueRole,const QString & rotationRole,QObject * parent)346 QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
347 const QString &rowRole,
348 const QString &columnRole,
349 const QString &valueRole,
350 const QString &rotationRole,
351 QObject *parent)
352 : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
353 {
354 dptr()->m_itemModelHandler->setItemModel(itemModel);
355 dptr()->m_rowRole = rowRole;
356 dptr()->m_columnRole = columnRole;
357 dptr()->m_valueRole = valueRole;
358 dptr()->m_rotationRole = rotationRole;
359 dptr()->connectItemModelHandler();
360 }
361
362 /*!
363 * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
364 * ownership of the \a itemModel, as typically item models are owned by other controls.
365 * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
366 * Row and column categories are set with \a rowCategories and \a columnCategories.
367 * This constructor also sets autoRowCategories and autoColumnCategories to false.
368 */
QItemModelBarDataProxy(QAbstractItemModel * itemModel,const QString & rowRole,const QString & columnRole,const QString & valueRole,const QStringList & rowCategories,const QStringList & columnCategories,QObject * parent)369 QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
370 const QString &rowRole,
371 const QString &columnRole,
372 const QString &valueRole,
373 const QStringList &rowCategories,
374 const QStringList &columnCategories,
375 QObject *parent)
376 : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
377 {
378 dptr()->m_itemModelHandler->setItemModel(itemModel);
379 dptr()->m_rowRole = rowRole;
380 dptr()->m_columnRole = columnRole;
381 dptr()->m_valueRole = valueRole;
382 dptr()->m_rowCategories = rowCategories;
383 dptr()->m_columnCategories = columnCategories;
384 dptr()->m_autoRowCategories = false;
385 dptr()->m_autoColumnCategories = false;
386 dptr()->connectItemModelHandler();
387 }
388
389 /*!
390 * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
391 * ownership of the \a itemModel, as typically item models are owned by other controls.
392 * The role mappings are set with \a rowRole, \a columnRole, \a valueRole, and \a rotationRole.
393 * Row and column categories are set with \a rowCategories and \a columnCategories.
394 * This constructor also sets autoRowCategories and autoColumnCategories to false.
395 */
QItemModelBarDataProxy(QAbstractItemModel * itemModel,const QString & rowRole,const QString & columnRole,const QString & valueRole,const QString & rotationRole,const QStringList & rowCategories,const QStringList & columnCategories,QObject * parent)396 QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
397 const QString &rowRole,
398 const QString &columnRole,
399 const QString &valueRole,
400 const QString &rotationRole,
401 const QStringList &rowCategories,
402 const QStringList &columnCategories,
403 QObject *parent)
404 : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
405 {
406 dptr()->m_itemModelHandler->setItemModel(itemModel);
407 dptr()->m_rowRole = rowRole;
408 dptr()->m_columnRole = columnRole;
409 dptr()->m_valueRole = valueRole;
410 dptr()->m_rotationRole = rotationRole;
411 dptr()->m_rowCategories = rowCategories;
412 dptr()->m_columnCategories = columnCategories;
413 dptr()->m_autoRowCategories = false;
414 dptr()->m_autoColumnCategories = false;
415 dptr()->connectItemModelHandler();
416 }
417
418 /*!
419 * Destroys QItemModelBarDataProxy.
420 */
~QItemModelBarDataProxy()421 QItemModelBarDataProxy::~QItemModelBarDataProxy()
422 {
423 }
424
425 /*!
426 * \property QItemModelBarDataProxy::itemModel
427 *
428 * \brief The item model.
429 */
430
431 /*!
432 * Sets the item model to \a itemModel. Does not take ownership of the model,
433 * but does connect to it to listen for changes.
434 */
setItemModel(QAbstractItemModel * itemModel)435 void QItemModelBarDataProxy::setItemModel(QAbstractItemModel *itemModel)
436 {
437 dptr()->m_itemModelHandler->setItemModel(itemModel);
438 }
439
itemModel() const440 QAbstractItemModel *QItemModelBarDataProxy::itemModel() const
441 {
442 return dptrc()->m_itemModelHandler->itemModel();
443 }
444
445 /*!
446 * \property QItemModelBarDataProxy::rowRole
447 *
448 * \brief The row role for the mapping.
449 */
setRowRole(const QString & role)450 void QItemModelBarDataProxy::setRowRole(const QString &role)
451 {
452 if (dptr()->m_rowRole != role) {
453 dptr()->m_rowRole = role;
454 emit rowRoleChanged(role);
455 }
456 }
457
rowRole() const458 QString QItemModelBarDataProxy::rowRole() const
459 {
460 return dptrc()->m_rowRole;
461 }
462
463 /*!
464 * \property QItemModelBarDataProxy::columnRole
465 *
466 * \brief The column role for the mapping.
467 */
setColumnRole(const QString & role)468 void QItemModelBarDataProxy::setColumnRole(const QString &role)
469 {
470 if (dptr()->m_columnRole != role) {
471 dptr()->m_columnRole = role;
472 emit columnRoleChanged(role);
473 }
474 }
475
columnRole() const476 QString QItemModelBarDataProxy::columnRole() const
477 {
478 return dptrc()->m_columnRole;
479 }
480
481 /*!
482 * \property QItemModelBarDataProxy::valueRole
483 *
484 * \brief The value role for the mapping.
485 */
setValueRole(const QString & role)486 void QItemModelBarDataProxy::setValueRole(const QString &role)
487 {
488 if (dptr()->m_valueRole != role) {
489 dptr()->m_valueRole = role;
490 emit valueRoleChanged(role);
491 }
492 }
493
valueRole() const494 QString QItemModelBarDataProxy::valueRole() const
495 {
496 return dptrc()->m_valueRole;
497 }
498
499 /*!
500 * \property QItemModelBarDataProxy::rotationRole
501 *
502 * \brief The rotation role for the mapping.
503 */
setRotationRole(const QString & role)504 void QItemModelBarDataProxy::setRotationRole(const QString &role)
505 {
506 if (dptr()->m_rotationRole != role) {
507 dptr()->m_rotationRole = role;
508 emit rotationRoleChanged(role);
509 }
510 }
511
rotationRole() const512 QString QItemModelBarDataProxy::rotationRole() const
513 {
514 return dptrc()->m_rotationRole;
515 }
516
517 /*!
518 * \property QItemModelBarDataProxy::rowCategories
519 *
520 * \brief The row categories for the mapping.
521 */
setRowCategories(const QStringList & categories)522 void QItemModelBarDataProxy::setRowCategories(const QStringList &categories)
523 {
524 if (dptr()->m_rowCategories != categories) {
525 dptr()->m_rowCategories = categories;
526 emit rowCategoriesChanged();
527 }
528 }
529
rowCategories() const530 QStringList QItemModelBarDataProxy::rowCategories() const
531 {
532 return dptrc()->m_rowCategories;
533 }
534
535 /*!
536 * \property QItemModelBarDataProxy::columnCategories
537 *
538 * \brief The column categories for the mapping.
539 */
setColumnCategories(const QStringList & categories)540 void QItemModelBarDataProxy::setColumnCategories(const QStringList &categories)
541 {
542 if (dptr()->m_columnCategories != categories) {
543 dptr()->m_columnCategories = categories;
544 emit columnCategoriesChanged();
545 }
546 }
547
columnCategories() const548 QStringList QItemModelBarDataProxy::columnCategories() const
549 {
550 return dptrc()->m_columnCategories;
551 }
552
553 /*!
554 * \property QItemModelBarDataProxy::useModelCategories
555 *
556 * \brief Whether row and column roles and categories are used for mapping.
557 *
558 * When set to \c true, the mapping ignores row and column roles and categories, and uses
559 * the rows and columns from the model instead. Defaults to \c{false}.
560 */
setUseModelCategories(bool enable)561 void QItemModelBarDataProxy::setUseModelCategories(bool enable)
562 {
563 if (dptr()->m_useModelCategories != enable) {
564 dptr()->m_useModelCategories = enable;
565 emit useModelCategoriesChanged(enable);
566 }
567 }
568
useModelCategories() const569 bool QItemModelBarDataProxy::useModelCategories() const
570 {
571 return dptrc()->m_useModelCategories;
572 }
573
574 /*!
575 * \property QItemModelBarDataProxy::autoRowCategories
576 *
577 * \brief Whether row categories are generated automatically.
578 *
579 * When set to \c true, the mapping ignores any explicitly set row categories
580 * and overwrites them with automatically generated ones whenever the
581 * data from model is resolved. Defaults to \c{true}.
582 */
setAutoRowCategories(bool enable)583 void QItemModelBarDataProxy::setAutoRowCategories(bool enable)
584 {
585 if (dptr()->m_autoRowCategories != enable) {
586 dptr()->m_autoRowCategories = enable;
587 emit autoRowCategoriesChanged(enable);
588 }
589 }
590
autoRowCategories() const591 bool QItemModelBarDataProxy::autoRowCategories() const
592 {
593 return dptrc()->m_autoRowCategories;
594 }
595
596 /*!
597 * \property QItemModelBarDataProxy::autoColumnCategories
598 *
599 * \brief Whether column categories are generated automatically.
600 *
601 * When set to \c true, the mapping ignores any explicitly set column categories
602 * and overwrites them with automatically generated ones whenever the
603 * data from model is resolved. Defaults to \c{true}.
604 */
setAutoColumnCategories(bool enable)605 void QItemModelBarDataProxy::setAutoColumnCategories(bool enable)
606 {
607 if (dptr()->m_autoColumnCategories != enable) {
608 dptr()->m_autoColumnCategories = enable;
609 emit autoColumnCategoriesChanged(enable);
610 }
611 }
612
autoColumnCategories() const613 bool QItemModelBarDataProxy::autoColumnCategories() const
614 {
615 return dptrc()->m_autoColumnCategories;
616 }
617
618 /*!
619 * Changes \a rowRole, \a columnRole, \a valueRole, \a rotationRole,
620 * \a rowCategories and \a columnCategories to the mapping.
621 */
remap(const QString & rowRole,const QString & columnRole,const QString & valueRole,const QString & rotationRole,const QStringList & rowCategories,const QStringList & columnCategories)622 void QItemModelBarDataProxy::remap(const QString &rowRole,
623 const QString &columnRole,
624 const QString &valueRole,
625 const QString &rotationRole,
626 const QStringList &rowCategories,
627 const QStringList &columnCategories)
628 {
629 setRowRole(rowRole);
630 setColumnRole(columnRole);
631 setValueRole(valueRole);
632 setRotationRole(rotationRole);
633 setRowCategories(rowCategories);
634 setColumnCategories(columnCategories);
635 }
636
637 /*!
638 * Returns the index of the specified \a category in row categories list.
639 * If the row categories list is empty, -1 is returned.
640 * \note If the automatic row categories generation is in use, this method will
641 * not return a valid index before the data in the model is resolved for the first time.
642 */
rowCategoryIndex(const QString & category)643 int QItemModelBarDataProxy::rowCategoryIndex(const QString &category)
644 {
645 return dptr()->m_rowCategories.indexOf(category);
646 }
647
648 /*!
649 * Returns the index of the specified \a category in column categories list.
650 * If the category is not found, -1 is returned.
651 * \note If the automatic column categories generation is in use, this method will
652 * not return a valid index before the data in the model is resolved for the first time.
653 */
columnCategoryIndex(const QString & category)654 int QItemModelBarDataProxy::columnCategoryIndex(const QString &category)
655 {
656 return dptr()->m_columnCategories.indexOf(category);
657 }
658
659 /*!
660 * \property QItemModelBarDataProxy::rowRolePattern
661 *
662 * \brief Whether a search and replace is performed on the value mapped by row
663 * role before it is used as a row category.
664 *
665 * This property specifies the regular expression to find the portion of the
666 * mapped value to replace and rowRoleReplace property contains the replacement string.
667 * This is useful for example in parsing row and column categories from a single
668 * timestamp field in the item model.
669 *
670 * \sa rowRole, rowRoleReplace
671 */
setRowRolePattern(const QRegExp & pattern)672 void QItemModelBarDataProxy::setRowRolePattern(const QRegExp &pattern)
673 {
674 if (dptr()->m_rowRolePattern != pattern) {
675 dptr()->m_rowRolePattern = pattern;
676 emit rowRolePatternChanged(pattern);
677 }
678 }
679
rowRolePattern() const680 QRegExp QItemModelBarDataProxy::rowRolePattern() const
681 {
682 return dptrc()->m_rowRolePattern;
683 }
684
685 /*!
686 * \property QItemModelBarDataProxy::columnRolePattern
687 *
688 * \brief Whether a search and replace is done on the value mapped by column
689 * role before it is used as a column category.
690 *
691 * This property specifies the regular expression to find the portion of the
692 * mapped value to replace and columnRoleReplace property contains the replacement string.
693 * This is useful for example in parsing row and column categories from
694 * a single timestamp field in the item model.
695 *
696 * \sa columnRole, columnRoleReplace
697 */
setColumnRolePattern(const QRegExp & pattern)698 void QItemModelBarDataProxy::setColumnRolePattern(const QRegExp &pattern)
699 {
700 if (dptr()->m_columnRolePattern != pattern) {
701 dptr()->m_columnRolePattern = pattern;
702 emit columnRolePatternChanged(pattern);
703 }
704 }
705
columnRolePattern() const706 QRegExp QItemModelBarDataProxy::columnRolePattern() const
707 {
708 return dptrc()->m_columnRolePattern;
709 }
710
711 /*!
712 * \property QItemModelBarDataProxy::valueRolePattern
713 *
714 * \brief Whether a search and replace is done on the value mapped by value role
715 * before it is used as a bar value.
716 *
717 * This property specifies the regular expression to find the portion of the
718 * mapped value to replace and valueRoleReplace property contains the replacement string.
719 *
720 * \sa valueRole, valueRoleReplace
721 */
setValueRolePattern(const QRegExp & pattern)722 void QItemModelBarDataProxy::setValueRolePattern(const QRegExp &pattern)
723 {
724 if (dptr()->m_valueRolePattern != pattern) {
725 dptr()->m_valueRolePattern = pattern;
726 emit valueRolePatternChanged(pattern);
727 }
728 }
729
valueRolePattern() const730 QRegExp QItemModelBarDataProxy::valueRolePattern() const
731 {
732 return dptrc()->m_valueRolePattern;
733 }
734
735 /*!
736 * \property QItemModelBarDataProxy::rotationRolePattern
737 *
738 * \brief Whether a search and replace is done on the value mapped by rotation
739 * role before it is used as a bar rotation angle.
740 *
741 * This property specifies the regular expression to find the portion
742 * of the mapped value to replace and rotationRoleReplace property contains the replacement string.
743 *
744 * \sa rotationRole, rotationRoleReplace
745 */
setRotationRolePattern(const QRegExp & pattern)746 void QItemModelBarDataProxy::setRotationRolePattern(const QRegExp &pattern)
747 {
748 if (dptr()->m_rotationRolePattern != pattern) {
749 dptr()->m_rotationRolePattern = pattern;
750 emit rotationRolePatternChanged(pattern);
751 }
752 }
753
rotationRolePattern() const754 QRegExp QItemModelBarDataProxy::rotationRolePattern() const
755 {
756 return dptrc()->m_rotationRolePattern;
757 }
758
759 /*!
760 * \property QItemModelBarDataProxy::rowRoleReplace
761 *
762 * \brief The replace content to be used in conjunction with rowRolePattern.
763 *
764 * Defaults to empty string. For more information on how the search and replace using regular
765 * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
766 * function documentation.
767 *
768 * \sa rowRole, rowRolePattern
769 */
setRowRoleReplace(const QString & replace)770 void QItemModelBarDataProxy::setRowRoleReplace(const QString &replace)
771 {
772 if (dptr()->m_rowRoleReplace != replace) {
773 dptr()->m_rowRoleReplace = replace;
774 emit rowRoleReplaceChanged(replace);
775 }
776 }
777
rowRoleReplace() const778 QString QItemModelBarDataProxy::rowRoleReplace() const
779 {
780 return dptrc()->m_rowRoleReplace;
781 }
782
783 /*!
784 * \property QItemModelBarDataProxy::columnRoleReplace
785 *
786 * \brief The replace content to be used in conjunction with columnRolePattern.
787 *
788 * Defaults to empty string. For more information on how the search and replace using regular
789 * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
790 * function documentation.
791 *
792 * \sa columnRole, columnRolePattern
793 */
setColumnRoleReplace(const QString & replace)794 void QItemModelBarDataProxy::setColumnRoleReplace(const QString &replace)
795 {
796 if (dptr()->m_columnRoleReplace != replace) {
797 dptr()->m_columnRoleReplace = replace;
798 emit columnRoleReplaceChanged(replace);
799 }
800 }
801
columnRoleReplace() const802 QString QItemModelBarDataProxy::columnRoleReplace() const
803 {
804 return dptrc()->m_columnRoleReplace;
805 }
806
807 /*!
808 * \property QItemModelBarDataProxy::valueRoleReplace
809 *
810 * \brief The replace content to be used in conjunction with valueRolePattern.
811 *
812 * Defaults to empty string. For more information on how the search and replace using regular
813 * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
814 * function documentation.
815 *
816 * \sa valueRole, valueRolePattern
817 */
setValueRoleReplace(const QString & replace)818 void QItemModelBarDataProxy::setValueRoleReplace(const QString &replace)
819 {
820 if (dptr()->m_valueRoleReplace != replace) {
821 dptr()->m_valueRoleReplace = replace;
822 emit valueRoleReplaceChanged(replace);
823 }
824 }
825
valueRoleReplace() const826 QString QItemModelBarDataProxy::valueRoleReplace() const
827 {
828 return dptrc()->m_valueRoleReplace;
829 }
830
831 /*!
832 * \property QItemModelBarDataProxy::rotationRoleReplace
833 *
834 * \brief The replace content to be used in conjunction with
835 * rotationRolePattern.
836 *
837 * Defaults to empty string. For more information on how the search and replace using regular
838 * expressions works, see QString::replace(const QRegExp &rx, const QString &after)
839 * function documentation.
840 *
841 * \sa rotationRole, rotationRolePattern
842 */
setRotationRoleReplace(const QString & replace)843 void QItemModelBarDataProxy::setRotationRoleReplace(const QString &replace)
844 {
845 if (dptr()->m_rotationRoleReplace != replace) {
846 dptr()->m_rotationRoleReplace = replace;
847 emit rotationRoleReplaceChanged(replace);
848 }
849 }
850
rotationRoleReplace() const851 QString QItemModelBarDataProxy::rotationRoleReplace() const
852 {
853 return dptrc()->m_rotationRoleReplace;
854 }
855
856 /*!
857 * \property QItemModelBarDataProxy::multiMatchBehavior
858 *
859 * \brief How multiple matches for each row/column combination are handled.
860 *
861 * Defaults to QItemModelBarDataProxy::MMBLast. The chosen behavior affects both bar value
862 * and rotation.
863 *
864 * For example, you might have an item model with timestamped data taken at irregular intervals
865 * and you want to visualize total value of data items on each day with a bar graph.
866 * This can be done by specifying row and column categories so that each bar represents a day,
867 * and setting multiMatchBehavior to QItemModelBarDataProxy::MMBCumulative.
868 */
setMultiMatchBehavior(QItemModelBarDataProxy::MultiMatchBehavior behavior)869 void QItemModelBarDataProxy::setMultiMatchBehavior(QItemModelBarDataProxy::MultiMatchBehavior behavior)
870 {
871 if (dptr()->m_multiMatchBehavior != behavior) {
872 dptr()->m_multiMatchBehavior = behavior;
873 emit multiMatchBehaviorChanged(behavior);
874 }
875 }
876
multiMatchBehavior() const877 QItemModelBarDataProxy::MultiMatchBehavior QItemModelBarDataProxy::multiMatchBehavior() const
878 {
879 return dptrc()->m_multiMatchBehavior;
880 }
881
882 /*!
883 * \internal
884 */
dptr()885 QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptr()
886 {
887 return static_cast<QItemModelBarDataProxyPrivate *>(d_ptr.data());
888 }
889
890 /*!
891 * \internal
892 */
dptrc() const893 const QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptrc() const
894 {
895 return static_cast<const QItemModelBarDataProxyPrivate *>(d_ptr.data());
896 }
897
898 // QItemModelBarDataProxyPrivate
899
QItemModelBarDataProxyPrivate(QItemModelBarDataProxy * q)900 QItemModelBarDataProxyPrivate::QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q)
901 : QBarDataProxyPrivate(q),
902 m_itemModelHandler(new BarItemModelHandler(q)),
903 m_useModelCategories(false),
904 m_autoRowCategories(true),
905 m_autoColumnCategories(true),
906 m_multiMatchBehavior(QItemModelBarDataProxy::MMBLast)
907 {
908 }
909
~QItemModelBarDataProxyPrivate()910 QItemModelBarDataProxyPrivate::~QItemModelBarDataProxyPrivate()
911 {
912 delete m_itemModelHandler;
913 }
914
qptr()915 QItemModelBarDataProxy *QItemModelBarDataProxyPrivate::qptr()
916 {
917 return static_cast<QItemModelBarDataProxy *>(q_ptr);
918 }
919
connectItemModelHandler()920 void QItemModelBarDataProxyPrivate::connectItemModelHandler()
921 {
922 QObject::connect(m_itemModelHandler, &BarItemModelHandler::itemModelChanged,
923 qptr(), &QItemModelBarDataProxy::itemModelChanged);
924 QObject::connect(qptr(), &QItemModelBarDataProxy::rowRoleChanged,
925 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
926 QObject::connect(qptr(), &QItemModelBarDataProxy::columnRoleChanged,
927 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
928 QObject::connect(qptr(), &QItemModelBarDataProxy::valueRoleChanged,
929 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
930 QObject::connect(qptr(), &QItemModelBarDataProxy::rotationRoleChanged,
931 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
932 QObject::connect(qptr(), &QItemModelBarDataProxy::rowCategoriesChanged,
933 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
934 QObject::connect(qptr(), &QItemModelBarDataProxy::columnCategoriesChanged,
935 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
936 QObject::connect(qptr(), &QItemModelBarDataProxy::useModelCategoriesChanged,
937 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
938 QObject::connect(qptr(), &QItemModelBarDataProxy::autoRowCategoriesChanged,
939 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
940 QObject::connect(qptr(), &QItemModelBarDataProxy::autoColumnCategoriesChanged,
941 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
942 QObject::connect(qptr(), &QItemModelBarDataProxy::rowRolePatternChanged,
943 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
944 QObject::connect(qptr(), &QItemModelBarDataProxy::columnRolePatternChanged,
945 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
946 QObject::connect(qptr(), &QItemModelBarDataProxy::valueRolePatternChanged,
947 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
948 QObject::connect(qptr(), &QItemModelBarDataProxy::rotationRolePatternChanged,
949 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
950 QObject::connect(qptr(), &QItemModelBarDataProxy::rowRoleReplaceChanged,
951 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
952 QObject::connect(qptr(), &QItemModelBarDataProxy::columnRoleReplaceChanged,
953 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
954 QObject::connect(qptr(), &QItemModelBarDataProxy::valueRoleReplaceChanged,
955 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
956 QObject::connect(qptr(), &QItemModelBarDataProxy::rotationRoleReplaceChanged,
957 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
958 QObject::connect(qptr(), &QItemModelBarDataProxy::multiMatchBehaviorChanged,
959 m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
960 }
961
962 QT_END_NAMESPACE_DATAVISUALIZATION
963