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