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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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