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

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