Revision control

Copy as Markdown

// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "baritemmodelhandler_p.h"
#include "qitemmodelbardataproxy_p.h"
#include "qgraphs3dlogging_p.h"
QT_BEGIN_NAMESPACE
/*!
* \class QItemModelBarDataProxy
* \inmodule QtGraphs
* \ingroup graphs_3D
* \brief Proxy class for presenting data in item models with Q3DBarsWidgetItem.
*
* QItemModelBarDataProxy allows you to use QAbstractItemModel derived models as
* a data source for Q3DBarsWidgetItem. It uses the defined mappings to map data from the
* model to rows, columns, and values of Q3DBarsWidgetItem graph.
*
* The data is resolved asynchronously whenever mappings or the model changes.
* QBarDataProxy::arrayReset() is emitted when the data has been resolved.
* However, when useModelCategories property is set to true, single item changes
* are resolved synchronously, unless the same frame also contains a change that
* causes the whole model to be resolved.
*
* Mappings can be used in the following ways:
*
* \list
* \li If useModelCategories property is set to true, this proxy will map rows and
* columns of QAbstractItemModel directly to rows and columns of Q3DBarsWidgetItem, and uses the value
* returned for Qt::DisplayRole as bar value by default.
* The value role to be used can be redefined if Qt::DisplayRole is not suitable.
*
* \li For models that do not have data already neatly sorted into rows and columns, such as
* QAbstractListModel based models, you can define a role from the model to map for each of the
* row, column and value.
*
* \li If you do not want to include all data contained in the model, or the autogenerated rows and
* columns are not ordered as you wish, you can specify which rows and columns should be included
* and in which order by defining an explicit list of categories for either or both of rows and
* columns.
* \endlist
*
* For example, assume that you have a custom QAbstractItemModel for storing various monthly values
* related to a business.
* Each item in the model has the roles "year", "month", "income", and "expenses".
* You could do the following to display the data in a bar graph:
*
* \snippet doc_src_qtgraphs.cpp barmodelproxy
*
* If the fields of the model do not contain the data in the exact format you
* need, you can specify a search pattern regular expression and a replace rule
* for each role to get the value in a format you need. For more information on how
* the replacement using regular expressions works, see QString::replace(const
* QRegularExpression &rx, const QString &after) function documentation. Note
* that using regular expressions has an impact on the performance, so it's more
* efficient to utilize item models where doing search and replace is not
* necessary to get the desired values.
*
* For example about using the search patterns in conjunction with the roles,
* see \l{Simple Bar Graph}.
*
* \sa {Qt Graphs Data Handling with 3D}
*/
/*!
* \qmltype ItemModelBarDataProxy
* \inqmlmodule QtGraphs
* \ingroup graphs_qml_3D
* \nativetype QItemModelBarDataProxy
* \inherits BarDataProxy
* \brief Proxy class for presenting data in item models with Bars3D.
*
* This type allows you to use AbstractItemModel derived models as a data source
* for Bars3D.
*
* Data is resolved asynchronously whenever the mapping or the model changes.
* QBarDataProxy::arrayReset() is emitted when the data has been resolved.
*
* For ItemModelBarDataProxy enums, see
* \l{QItemModelBarDataProxy::MultiMatchBehavior}.
*
* For more details, see QItemModelBarDataProxy documentation.
*
* Usage example:
*
* \snippet doc_src_qmlgraphs.cpp 7
*
* \sa BarDataProxy, {Qt Graphs Data Handling with 3D}
*/
/*!
* \qmlproperty model ItemModelBarDataProxy::itemModel
* The item model.
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::rowRole
* The item model role to map into row category.
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::columnRole
* The item model role to map into column category.
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::valueRole
* The item model role to map into bar value.
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::rotationRole
* The item model role to map into bar rotation angle.
*/
/*!
* \qmlproperty list<String> ItemModelBarDataProxy::rowCategories
* The row categories of the mapping. Only items with row role values that are
* found in this list are included when the data is resolved. The rows are
* ordered in the same order as they are in this list.
*/
/*!
* \qmlproperty list<String> ItemModelBarDataProxy::columnCategories
* The column categories of the mapping. Only items with column role values that
* are found in this list are included when the data is resolved. The columns
* are ordered in the same order as they are in this list.
*/
/*!
* \qmlproperty bool ItemModelBarDataProxy::useModelCategories
* When set to \c true, the mapping ignores row and column roles and categories,
* and uses the rows and columns from the model instead. Row and column headers
* are used for row and column labels. Defaults to \c{false}.
*/
/*!
* \qmlproperty bool ItemModelBarDataProxy::autoRowCategories
* When set to \c true, the mapping ignores any explicitly set row categories
* and overwrites them with automatically generated ones whenever the
* data from the model is resolved. Defaults to \c{true}.
*/
/*!
* \qmlproperty bool ItemModelBarDataProxy::autoColumnCategories
* When set to \c true, the mapping ignores any explicitly set column categories
* and overwrites them with automatically generated ones whenever the
* data from model is resolved. Defaults to \c{true}.
*/
/*!
* \qmlproperty regExp ItemModelBarDataProxy::rowRolePattern
* When set, a search and replace is done on the value mapped by row role before
* it is used as a row category. This property specifies the regular expression
* to find the portion of the mapped value to replace and rowRoleReplace
* property contains the replacement string. This is useful for example in
* parsing row and column categories from a single timestamp field in the item
* model.
*
* \sa rowRole, rowRoleReplace
*/
/*!
* \qmlproperty regExp ItemModelBarDataProxy::columnRolePattern
* When set, a search and replace is done on the value mapped by column role
* before it is used as a column category. This property specifies the regular
* expression to find the portion of the mapped value to replace and
* columnRoleReplace property contains the replacement string. This is useful
* for example in parsing row and column categories from a single timestamp
* field in the item model.
*
* \sa columnRole, columnRoleReplace
*/
/*!
* \qmlproperty regExp ItemModelBarDataProxy::valueRolePattern
* When set, a search and replace is done on the value mapped by value role
* before it is used as a bar value. This property specifies the regular
* expression to find the portion of the mapped value to replace and
* valueRoleReplace property contains the replacement string.
*
* \sa valueRole, valueRoleReplace
*/
/*!
* \qmlproperty regExp ItemModelBarDataProxy::rotationRolePattern
* When set, a search and replace is done on the value mapped by rotation role
* before it is used as a bar rotation angle. This property specifies the
* regular expression to find the portion of the mapped value to replace and
* rotationRoleReplace property contains the replacement string.
*
* \sa rotationRole, rotationRoleReplace
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::rowRoleReplace
* This property defines the replacement content to be used in conjunction with
* rowRolePattern. Defaults to empty string. For more information on how the
* search and replace using regular expressions works, see
* QString::replace(const QRegularExpression &rx, const QString &after) function
* documentation.
*
* \sa rowRole, rowRolePattern
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::columnRoleReplace
* This property defines the replacement content to be used in conjunction with
* columnRolePattern. Defaults to empty string. For more information on how the
* search and replace using regular expressions works, see
* QString::replace(const QRegularExpression &rx, const QString &after) function
* documentation.
*
* \sa columnRole, columnRolePattern
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::valueRoleReplace
* This property defines the replacement content to be used in conjunction with
* valueRolePattern. Defaults to empty string. For more information on how the
* search and replace using regular expressions works, see
* QString::replace(const QRegularExpression &rx, const QString &after) function
* documentation.
*
* \sa valueRole, valueRolePattern
*/
/*!
* \qmlproperty string ItemModelBarDataProxy::rotationRoleReplace
* This property defines the replacement content to be used in conjunction with
* rotationRolePattern. Defaults to empty string. For more information on how
* the search and replace using regular expressions works, see
* QString::replace(const QRegularExpression &rx, const QString &after) function
* documentation.
*
* \sa rotationRole, rotationRolePattern
*/
/*!
* \qmlproperty enumeration ItemModelBarDataProxy::multiMatchBehavior
* Defines how multiple matches for each row/column combination are handled.
* Defaults to
* \l{QItemModelBarDataProxy::MultiMatchBehavior::Last}
* {ItemModelBarDataProxy.MultiMatchBehavior.Last}.
* The chosen behavior affects both bar value and rotation.
*
* For example, you might have an item model with timestamped data taken at
* irregular intervals and you want to visualize total value of data items on
* each day with a bar graph. This can be done by specifying row and column
* categories so that each bar represents a day, and setting multiMatchBehavior
* to
* \l{QItemModelBarDataProxy::MultiMatchBehavior::Cumulative}
* {ItemModelBarDataProxy.MultiMatchBehavior.Cumulative}.
*/
/*!
\qmlsignal ItemModelBarDataProxy::itemModelChanged(model itemModel)
This signal is emitted when itemModel changes to \a itemModel.
*/
/*!
\qmlsignal ItemModelBarDataProxy::rowRoleChanged(string role)
This signal is emitted when rowRole changes to \a role.
*/
/*!
\qmlsignal ItemModelBarDataProxy::columnRoleChanged(string role)
This signal is emitted when columnRole changes to \a role.
*/
/*!
\qmlsignal ItemModelBarDataProxy::valueRoleChanged(string role)
This signal is emitted when valueRole changes to \a role.
*/
/*!
\qmlsignal ItemModelBarDataProxy::rotationRoleChanged(string role)
This signal is emitted when rotationRole changes to \a role.
*/
/*!
\qmlsignal ItemModelBarDataProxy::rowCategoriesChanged()
This signal is emitted when rowCategories changes.
*/
/*!
\qmlsignal ItemModelBarDataProxy::columnCategoriesChanged()
This signal is emitted when columnCategories changes.
*/
/*!
\qmlsignal ItemModelBarDataProxy::useModelCategoriesChanged(bool enable)
This signal is emitted when useModelCategories changes to \a enable.
*/
/*!
\qmlsignal ItemModelBarDataProxy::autoRowCategoriesChanged(bool enable)
This signal is emitted when autoRowCategories changes to \a enable.
*/
/*!
\qmlsignal ItemModelBarDataProxy::autoColumnCategoriesChanged(bool enable)
This signal is emitted when autoColumnCategories changes to \a enable.
*/
/*!
\qmlsignal ItemModelBarDataProxy::rowRolePatternChanged(regExp pattern)
This signal is emitted when rowRolePattern changes to \a pattern.
*/
/*!
\qmlsignal ItemModelBarDataProxy::columnRolePatternChanged(regExp pattern)
This signal is emitted when columnRolePattern changes to \a pattern.
*/
/*!
\qmlsignal ItemModelBarDataProxy::valueRolePatternChanged(regExp pattern)
This signal is emitted when valueRolePattern changes to \a pattern.
*/
/*!
\qmlsignal ItemModelBarDataProxy::rotationRolePatternChanged(regExp pattern)
This signal is emitted when rotationRolePattern changes to \a pattern.
*/
/*!
\qmlsignal ItemModelBarDataProxy::rowRoleReplaceChanged(string replace)
This signal is emitted when rowRoleReplace changes to \a replace.
*/
/*!
\qmlsignal ItemModelBarDataProxy::columnRoleReplaceChanged(string replace)
This signal is emitted when columnRoleReplace changes to \a replace.
*/
/*!
\qmlsignal ItemModelBarDataProxy::valueRoleReplaceChanged(string replace)
This signal is emitted when valueRoleReplace changes to \a replace.
*/
/*!
\qmlsignal ItemModelBarDataProxy::rotationRoleReplaceChanged(string replace)
This signal is emitted when rotationRoleReplace changes to \a replace.
*/
/*!
\qmlsignal ItemModelBarDataProxy::multiMatchBehaviorChanged(enumeration behavior)
This signal is emitted when multiMatchBehavior changes to \a behavior.
*/
/*!
* \enum QItemModelBarDataProxy::MultiMatchBehavior
*
* Behavior types for QItemModelBarDataProxy::multiMatchBehavior property.
*
* \value First
* The value is taken from the first item in the item model that matches
* each row/column combination.
* \value Last
* The value is taken from the last item in the item model that matches
* each row/column combination.
* \value Average
* The values from all items matching each row/column combination are
* averaged together and the average is used as the bar value.
* \value Cumulative
* The values from all items matching each row/column combination are
* added together and the total is used as the bar value.
*/
/*!
* Constructs QItemModelBarDataProxy with an optional \a parent.
*/
QItemModelBarDataProxy::QItemModelBarDataProxy(QObject *parent)
: QBarDataProxy(*(new QItemModelBarDataProxyPrivate(this)), parent)
{
Q_D(QItemModelBarDataProxy);
d->connectItemModelHandler();
}
/*!
* Constructs QItemModelBarDataProxy with \a itemModel and an optional \a parent.
* The proxy doesn't take ownership of the \a itemModel, as typically item models
* are owned by other controls.
*/
QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel, QObject *parent)
: QBarDataProxy(*(new QItemModelBarDataProxyPrivate(this)), parent)
{
Q_D(QItemModelBarDataProxy);
setItemModel(itemModel);
d->connectItemModelHandler();
}
/*!
* Constructs QItemModelBarDataProxy with \a itemModel and an optional \a parent.
* The proxy doesn't take ownership of the \a itemModel, as typically item models
* are owned by other controls. The value role is set to \a valueRole. This
* constructor is meant to be used with models that have data properly sorted in
* rows and columns already, so it also sets useModelCategories property to
* true.
*/
QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &valueRole,
QObject *parent)
: QBarDataProxy(*(new QItemModelBarDataProxyPrivate(this)), parent)
{
Q_D(QItemModelBarDataProxy);
d->m_itemModelHandler->setItemModel(itemModel);
d->m_valueRole = valueRole;
d->m_useModelCategories = true;
d->connectItemModelHandler();
}
/*!
* Constructs QItemModelBarDataProxy with \a itemModel and an optional \a parent.
* The proxy doesn't take ownership of the \a itemModel, as typically item models
* are owned by other controls. The role mappings are set with \a rowRole, \a
* columnRole, and \a valueRole.
*/
QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
QObject *parent)
: QBarDataProxy(*(new QItemModelBarDataProxyPrivate(this)), parent)
{
Q_D(QItemModelBarDataProxy);
d->m_itemModelHandler->setItemModel(itemModel);
d->m_rowRole = rowRole;
d->m_columnRole = columnRole;
d->m_valueRole = valueRole;
d->connectItemModelHandler();
}
/*!
* Constructs QItemModelBarDataProxy with \a itemModel and an optional \a parent.
* The proxy doesn't take ownership of the \a itemModel, as typically item models
* are owned by other controls. The role mappings are set with \a rowRole, \a
* columnRole, \a valueRole, and \a rotationRole.
*/
QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
const QString &rotationRole,
QObject *parent)
: QBarDataProxy(*(new QItemModelBarDataProxyPrivate(this)), parent)
{
Q_D(QItemModelBarDataProxy);
d->m_itemModelHandler->setItemModel(itemModel);
d->m_rowRole = rowRole;
d->m_columnRole = columnRole;
d->m_valueRole = valueRole;
d->m_rotationRole = rotationRole;
d->connectItemModelHandler();
}
/*!
* Constructs QItemModelBarDataProxy with \a itemModel and an optional \a parent.
* The proxy doesn't take ownership of the \a itemModel, as typically item models
* are owned by other controls. The role mappings are set with \a rowRole, \a
* columnRole, and \a valueRole. Row and column categories are set with \a
* rowCategories and \a columnCategories. This constructor also sets
* autoRowCategories and autoColumnCategories to false.
*/
QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
const QStringList &rowCategories,
const QStringList &columnCategories,
QObject *parent)
: QBarDataProxy(*(new QItemModelBarDataProxyPrivate(this)), parent)
{
Q_D(QItemModelBarDataProxy);
d->m_itemModelHandler->setItemModel(itemModel);
d->m_rowRole = rowRole;
d->m_columnRole = columnRole;
d->m_valueRole = valueRole;
d->m_rowCategories = rowCategories;
d->m_columnCategories = columnCategories;
d->m_autoRowCategories = false;
d->m_autoColumnCategories = false;
d->connectItemModelHandler();
}
/*!
* Constructs QItemModelBarDataProxy with \a itemModel and an optional \a parent.
* The proxy doesn't take ownership of the \a itemModel, as typically item models
* are owned by other controls. The role mappings are set with \a rowRole, \a
* columnRole, \a valueRole, and \a rotationRole. Row and column categories are
* set with \a rowCategories and \a columnCategories. This constructor also sets
* autoRowCategories and autoColumnCategories to false.
*/
QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
const QString &rotationRole,
const QStringList &rowCategories,
const QStringList &columnCategories,
QObject *parent)
: QBarDataProxy(*(new QItemModelBarDataProxyPrivate(this)), parent)
{
Q_D(QItemModelBarDataProxy);
d->m_itemModelHandler->setItemModel(itemModel);
d->m_rowRole = rowRole;
d->m_columnRole = columnRole;
d->m_valueRole = valueRole;
d->m_rotationRole = rotationRole;
d->m_rowCategories = rowCategories;
d->m_columnCategories = columnCategories;
d->m_autoRowCategories = false;
d->m_autoColumnCategories = false;
d->connectItemModelHandler();
}
/*!
* Destroys QItemModelBarDataProxy.
*/
QItemModelBarDataProxy::~QItemModelBarDataProxy() {}
/*!
* \property QItemModelBarDataProxy::itemModel
*
* \brief The item model.
*/
/*!
* Sets the item model to \a itemModel. Does not take ownership of the model,
* but does connect to it to listen for changes.
*/
void QItemModelBarDataProxy::setItemModel(QAbstractItemModel *itemModel)
{
Q_D(QItemModelBarDataProxy);
d->m_itemModelHandler->setItemModel(itemModel);
}
QAbstractItemModel *QItemModelBarDataProxy::itemModel() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_itemModelHandler->itemModel();
}
/*!
* \property QItemModelBarDataProxy::rowRole
*
* \brief The row role for the mapping.
*/
void QItemModelBarDataProxy::setRowRole(const QString &role)
{
Q_D(QItemModelBarDataProxy);
if (d->m_rowRole == role) {
qCDebug(lcProperties3D, "%s Value is already set to: %s",
qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(role));
return;
}
d->m_rowRole = role;
emit rowRoleChanged(role);
}
QString QItemModelBarDataProxy::rowRole() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_rowRole;
}
/*!
* \property QItemModelBarDataProxy::columnRole
*
* \brief The column role for the mapping.
*/
void QItemModelBarDataProxy::setColumnRole(const QString &role)
{
Q_D(QItemModelBarDataProxy);
if (d->m_columnRole == role) {
qCDebug(lcProperties3D, "%s value is already set to: %s",
qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(role));
return;
}
d->m_columnRole = role;
emit columnRoleChanged(role);
}
QString QItemModelBarDataProxy::columnRole() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_columnRole;
}
/*!
* \property QItemModelBarDataProxy::valueRole
*
* \brief The value role for the mapping.
*/
void QItemModelBarDataProxy::setValueRole(const QString &role)
{
Q_D(QItemModelBarDataProxy);
if (d->m_valueRole == role) {
qCDebug(lcProperties3D, "%s Value is already set to: %s",
qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(role));
return;
}
d->m_valueRole = role;
emit valueRoleChanged(role);
}
QString QItemModelBarDataProxy::valueRole() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_valueRole;
}
/*!
* \property QItemModelBarDataProxy::rotationRole
*
* \brief The rotation role for the mapping.
*/
void QItemModelBarDataProxy::setRotationRole(const QString &role)
{
Q_D(QItemModelBarDataProxy);
if (d->m_rotationRole == role) {
qCDebug(lcProperties3D, "%s value is already set to: %s",
qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(role));
return;
}
d->m_rotationRole = role;
emit rotationRoleChanged(role);
}
QString QItemModelBarDataProxy::rotationRole() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_rotationRole;
}
/*!
* \property QItemModelBarDataProxy::rowCategories
*
* \brief The row categories for the mapping.
*/
void QItemModelBarDataProxy::setRowCategories(const QStringList &categories)
{
Q_D(QItemModelBarDataProxy);
if (d->m_rowCategories == categories) {
qCDebug(lcProperties3D) << qUtf8Printable(QLatin1String(__FUNCTION__))
<< "value is already set to:" << categories;
return;
}
d->m_rowCategories = categories;
emit rowCategoriesChanged();
}
QStringList QItemModelBarDataProxy::rowCategories() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_rowCategories;
}
/*!
* \property QItemModelBarDataProxy::columnCategories
*
* \brief The column categories for the mapping.
*/
void QItemModelBarDataProxy::setColumnCategories(const QStringList &categories)
{
Q_D(QItemModelBarDataProxy);
if (d->m_columnCategories == categories) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << categories;
return;
}
d->m_columnCategories = categories;
emit columnCategoriesChanged();
}
QStringList QItemModelBarDataProxy::columnCategories() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_columnCategories;
}
/*!
* \property QItemModelBarDataProxy::useModelCategories
*
* \brief Whether row and column roles and categories are used for mapping.
*
* When set to \c true, the mapping ignores row and column roles and categories,
* and uses the rows and columns from the model instead. Defaults to \c{false}.
*/
void QItemModelBarDataProxy::setUseModelCategories(bool enable)
{
Q_D(QItemModelBarDataProxy);
if (d->m_useModelCategories == enable) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << enable;
return;
}
d->m_useModelCategories = enable;
emit useModelCategoriesChanged(enable);
}
bool QItemModelBarDataProxy::useModelCategories() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_useModelCategories;
}
/*!
* \property QItemModelBarDataProxy::autoRowCategories
*
* \brief Whether row categories are generated automatically.
*
* When set to \c true, the mapping ignores any explicitly set row categories
* and overwrites them with automatically generated ones whenever the
* data from model is resolved. Defaults to \c{true}.
*/
void QItemModelBarDataProxy::setAutoRowCategories(bool enable)
{
Q_D(QItemModelBarDataProxy);
if (d->m_autoRowCategories == enable) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << enable;
return;
}
d->m_autoRowCategories = enable;
emit autoRowCategoriesChanged(enable);
}
bool QItemModelBarDataProxy::autoRowCategories() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_autoRowCategories;
}
/*!
* \property QItemModelBarDataProxy::autoColumnCategories
*
* \brief Whether column categories are generated automatically.
*
* When set to \c true, the mapping ignores any explicitly set column categories
* and overwrites them with automatically generated ones whenever the
* data from model is resolved. Defaults to \c{true}.
*/
void QItemModelBarDataProxy::setAutoColumnCategories(bool enable)
{
Q_D(QItemModelBarDataProxy);
if (d->m_autoColumnCategories == enable) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << enable;
return;
}
d->m_autoColumnCategories = enable;
emit autoColumnCategoriesChanged(enable);
}
bool QItemModelBarDataProxy::autoColumnCategories() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_autoColumnCategories;
}
/*!
* Changes \a rowRole, \a columnRole, \a valueRole, \a rotationRole,
* \a rowCategories and \a columnCategories to the mapping.
*/
void QItemModelBarDataProxy::remap(const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
const QString &rotationRole,
const QStringList &rowCategories,
const QStringList &columnCategories)
{
setRowRole(rowRole);
setColumnRole(columnRole);
setValueRole(valueRole);
setRotationRole(rotationRole);
setRowCategories(rowCategories);
setColumnCategories(columnCategories);
}
/*!
* Returns the index of the specified \a category in row categories list.
* If the row categories list is empty, -1 is returned.
* \note If the automatic row categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the
* first time.
*/
qsizetype QItemModelBarDataProxy::rowCategoryIndex(const QString &category)
{
Q_D(QItemModelBarDataProxy);
return d->m_rowCategories.indexOf(category);
}
/*!
* Returns the index of the specified \a category in column categories list.
* If the category is not found, -1 is returned.
* \note If the automatic column categories generation is in use, this method
* will not return a valid index before the data in the model is resolved for
* the first time.
*/
qsizetype QItemModelBarDataProxy::columnCategoryIndex(const QString &category)
{
Q_D(QItemModelBarDataProxy);
return d->m_columnCategories.indexOf(category);
}
/*!
* \property QItemModelBarDataProxy::rowRolePattern
*
* \brief Whether a search and replace is performed on the value mapped by row
* role before it is used as a row category.
*
* This property specifies the regular expression to find the portion of the
* mapped value to replace and rowRoleReplace property contains the replacement
* string. This is useful for example in parsing row and column categories from
* a single timestamp field in the item model.
*
* \sa rowRole, rowRoleReplace
*/
void QItemModelBarDataProxy::setRowRolePattern(const QRegularExpression &pattern)
{
Q_D(QItemModelBarDataProxy);
if (d->m_rowRolePattern == pattern) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << pattern;
return;
}
d->m_rowRolePattern = pattern;
emit rowRolePatternChanged(pattern);
}
QRegularExpression QItemModelBarDataProxy::rowRolePattern() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_rowRolePattern;
}
/*!
* \property QItemModelBarDataProxy::columnRolePattern
*
* \brief Whether a search and replace is done on the value mapped by column
* role before it is used as a column category.
*
* This property specifies the regular expression to find the portion of the
* mapped value to replace and columnRoleReplace property contains the
* replacement string. This is useful for example in parsing row and column
* categories from a single timestamp field in the item model.
*
* \sa columnRole, columnRoleReplace
*/
void QItemModelBarDataProxy::setColumnRolePattern(const QRegularExpression &pattern)
{
Q_D(QItemModelBarDataProxy);
if (d->m_columnRolePattern == pattern) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << pattern;
return;
}
d->m_columnRolePattern = pattern;
emit columnRolePatternChanged(pattern);
}
QRegularExpression QItemModelBarDataProxy::columnRolePattern() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_columnRolePattern;
}
/*!
* \property QItemModelBarDataProxy::valueRolePattern
*
* \brief Whether a search and replace is done on the value mapped by value role
* before it is used as a bar value.
*
* This property specifies the regular expression to find the portion of the
* mapped value to replace and valueRoleReplace property contains the
* replacement string.
*
* \sa valueRole, valueRoleReplace
*/
void QItemModelBarDataProxy::setValueRolePattern(const QRegularExpression &pattern)
{
Q_D(QItemModelBarDataProxy);
if (d->m_valueRolePattern == pattern) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << pattern;
return;
}
d->m_valueRolePattern = pattern;
emit valueRolePatternChanged(pattern);
}
QRegularExpression QItemModelBarDataProxy::valueRolePattern() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_valueRolePattern;
}
/*!
* \property QItemModelBarDataProxy::rotationRolePattern
*
* \brief Whether a search and replace is done on the value mapped by rotation
* role before it is used as a bar rotation angle.
*
* This property specifies the regular expression to find the portion
* of the mapped value to replace and rotationRoleReplace property contains the
* replacement string.
*
* \sa rotationRole, rotationRoleReplace
*/
void QItemModelBarDataProxy::setRotationRolePattern(const QRegularExpression &pattern)
{
Q_D(QItemModelBarDataProxy);
if (d->m_rotationRolePattern == pattern) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << pattern;
return;
}
d->m_rotationRolePattern = pattern;
emit rotationRolePatternChanged(pattern);
}
QRegularExpression QItemModelBarDataProxy::rotationRolePattern() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_rotationRolePattern;
}
/*!
* \property QItemModelBarDataProxy::rowRoleReplace
*
* \brief The replacement content to be used in conjunction with rowRolePattern.
*
* Defaults to empty string. For more information on how the search and replace
* using regular expressions works, see QString::replace(const
* QRegularExpression &rx, const QString &after) function documentation.
*
* \sa rowRole, rowRolePattern
*/
void QItemModelBarDataProxy::setRowRoleReplace(const QString &replace)
{
Q_D(QItemModelBarDataProxy);
if (d->m_rowRoleReplace == replace) {
qCDebug(lcProperties3D, "%s value is already set to: %s",
qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(replace));
return;
}
d->m_rowRoleReplace = replace;
emit rowRoleReplaceChanged(replace);
}
QString QItemModelBarDataProxy::rowRoleReplace() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_rowRoleReplace;
}
/*!
* \property QItemModelBarDataProxy::columnRoleReplace
*
* \brief The replacement content to be used in conjunction with columnRolePattern.
*
* Defaults to empty string. For more information on how the search and replace
* using regular expressions works, see QString::replace(const
* QRegularExpression &rx, const QString &after) function documentation.
*
* \sa columnRole, columnRolePattern
*/
void QItemModelBarDataProxy::setColumnRoleReplace(const QString &replace)
{
Q_D(QItemModelBarDataProxy);
if (d->m_columnRoleReplace == replace) {
qCDebug(lcProperties3D, "%s value is already set to: %s",
qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(replace));
return;
}
d->m_columnRoleReplace = replace;
emit columnRoleReplaceChanged(replace);
}
QString QItemModelBarDataProxy::columnRoleReplace() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_columnRoleReplace;
}
/*!
* \property QItemModelBarDataProxy::valueRoleReplace
*
* \brief The replacement content to be used in conjunction with valueRolePattern.
*
* Defaults to empty string. For more information on how the search and replace
* using regular expressions works, see QString::replace(const
* QRegularExpression &rx, const QString &after) function documentation.
*
* \sa valueRole, valueRolePattern
*/
void QItemModelBarDataProxy::setValueRoleReplace(const QString &replace)
{
Q_D(QItemModelBarDataProxy);
if (d->m_valueRoleReplace == replace) {
qCDebug(lcProperties3D, "%s value is already set to: %s",
qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(replace));
return;
}
d->m_valueRoleReplace = replace;
emit valueRoleReplaceChanged(replace);
}
QString QItemModelBarDataProxy::valueRoleReplace() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_valueRoleReplace;
}
/*!
* \property QItemModelBarDataProxy::rotationRoleReplace
*
* \brief The replacement content to be used in conjunction with
* rotationRolePattern.
*
* Defaults to empty string. For more information on how the search and replace
* using regular expressions works, see QString::replace(const
* QRegularExpression &rx, const QString &after) function documentation.
*
* \sa rotationRole, rotationRolePattern
*/
void QItemModelBarDataProxy::setRotationRoleReplace(const QString &replace)
{
Q_D(QItemModelBarDataProxy);
if (d->m_rotationRoleReplace == replace) {
qCDebug(lcProperties3D, "%s value is already set to: %s",
qUtf8Printable(QLatin1String(__FUNCTION__)), qUtf8Printable(replace));
return;
}
d->m_rotationRoleReplace = replace;
emit rotationRoleReplaceChanged(replace);
}
QString QItemModelBarDataProxy::rotationRoleReplace() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_rotationRoleReplace;
}
/*!
* \property QItemModelBarDataProxy::multiMatchBehavior
*
* \brief How multiple matches for each row/column combination are handled.
*
* Defaults to QItemModelBarDataProxy::MultiMatchBehavior::Last. The chosen
* behavior affects both bar value and rotation.
*
* For example, you might have an item model with timestamped data taken at
* irregular intervals and you want to visualize total value of data items on
* each day with a bar graph. This can be done by specifying row and column
* categories so that each bar represents a day, and setting multiMatchBehavior
* to QItemModelBarDataProxy::MultiMatchBehavior::Cumulative.
*/
void QItemModelBarDataProxy::setMultiMatchBehavior(
QItemModelBarDataProxy::MultiMatchBehavior behavior)
{
Q_D(QItemModelBarDataProxy);
if (d->m_multiMatchBehavior == behavior) {
qCDebug(lcProperties3D) << __FUNCTION__
<< "value is already set to:" << behavior;
return;
}
d->m_multiMatchBehavior = behavior;
emit multiMatchBehaviorChanged(behavior);
}
QItemModelBarDataProxy::MultiMatchBehavior QItemModelBarDataProxy::multiMatchBehavior() const
{
Q_D(const QItemModelBarDataProxy);
return d->m_multiMatchBehavior;
}
// QItemModelBarDataProxyPrivate
QItemModelBarDataProxyPrivate::QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q)
: m_itemModelHandler(new BarItemModelHandler(q))
, m_useModelCategories(false)
, m_autoRowCategories(true)
, m_autoColumnCategories(true)
, m_multiMatchBehavior(QItemModelBarDataProxy::MultiMatchBehavior::Last)
{}
QItemModelBarDataProxyPrivate::~QItemModelBarDataProxyPrivate()
{
delete m_itemModelHandler;
}
void QItemModelBarDataProxyPrivate::connectItemModelHandler()
{
Q_Q(QItemModelBarDataProxy);
QObject::connect(m_itemModelHandler,
&BarItemModelHandler::itemModelChanged,
q,
&QItemModelBarDataProxy::itemModelChanged);
QObject::connect(q,
&QItemModelBarDataProxy::rowRoleChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::columnRoleChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::valueRoleChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::rotationRoleChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::rowCategoriesChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::columnCategoriesChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::useModelCategoriesChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::autoRowCategoriesChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::autoColumnCategoriesChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::rowRolePatternChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::columnRolePatternChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::valueRolePatternChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::rotationRolePatternChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::rowRoleReplaceChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::columnRoleReplaceChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::valueRoleReplaceChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::rotationRoleReplaceChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
QObject::connect(q,
&QItemModelBarDataProxy::multiMatchBehaviorChanged,
m_itemModelHandler,
&AbstractItemModelHandler::handleMappingChanged);
}
QT_END_NAMESPACE
#include "moc_qitemmodelbardataproxy.cpp"