summaryrefslogtreecommitdiffstats
path: root/src/datavisualization
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-01-29 12:51:55 +0200
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-01-29 13:07:16 +0200
commit201a480af6ad2d36896570683ab87014827b9697 (patch)
tree3c12f6cf9c5a13a758e0e056515a05c96164b8d0 /src/datavisualization
parente616a4737c932546ab5eadee8f4f766d35d260d7 (diff)
Rotation support for item models
Task-number: QTRD-2654 Change-Id: Ie919c3032731724f750fc0ccb237379454009585 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization')
-rw-r--r--src/datavisualization/data/baritemmodelhandler.cpp18
-rw-r--r--src/datavisualization/data/qbar3dseries.cpp58
-rw-r--r--src/datavisualization/data/qbar3dseries.h5
-rw-r--r--src/datavisualization/data/qbar3dseries_p.h4
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.cpp74
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.h11
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy_p.h1
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.cpp46
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.h8
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy_p.h1
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler.cpp27
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler_p.h1
12 files changed, 251 insertions, 3 deletions
diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp
index 611fbcb9..4f44fe1d 100644
--- a/src/datavisualization/data/baritemmodelhandler.cpp
+++ b/src/datavisualization/data/baritemmodelhandler.cpp
@@ -20,6 +20,8 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+static const int noRoleIndex = -1;
+
BarItemModelHandler::BarItemModelHandler(QItemModelBarDataProxy *proxy, QObject *parent)
: AbstractItemModelHandler(parent),
m_proxy(proxy),
@@ -51,8 +53,9 @@ void BarItemModelHandler::resolveModel()
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
- // Default to display role if no mapping
+ // Default value role to display role if no mapping
int valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole);
+ int rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex);
int rowCount = m_itemModel->rowCount();
int columnCount = m_itemModel->columnCount();
@@ -67,8 +70,11 @@ void BarItemModelHandler::resolveModel()
}
for (int i = 0; i < rowCount; i++) {
QBarDataRow &newProxyRow = *m_proxyArray->at(i);
- for (int j = 0; j < columnCount; j++)
+ for (int j = 0; j < columnCount; j++) {
newProxyRow[j].setValue(m_itemModel->index(i, j).data(valueRole).toReal());
+ if (rotationRole != noRoleIndex)
+ newProxyRow[j].setRotation(m_itemModel->index(i, j).data(rotationRole).toReal());
+ }
}
// Generate labels from headers if using model rows/columns
for (int i = 0; i < rowCount; i++)
@@ -92,12 +98,15 @@ void BarItemModelHandler::resolveModel()
// Sort values into rows and columns
typedef QHash<QString, float> ColumnValueMap;
QHash <QString, ColumnValueMap> itemValueMap;
+ QHash <QString, ColumnValueMap> itemRotationMap;
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < columnCount; j++) {
QModelIndex index = m_itemModel->index(i, j);
QString rowRoleStr = index.data(rowRole).toString();
QString columnRoleStr = index.data(columnRole).toString();
itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal();
+ if (rotationRole != noRoleIndex)
+ itemRotationMap[rowRoleStr][columnRoleStr] = index.data(rotationRole).toReal();
if (generateRows && !rowListHash.value(rowRoleStr, false)) {
rowListHash.insert(rowRoleStr, true);
rowList << rowRoleStr;
@@ -131,8 +140,11 @@ void BarItemModelHandler::resolveModel()
for (int i = 0; i < rowList.size(); i++) {
QString rowKey = rowList.at(i);
QBarDataRow &newProxyRow = *m_proxyArray->at(i);
- for (int j = 0; j < columnList.size(); j++)
+ for (int j = 0; j < columnList.size(); j++) {
newProxyRow[j].setValue(itemValueMap[rowKey][columnList.at(j)]);
+ if (rotationRole != noRoleIndex)
+ newProxyRow[j].setRotation(itemRotationMap[rowKey][columnList.at(j)]);
+ }
}
rowLabels = rowList;
diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp
index 1440476b..25ff505f 100644
--- a/src/datavisualization/data/qbar3dseries.cpp
+++ b/src/datavisualization/data/qbar3dseries.cpp
@@ -18,6 +18,7 @@
#include "qbar3dseries_p.h"
#include "bars3dcontroller_p.h"
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -114,6 +115,17 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty real Bar3DSeries::meshAngle
+ *
+ * A convenience property for defining the series rotation \a angle in degrees.
+ *
+ * \note: When reading this property, it is calculated from Abstract3DSeries::meshRotation value and
+ * always returns a value from zero to 360 degrees. It may also have small rounding errors.
+ *
+ * \sa Abstract3DSeries::meshRotation
+ */
+
+/*!
* Constructs QBar3DSeries with the given \a parent.
*/
QBar3DSeries::QBar3DSeries(QObject *parent) :
@@ -121,6 +133,7 @@ QBar3DSeries::QBar3DSeries(QObject *parent) :
{
// Default proxy
dptr()->setDataProxy(new QBarDataProxy);
+ dptr()->connectSignals();
}
/*!
@@ -130,6 +143,7 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) :
QAbstract3DSeries(new QBar3DSeriesPrivate(this), parent)
{
dptr()->setDataProxy(dataProxy);
+ dptr()->connectSignals();
}
/*!
@@ -138,6 +152,7 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) :
QBar3DSeries::QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent) :
QAbstract3DSeries(d, parent)
{
+ dptr()->connectSignals();
}
/*!
@@ -204,6 +219,38 @@ QPoint QBar3DSeries::invalidSelectionPosition()
return Bars3DController::invalidSelectionPosition();
}
+static inline float quaternionAngle(const QQuaternion &rotation)
+{
+ return qAcos(rotation.scalar()) * 360.0f / M_PI;
+}
+
+/*!
+ * \property QBar3DSeries::meshAngle
+ *
+ * A convenience property for defining the series rotation \a angle in degrees.
+ * Setting this property is equivalent to the following call:
+ * \code setMeshRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, angle)) \endcode
+ *
+ * \note: When reading this property, it is calculated from QAbstract3DSeries::meshRotation value
+ * and always returns a value from zero to 360 degrees. It may also have small rounding errors.
+ *
+ * \sa QAbstract3DSeries::meshRotation
+ */
+void QBar3DSeries::setMeshAngle(float angle)
+{
+ setMeshRotation(QQuaternion::fromAxisAndAngle(upVector, angle));
+}
+
+float QBar3DSeries::meshAngle() const
+{
+ QQuaternion rotation = meshRotation();
+
+ if (rotation.isIdentity() || rotation.x() != 0.0f || rotation.z() != 0.0f)
+ return 0.0f;
+ else
+ return quaternionAngle(rotation);
+}
+
/*!
* \internal
*/
@@ -279,6 +326,11 @@ void QBar3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newCon
}
}
+void QBar3DSeriesPrivate::handleMeshRotationChanged(const QQuaternion &rotation)
+{
+ emit qptr()->meshAngleChanged(quaternionAngle(rotation));
+}
+
void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position)
{
if (position != m_selectedBar) {
@@ -287,4 +339,10 @@ void QBar3DSeriesPrivate::setSelectedBar(const QPoint &position)
}
}
+void QBar3DSeriesPrivate::connectSignals()
+{
+ QObject::connect(q_ptr, &QAbstract3DSeries::meshRotationChanged, this,
+ &QBar3DSeriesPrivate::handleMeshRotationChanged);
+}
+
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qbar3dseries.h b/src/datavisualization/data/qbar3dseries.h
index be748516..aa67dadb 100644
--- a/src/datavisualization/data/qbar3dseries.h
+++ b/src/datavisualization/data/qbar3dseries.h
@@ -32,6 +32,7 @@ class QT_DATAVISUALIZATION_EXPORT QBar3DSeries : public QAbstract3DSeries
Q_OBJECT
Q_PROPERTY(QBarDataProxy *dataProxy READ dataProxy WRITE setDataProxy NOTIFY dataProxyChanged)
Q_PROPERTY(QPoint selectedBar READ selectedBar WRITE setSelectedBar NOTIFY selectedBarChanged)
+ Q_PROPERTY(float meshAngle READ meshAngle WRITE setMeshAngle NOTIFY meshAngleChanged)
public:
explicit QBar3DSeries(QObject *parent = 0);
@@ -45,9 +46,13 @@ public:
QPoint selectedBar() const;
static QPoint invalidSelectionPosition();
+ void setMeshAngle(float angle);
+ float meshAngle() const;
+
signals:
void dataProxyChanged(QBarDataProxy *proxy);
void selectedBarChanged(QPoint position);
+ void meshAngleChanged(float angle);
protected:
explicit QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent = 0);
diff --git a/src/datavisualization/data/qbar3dseries_p.h b/src/datavisualization/data/qbar3dseries_p.h
index 173f1cd9..718f1237 100644
--- a/src/datavisualization/data/qbar3dseries_p.h
+++ b/src/datavisualization/data/qbar3dseries_p.h
@@ -44,8 +44,12 @@ public:
virtual void setDataProxy(QAbstractDataProxy *proxy);
virtual void connectControllerAndProxy(Abstract3DController *newController);
+ void handleMeshRotationChanged(const QQuaternion &rotation);
+
void setSelectedBar(const QPoint &position);
+ void connectSignals();
+
private:
QBar3DSeries *qptr();
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp
index 97289da1..6a1e9c15 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelbardataproxy.cpp
@@ -105,6 +105,12 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty string ItemModelBarDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ */
+
+/*!
* \qmlproperty list ItemModelBarDataProxy::rowCategories
* The row categories of the mapping. Only items with row roles 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.
@@ -195,6 +201,27 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
/*!
* Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. 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(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QString &rotationRole,
+ QObject *parent)
+ : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rotationRole = rotationRole;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. 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.
@@ -220,6 +247,35 @@ QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemMod
}
/*!
+ * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. 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(const 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)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rotationRole = rotationRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+ dptr()->m_autoRowCategories = false;
+ dptr()->m_autoColumnCategories = false;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
* Destroys QItemModelBarDataProxy.
*/
QItemModelBarDataProxy::~QItemModelBarDataProxy()
@@ -297,6 +353,24 @@ QString QItemModelBarDataProxy::valueRole() const
}
/*!
+ * \property QItemModelBarDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ */
+void QItemModelBarDataProxy::setRotationRole(const QString &role)
+{
+ if (dptr()->m_rotationRole != role) {
+ dptr()->m_rotationRole = role;
+ emit rotationRoleChanged(role);
+ }
+}
+
+QString QItemModelBarDataProxy::rotationRole() const
+{
+ return dptrc()->m_rotationRole;
+}
+
+/*!
* \property QItemModelBarDataProxy::rowCategories
*
* Defines the row categories for the mapping.
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.h b/src/datavisualization/data/qitemmodelbardataproxy.h
index 4e62b4c3..f6b0b64f 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.h
+++ b/src/datavisualization/data/qitemmodelbardataproxy.h
@@ -34,6 +34,7 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataProxy : public QBarDataProxy
Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole NOTIFY rowRoleChanged)
Q_PROPERTY(QString columnRole READ columnRole WRITE setColumnRole NOTIFY columnRoleChanged)
Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged)
+ Q_PROPERTY(QString rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged)
Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories NOTIFY rowCategoriesChanged)
Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories NOTIFY columnCategoriesChanged)
Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories NOTIFY useModelCategoriesChanged)
@@ -50,8 +51,15 @@ public:
QObject *parent = 0);
QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
const QString &columnRole, const QString &valueRole,
+ const QString &rotationRole, QObject *parent = 0);
+ QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ const QString &columnRole, const QString &valueRole,
const QStringList &rowCategories, const QStringList &columnCategories,
QObject *parent = 0);
+ QItemModelBarDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ const QString &columnRole, const QString &valueRole,
+ const QString &rotationRole, const QStringList &rowCategories,
+ const QStringList &columnCategories, QObject *parent = 0);
virtual ~QItemModelBarDataProxy();
void setItemModel(const QAbstractItemModel *itemModel);
@@ -63,6 +71,8 @@ public:
QString columnRole() const;
void setValueRole(const QString &role);
QString valueRole() const;
+ void setRotationRole(const QString &role);
+ QString rotationRole() const;
void setRowCategories(const QStringList &categories);
QStringList rowCategories() const;
@@ -88,6 +98,7 @@ signals:
void rowRoleChanged(QString role);
void columnRoleChanged(QString role);
void valueRoleChanged(QString role);
+ void rotationRoleChanged(QString role);
void rowCategoriesChanged(QStringList categories);
void columnCategoriesChanged(QStringList categories);
void useModelCategoriesChanged(bool enable);
diff --git a/src/datavisualization/data/qitemmodelbardataproxy_p.h b/src/datavisualization/data/qitemmodelbardataproxy_p.h
index 0c987a00..2fd74bb2 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelbardataproxy_p.h
@@ -53,6 +53,7 @@ private:
QString m_rowRole;
QString m_columnRole;
QString m_valueRole;
+ QString m_rotationRole;
// For row/column items, sort items into these categories. Other categories are ignored.
QStringList m_rowCategories;
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
index 1edee53c..489f8da7 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
@@ -93,6 +93,12 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty string ItemModelScatterDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ */
+
+/*!
* Constructs QItemModelScatterDataProxy with optional \a parent.
*/
QItemModelScatterDataProxy::QItemModelScatterDataProxy(QObject *parent)
@@ -134,6 +140,28 @@ QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel
}
/*!
+ * Constructs QItemModelScatterDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The xPosRole property is set to \a xPosRole, yPosRole property to \a yPosRole, zPosRole property
+ * to \a zPosRole, and rotationRole property to \a rotationRole.
+ */
+QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
+ const QString &rotationRole,
+ QObject *parent)
+ : QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_xPosRole = xPosRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = zPosRole;
+ dptr()->m_rotationRole = rotationRole;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
* Destroys QItemModelScatterDataProxy.
*/
QItemModelScatterDataProxy::~QItemModelScatterDataProxy()
@@ -211,6 +239,24 @@ QString QItemModelScatterDataProxy::zPosRole() const
}
/*!
+ * \property QItemModelScatterDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ */
+void QItemModelScatterDataProxy::setRotationRole(const QString &role)
+{
+ if (dptr()->m_rotationRole != role) {
+ dptr()->m_rotationRole = role;
+ emit rotationRoleChanged(role);
+ }
+}
+
+QString QItemModelScatterDataProxy::rotationRole() const
+{
+ return dptrc()->m_rotationRole;
+}
+
+/*!
* Changes \a xPosRole, \a yPosRole and \a zPosRole mapping.
*/
void QItemModelScatterDataProxy::remap(const QString &xPosRole, const QString &yPosRole,
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.h b/src/datavisualization/data/qitemmodelscatterdataproxy.h
index 0f69afa7..accfeb18 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy.h
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.h
@@ -34,6 +34,7 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelScatterDataProxy : public QScatterDa
Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole NOTIFY xPosRoleChanged)
Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole NOTIFY yPosRoleChanged)
Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole NOTIFY zPosRoleChanged)
+ Q_PROPERTY(QString rotationRole READ rotationRole WRITE setRotationRole NOTIFY rotationRoleChanged)
public:
explicit QItemModelScatterDataProxy(QObject *parent = 0);
@@ -41,6 +42,10 @@ public:
QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
const QString &xPosRole, const QString &yPosRole,
const QString &zPosRole, QObject *parent = 0);
+ QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+ const QString &xPosRole, const QString &yPosRole,
+ const QString &zPosRole, const QString &rotationRole,
+ QObject *parent = 0);
virtual ~QItemModelScatterDataProxy();
void setItemModel(const QAbstractItemModel *itemModel);
@@ -52,6 +57,8 @@ public:
QString yPosRole() const;
void setZPosRole(const QString &role);
QString zPosRole() const;
+ void setRotationRole(const QString &role);
+ QString rotationRole() const;
void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole);
@@ -60,6 +67,7 @@ signals:
void xPosRoleChanged(QString role);
void yPosRoleChanged(QString role);
void zPosRoleChanged(QString role);
+ void rotationRoleChanged(QString role);
protected:
QItemModelScatterDataProxyPrivate *dptr();
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
index b8804c5c..4e1f321f 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
@@ -52,6 +52,7 @@ private:
QString m_xPosRole;
QString m_yPosRole;
QString m_zPosRole;
+ QString m_rotationRole;
friend class ScatterItemModelHandler;
friend class QItemModelScatterDataProxy;
diff --git a/src/datavisualization/data/scatteritemmodelhandler.cpp b/src/datavisualization/data/scatteritemmodelhandler.cpp
index 1c936d08..1b1aaefe 100644
--- a/src/datavisualization/data/scatteritemmodelhandler.cpp
+++ b/src/datavisualization/data/scatteritemmodelhandler.cpp
@@ -92,6 +92,30 @@ void ScatterItemModelHandler::handleRowsRemoved(const QModelIndex &parent, int s
}
}
+static inline QQuaternion toQuaternion(const QVariant &variant)
+{
+ if (variant.canConvert<QQuaternion>()) {
+ return variant.value<QQuaternion>();
+ } else if (variant.canConvert<QString>()) {
+ QString s = variant.toString();
+ if (!s.isEmpty() && s.count(QLatin1Char(',')) == 3) {
+ int index = s.indexOf(QLatin1Char(','));
+ int index2 = s.indexOf(QLatin1Char(','), index + 1);
+ int index3 = s.indexOf(QLatin1Char(','), index2 + 1);
+
+ bool sGood, xGood, yGood, zGood;
+ float sCoord = s.left(index).toFloat(&sGood);
+ float xCoord = s.mid(index + 1, index2 - index - 1).toFloat(&xGood);
+ float yCoord = s.mid(index2 + 1, index3 - index2 - 1).toFloat(&yGood);
+ float zCoord = s.mid(index3 + 1).toFloat(&zGood);
+
+ if (sGood && xGood && yGood && zGood)
+ return QQuaternion(sCoord, xCoord, yCoord, zCoord);
+ }
+ }
+ return QQuaternion();
+}
+
void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColumn,
QScatterDataItem &item)
{
@@ -105,6 +129,8 @@ void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColum
yPos = index.data(m_yPosRole).toFloat();
if (m_zPosRole != noRoleIndex)
zPos = index.data(m_zPosRole).toFloat();
+ if (m_rotationRole != noRoleIndex)
+ item.setRotation(toQuaternion(index.data(m_rotationRole)));
item.setPosition(QVector3D(xPos, yPos, zPos));
}
@@ -121,6 +147,7 @@ void ScatterItemModelHandler::resolveModel()
m_xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex);
m_yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), noRoleIndex);
m_zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex);
+ m_rotationRole = roleHash.key(m_proxy->rotationRole().toLatin1(), noRoleIndex);
const int columnCount = m_itemModel->columnCount();
const int rowCount = m_itemModel->rowCount();
const int totalCount = rowCount * columnCount;
diff --git a/src/datavisualization/data/scatteritemmodelhandler_p.h b/src/datavisualization/data/scatteritemmodelhandler_p.h
index f0e4fa84..0661d734 100644
--- a/src/datavisualization/data/scatteritemmodelhandler_p.h
+++ b/src/datavisualization/data/scatteritemmodelhandler_p.h
@@ -58,6 +58,7 @@ private:
int m_xPosRole;
int m_yPosRole;
int m_zPosRole;
+ int m_rotationRole;
};
QT_END_NAMESPACE_DATAVISUALIZATION