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

source code of qtgraphs/src/graphs/data/qitemmodelbardataproxy.cpp