summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/datavisualization/data/baritemmodelhandler.cpp10
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.cpp420
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.h43
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy_p.h12
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp12
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp115
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler_p.h9
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2_plugin.cpp1
-rw-r--r--tests/itemmodeltest/main.cpp37
-rw-r--r--tests/qmlmultitest/main.cpp47
-rw-r--r--tests/qmlmultitest/qml/qmlmultitest/Data.qml48
-rw-r--r--tests/qmlmultitest/qml/qmlmultitest/NewButton.qml52
-rw-r--r--tests/qmlmultitest/qml/qmlmultitest/main.qml231
-rw-r--r--tests/qmlmultitest/qmlmultitest.pro12
-rw-r--r--tests/qmlmultitest/qmlmultitest.qrc7
-rw-r--r--tests/tests.pro3
16 files changed, 990 insertions, 69 deletions
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<String> 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.
*/
/*!
@@ -159,6 +173,111 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \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.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QObject *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)
{
@@ -561,6 +684,231 @@ int QItemModelSurfaceDataProxy::columnCategoryIndex(const QString &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
*/
QItemModelSurfaceDataProxyPrivate *QItemModelSurfaceDataProxy::dptr()
@@ -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 <QtDataVisualization/qsurfacedataproxy.h>
#include <QtCore/QAbstractItemModel>
#include <QtCore/QStringList>
+#include <QtCore/QRegExp>
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<int, QByteArray> 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
diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
index d419d904..09afb6b1 100644
--- a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
+++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
@@ -93,6 +93,7 @@ void QtDataVisualizationQml2Plugin::registerTypes(const char *uri)
qmlRegisterUncreatableType<AbstractDeclarative, 1>(uri, 1, 1, "AbstractGraph3D",
QLatin1String("Trying to create uncreatable: AbstractGraph3D."));
qmlRegisterType<QItemModelBarDataProxy, 1>(uri, 1, 1, "ItemModelBarDataProxy");
+ qmlRegisterType<QItemModelSurfaceDataProxy, 1>(uri, 1, 1, "ItemModelSurfaceDataProxy");
// New types
qmlRegisterType<QValue3DAxisFormatter>(uri, 1, 1, "ValueAxis3DFormatter");
diff --git a/tests/itemmodeltest/main.cpp b/tests/itemmodeltest/main.cpp
index a607fe8d..38454948 100644
--- a/tests/itemmodeltest/main.cpp
+++ b/tests/itemmodeltest/main.cpp
@@ -49,9 +49,6 @@ public:
void setupModel();
void addRow();
- void changeStyle();
- void changePresetCamera();
- void changeTheme();
void start();
void selectFromTable(const QPoint &selection);
void selectedFromTable(int currentRow, int currentColumn, int previousRow, int previousColumn);
@@ -148,12 +145,14 @@ void GraphDataGenerator::setupModel()
QStringList weeks;
weeks << "week 1" << "week 2" << "week 3" << "week 4" << "week 5";
- // Set up data Mon Tue Wed Thu Fri Sat Sun
- const char *hours[5][7] = {{"2.0/30", "1.0/30", "3.0/30", "0.2/30", "1.0/30", "5.0/30", "10.0/30"}, // week 1
- {"0.5/45", "1.0/45", "3.0/45", "1.0/45", "2.0/45", "2.0/45", "3.0/45"}, // week 2
- {"1.0/60", "1.0/60", "2.0/60", "1.0/60", "4.0/60", "4.0/60", "4.0/60"}, // week 3
- {"0.0/75", "1.0/75", "0.0/75", "0.0/75", "2.0/75", "2.0/75", "0.3/75"}, // week 4
- {"3.0/90", "3.0/90", "6.0/90", "2.0/90", "2.0/90", "1.0/90", "1.0/90"}}; // week 5
+ // Set up data
+ const char *hours[5][7] =
+ // Mon Tue Wed Thu Fri Sat Sun
+ {{"9/10/2.0/30", "9/11/1.0/30", "9/12/3.0/30", "9/13/0.2/30", "9/14/1.0/30", "9/15/5.0/30", "9/16/10.0/30"}, // week 1
+ {"8/10/0.5/45", "8/11/1.0/45", "8/12/3.0/45", "8/13/1.0/45", "8/14/2.0/45", "8/15/2.0/45", "8/16/3.0/45"}, // week 2
+ {"7/10/1.0/60", "7/11/1.0/60", "7/12/2.0/60", "7/13/1.0/60", "7/14/4.0/60", "7/15/4.0/60", "7/16/4.0/60"}, // week 3
+ {"6/10/0.0/75", "6/11/1.0/75", "6/12/0.0/75", "6/13/0.0/75", "6/14/2.0/75", "6/15/2.0/75", "6/16/0.3/75"}, // week 4
+ {"5/10/3.0/90", "5/11/3.0/90", "5/12/6.0/90", "5/13/2.0/90", "5/14/2.0/90", "5/15/1.0/90", "5/16/1.0/90"}}; // week 5
// Add labels
m_barGraph->rowAxis()->setTitle("Week of year");
@@ -275,17 +274,27 @@ int main(int argc, char **argv)
barProxy->setUseModelCategories(true);
surfaceProxy->setUseModelCategories(true);
barProxy->setRotationRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
- barProxy->setValueRolePattern(QRegExp(QStringLiteral("^(\\d*[\\.\\,]?\\d*)\\/(\\d*[\\.\\,]?\\d*)$")));
- barProxy->setRotationRolePattern(QRegExp(QStringLiteral("^(\\d*[\\.\\,]?\\d*)\\/(\\d*[\\.\\,]?\\d*)$")));
- barProxy->setValueRoleReplace(QStringLiteral("\\1"));
- barProxy->setRotationRoleReplace(QStringLiteral("\\2"));
- // TODO surface proxy test
+ barProxy->setValueRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)(\\d*)\\/(\\d*[\\.\\,]?\\d*)\\/\\d*[\\.\\,]?\\d*$")));
+ barProxy->setRotationRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)\\d*\\/\\d*([\\.\\,]?)\\d*(\\/)(\\d*[\\.\\,]?\\d*)$")));
+ barProxy->setValueRoleReplace(QStringLiteral("\\4"));
+ barProxy->setRotationRoleReplace(QStringLiteral("\\5"));
+ surfaceProxy->setXPosRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
+ surfaceProxy->setZPosRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
+ surfaceProxy->setXPosRolePattern(QRegExp(QStringLiteral("^(\\d*)\\/(\\d*)\\/\\d*[\\.\\,]?\\d*\\/\\d*[\\.\\,]?\\d*$")));
+ surfaceProxy->setXPosRoleReplace(QStringLiteral("\\2"));
+ surfaceProxy->setYPosRolePattern(QRegExp(QStringLiteral("^\\d*(\\/)(\\d*)\\/(\\d*[\\.\\,]?\\d*)\\/\\d*[\\.\\,]?\\d*$")));
+ surfaceProxy->setYPosRoleReplace(QStringLiteral("\\3"));
+ surfaceProxy->setZPosRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)(\\d*)\\/\\d*[\\.\\,]?\\d*\\/\\d*[\\.\\,]?\\d*$")));
+ surfaceProxy->setZPosRoleReplace(QStringLiteral("\\1"));
QBar3DSeries *barSeries = new QBar3DSeries(barProxy);
QSurface3DSeries *surfaceSeries = new QSurface3DSeries(surfaceProxy);
barSeries->setMesh(QAbstract3DSeries::MeshPyramid);
barGraph->addSeries(barSeries);
surfaceGraph->addSeries(surfaceSeries);
+ barGraph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetBehind);
+ surfaceGraph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
+
GraphDataGenerator generator(barGraph, surfaceGraph, tableWidget);
QObject::connect(barSeries, &QBar3DSeries::selectedBarChanged, &generator,
&GraphDataGenerator::selectFromTable);
diff --git a/tests/qmlmultitest/main.cpp b/tests/qmlmultitest/main.cpp
new file mode 100644
index 00000000..a4754f56
--- /dev/null
+++ b/tests/qmlmultitest/main.cpp
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include <QtCore/QDir>
+#include <QtQuick/QQuickView>
+#include <QtQml/QQmlEngine>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QQuickView viewer;
+
+ // The following are needed to make examples run without having to install the module
+ // in desktop environments.
+#ifdef Q_OS_WIN
+ QString extraImportPath(QStringLiteral("%1/../../../%2"));
+#else
+ QString extraImportPath(QStringLiteral("%1/../../%2"));
+#endif
+ viewer.engine()->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
+ QString::fromLatin1("qml")));
+ QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
+
+ viewer.setTitle(QStringLiteral("QML multitest"));
+ viewer.setSource(QUrl("qrc:/qml/qmlmultitest/main.qml"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/tests/qmlmultitest/qml/qmlmultitest/Data.qml b/tests/qmlmultitest/qml/qmlmultitest/Data.qml
new file mode 100644
index 00000000..ddc0aad8
--- /dev/null
+++ b/tests/qmlmultitest/qml/qmlmultitest/Data.qml
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+
+Item {
+ property alias sharedData: dataModel
+
+ ListModel {
+ id: dataModel
+ ListElement{ coords: "0,0"; data: "20.0/10.0/4.75"; }
+ ListElement{ coords: "1,0"; data: "21.1/10.3/3.00"; }
+ ListElement{ coords: "2,0"; data: "22.5/10.7/1.24"; }
+ ListElement{ coords: "3,0"; data: "24.0/10.5/2.53"; }
+ ListElement{ coords: "0,1"; data: "20.2/11.2/3.55"; }
+ ListElement{ coords: "1,1"; data: "21.3/11.5/3.03"; }
+ ListElement{ coords: "2,1"; data: "22.6/11.7/3.46"; }
+ ListElement{ coords: "3,1"; data: "23.4/11.5/4.12"; }
+ ListElement{ coords: "0,2"; data: "20.2/12.3/3.37"; }
+ ListElement{ coords: "1,2"; data: "21.1/12.4/2.98"; }
+ ListElement{ coords: "2,2"; data: "22.5/12.1/3.33"; }
+ ListElement{ coords: "3,2"; data: "23.3/12.7/3.23"; }
+ ListElement{ coords: "0,3"; data: "20.7/13.3/5.34"; }
+ ListElement{ coords: "1,3"; data: "21.5/13.2/4.54"; }
+ ListElement{ coords: "2,3"; data: "22.4/13.6/4.65"; }
+ ListElement{ coords: "3,3"; data: "23.2/13.4/6.67"; }
+ ListElement{ coords: "0,4"; data: "20.6/15.0/6.01"; }
+ ListElement{ coords: "1,4"; data: "21.3/14.6/5.83"; }
+ ListElement{ coords: "2,4"; data: "22.5/14.8/7.32"; }
+ ListElement{ coords: "3,4"; data: "23.7/14.3/6.90"; }
+ }
+}
+
diff --git a/tests/qmlmultitest/qml/qmlmultitest/NewButton.qml b/tests/qmlmultitest/qml/qmlmultitest/NewButton.qml
new file mode 100644
index 00000000..e4fb99d2
--- /dev/null
+++ b/tests/qmlmultitest/qml/qmlmultitest/NewButton.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+
+Item {
+ id: newbutton
+
+ property alias text: buttonText.text
+
+ signal clicked
+
+ implicitWidth: buttonText.implicitWidth + 5
+ implicitHeight: buttonText.implicitHeight + 10
+
+ Button {
+ id: buttonText
+ width: parent.width
+ height: parent.height
+
+ style: ButtonStyle {
+ label: Component {
+ Text {
+ text: buttonText.text
+ clip: true
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+ }
+ }
+ onClicked: newbutton.clicked()
+ }
+}
diff --git a/tests/qmlmultitest/qml/qmlmultitest/main.qml b/tests/qmlmultitest/qml/qmlmultitest/main.qml
new file mode 100644
index 00000000..da34c0bf
--- /dev/null
+++ b/tests/qmlmultitest/qml/qmlmultitest/main.qml
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import QtDataVisualization 1.1
+import "."
+
+Rectangle {
+ id: mainView
+ width: 800
+ height: 600
+
+ Data {
+ id: data
+ }
+
+ GridLayout {
+ id: gridLayout
+ columns: 2
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ anchors.top: mainView.top
+ anchors.bottom: mainView.bottom
+ anchors.left: mainView.left
+ anchors.right: mainView.right
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ border.color: surfaceGraph.theme.gridLineColor
+ border.width: 2
+
+ Surface3D {
+ id: surfaceGraph
+ anchors.fill: parent
+ anchors.margins: parent.border.width
+ theme: Theme3D {
+ type: Theme3D.ThemePrimaryColors
+ font.pointSize: 60
+ }
+ scene.activeCamera.cameraPreset: Camera3D.CameraPresetIsometricLeftHigh
+
+ Surface3DSeries {
+ itemLabelFormat: "Pop density at (@xLabel N, @zLabel E): @yLabel"
+ ItemModelSurfaceDataProxy {
+ itemModel: data.sharedData
+ // The surface data points are not neatly lined up in rows and columns,
+ // so we define explicit row and column roles.
+ rowRole: "coords"
+ columnRole: "coords"
+ xPosRole: "data"
+ zPosRole: "data"
+ yPosRole: "data"
+ rowRolePattern: /(\d),\d/
+ columnRolePattern: /(\d),(\d)/
+ xPosRolePattern: /^([asd]*)([fgh]*)([jkl]*)[^\/]*\/([^\/]*)\/.*$/
+ yPosRolePattern: /^([^\/]*)\/([^\/]*)\/(.*)$/
+ zPosRolePattern: /^([asd]*)([qwe]*)([tyu]*)([fgj]*)([^\/]*)\/[^\/]*\/.*$/
+ rowRoleReplace: "\\1"
+ columnRoleReplace: "\\2"
+ xPosRoleReplace: "\\4"
+ yPosRoleReplace: "\\3"
+ zPosRoleReplace: "\\5"
+ }
+ }
+ }
+ }
+
+ // We'll use one grid cell for buttons
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ GridLayout {
+ anchors.right: parent.right
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ columns: 2
+
+ NewButton {
+ Layout.minimumWidth: parent.width / 2
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Clear Selections"
+ onClicked: clearSelections() // call a helper function to keep button itself simpler
+ }
+
+ NewButton {
+ Layout.minimumWidth: parent.width / 2
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Quit"
+ onClicked: Qt.quit(0);
+ }
+
+ NewButton {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Reset Cameras"
+ onClicked: resetCameras() // call a helper function to keep button itself simpler
+ }
+
+ NewButton {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ text: "Toggle Mesh Styles"
+ onClicked: toggleMeshStyle() // call a helper function to keep button itself simpler
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ border.color: scatterGraph.theme.gridLineColor
+ border.width: 2
+
+ Scatter3D {
+ id: scatterGraph
+ anchors.fill: parent
+ anchors.margins: parent.border.width
+ theme: Theme3D {
+ type: Theme3D.ThemeDigia
+ font.pointSize: 60
+ }
+ scene.activeCamera.cameraPreset: Camera3D.CameraPresetIsometricLeftHigh
+
+ Scatter3DSeries {
+ itemLabelFormat: "Pop density at (@xLabel N, @zLabel E): @yLabel"
+ ItemModelScatterDataProxy {
+ itemModel: data.sharedData
+ // Mapping model roles to scatter series item coordinates.
+ xPosRole: "data"
+ zPosRole: "data"
+ yPosRole: "data"
+ // TODO scatter test
+// xPosRolePattern: /^([asd]*)([fgh]*)([jkl]*)[^\/]*\/([^\/]*)\/.*$/
+// yPosRolePattern: /^([^\/]*)\/([^\/]*)\/(.*)$/
+// zPosRolePattern: /^([asd]*)([qwe]*)([tyu]*)([fgj]*)([^\/]*)\/[^\/]*\/.*$/
+// xPosRoleReplace: "\\4"
+// yPosRoleReplace: "\\3"
+// zPosRoleReplace: "\\5"
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ border.color: barGraph.theme.gridLineColor
+ border.width: 2
+
+ Bars3D {
+ id: barGraph
+ anchors.fill: parent
+ anchors.margins: parent.border.width
+ theme: Theme3D {
+ type: Theme3D.ThemeQt
+ font.pointSize: 60
+ }
+ selectionMode: AbstractGraph3D.SelectionItemAndRow | AbstractGraph3D.SelectionSlice
+ scene.activeCamera.cameraPreset: Camera3D.CameraPresetIsometricLeftHigh
+
+ Bar3DSeries {
+ itemLabelFormat: "@seriesName: @valueLabel"
+ name: "Population density"
+
+ ItemModelBarDataProxy {
+ itemModel: data.sharedData
+ // Mapping model roles to bar series rows, columns, and values.
+ rowRole: "coords"
+ columnRole: "coords"
+ valueRole: "data"
+ rowRolePattern: /(\d),\d/
+ columnRolePattern: /(\d),(\d)/
+ valueRolePattern: /^([^\/]*)\/([^\/]*)\/(.*)$/
+ rowRoleReplace: "\\1"
+ columnRoleReplace: "\\2"
+ valueRoleReplace: "\\3"
+ }
+ }
+ }
+ }
+ }
+
+ function clearSelections() {
+ barGraph.clearSelection()
+ scatterGraph.clearSelection()
+ surfaceGraph.clearSelection()
+ }
+
+ function resetCameras() {
+ surfaceGraph.scene.activeCamera.cameraPreset = Camera3D.CameraPresetIsometricLeftHigh
+ scatterGraph.scene.activeCamera.cameraPreset = Camera3D.CameraPresetIsometricLeftHigh
+ barGraph.scene.activeCamera.cameraPreset = Camera3D.CameraPresetIsometricLeftHigh
+ surfaceGraph.scene.activeCamera.zoomLevel = 100.0
+ scatterGraph.scene.activeCamera.zoomLevel = 100.0
+ barGraph.scene.activeCamera.zoomLevel = 100.0
+ }
+
+ function toggleMeshStyle() {
+ if (barGraph.seriesList[0].meshSmooth === true) {
+ barGraph.seriesList[0].meshSmooth = false
+ if (surfaceGraph.seriesList[0].flatShadingSupported)
+ surfaceGraph.seriesList[0].flatShadingEnabled = true
+ scatterGraph.seriesList[0].meshSmooth = false
+ } else {
+ barGraph.seriesList[0].meshSmooth = true
+ surfaceGraph.seriesList[0].flatShadingEnabled = false
+ scatterGraph.seriesList[0].meshSmooth = true
+ }
+ }
+}
diff --git a/tests/qmlmultitest/qmlmultitest.pro b/tests/qmlmultitest/qmlmultitest.pro
new file mode 100644
index 00000000..6e5e1b98
--- /dev/null
+++ b/tests/qmlmultitest/qmlmultitest.pro
@@ -0,0 +1,12 @@
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
+
+# The .cpp file which was generated for your project. Feel free to hack it.
+SOURCES += main.cpp
+
+RESOURCES += qmlmultitest.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/* \
+ qml/qmlmultitest/*
diff --git a/tests/qmlmultitest/qmlmultitest.qrc b/tests/qmlmultitest/qmlmultitest.qrc
new file mode 100644
index 00000000..7fc9ade2
--- /dev/null
+++ b/tests/qmlmultitest/qmlmultitest.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/qmlmultitest/Data.qml</file>
+ <file>qml/qmlmultitest/main.qml</file>
+ <file>qml/qmlmultitest/NewButton.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/tests.pro b/tests/tests.pro
index 7b690c7d..8bbdc3f2 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -15,7 +15,8 @@ SUBDIRS += barstest \
multigraphs \
directional \
qmlmultiwindow \
- itemmodeltest
+ itemmodeltest \
+ qmlmultitest
#SUBDIRS += kinectsurface