From 4dcef4be656aedb7c6c9e222f291a1a508641007 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 12 May 2014 11:10:46 +0300 Subject: Enable mapping single role to multiple properties for surface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-3074 Change-Id: If40de067526b6f24b3e55bf64ed804a79d473e5f Reviewed-by: Tomi Korpipää Reviewed-by: Titta Heikkala --- src/datavisualization/data/baritemmodelhandler.cpp | 10 +- .../data/qitemmodelsurfacedataproxy.cpp | 420 +++++++++++++++++++-- .../data/qitemmodelsurfacedataproxy.h | 43 +++ .../data/qitemmodelsurfacedataproxy_p.h | 12 + src/datavisualization/data/qsurfacedataproxy.cpp | 12 +- .../data/surfaceitemmodelhandler.cpp | 115 +++++- .../data/surfaceitemmodelhandler_p.h | 9 + 7 files changed, 567 insertions(+), 54 deletions(-) (limited to 'src/datavisualization') diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp index e8941c4b..4685be44 100644 --- a/src/datavisualization/data/baritemmodelhandler.cpp +++ b/src/datavisualization/data/baritemmodelhandler.cpp @@ -55,8 +55,9 @@ void BarItemModelHandler::handleDataChanged(const QModelIndex &topLeft, for (int i = startRow; i <= endRow; i++) { for (int j = startCol; j <= endCol; j++) { + QModelIndex index = m_itemModel->index(i, j); QBarDataItem item; - QVariant valueVar = m_itemModel->index(i, j).data(m_valueRole); + QVariant valueVar = index.data(m_valueRole); float value; if (m_haveValuePattern) value = valueVar.toString().replace(m_valuePattern, m_valueReplace).toFloat(); @@ -64,7 +65,7 @@ void BarItemModelHandler::handleDataChanged(const QModelIndex &topLeft, value = valueVar.toFloat(); item.setValue(value); if (m_rotationRole != noRoleIndex) { - QVariant rotationVar = m_itemModel->index(i, j).data(m_rotationRole); + QVariant rotationVar = index.data(m_rotationRole); float rotation; if (m_haveRotationPattern) { rotation = rotationVar.toString().replace(m_rotationPattern, @@ -133,7 +134,8 @@ void BarItemModelHandler::resolveModel() for (int i = 0; i < rowCount; i++) { QBarDataRow &newProxyRow = *m_proxyArray->at(i); for (int j = 0; j < columnCount; j++) { - QVariant valueVar = m_itemModel->index(i, j).data(m_valueRole); + QModelIndex index = m_itemModel->index(i, j); + QVariant valueVar = index.data(m_valueRole); float value; if (m_haveValuePattern) value = valueVar.toString().replace(m_valuePattern, m_valueReplace).toFloat(); @@ -141,7 +143,7 @@ void BarItemModelHandler::resolveModel() value = valueVar.toFloat(); newProxyRow[j].setValue(value); if (m_rotationRole != noRoleIndex) { - QVariant rotationVar = m_itemModel->index(i, j).data(m_rotationRole); + QVariant rotationVar = index.data(m_rotationRole); float rotation; if (m_haveRotationPattern) { rotation = rotationVar.toString().replace(m_rotationPattern, diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp index 440ce2d6..77f90ed4 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp @@ -54,13 +54,24 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * and in which order by defining an explicit list of categories for either or both of rows and * columns. * - * For example, assume that you have a custom QAbstractItemModel storing surface topography data. - * Each item in the model has the roles "longitude", "latitude", and "height". The item model already - * contains the data properly sorted so that longitudes and latitudes are first encountered in - * correct order, which enables us to utilize the row and column category autogeneration. - * You could do the following to display the data in a surface graph: + * For example, assume that you have a custom QAbstractItemModel storing surface topography data. + * Each item in the model has the roles "longitude", "latitude", and "height". + * The item model already contains the data properly sorted so that longitudes and latitudes are + * first encountered in correct order, which enables us to utilize the row and column category + * autogeneration. + * You could do the following to display the data in a surface graph: * - * \snippet doc_src_qtdatavisualization.cpp 5 + * \snippet doc_src_qtdatavisualization.cpp 5 + * + * 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 how the replace using regular expressions works, see + * QString::replace(const QRegExp &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 + * ItemModelBarDataProxy usage in \l{Qt Quick 2 Bars Example}. * * \sa {Qt Data Visualization Data Handling} */ @@ -95,33 +106,35 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \qmlproperty string ItemModelSurfaceDataProxy::rowRole - * The row role of the mapping. + * Defines the item model role to map into row category. * In addition to defining which row the data belongs to, the value indicated by row role - * is also set as the Z-coordinate value of the QSurfaceDataItem when model data is resolved. + * is also set as the Z-coordinate value of the QSurfaceDataItem when model data is resolved, + * unless a separate zPos role is also defined. */ /*! * \qmlproperty string ItemModelSurfaceDataProxy::columnRole - * The column role of the mapping. + * Defines the item model role to map into column category. * In addition to defining which column the data belongs to, the value indicated by column role - * is also set as the X-coordinate value of the QSurfaceDataItem when model data is resolved. + * is also set as the X-coordinate value of the QSurfaceDataItem when model data is resolved, + * unless a separate xPos role is also defined. */ /*! * \qmlproperty string ItemModelSurfaceDataProxy::xPosRole - * The X position role of the mapping. If this role is not defined, columnRole is used to - * determine the X-coordinate value of resolved QSurfaceDataItems. + * Defines the item model role to map into X position. If this role is not defined, columnRole is + * used to determine the X-coordinate value of resolved QSurfaceDataItems. */ /*! * \qmlproperty string ItemModelSurfaceDataProxy::yPosRole - * The Y position role of the mapping. + * Defines the item model role to map into Y position. */ /*! * \qmlproperty string ItemModelSurfaceDataProxy::zPosRole - * The Z position role of the mapping. If this role is not defined, rowRole is used to - * determine the Z-coordinate value of resolved QSurfaceDataItems. + * Defines the item model role to map into Z position. If this role is not defined, rowRole is + * used to determine the Z-coordinate value of resolved QSurfaceDataItems. */ /*! @@ -132,8 +145,9 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! * \qmlproperty list ItemModelSurfaceDataProxy::columnCategories - * The column categories of the mapping. Only items with column roles that are found in this list are - * included when data is resolved. The columns are ordered in the same order as they are in this list. + * The column categories of the mapping. Only items with column roles that are found in this + * list are included when data is resolved. The columns are ordered in the same order as they are + * in this list. */ /*! @@ -158,6 +172,111 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * autogenerated from data when this is set to true. Defaults to \c{true}. */ +/*! + * \qmlproperty regExp ItemModelSurfaceDataProxy::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. + * + * \sa rowRole, rowRoleReplace + */ + +/*! + * \qmlproperty regExp ItemModelSurfaceDataProxy::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. + * + * \sa columnRole, columnRoleReplace + */ + +/*! + * \qmlproperty regExp ItemModelSurfaceDataProxy::xPosRolePattern + * + * When set, a search and replace is done on the value mapped by xPos role before it is used as + * a item position value. This property specifies the regular expression to find the portion of the + * mapped value to replace and xPosRoleReplace property contains the replacement string. + * + * \sa xPosRole, xPosRoleReplace + */ + +/*! + * \qmlproperty regExp ItemModelSurfaceDataProxy::yPosRolePattern + * + * When set, a search and replace is done on the value mapped by yPos role before it is used as + * a item position value. This property specifies the regular expression to find the portion of the + * mapped value to replace and yPosRoleReplace property contains the replacement string. + * + * \sa yPosRole, yPosRoleReplace + */ + +/*! + * \qmlproperty regExp ItemModelSurfaceDataProxy::zPosRolePattern + * + * When set, a search and replace is done on the value mapped by zPos role before it is used as + * a item position value. This property specifies the regular expression to find the portion of the + * mapped value to replace and zPosRoleReplace property contains the replacement string. + * + * \sa zPosRole, zPosRoleReplace + */ + +/*! + * \qmlproperty string ItemModelSurfaceDataProxy::rowRoleReplace + * + * This property defines the replace 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 QRegExp &rx, const QString &after) + * function documentation. + * + * \sa rowRole, rowRolePattern + */ + +/*! + * \qmlproperty string ItemModelSurfaceDataProxy::columnRoleReplace + * + * This property defines the replace 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 QRegExp &rx, const QString &after) + * function documentation. + * + * \sa columnRole, columnRolePattern + */ + +/*! + * \qmlproperty string ItemModelSurfaceDataProxy::xPosRoleReplace + * + * This property defines the replace content to be used in conjunction with xPosRolePattern. + * Defaults to empty string. For more information on how the search and replace using regular + * expressions works, see QString::replace(const QRegExp &rx, const QString &after) + * function documentation. + * + * \sa xPosRole, xPosRolePattern + */ + +/*! + * \qmlproperty string ItemModelSurfaceDataProxy::yPosRoleReplace + * + * This property defines the replace content to be used in conjunction with yPosRolePattern. + * Defaults to empty string. For more information on how the search and replace using regular + * expressions works, see QString::replace(const QRegExp &rx, const QString &after) + * function documentation. + * + * \sa yPosRole, yPosRolePattern + */ + +/*! + * \qmlproperty string ItemModelSurfaceDataProxy::zPosRoleReplace + * + * This property defines the replace content to be used in conjunction with zPosRolePattern. + * Defaults to empty string. For more information on how the search and replace using regular + * expressions works, see QString::replace(const QRegExp &rx, const QString &after) + * function documentation. + * + * \sa zPosRole, zPosRolePattern + */ + /*! * Constructs QItemModelSurfaceDataProxy with optional \a parent. */ @@ -331,7 +450,10 @@ const QAbstractItemModel *QItemModelSurfaceDataProxy::itemModel() const /*! * \property QItemModelSurfaceDataProxy::rowRole * - * Defines the row \a role for the mapping. + * Defines the item model role to map into row category. + * In addition to defining which row the data belongs to, the value indicated by row role + * is also set as the Z-coordinate value of the QSurfaceDataItem when model data is resolved, + * unless a separate zPos role is also defined. */ void QItemModelSurfaceDataProxy::setRowRole(const QString &role) { @@ -349,7 +471,10 @@ QString QItemModelSurfaceDataProxy::rowRole() const /*! * \property QItemModelSurfaceDataProxy::columnRole * - * Defines the column \a role for the mapping. + * Defines the item model role to map into column category. + * In addition to defining which column the data belongs to, the value indicated by column role + * is also set as the X-coordinate value of the QSurfaceDataItem when model data is resolved, + * unless a separate xPos role is also defined. */ void QItemModelSurfaceDataProxy::setColumnRole(const QString &role) { @@ -367,9 +492,8 @@ QString QItemModelSurfaceDataProxy::columnRole() const /*! * \property QItemModelSurfaceDataProxy::xPosRole * - * Defines the X position \a role for the mapping. - * If this role is not defined, columnRole is used to determine the X-coordinate - * value of resolved QSurfaceDataItems. + * Defines the item model role to map into X position. If this role is not defined, columnRole is + * used to determine the X-coordinate value of resolved QSurfaceDataItems. */ void QItemModelSurfaceDataProxy::setXPosRole(const QString &role) { @@ -387,7 +511,7 @@ QString QItemModelSurfaceDataProxy::xPosRole() const /*! * \property QItemModelSurfaceDataProxy::yPosRole * - * Defines the Y position \a role for the mapping. + * Defines the item model role to map into Y position. */ void QItemModelSurfaceDataProxy::setYPosRole(const QString &role) { @@ -405,9 +529,8 @@ QString QItemModelSurfaceDataProxy::yPosRole() const /*! * \property QItemModelSurfaceDataProxy::zPosRole * - * Defines the Z position \a role for the mapping. - * If this role is not defined, rowRole is used to determine the Z-coordinate - * value of resolved QSurfaceDataItems. + * Defines the item model role to map into Z position. If this role is not defined, rowRole is + * used to determine the Z-coordinate value of resolved QSurfaceDataItems. */ void QItemModelSurfaceDataProxy::setZPosRole(const QString &role) { @@ -560,6 +683,231 @@ int QItemModelSurfaceDataProxy::columnCategoryIndex(const QString &category) return dptr()->m_columnCategories.indexOf(category); } +/*! + * \property QItemModelSurfaceDataProxy::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. + * + * \sa rowRole, rowRoleReplace + */ +void QItemModelSurfaceDataProxy::setRowRolePattern(const QRegExp &pattern) +{ + if (dptr()->m_rowRolePattern != pattern) { + dptr()->m_rowRolePattern = pattern; + emit rowRolePatternChanged(pattern); + } +} + +QRegExp QItemModelSurfaceDataProxy::rowRolePattern() const +{ + return dptrc()->m_rowRolePattern; +} + +/*! + * \property QItemModelSurfaceDataProxy::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. + * + * \sa columnRole, columnRoleReplace + */ +void QItemModelSurfaceDataProxy::setColumnRolePattern(const QRegExp &pattern) +{ + if (dptr()->m_columnRolePattern != pattern) { + dptr()->m_columnRolePattern = pattern; + emit columnRolePatternChanged(pattern); + } +} + +QRegExp QItemModelSurfaceDataProxy::columnRolePattern() const +{ + return dptrc()->m_columnRolePattern; +} + +/*! + * \property QItemModelSurfaceDataProxy::xPosRolePattern + * + * When set, a search and replace is done on the value mapped by xPos role before it is used as + * a item position value. This property specifies the regular expression to find the portion of the + * mapped value to replace and xPosRoleReplace property contains the replacement string. + * + * \sa xPosRole, xPosRoleReplace + */ +void QItemModelSurfaceDataProxy::setXPosRolePattern(const QRegExp &pattern) +{ + if (dptr()->m_xPosRolePattern != pattern) { + dptr()->m_xPosRolePattern = pattern; + emit xPosRolePatternChanged(pattern); + } +} + +QRegExp QItemModelSurfaceDataProxy::xPosRolePattern() const +{ + return dptrc()->m_xPosRolePattern; +} + +/*! + * \property QItemModelSurfaceDataProxy::yPosRolePattern + * + * When set, a search and replace is done on the value mapped by yPos role before it is used as + * a item position value. This property specifies the regular expression to find the portion of the + * mapped value to replace and yPosRoleReplace property contains the replacement string. + * + * \sa yPosRole, yPosRoleReplace + */ +void QItemModelSurfaceDataProxy::setYPosRolePattern(const QRegExp &pattern) +{ + if (dptr()->m_yPosRolePattern != pattern) { + dptr()->m_yPosRolePattern = pattern; + emit yPosRolePatternChanged(pattern); + } +} + +QRegExp QItemModelSurfaceDataProxy::yPosRolePattern() const +{ + return dptrc()->m_yPosRolePattern; +} + +/*! + * \property QItemModelSurfaceDataProxy::zPosRolePattern + * + * When set, a search and replace is done on the value mapped by zPos role before it is used as + * a item position value. This property specifies the regular expression to find the portion of the + * mapped value to replace and zPosRoleReplace property contains the replacement string. + * + * \sa zPosRole, zPosRoleReplace + */ +void QItemModelSurfaceDataProxy::setZPosRolePattern(const QRegExp &pattern) +{ + if (dptr()->m_zPosRolePattern != pattern) { + dptr()->m_zPosRolePattern = pattern; + emit zPosRolePatternChanged(pattern); + } +} + +QRegExp QItemModelSurfaceDataProxy::zPosRolePattern() const +{ + return dptrc()->m_zPosRolePattern; +} + +/*! + * \property QItemModelSurfaceDataProxy::rowRoleReplace + * + * This property defines the replace 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 QRegExp &rx, const QString &after) + * function documentation. + * + * \sa rowRole, rowRolePattern + */ +void QItemModelSurfaceDataProxy::setRowRoleReplace(const QString &replace) +{ + if (dptr()->m_rowRoleReplace != replace) { + dptr()->m_rowRoleReplace = replace; + emit rowRoleReplaceChanged(replace); + } +} + +QString QItemModelSurfaceDataProxy::rowRoleReplace() const +{ + return dptrc()->m_rowRoleReplace; +} + +/*! + * \property QItemModelSurfaceDataProxy::columnRoleReplace + * + * This property defines the replace 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 QRegExp &rx, const QString &after) + * function documentation. + * + * \sa columnRole, columnRolePattern + */ +void QItemModelSurfaceDataProxy::setColumnRoleReplace(const QString &replace) +{ + if (dptr()->m_columnRoleReplace != replace) { + dptr()->m_columnRoleReplace = replace; + emit columnRoleReplaceChanged(replace); + } +} + +QString QItemModelSurfaceDataProxy::columnRoleReplace() const +{ + return dptrc()->m_columnRoleReplace; +} + +/*! + * \property QItemModelSurfaceDataProxy::xPosRoleReplace + * + * This property defines the replace content to be used in conjunction with xPosRolePattern. + * Defaults to empty string. For more information on how the search and replace using regular + * expressions works, see QString::replace(const QRegExp &rx, const QString &after) + * function documentation. + * + * \sa xPosRole, xPosRolePattern + */ +void QItemModelSurfaceDataProxy::setXPosRoleReplace(const QString &replace) +{ + if (dptr()->m_xPosRoleReplace != replace) { + dptr()->m_xPosRoleReplace = replace; + emit xPosRoleReplaceChanged(replace); + } +} + +QString QItemModelSurfaceDataProxy::xPosRoleReplace() const +{ + return dptrc()->m_xPosRoleReplace; +} + +/*! + * \property QItemModelSurfaceDataProxy::yPosRoleReplace + * + * This property defines the replace content to be used in conjunction with yPosRolePattern. + * Defaults to empty string. For more information on how the search and replace using regular + * expressions works, see QString::replace(const QRegExp &rx, const QString &after) + * function documentation. + * + * \sa yPosRole, yPosRolePattern + */ +void QItemModelSurfaceDataProxy::setYPosRoleReplace(const QString &replace) +{ + if (dptr()->m_yPosRoleReplace != replace) { + dptr()->m_yPosRoleReplace = replace; + emit yPosRoleReplaceChanged(replace); + } +} + +QString QItemModelSurfaceDataProxy::yPosRoleReplace() const +{ + return dptrc()->m_yPosRoleReplace; +} + +/*! + * \property QItemModelSurfaceDataProxy::zPosRoleReplace + * + * This property defines the replace content to be used in conjunction with zPosRolePattern. + * Defaults to empty string. For more information on how the search and replace using regular + * expressions works, see QString::replace(const QRegExp &rx, const QString &after) + * function documentation. + * + * \sa zPosRole, zPosRolePattern + */ +void QItemModelSurfaceDataProxy::setZPosRoleReplace(const QString &replace) +{ + if (dptr()->m_zPosRoleReplace != replace) { + dptr()->m_zPosRoleReplace = replace; + emit zPosRoleReplaceChanged(replace); + } +} + +QString QItemModelSurfaceDataProxy::zPosRoleReplace() const +{ + return dptrc()->m_zPosRoleReplace; +} + /*! * \internal */ @@ -621,6 +969,26 @@ void QItemModelSurfaceDataProxyPrivate::connectItemModelHandler() m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); QObject::connect(qptr(), &QItemModelSurfaceDataProxy::autoColumnCategoriesChanged, m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::rowRolePatternChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::columnRolePatternChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::xPosRolePatternChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::yPosRolePatternChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::zPosRolePatternChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::rowRoleReplaceChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::columnRoleReplaceChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::xPosRoleReplaceChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::yPosRoleReplaceChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); + QObject::connect(qptr(), &QItemModelSurfaceDataProxy::zPosRoleReplaceChanged, + m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged); } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.h b/src/datavisualization/data/qitemmodelsurfacedataproxy.h index b1ebbeed..8fe736f5 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy.h +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.h @@ -22,6 +22,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -41,6 +42,16 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories NOTIFY useModelCategoriesChanged) Q_PROPERTY(bool autoRowCategories READ autoRowCategories WRITE setAutoRowCategories NOTIFY autoRowCategoriesChanged) Q_PROPERTY(bool autoColumnCategories READ autoColumnCategories WRITE setAutoColumnCategories NOTIFY autoColumnCategoriesChanged) + Q_PROPERTY(QRegExp rowRolePattern READ rowRolePattern WRITE setRowRolePattern NOTIFY rowRolePatternChanged REVISION 1) + Q_PROPERTY(QRegExp columnRolePattern READ columnRolePattern WRITE setColumnRolePattern NOTIFY columnRolePatternChanged REVISION 1) + Q_PROPERTY(QRegExp xPosRolePattern READ xPosRolePattern WRITE setXPosRolePattern NOTIFY xPosRolePatternChanged REVISION 1) + Q_PROPERTY(QRegExp yPosRolePattern READ yPosRolePattern WRITE setYPosRolePattern NOTIFY yPosRolePatternChanged REVISION 1) + Q_PROPERTY(QRegExp zPosRolePattern READ zPosRolePattern WRITE setZPosRolePattern NOTIFY zPosRolePatternChanged REVISION 1) + Q_PROPERTY(QString rowRoleReplace READ rowRoleReplace WRITE setRowRoleReplace NOTIFY rowRoleReplaceChanged REVISION 1) + Q_PROPERTY(QString columnRoleReplace READ columnRoleReplace WRITE setColumnRoleReplace NOTIFY columnRoleReplaceChanged REVISION 1) + Q_PROPERTY(QString xPosRoleReplace READ xPosRoleReplace WRITE setXPosRoleReplace NOTIFY xPosRoleReplaceChanged REVISION 1) + Q_PROPERTY(QString yPosRoleReplace READ yPosRoleReplace WRITE setYPosRoleReplace NOTIFY yPosRoleReplaceChanged REVISION 1) + Q_PROPERTY(QString zPosRoleReplace READ zPosRoleReplace WRITE setZPosRoleReplace NOTIFY zPosRoleReplaceChanged REVISION 1) public: explicit QItemModelSurfaceDataProxy(QObject *parent = 0); @@ -99,6 +110,28 @@ public: Q_INVOKABLE int rowCategoryIndex(const QString& category); Q_INVOKABLE int columnCategoryIndex(const QString& category); + void setRowRolePattern(const QRegExp &pattern); + QRegExp rowRolePattern() const; + void setColumnRolePattern(const QRegExp &pattern); + QRegExp columnRolePattern() const; + void setXPosRolePattern(const QRegExp &pattern); + QRegExp xPosRolePattern() const; + void setYPosRolePattern(const QRegExp &pattern); + QRegExp yPosRolePattern() const; + void setZPosRolePattern(const QRegExp &pattern); + QRegExp zPosRolePattern() const; + + void setRowRoleReplace(const QString &replace); + QString rowRoleReplace() const; + void setColumnRoleReplace(const QString &replace); + QString columnRoleReplace() const; + void setXPosRoleReplace(const QString &replace); + QString xPosRoleReplace() const; + void setYPosRoleReplace(const QString &replace); + QString yPosRoleReplace() const; + void setZPosRoleReplace(const QString &replace); + QString zPosRoleReplace() const; + signals: void itemModelChanged(const QAbstractItemModel* itemModel); void rowRoleChanged(const QString &role); @@ -111,6 +144,16 @@ signals: void useModelCategoriesChanged(bool enable); void autoRowCategoriesChanged(bool enable); void autoColumnCategoriesChanged(bool enable); + Q_REVISION(1) void rowRolePatternChanged(const QRegExp &pattern); + Q_REVISION(1) void columnRolePatternChanged(const QRegExp &pattern); + Q_REVISION(1) void xPosRolePatternChanged(const QRegExp &pattern); + Q_REVISION(1) void yPosRolePatternChanged(const QRegExp &pattern); + Q_REVISION(1) void zPosRolePatternChanged(const QRegExp &pattern); + Q_REVISION(1) void rowRoleReplaceChanged(const QString &replace); + Q_REVISION(1) void columnRoleReplaceChanged(const QString &replace); + Q_REVISION(1) void xPosRoleReplaceChanged(const QString &replace); + Q_REVISION(1) void yPosRoleReplaceChanged(const QString &replace); + Q_REVISION(1) void zPosRoleReplaceChanged(const QString &replace); protected: QItemModelSurfaceDataProxyPrivate *dptr(); diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h index 0aaea8fd..06bfe2a1 100644 --- a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h +++ b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h @@ -64,6 +64,18 @@ private: bool m_autoRowCategories; bool m_autoColumnCategories; + QRegExp m_rowRolePattern; + QRegExp m_columnRolePattern; + QRegExp m_xPosRolePattern; + QRegExp m_yPosRolePattern; + QRegExp m_zPosRolePattern; + + QString m_rowRoleReplace; + QString m_columnRoleReplace; + QString m_xPosRoleReplace; + QString m_yPosRoleReplace; + QString m_zPosRoleReplace; + friend class SurfaceItemModelHandler; friend class QItemModelSurfaceDataProxy; }; diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp index f8f2c900..058b0e21 100644 --- a/src/datavisualization/data/qsurfacedataproxy.cpp +++ b/src/datavisualization/data/qsurfacedataproxy.cpp @@ -521,10 +521,14 @@ void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxV minValues.setY(min); maxValues.setY(max); if (columns) { - minValues.setX(m_dataArray->at(0)->at(0).x()); - minValues.setZ(m_dataArray->at(0)->at(0).z()); - maxValues.setX(m_dataArray->at(0)->last().x()); - maxValues.setZ(m_dataArray->last()->at(0).z()); + float xLow = m_dataArray->at(0)->at(0).x(); + float xHigh = m_dataArray->at(0)->last().x(); + float zLow = m_dataArray->at(0)->at(0).z(); + float zHigh = m_dataArray->last()->at(0).z(); + minValues.setX(qMin(xLow, xHigh)); + minValues.setZ(qMin(zLow, zHigh)); + maxValues.setX(qMax(xLow, xHigh)); + maxValues.setZ(qMax(zLow, zHigh)); } else { minValues.setX(0.0f); minValues.setZ(0.0f); diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp index 584ddf28..fad02464 100644 --- a/src/datavisualization/data/surfaceitemmodelhandler.cpp +++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp @@ -28,7 +28,10 @@ SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *pro m_proxyArray(0), m_xPosRole(noRoleIndex), m_yPosRole(noRoleIndex), - m_zPosRole(noRoleIndex) + m_zPosRole(noRoleIndex), + m_haveXPosPattern(false), + m_haveYPosPattern(false), + m_haveZPosPattern(false) { } @@ -53,21 +56,38 @@ void SurfaceItemModelHandler::handleDataChanged(const QModelIndex &topLeft, for (int i = startRow; i <= endRow; i++) { for (int j = startCol; j <= endCol; j++) { + QModelIndex index = m_itemModel->index(i, j); QSurfaceDataItem item; + QVariant xValueVar = index.data(m_xPosRole); + QVariant yValueVar = index.data(m_yPosRole); + QVariant zValueVar = index.data(m_zPosRole); const QSurfaceDataItem *oldItem = m_proxy->itemAt(i, j); float xPos; + float yPos; float zPos; - if (m_xPosRole != noRoleIndex) - xPos = m_itemModel->index(i, j).data(m_xPosRole).toFloat(); - else + if (m_xPosRole != noRoleIndex) { + if (m_haveXPosPattern) + xPos = xValueVar.toString().replace(m_xPosPattern, m_xPosReplace).toFloat(); + else + xPos = xValueVar.toFloat(); + } else { xPos = oldItem->x(); - if (m_zPosRole != noRoleIndex) - zPos = m_itemModel->index(i, j).data(m_zPosRole).toFloat(); + } + + if (m_haveYPosPattern) + yPos = yValueVar.toString().replace(m_yPosPattern, m_yPosReplace).toFloat(); else + yPos = yValueVar.toFloat(); + + if (m_zPosRole != noRoleIndex) { + if (m_haveZPosPattern) + zPos = zValueVar.toString().replace(m_zPosPattern, m_zPosReplace).toFloat(); + else + zPos = zValueVar.toFloat(); + } else { zPos = oldItem->z(); - item.setPosition(QVector3D(xPos, - m_itemModel->index(i, j).data(m_yPosRole).toFloat(), - zPos)); + } + item.setPosition(QVector3D(xPos, yPos, zPos)); m_proxy->setItem(i, j, item); } } @@ -91,6 +111,23 @@ void SurfaceItemModelHandler::resolveModel() return; } + // Position patterns can be reused on single item changes, so store them to member variables. + QRegExp rowPattern(m_proxy->rowRolePattern()); + QRegExp colPattern(m_proxy->columnRolePattern()); + m_xPosPattern = m_proxy->xPosRolePattern(); + m_yPosPattern = m_proxy->yPosRolePattern(); + m_zPosPattern = m_proxy->zPosRolePattern(); + QString rowReplace = m_proxy->rowRoleReplace(); + QString colReplace = m_proxy->columnRoleReplace(); + m_xPosReplace = m_proxy->xPosRoleReplace(); + m_yPosReplace = m_proxy->yPosRoleReplace(); + m_zPosReplace = m_proxy->zPosRoleReplace(); + bool haveRowPattern = !rowPattern.isEmpty() && rowPattern.isValid(); + bool haveColPattern = !colPattern.isEmpty() && colPattern.isValid(); + m_haveXPosPattern = !m_xPosPattern.isEmpty() && m_xPosPattern.isValid(); + m_haveYPosPattern = !m_yPosPattern.isEmpty() && m_yPosPattern.isValid(); + m_haveZPosPattern = !m_zPosPattern.isEmpty() && m_zPosPattern.isValid(); + QHash roleHash = m_itemModel->roleNames(); // Default to display role if no mapping @@ -112,32 +149,49 @@ void SurfaceItemModelHandler::resolveModel() for (int i = 0; i < rowCount; i++) { QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i); for (int j = 0; j < columnCount; j++) { - float xPos = float(j); - float zPos = float(i); + QModelIndex index = m_itemModel->index(i, j); + QVariant xValueVar = index.data(m_xPosRole); + QVariant yValueVar = index.data(m_yPosRole); + QVariant zValueVar = index.data(m_zPosRole); + float xPos; + float yPos; + float zPos; if (m_xPosRole != noRoleIndex) { - xPos = m_itemModel->index(i, j).data(m_xPosRole).toFloat(); + if (m_haveXPosPattern) + xPos = xValueVar.toString().replace(m_xPosPattern, m_xPosReplace).toFloat(); + else + xPos = xValueVar.toFloat(); } else { QString header = m_itemModel->headerData(j, Qt::Horizontal).toString(); bool ok = false; float headerValue = header.toFloat(&ok); if (ok) xPos = headerValue; + else + xPos = float(j); } + if (m_haveYPosPattern) + yPos = yValueVar.toString().replace(m_yPosPattern, m_yPosReplace).toFloat(); + else + yPos = yValueVar.toFloat(); + if (m_zPosRole != noRoleIndex) { - zPos = m_itemModel->index(i, j).data(m_zPosRole).toFloat(); + if (m_haveZPosPattern) + zPos = zValueVar.toString().replace(m_zPosPattern, m_zPosReplace).toFloat(); + else + zPos = zValueVar.toFloat(); } else { QString header = m_itemModel->headerData(i, Qt::Vertical).toString(); bool ok = false; float headerValue = header.toFloat(&ok); if (ok) zPos = headerValue; + else + zPos = float(i); } - newProxyRow[j].setPosition( - QVector3D(xPos, - m_itemModel->index(i, j).data(m_yPosRole).toFloat(), - zPos)); + newProxyRow[j].setPosition(QVector3D(xPos, yPos, zPos)); } } } else { @@ -165,10 +219,31 @@ void SurfaceItemModelHandler::resolveModel() for (int j = 0; j < columnCount; j++) { QModelIndex index = m_itemModel->index(i, j); QString rowRoleStr = index.data(rowRole).toString(); + if (haveRowPattern) + rowRoleStr.replace(rowPattern, rowReplace); QString columnRoleStr = index.data(columnRole).toString(); - QVector3D itemPos(index.data(m_xPosRole).toFloat(), - index.data(m_yPosRole).toFloat(), - index.data(m_zPosRole).toFloat()); + if (haveColPattern) + columnRoleStr.replace(colPattern, colReplace); + QVariant xValueVar = index.data(m_xPosRole); + QVariant yValueVar = index.data(m_yPosRole); + QVariant zValueVar = index.data(m_zPosRole); + float xPos; + float yPos; + float zPos; + if (m_haveXPosPattern) + xPos = xValueVar.toString().replace(m_xPosPattern, m_xPosReplace).toFloat(); + else + xPos = xValueVar.toFloat(); + if (m_haveYPosPattern) + yPos = yValueVar.toString().replace(m_yPosPattern, m_yPosReplace).toFloat(); + else + yPos = yValueVar.toFloat(); + if (m_haveZPosPattern) + zPos = zValueVar.toString().replace(m_zPosPattern, m_zPosReplace).toFloat(); + else + zPos = zValueVar.toFloat(); + + QVector3D itemPos(xPos, yPos, zPos); itemValueMap[rowRoleStr][columnRoleStr] = itemPos; if (generateRows && !rowListHash.value(rowRoleStr, false)) { rowListHash.insert(rowRoleStr, true); diff --git a/src/datavisualization/data/surfaceitemmodelhandler_p.h b/src/datavisualization/data/surfaceitemmodelhandler_p.h index dbed0a60..572788d6 100644 --- a/src/datavisualization/data/surfaceitemmodelhandler_p.h +++ b/src/datavisualization/data/surfaceitemmodelhandler_p.h @@ -53,6 +53,15 @@ protected: int m_xPosRole; int m_yPosRole; int m_zPosRole; + QRegExp m_xPosPattern; + QRegExp m_yPosPattern; + QRegExp m_zPosPattern; + QString m_xPosReplace; + QString m_yPosReplace; + QString m_zPosReplace; + bool m_haveXPosPattern; + bool m_haveYPosPattern; + bool m_haveZPosPattern; }; QT_END_NAMESPACE_DATAVISUALIZATION -- cgit v1.2.3