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 | |
7 | QT_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 | */ |
263 | QItemModelBarDataProxy::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 | */ |
273 | QItemModelBarDataProxy::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 | */ |
287 | QItemModelBarDataProxy::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 | */ |
302 | QItemModelBarDataProxy::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 | */ |
320 | QItemModelBarDataProxy::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 | */ |
343 | QItemModelBarDataProxy::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 | */ |
370 | QItemModelBarDataProxy::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 | */ |
395 | QItemModelBarDataProxy::~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 | */ |
409 | void QItemModelBarDataProxy::setItemModel(QAbstractItemModel *itemModel) |
410 | { |
411 | dptr()->m_itemModelHandler->setItemModel(itemModel); |
412 | } |
413 | |
414 | QAbstractItemModel *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 | */ |
424 | void QItemModelBarDataProxy::setRowRole(const QString &role) |
425 | { |
426 | if (dptr()->m_rowRole != role) { |
427 | dptr()->m_rowRole = role; |
428 | emit rowRoleChanged(role); |
429 | } |
430 | } |
431 | |
432 | QString 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 | */ |
442 | void QItemModelBarDataProxy::setColumnRole(const QString &role) |
443 | { |
444 | if (dptr()->m_columnRole != role) { |
445 | dptr()->m_columnRole = role; |
446 | emit columnRoleChanged(role); |
447 | } |
448 | } |
449 | |
450 | QString 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 | */ |
460 | void QItemModelBarDataProxy::setValueRole(const QString &role) |
461 | { |
462 | if (dptr()->m_valueRole != role) { |
463 | dptr()->m_valueRole = role; |
464 | emit valueRoleChanged(role); |
465 | } |
466 | } |
467 | |
468 | QString 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 | */ |
478 | void QItemModelBarDataProxy::setRotationRole(const QString &role) |
479 | { |
480 | if (dptr()->m_rotationRole != role) { |
481 | dptr()->m_rotationRole = role; |
482 | emit rotationRoleChanged(role); |
483 | } |
484 | } |
485 | |
486 | QString 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 | */ |
496 | void QItemModelBarDataProxy::setRowCategories(const QStringList &categories) |
497 | { |
498 | if (dptr()->m_rowCategories != categories) { |
499 | dptr()->m_rowCategories = categories; |
500 | emit rowCategoriesChanged(); |
501 | } |
502 | } |
503 | |
504 | QStringList 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 | */ |
514 | void QItemModelBarDataProxy::setColumnCategories(const QStringList &categories) |
515 | { |
516 | if (dptr()->m_columnCategories != categories) { |
517 | dptr()->m_columnCategories = categories; |
518 | emit columnCategoriesChanged(); |
519 | } |
520 | } |
521 | |
522 | QStringList 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 | */ |
535 | void QItemModelBarDataProxy::setUseModelCategories(bool enable) |
536 | { |
537 | if (dptr()->m_useModelCategories != enable) { |
538 | dptr()->m_useModelCategories = enable; |
539 | emit useModelCategoriesChanged(enable); |
540 | } |
541 | } |
542 | |
543 | bool 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 | */ |
557 | void QItemModelBarDataProxy::setAutoRowCategories(bool enable) |
558 | { |
559 | if (dptr()->m_autoRowCategories != enable) { |
560 | dptr()->m_autoRowCategories = enable; |
561 | emit autoRowCategoriesChanged(enable); |
562 | } |
563 | } |
564 | |
565 | bool 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 | */ |
579 | void QItemModelBarDataProxy::setAutoColumnCategories(bool enable) |
580 | { |
581 | if (dptr()->m_autoColumnCategories != enable) { |
582 | dptr()->m_autoColumnCategories = enable; |
583 | emit autoColumnCategoriesChanged(enable); |
584 | } |
585 | } |
586 | |
587 | bool 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 | */ |
596 | void 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 | */ |
617 | int 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 | */ |
628 | int 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 | */ |
646 | void QItemModelBarDataProxy::setRowRolePattern(const QRegularExpression &pattern) |
647 | { |
648 | if (dptr()->m_rowRolePattern != pattern) { |
649 | dptr()->m_rowRolePattern = pattern; |
650 | emit rowRolePatternChanged(pattern); |
651 | } |
652 | } |
653 | |
654 | QRegularExpression 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 | */ |
672 | void QItemModelBarDataProxy::setColumnRolePattern(const QRegularExpression &pattern) |
673 | { |
674 | if (dptr()->m_columnRolePattern != pattern) { |
675 | dptr()->m_columnRolePattern = pattern; |
676 | emit columnRolePatternChanged(pattern); |
677 | } |
678 | } |
679 | |
680 | QRegularExpression 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 | */ |
696 | void QItemModelBarDataProxy::setValueRolePattern(const QRegularExpression &pattern) |
697 | { |
698 | if (dptr()->m_valueRolePattern != pattern) { |
699 | dptr()->m_valueRolePattern = pattern; |
700 | emit valueRolePatternChanged(pattern); |
701 | } |
702 | } |
703 | |
704 | QRegularExpression 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 | */ |
720 | void QItemModelBarDataProxy::setRotationRolePattern(const QRegularExpression &pattern) |
721 | { |
722 | if (dptr()->m_rotationRolePattern != pattern) { |
723 | dptr()->m_rotationRolePattern = pattern; |
724 | emit rotationRolePatternChanged(pattern); |
725 | } |
726 | } |
727 | |
728 | QRegularExpression 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 | */ |
744 | void QItemModelBarDataProxy::setRowRoleReplace(const QString &replace) |
745 | { |
746 | if (dptr()->m_rowRoleReplace != replace) { |
747 | dptr()->m_rowRoleReplace = replace; |
748 | emit rowRoleReplaceChanged(replace); |
749 | } |
750 | } |
751 | |
752 | QString 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 | */ |
768 | void QItemModelBarDataProxy::setColumnRoleReplace(const QString &replace) |
769 | { |
770 | if (dptr()->m_columnRoleReplace != replace) { |
771 | dptr()->m_columnRoleReplace = replace; |
772 | emit columnRoleReplaceChanged(replace); |
773 | } |
774 | } |
775 | |
776 | QString 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 | */ |
792 | void QItemModelBarDataProxy::setValueRoleReplace(const QString &replace) |
793 | { |
794 | if (dptr()->m_valueRoleReplace != replace) { |
795 | dptr()->m_valueRoleReplace = replace; |
796 | emit valueRoleReplaceChanged(replace); |
797 | } |
798 | } |
799 | |
800 | QString 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 | */ |
817 | void QItemModelBarDataProxy::setRotationRoleReplace(const QString &replace) |
818 | { |
819 | if (dptr()->m_rotationRoleReplace != replace) { |
820 | dptr()->m_rotationRoleReplace = replace; |
821 | emit rotationRoleReplaceChanged(replace); |
822 | } |
823 | } |
824 | |
825 | QString 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 | */ |
843 | void QItemModelBarDataProxy::setMultiMatchBehavior(QItemModelBarDataProxy::MultiMatchBehavior behavior) |
844 | { |
845 | if (dptr()->m_multiMatchBehavior != behavior) { |
846 | dptr()->m_multiMatchBehavior = behavior; |
847 | emit multiMatchBehaviorChanged(behavior); |
848 | } |
849 | } |
850 | |
851 | QItemModelBarDataProxy::MultiMatchBehavior QItemModelBarDataProxy::multiMatchBehavior() const |
852 | { |
853 | return dptrc()->m_multiMatchBehavior; |
854 | } |
855 | |
856 | /*! |
857 | * \internal |
858 | */ |
859 | QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptr() |
860 | { |
861 | return static_cast<QItemModelBarDataProxyPrivate *>(d_ptr.data()); |
862 | } |
863 | |
864 | /*! |
865 | * \internal |
866 | */ |
867 | const QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptrc() const |
868 | { |
869 | return static_cast<const QItemModelBarDataProxyPrivate *>(d_ptr.data()); |
870 | } |
871 | |
872 | // QItemModelBarDataProxyPrivate |
873 | |
874 | QItemModelBarDataProxyPrivate::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 | |
884 | QItemModelBarDataProxyPrivate::~QItemModelBarDataProxyPrivate() |
885 | { |
886 | delete m_itemModelHandler; |
887 | } |
888 | |
889 | QItemModelBarDataProxy *QItemModelBarDataProxyPrivate::qptr() |
890 | { |
891 | return static_cast<QItemModelBarDataProxy *>(q_ptr); |
892 | } |
893 | |
894 | void 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 | |
936 | QT_END_NAMESPACE |
937 | |