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
33QT_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 */
289QItemModelBarDataProxy::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 */
299QItemModelBarDataProxy::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 */
313QItemModelBarDataProxy::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 */
328QItemModelBarDataProxy::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 */
346QItemModelBarDataProxy::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 */
369QItemModelBarDataProxy::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 */
396QItemModelBarDataProxy::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 */
421QItemModelBarDataProxy::~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 */
435void QItemModelBarDataProxy::setItemModel(QAbstractItemModel *itemModel)
436{
437 dptr()->m_itemModelHandler->setItemModel(itemModel);
438}
439
440QAbstractItemModel *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 */
450void QItemModelBarDataProxy::setRowRole(const QString &role)
451{
452 if (dptr()->m_rowRole != role) {
453 dptr()->m_rowRole = role;
454 emit rowRoleChanged(role);
455 }
456}
457
458QString 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 */
468void QItemModelBarDataProxy::setColumnRole(const QString &role)
469{
470 if (dptr()->m_columnRole != role) {
471 dptr()->m_columnRole = role;
472 emit columnRoleChanged(role);
473 }
474}
475
476QString 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 */
486void QItemModelBarDataProxy::setValueRole(const QString &role)
487{
488 if (dptr()->m_valueRole != role) {
489 dptr()->m_valueRole = role;
490 emit valueRoleChanged(role);
491 }
492}
493
494QString 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 */
504void QItemModelBarDataProxy::setRotationRole(const QString &role)
505{
506 if (dptr()->m_rotationRole != role) {
507 dptr()->m_rotationRole = role;
508 emit rotationRoleChanged(role);
509 }
510}
511
512QString 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 */
522void QItemModelBarDataProxy::setRowCategories(const QStringList &categories)
523{
524 if (dptr()->m_rowCategories != categories) {
525 dptr()->m_rowCategories = categories;
526 emit rowCategoriesChanged();
527 }
528}
529
530QStringList 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 */
540void QItemModelBarDataProxy::setColumnCategories(const QStringList &categories)
541{
542 if (dptr()->m_columnCategories != categories) {
543 dptr()->m_columnCategories = categories;
544 emit columnCategoriesChanged();
545 }
546}
547
548QStringList 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 */
561void QItemModelBarDataProxy::setUseModelCategories(bool enable)
562{
563 if (dptr()->m_useModelCategories != enable) {
564 dptr()->m_useModelCategories = enable;
565 emit useModelCategoriesChanged(enable);
566 }
567}
568
569bool 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 */
583void QItemModelBarDataProxy::setAutoRowCategories(bool enable)
584{
585 if (dptr()->m_autoRowCategories != enable) {
586 dptr()->m_autoRowCategories = enable;
587 emit autoRowCategoriesChanged(enable);
588 }
589}
590
591bool 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 */
605void QItemModelBarDataProxy::setAutoColumnCategories(bool enable)
606{
607 if (dptr()->m_autoColumnCategories != enable) {
608 dptr()->m_autoColumnCategories = enable;
609 emit autoColumnCategoriesChanged(enable);
610 }
611}
612
613bool 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 */
622void 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 */
643int QItemModelBarDataProxy::rowCategoryIndex(const QString &category)
644{
645 return dptr()->m_rowCategories.indexOf(t: 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 */
654int QItemModelBarDataProxy::columnCategoryIndex(const QString &category)
655{
656 return dptr()->m_columnCategories.indexOf(t: 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 */
672void QItemModelBarDataProxy::setRowRolePattern(const QRegExp &pattern)
673{
674 if (dptr()->m_rowRolePattern != pattern) {
675 dptr()->m_rowRolePattern = pattern;
676 emit rowRolePatternChanged(pattern);
677 }
678}
679
680QRegExp 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 */
698void QItemModelBarDataProxy::setColumnRolePattern(const QRegExp &pattern)
699{
700 if (dptr()->m_columnRolePattern != pattern) {
701 dptr()->m_columnRolePattern = pattern;
702 emit columnRolePatternChanged(pattern);
703 }
704}
705
706QRegExp 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 */
722void QItemModelBarDataProxy::setValueRolePattern(const QRegExp &pattern)
723{
724 if (dptr()->m_valueRolePattern != pattern) {
725 dptr()->m_valueRolePattern = pattern;
726 emit valueRolePatternChanged(pattern);
727 }
728}
729
730QRegExp 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 */
746void QItemModelBarDataProxy::setRotationRolePattern(const QRegExp &pattern)
747{
748 if (dptr()->m_rotationRolePattern != pattern) {
749 dptr()->m_rotationRolePattern = pattern;
750 emit rotationRolePatternChanged(pattern);
751 }
752}
753
754QRegExp 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 */
770void QItemModelBarDataProxy::setRowRoleReplace(const QString &replace)
771{
772 if (dptr()->m_rowRoleReplace != replace) {
773 dptr()->m_rowRoleReplace = replace;
774 emit rowRoleReplaceChanged(replace);
775 }
776}
777
778QString 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 */
794void QItemModelBarDataProxy::setColumnRoleReplace(const QString &replace)
795{
796 if (dptr()->m_columnRoleReplace != replace) {
797 dptr()->m_columnRoleReplace = replace;
798 emit columnRoleReplaceChanged(replace);
799 }
800}
801
802QString 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 */
818void QItemModelBarDataProxy::setValueRoleReplace(const QString &replace)
819{
820 if (dptr()->m_valueRoleReplace != replace) {
821 dptr()->m_valueRoleReplace = replace;
822 emit valueRoleReplaceChanged(replace);
823 }
824}
825
826QString 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 */
843void QItemModelBarDataProxy::setRotationRoleReplace(const QString &replace)
844{
845 if (dptr()->m_rotationRoleReplace != replace) {
846 dptr()->m_rotationRoleReplace = replace;
847 emit rotationRoleReplaceChanged(replace);
848 }
849}
850
851QString 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 */
869void QItemModelBarDataProxy::setMultiMatchBehavior(QItemModelBarDataProxy::MultiMatchBehavior behavior)
870{
871 if (dptr()->m_multiMatchBehavior != behavior) {
872 dptr()->m_multiMatchBehavior = behavior;
873 emit multiMatchBehaviorChanged(behavior);
874 }
875}
876
877QItemModelBarDataProxy::MultiMatchBehavior QItemModelBarDataProxy::multiMatchBehavior() const
878{
879 return dptrc()->m_multiMatchBehavior;
880}
881
882/*!
883 * \internal
884 */
885QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptr()
886{
887 return static_cast<QItemModelBarDataProxyPrivate *>(d_ptr.data());
888}
889
890/*!
891 * \internal
892 */
893const QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptrc() const
894{
895 return static_cast<const QItemModelBarDataProxyPrivate *>(d_ptr.data());
896}
897
898// QItemModelBarDataProxyPrivate
899
900QItemModelBarDataProxyPrivate::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
910QItemModelBarDataProxyPrivate::~QItemModelBarDataProxyPrivate()
911{
912 delete m_itemModelHandler;
913}
914
915QItemModelBarDataProxy *QItemModelBarDataProxyPrivate::qptr()
916{
917 return static_cast<QItemModelBarDataProxy *>(q_ptr);
918}
919
920void QItemModelBarDataProxyPrivate::connectItemModelHandler()
921{
922 QObject::connect(sender: m_itemModelHandler, signal: &BarItemModelHandler::itemModelChanged,
923 receiver: qptr(), slot: &QItemModelBarDataProxy::itemModelChanged);
924 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::rowRoleChanged,
925 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
926 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::columnRoleChanged,
927 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
928 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::valueRoleChanged,
929 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
930 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::rotationRoleChanged,
931 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
932 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::rowCategoriesChanged,
933 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
934 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::columnCategoriesChanged,
935 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
936 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::useModelCategoriesChanged,
937 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
938 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::autoRowCategoriesChanged,
939 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
940 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::autoColumnCategoriesChanged,
941 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
942 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::rowRolePatternChanged,
943 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
944 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::columnRolePatternChanged,
945 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
946 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::valueRolePatternChanged,
947 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
948 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::rotationRolePatternChanged,
949 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
950 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::rowRoleReplaceChanged,
951 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
952 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::columnRoleReplaceChanged,
953 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
954 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::valueRoleReplaceChanged,
955 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
956 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::rotationRoleReplaceChanged,
957 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
958 QObject::connect(sender: qptr(), signal: &QItemModelBarDataProxy::multiMatchBehaviorChanged,
959 receiver: m_itemModelHandler, slot: &AbstractItemModelHandler::handleMappingChanged);
960}
961
962QT_END_NAMESPACE_DATAVISUALIZATION
963

source code of qtdatavis3d/src/datavisualization/data/qitemmodelbardataproxy.cpp