summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualization/data')
-rw-r--r--src/datavisualization/data/abstractitemmodelhandler.cpp1
-rw-r--r--src/datavisualization/data/abstractitemmodelhandler_p.h6
-rw-r--r--src/datavisualization/data/abstractrenderitem.cpp24
-rw-r--r--src/datavisualization/data/abstractrenderitem_p.h23
-rw-r--r--src/datavisualization/data/baritemmodelhandler.cpp18
-rw-r--r--src/datavisualization/data/barrenderitem.cpp39
-rw-r--r--src/datavisualization/data/barrenderitem_p.h45
-rw-r--r--src/datavisualization/data/labelitem_p.h4
-rw-r--r--src/datavisualization/data/qabstract3dseries.cpp18
-rw-r--r--src/datavisualization/data/qabstract3dseries.h31
-rw-r--r--src/datavisualization/data/qabstract3dseries_p.h1
-rw-r--r--src/datavisualization/data/qabstractdataproxy.h5
-rw-r--r--src/datavisualization/data/qabstractdataproxy_p.h1
-rw-r--r--src/datavisualization/data/qbar3dseries.cpp67
-rw-r--r--src/datavisualization/data/qbar3dseries.h10
-rw-r--r--src/datavisualization/data/qbar3dseries_p.h4
-rw-r--r--src/datavisualization/data/qbardataitem.h2
-rw-r--r--src/datavisualization/data/qbardataproxy.cpp21
-rw-r--r--src/datavisualization/data/qbardataproxy.h8
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp12
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.h9
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy_p.h2
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.cpp91
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.h27
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy_p.h1
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.cpp61
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.h21
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy_p.h1
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.cpp185
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.h46
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy_p.h4
-rw-r--r--src/datavisualization/data/qscatterdataitem.cpp10
-rw-r--r--src/datavisualization/data/qscatterdataitem.h7
-rw-r--r--src/datavisualization/data/qscatterdataproxy.cpp2
-rw-r--r--src/datavisualization/data/qscatterdataproxy.h2
-rw-r--r--src/datavisualization/data/qsurface3dseries.cpp2
-rw-r--r--src/datavisualization/data/qsurface3dseries.h2
-rw-r--r--src/datavisualization/data/qsurfacedataitem.h5
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp43
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.h6
-rw-r--r--src/datavisualization/data/qsurfacedataproxy_p.h2
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler.cpp39
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler_p.h1
-rw-r--r--src/datavisualization/data/scatterrenderitem.cpp1
-rw-r--r--src/datavisualization/data/scatterrenderitem_p.h14
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp52
46 files changed, 738 insertions, 238 deletions
diff --git a/src/datavisualization/data/abstractitemmodelhandler.cpp b/src/datavisualization/data/abstractitemmodelhandler.cpp
index 63eb7e45..9f2ccd86 100644
--- a/src/datavisualization/data/abstractitemmodelhandler.cpp
+++ b/src/datavisualization/data/abstractitemmodelhandler.cpp
@@ -17,7 +17,6 @@
****************************************************************************/
#include "abstractitemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/abstractitemmodelhandler_p.h b/src/datavisualization/data/abstractitemmodelhandler_p.h
index c238a63b..ecbfe61c 100644
--- a/src/datavisualization/data/abstractitemmodelhandler_p.h
+++ b/src/datavisualization/data/abstractitemmodelhandler_p.h
@@ -30,9 +30,9 @@
#define ABSTRACTITEMMODELHANDLER_P_H
#include "datavisualizationglobal_p.h"
-#include <QAbstractItemModel>
-#include <QPointer>
-#include <QTimer>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QPointer>
+#include <QtCore/QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/abstractrenderitem.cpp b/src/datavisualization/data/abstractrenderitem.cpp
index 522fd144..59ffab22 100644
--- a/src/datavisualization/data/abstractrenderitem.cpp
+++ b/src/datavisualization/data/abstractrenderitem.cpp
@@ -21,39 +21,17 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
AbstractRenderItem::AbstractRenderItem()
- : m_selectionLabelItem(0)
{
}
AbstractRenderItem::AbstractRenderItem(const AbstractRenderItem &other)
{
- m_selectionLabel = other.m_selectionLabel;
m_translation = other.m_translation;
- m_selectionLabelItem = 0;
+ m_rotation = other.m_rotation;
}
AbstractRenderItem::~AbstractRenderItem()
{
- delete m_selectionLabelItem;
-}
-
-LabelItem &AbstractRenderItem::selectionLabelItem()
-{
- if (!m_selectionLabelItem)
- m_selectionLabelItem = new LabelItem;
- return *m_selectionLabelItem;
-}
-
-void AbstractRenderItem::setSelectionLabel(const QString &label)
-{
- if (m_selectionLabelItem)
- m_selectionLabelItem->clear();
- m_selectionLabel = label;
-}
-
-QString &AbstractRenderItem::selectionLabel()
-{
- return m_selectionLabel;
}
QT_END_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/abstractrenderitem_p.h b/src/datavisualization/data/abstractrenderitem_p.h
index fa06db54..912a09f3 100644
--- a/src/datavisualization/data/abstractrenderitem_p.h
+++ b/src/datavisualization/data/abstractrenderitem_p.h
@@ -32,10 +32,10 @@
#include "datavisualizationglobal_p.h"
#include "labelitem_p.h"
-#include <QOpenGLFunctions>
-#include <QString>
-#include <QVector3D>
-#include <QQuaternion>
+#include <QtCore/QString>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QVector3D>
+#include <QtGui/QQuaternion>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -50,17 +50,16 @@ public:
inline void setTranslation(const QVector3D &translation) { m_translation = translation; }
inline const QVector3D &translation() const {return m_translation; }
- // Selection label item (containing special selection texture, if mode is activated)
- LabelItem &selectionLabelItem();
-
- // Formatted selection label for item.
- void setSelectionLabel(const QString &label);
- QString &selectionLabel(); // Formats selection label if not previously formatted
+ inline QQuaternion rotation() const { return m_rotation; }
+ inline void setRotation(const QQuaternion &rotation)
+ {
+ if (m_rotation != rotation)
+ m_rotation = rotation;
+ }
protected:
- QString m_selectionLabel;
QVector3D m_translation;
- LabelItem *m_selectionLabelItem;
+ QQuaternion m_rotation;
friend class QAbstractDataItem;
};
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/barrenderitem.cpp b/src/datavisualization/data/barrenderitem.cpp
index 915f3f78..50d2a4b4 100644
--- a/src/datavisualization/data/barrenderitem.cpp
+++ b/src/datavisualization/data/barrenderitem.cpp
@@ -25,7 +25,6 @@ BarRenderItem::BarRenderItem()
: AbstractRenderItem(),
m_value(0),
m_height(0.0f),
- m_sliceLabelItem(0),
m_seriesIndex(0)
{
}
@@ -36,32 +35,58 @@ BarRenderItem::BarRenderItem(const BarRenderItem &other)
m_value = other.m_value;
m_position = other.m_position;
m_height = other.m_height;
- m_sliceLabel = other.m_sliceLabel;
- m_sliceLabelItem = 0;
m_seriesIndex = other.m_seriesIndex;
- m_rotation = other.m_rotation;
}
BarRenderItem::~BarRenderItem()
{
+}
+
+BarRenderSliceItem::BarRenderSliceItem()
+ : BarRenderItem(),
+ m_sliceLabelItem(0)
+{
+}
+
+BarRenderSliceItem::BarRenderSliceItem(const BarRenderSliceItem &other)
+ : BarRenderItem(other)
+{
+ m_sliceLabel = other.m_sliceLabel;
+ m_sliceLabelItem = 0;
+}
+
+BarRenderSliceItem::~BarRenderSliceItem()
+{
delete m_sliceLabelItem;
}
-LabelItem &BarRenderItem::sliceLabelItem()
+void BarRenderSliceItem::setItem(const BarRenderItem &renderItem)
+{
+ m_translation = renderItem.translation();
+ m_rotation = renderItem.rotation();
+ m_value = renderItem.value();
+ m_position = renderItem.position();
+ m_height = renderItem.height();
+ m_seriesIndex = renderItem.seriesIndex();
+ m_sliceLabel = QString();
+ m_sliceLabelItem = 0;
+}
+
+LabelItem &BarRenderSliceItem::sliceLabelItem()
{
if (!m_sliceLabelItem)
m_sliceLabelItem = new LabelItem;
return *m_sliceLabelItem;
}
-void BarRenderItem::setSliceLabel(const QString &label)
+void BarRenderSliceItem::setSliceLabel(const QString &label)
{
if (m_sliceLabelItem)
m_sliceLabelItem->clear();
m_sliceLabel = label;
}
-const QString &BarRenderItem::sliceLabel() const
+const QString &BarRenderSliceItem::sliceLabel() const
{
return m_sliceLabel;
}
diff --git a/src/datavisualization/data/barrenderitem_p.h b/src/datavisualization/data/barrenderitem_p.h
index e1062969..1122053d 100644
--- a/src/datavisualization/data/barrenderitem_p.h
+++ b/src/datavisualization/data/barrenderitem_p.h
@@ -47,48 +47,49 @@ public:
inline const QPoint &position() const { return m_position; }
// Actual cached data value of the bar (needed to trigger label reformats)
- inline void setValue(float value)
- {
- m_value = value;
- // Force reformatting on next access by setting label string to null string
- if (!m_sliceLabel.isNull())
- setSliceLabel(QString());
- if (!m_selectionLabel.isNull())
- setSelectionLabel(QString());
- }
+ inline void setValue(float value) { m_value = value; }
inline float value() const { return m_value; }
// Normalized bar height
inline void setHeight(GLfloat height) { m_height = height; }
inline GLfloat height() const { return m_height; }
- // Label item for formatted label
- LabelItem &sliceLabelItem();
-
- // Formatted label for item.
- void setSliceLabel(const QString &label);
- const QString &sliceLabel() const; // Formats label if not previously formatted
-
// Series index in visual series that this item belongs to.
// This is only utilized by slicing, so it may not be up to date on all items.
inline void setSeriesIndex(int seriesIndex) { m_seriesIndex = seriesIndex; }
inline int seriesIndex() const { return m_seriesIndex; }
- inline void setRotation(const QQuaternion &rotation) { m_rotation = rotation; }
- inline const QQuaternion &rotation() const { return m_rotation; }
-
protected:
float m_value;
QPoint m_position; // x = row, y = column
GLfloat m_height;
- QString m_sliceLabel;
- LabelItem *m_sliceLabelItem;
int m_seriesIndex;
- QQuaternion m_rotation;
friend class QBarDataItem;
};
+class BarRenderSliceItem : public BarRenderItem
+{
+public:
+ BarRenderSliceItem();
+ BarRenderSliceItem(const BarRenderSliceItem &other);
+ virtual ~BarRenderSliceItem();
+
+ void setItem(const BarRenderItem &renderItem);
+
+ // Label item for formatted label
+ LabelItem &sliceLabelItem();
+
+ // Formatted label for item.
+ void setSliceLabel(const QString &label);
+ const QString &sliceLabel() const; // Formats label if not previously formatted
+
+protected:
+ QString m_sliceLabel;
+ LabelItem *m_sliceLabelItem;
+ bool m_isNull;
+};
+
typedef QVector<BarRenderItem> BarRenderItemRow;
typedef QVector<BarRenderItemRow> BarRenderItemArray;
diff --git a/src/datavisualization/data/labelitem_p.h b/src/datavisualization/data/labelitem_p.h
index ca60f742..3a2c1eb1 100644
--- a/src/datavisualization/data/labelitem_p.h
+++ b/src/datavisualization/data/labelitem_p.h
@@ -30,8 +30,8 @@
#define LABELITEM_P_H
#include "datavisualizationglobal_p.h"
-#include <QOpenGLFunctions>
-#include <QSize>
+#include <QtGui/QOpenGLFunctions>
+#include <QtCore/QSize>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qabstract3dseries.cpp b/src/datavisualization/data/qabstract3dseries.cpp
index dc241fdb..4d201c45 100644
--- a/src/datavisualization/data/qabstract3dseries.cpp
+++ b/src/datavisualization/data/qabstract3dseries.cpp
@@ -240,6 +240,14 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlmethod void Abstract3DSeries::setMeshAxisAndAngle(vector3d axis, real angle)
+ *
+ * A convenience function to construct mesh rotation quaternion from axis and angle.
+ *
+ * \sa meshRotation
+ */
+
+/*!
* \internal
*/
QAbstract3DSeries::QAbstract3DSeries(QAbstract3DSeriesPrivate *d, QObject *parent) :
@@ -375,6 +383,16 @@ QQuaternion QAbstract3DSeries::meshRotation() const
}
/*!
+ * A convenience function to construct mesh rotation quaternion from \a axis and \a angle.
+ *
+ * \sa meshRotation
+ */
+void QAbstract3DSeries::setMeshAxisAndAngle(const QVector3D &axis, float angle)
+{
+ setMeshRotation(QQuaternion::fromAxisAndAngle(axis, angle));
+}
+
+/*!
* \property QAbstract3DSeries::userDefinedMesh
*
* Sets the \a fileName for user defined custom mesh for objects that is used when mesh
diff --git a/src/datavisualization/data/qabstract3dseries.h b/src/datavisualization/data/qabstract3dseries.h
index ebb22b7f..9f82901d 100644
--- a/src/datavisualization/data/qabstract3dseries.h
+++ b/src/datavisualization/data/qabstract3dseries.h
@@ -20,10 +20,11 @@
#define QABSTRACT3DSERIES_H
#include <QtDataVisualization/q3dtheme.h>
-#include <QObject>
-#include <QScopedPointer>
-#include <QLinearGradient>
-#include <QQuaternion>
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QString>
+#include <QtGui/QLinearGradient>
+#include <QtGui/QQuaternion>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -95,6 +96,7 @@ public:
void setMeshRotation(const QQuaternion &rotation);
QQuaternion meshRotation() const;
+ Q_INVOKABLE void setMeshAxisAndAngle(const QVector3D &axis, float angle);
void setUserDefinedMesh(const QString &fileName);
QString userDefinedMesh() const;
@@ -118,20 +120,20 @@ public:
QString name() const;
signals:
- void itemLabelFormatChanged(QString format);
+ void itemLabelFormatChanged(const QString &format);
void visibilityChanged(bool visible);
void meshChanged(Mesh mesh);
void meshSmoothChanged(bool enabled);
- void meshRotationChanged(QQuaternion rotation);
- void userDefinedMeshChanged(QString fileName);
+ void meshRotationChanged(const QQuaternion &rotation);
+ void userDefinedMeshChanged(const QString &fileName);
void colorStyleChanged(Q3DTheme::ColorStyle style);
- void baseColorChanged(QColor color);
- void baseGradientChanged(QLinearGradient gradient);
- void singleHighlightColorChanged(QColor color);
- void singleHighlightGradientChanged(QLinearGradient gradient);
- void multiHighlightColorChanged(QColor color);
- void multiHighlightGradientChanged(QLinearGradient gradient);
- void nameChanged(QString name);
+ void baseColorChanged(const QColor &color);
+ void baseGradientChanged(const QLinearGradient &gradient);
+ void singleHighlightColorChanged(const QColor &color);
+ void singleHighlightGradientChanged(const QLinearGradient &gradient);
+ void multiHighlightColorChanged(const QColor &color);
+ void multiHighlightGradientChanged(const QLinearGradient &gradient);
+ void nameChanged(const QString &name);
protected:
QScopedPointer<QAbstract3DSeriesPrivate> d_ptr;
@@ -142,6 +144,7 @@ private:
friend class Abstract3DController;
friend class Bars3DController;
friend class Surface3DController;
+ friend class Surface3DRenderer;
friend class Scatter3DController;
friend class QBar3DSeries;
friend class SeriesRenderCache;
diff --git a/src/datavisualization/data/qabstract3dseries_p.h b/src/datavisualization/data/qabstract3dseries_p.h
index 6fbabd3d..a803e99b 100644
--- a/src/datavisualization/data/qabstract3dseries_p.h
+++ b/src/datavisualization/data/qabstract3dseries_p.h
@@ -28,7 +28,6 @@
#include "datavisualizationglobal_p.h"
#include "qabstract3dseries.h"
-#include <QString>
#ifndef QABSTRACT3DSERIES_P_H
#define QABSTRACT3DSERIES_P_H
diff --git a/src/datavisualization/data/qabstractdataproxy.h b/src/datavisualization/data/qabstractdataproxy.h
index 52c2e2c6..c643c675 100644
--- a/src/datavisualization/data/qabstractdataproxy.h
+++ b/src/datavisualization/data/qabstractdataproxy.h
@@ -20,9 +20,8 @@
#define QABSTRACTDATAPROXY_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QObject>
-#include <QScopedPointer>
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qabstractdataproxy_p.h b/src/datavisualization/data/qabstractdataproxy_p.h
index 093629d5..eb901f4c 100644
--- a/src/datavisualization/data/qabstractdataproxy_p.h
+++ b/src/datavisualization/data/qabstractdataproxy_p.h
@@ -28,7 +28,6 @@
#include "datavisualizationglobal_p.h"
#include "qabstractdataproxy.h"
-#include <QString>
#ifndef QABSTRACTDATAPROXY_P_H
#define QABSTRACTDATAPROXY_P_H
diff --git a/src/datavisualization/data/qbar3dseries.cpp b/src/datavisualization/data/qbar3dseries.cpp
index 1440476b..ed4ffaba 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
+ * using floating point precision and always returns a value from zero to 360 degrees.
+ *
+ * \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,14 +143,7 @@ QBar3DSeries::QBar3DSeries(QBarDataProxy *dataProxy, QObject *parent) :
QAbstract3DSeries(new QBar3DSeriesPrivate(this), parent)
{
dptr()->setDataProxy(dataProxy);
-}
-
-/*!
- * \internal
- */
-QBar3DSeries::QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent) :
- QAbstract3DSeries(d, parent)
-{
+ dptr()->connectSignals();
}
/*!
@@ -183,7 +189,7 @@ void QBar3DSeries::setSelectedBar(const QPoint &position)
{
// Don't do this in private to avoid loops, as that is used for callback from controller.
if (d_ptr->m_controller)
- static_cast<Bars3DController *>(d_ptr->m_controller)->setSelectedBar(position, this);
+ static_cast<Bars3DController *>(d_ptr->m_controller)->setSelectedBar(position, this, true);
else
dptr()->setSelectedBar(position);
}
@@ -204,6 +210,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
+ * using floating point precision and always returns a value from zero to 360 degrees.
+ *
+ * \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 +317,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 +330,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..c56bc354 100644
--- a/src/datavisualization/data/qbar3dseries.h
+++ b/src/datavisualization/data/qbar3dseries.h
@@ -21,7 +21,7 @@
#include <QtDataVisualization/qabstract3dseries.h>
#include <QtDataVisualization/qbardataproxy.h>
-#include <QPoint>
+#include <QtCore/QPoint>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -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,12 +46,15 @@ public:
QPoint selectedBar() const;
static QPoint invalidSelectionPosition();
+ void setMeshAngle(float angle);
+ float meshAngle() const;
+
signals:
void dataProxyChanged(QBarDataProxy *proxy);
- void selectedBarChanged(QPoint position);
+ void selectedBarChanged(const QPoint &position);
+ void meshAngleChanged(float angle);
protected:
- explicit QBar3DSeries(QBar3DSeriesPrivate *d, QObject *parent = 0);
QBar3DSeriesPrivate *dptr();
const QBar3DSeriesPrivate *dptrc() const;
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/qbardataitem.h b/src/datavisualization/data/qbardataitem.h
index 84e7cd92..e7fce93b 100644
--- a/src/datavisualization/data/qbardataitem.h
+++ b/src/datavisualization/data/qbardataitem.h
@@ -42,7 +42,7 @@ public:
inline float rotation() const { return m_angle; }
protected:
- virtual void createExtraData();
+ void createExtraData();
QBarDataItemPrivate *d_ptr;
diff --git a/src/datavisualization/data/qbardataproxy.cpp b/src/datavisualization/data/qbardataproxy.cpp
index a26e446e..d2553f32 100644
--- a/src/datavisualization/data/qbardataproxy.cpp
+++ b/src/datavisualization/data/qbardataproxy.cpp
@@ -130,7 +130,7 @@ QBarDataProxy::~QBarDataProxy()
*
* The series this proxy is attached to.
*/
-QBar3DSeries *QBarDataProxy::series()
+QBar3DSeries *QBarDataProxy::series() const
{
return static_cast<QBar3DSeries *>(d_ptr->series());
}
@@ -227,6 +227,15 @@ void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &i
}
/*!
+ * Changes a single item at \a position to the \a item.
+ * The X-value of \a position indicates the row and the Y-value indicates the column.
+ */
+void QBarDataProxy::setItem(const QPoint &position, const QBarDataItem &item)
+{
+ setItem(position.x(), position.y(), item);
+}
+
+/*!
* Adds a new \a row to the end of array.
* Existing row labels are not affected.
*
@@ -427,6 +436,16 @@ const QBarDataItem *QBarDataProxy::itemAt(int rowIndex, int columnIndex) const
}
/*!
+ * \return pointer to the item at \a position. The X-value of \a position indicates the row
+ * and the Y-value indicates the column. The item is guaranteed to be valid only
+ * until the next call that modifies data.
+ */
+const QBarDataItem *QBarDataProxy::itemAt(const QPoint &position) const
+{
+ return itemAt(position.x(), position.y());
+}
+
+/*!
* \internal
*/
QBarDataProxyPrivate *QBarDataProxy::dptr()
diff --git a/src/datavisualization/data/qbardataproxy.h b/src/datavisualization/data/qbardataproxy.h
index 0ad71365..55c11de3 100644
--- a/src/datavisualization/data/qbardataproxy.h
+++ b/src/datavisualization/data/qbardataproxy.h
@@ -21,8 +21,8 @@
#include <QtDataVisualization/qabstractdataproxy.h>
#include <QtDataVisualization/qbardataitem.h>
-#include <QVector>
-#include <QStringList>
+#include <QtCore/QVector>
+#include <QtCore/QStringList>
namespace QtDataVisualization {
// typedefs introduced this way because QDoc doesn't understand namespace macros
@@ -47,7 +47,7 @@ public:
explicit QBarDataProxy(QObject *parent = 0);
virtual ~QBarDataProxy();
- QBar3DSeries *series();
+ QBar3DSeries *series() const;
int rowCount() const;
QStringList rowLabels() const;
@@ -58,6 +58,7 @@ public:
const QBarDataArray *array() const;
const QBarDataRow *rowAt(int rowIndex) const;
const QBarDataItem *itemAt(int rowIndex, int columnIndex) const;
+ const QBarDataItem *itemAt(const QPoint &position) const;
void resetArray();
void resetArray(QBarDataArray *newArray);
@@ -70,6 +71,7 @@ public:
void setRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels);
void setItem(int rowIndex, int columnIndex, const QBarDataItem &item);
+ void setItem(const QPoint &position, const QBarDataItem &item);
int addRow(QBarDataRow *row);
int addRow(QBarDataRow *row, const QString &label);
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
index 9ac5c90f..1aead1d7 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -134,6 +134,18 @@ QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QImage &image, QObj
}
/*!
+ * Constructs QHeightMapSurfaceDataProxy from the given image \a filename and \a parent. Height map is set
+ * by calling setHeightMapFile() with \a filename.
+ *
+ * \sa heightMapFile
+ */
+QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QString &filename, QObject *parent) :
+ QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent)
+{
+ setHeightMapFile(filename);
+}
+
+/*!
* \internal
*/
QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.h b/src/datavisualization/data/qheightmapsurfacedataproxy.h
index d506d4e8..5b6eb284 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy.h
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.h
@@ -20,8 +20,8 @@
#define QHEIGHTMAPSURFACEDATAPROXY_H
#include <QtDataVisualization/qsurfacedataproxy.h>
-
-#include <QImage>
+#include <QtGui/QImage>
+#include <QtCore/QString>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -41,6 +41,7 @@ class QT_DATAVISUALIZATION_EXPORT QHeightMapSurfaceDataProxy : public QSurfaceDa
public:
explicit QHeightMapSurfaceDataProxy(QObject *parent = 0);
explicit QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent = 0);
+ explicit QHeightMapSurfaceDataProxy(const QString &filename, QObject *parent = 0);
virtual ~QHeightMapSurfaceDataProxy();
void setHeightMap(const QImage &image);
@@ -59,8 +60,8 @@ public:
float maxZValue() const;
signals:
- void heightMapChanged(QImage image);
- void heightMapFileChanged(QString filename);
+ void heightMapChanged(const QImage &image);
+ void heightMapFileChanged(const QString &filename);
void minXValueChanged(float value);
void maxXValueChanged(float value);
void minZValueChanged(float value);
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
index 0e947666..5cc9993a 100644
--- a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
@@ -31,7 +31,7 @@
#include "qheightmapsurfacedataproxy.h"
#include "qsurfacedataproxy_p.h"
-#include <QTimer>
+#include <QtCore/QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp
index 97289da1..0e880c77 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelbardataproxy.cpp
@@ -18,7 +18,6 @@
#include "qitemmodelbardataproxy_p.h"
#include "baritemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -105,6 +104,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 +200,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 +246,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 +352,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.
@@ -305,7 +378,7 @@ void QItemModelBarDataProxy::setRowCategories(const QStringList &categories)
{
if (dptr()->m_rowCategories != categories) {
dptr()->m_rowCategories = categories;
- emit rowCategoriesChanged(categories);
+ emit rowCategoriesChanged();
}
}
@@ -323,7 +396,7 @@ void QItemModelBarDataProxy::setColumnCategories(const QStringList &categories)
{
if (dptr()->m_columnCategories != categories) {
dptr()->m_columnCategories = categories;
- emit columnCategoriesChanged(categories);
+ emit columnCategoriesChanged();
}
}
@@ -392,24 +465,26 @@ bool QItemModelBarDataProxy::autoColumnCategories() const
}
/*!
- * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the
- * mapping.
+ * Changes \a rowRole, \a columnRole, \a valueRole, \a rotationRole,
+ * \a rowCategories and \a columnCategories to the mapping.
*/
void QItemModelBarDataProxy::remap(const QString &rowRole,
const QString &columnRole,
const QString &valueRole,
+ const QString &rotationRole,
const QStringList &rowCategories,
const QStringList &columnCategories)
{
setRowRole(rowRole);
setColumnRole(columnRole);
setValueRole(valueRole);
+ setRotationRole(rotationRole);
setRowCategories(rowCategories);
setColumnCategories(columnCategories);
}
/*!
- * /return index of the specified \a category in row categories list.
+ * \return index of the specified \a category in row categories list.
* If the row categories list is empty, -1 is returned.
* \note If the automatic row categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the first time.
@@ -420,7 +495,7 @@ int QItemModelBarDataProxy::rowCategoryIndex(const QString &category)
}
/*!
- * /return index of the specified \a category in column categories list.
+ * \return index of the specified \a category in column categories list.
* If the category is not found, -1 is returned.
* \note If the automatic column categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the first time.
@@ -477,6 +552,8 @@ void QItemModelBarDataProxyPrivate::connectItemModelHandler()
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelBarDataProxy::valueRoleChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelBarDataProxy::rotationRoleChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelBarDataProxy::rowCategoriesChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelBarDataProxy::columnCategoriesChanged,
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.h b/src/datavisualization/data/qitemmodelbardataproxy.h
index 4e62b4c3..f19b4445 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.h
+++ b/src/datavisualization/data/qitemmodelbardataproxy.h
@@ -20,8 +20,7 @@
#define QITEMMODELBARDATAPROXY_H
#include <QtDataVisualization/qbardataproxy.h>
-#include <QAbstractItemModel>
-#include <QStringList>
+#include <QtCore/QAbstractItemModel>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -34,6 +33,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 +50,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 +70,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;
@@ -77,7 +86,8 @@ public:
bool autoColumnCategories() const;
void remap(const QString &rowRole, const QString &columnRole,
- const QString &valueRole, const QStringList &rowCategories,
+ const QString &valueRole, const QString &rotationRole,
+ const QStringList &rowCategories,
const QStringList &columnCategories);
Q_INVOKABLE int rowCategoryIndex(const QString& category);
@@ -85,11 +95,12 @@ public:
signals:
void itemModelChanged(const QAbstractItemModel* itemModel);
- void rowRoleChanged(QString role);
- void columnRoleChanged(QString role);
- void valueRoleChanged(QString role);
- void rowCategoriesChanged(QStringList categories);
- void columnCategoriesChanged(QStringList categories);
+ void rowRoleChanged(const QString &role);
+ void columnRoleChanged(const QString &role);
+ void valueRoleChanged(const QString &role);
+ void rotationRoleChanged(const QString &role);
+ void rowCategoriesChanged();
+ void columnCategoriesChanged();
void useModelCategoriesChanged(bool enable);
void autoRowCategoriesChanged(bool enable);
void autoColumnCategoriesChanged(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..a5287abc 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
@@ -18,7 +18,6 @@
#include "qitemmodelscatterdataproxy_p.h"
#include "scatteritemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -93,6 +92,16 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
+ * \qmlproperty string ItemModelScatterDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ * The model may supply the value for rotation as either variant that is directly convertible
+ * to QQuaternion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first
+ * will construct the quaternion directly with given values, and the second one will construct
+ * the quaternion using QQuaternion::fromAxisAndAngle() method.
+ */
+
+/*!
* Constructs QItemModelScatterDataProxy with optional \a parent.
*/
QItemModelScatterDataProxy::QItemModelScatterDataProxy(QObject *parent)
@@ -134,6 +143,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,14 +242,38 @@ QString QItemModelScatterDataProxy::zPosRole() const
}
/*!
- * Changes \a xPosRole, \a yPosRole and \a zPosRole mapping.
+ * \property QItemModelScatterDataProxy::rotationRole
+ *
+ * Defines the rotation role for the mapping.
+ *
+ * The model may supply the value for rotation as either variant that is directly convertible
+ * to QQuartenion, or as one of the string representations: \c{"scalar,x,y,z"} or \c{"@angle,x,y,z"}. The first
+ * will construct the quaternion directly with given values, and the second one will construct
+ * the quaternion using QQuaternion::fromAxisAndAngle() method.
+ */
+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, \a zPosRole, and \a rotationRole mapping.
*/
void QItemModelScatterDataProxy::remap(const QString &xPosRole, const QString &yPosRole,
- const QString &zPosRole)
+ const QString &zPosRole, const QString &rotationRole)
{
setXPosRole(xPosRole);
setYPosRole(yPosRole);
setZPosRole(zPosRole);
+ setRotationRole(rotationRole);
}
/*!
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.h b/src/datavisualization/data/qitemmodelscatterdataproxy.h
index 0f69afa7..c6d2245d 100644
--- a/src/datavisualization/data/qitemmodelscatterdataproxy.h
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.h
@@ -20,8 +20,8 @@
#define QITEMMODELSCATTERDATAPROXY_H
#include <QtDataVisualization/qscatterdataproxy.h>
-#include <QAbstractItemModel>
-#include <QStringList>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QString>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -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,14 +57,18 @@ 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);
+ void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole,
+ const QString &rotationRole);
signals:
void itemModelChanged(const QAbstractItemModel* itemModel);
- void xPosRoleChanged(QString role);
- void yPosRoleChanged(QString role);
- void zPosRoleChanged(QString role);
+ void xPosRoleChanged(const QString &role);
+ void yPosRoleChanged(const QString &role);
+ void zPosRoleChanged(const QString &role);
+ void rotationRoleChanged(const 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/qitemmodelsurfacedataproxy.cpp b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
index 0c206b81..f15a8923 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
@@ -18,7 +18,6 @@
#include "qitemmodelsurfacedataproxy_p.h"
#include "surfaceitemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -30,7 +29,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* QItemModelSurfaceDataProxy allows you to use QAbstractItemModel derived models as a data source
* for Q3DSurface. It uses the defined mappings to map data from the model to rows, columns, and
- * values of Q3DSurface graph.
+ * surface points of Q3DSurface graph.
*
* Data is resolved asynchronously whenever the mapping or the model changes.
* QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved.
@@ -39,8 +38,12 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*
* 1) If useModelCategories property is set to true, this proxy will map rows and
* columns of QAbstractItemModel to rows and columns of Q3DSurface, and uses the value returned for
- * Qt::DisplayRole as bar value by default.
- * The value role to be used can be redefined if Qt::DisplayRole is not suitable.
+ * Qt::DisplayRole as Y-position by default. Row and column headers are used for Z-position and
+ * X-position by default, if they can be converted to floats. Otherwise row and column indices
+ * are used.
+ * The Y-position role to be used can be redefined if Qt::DisplayRole is not suitable.
+ * The Z-position and X-position roles to be used can be redefined if the headers or indices
+ * are not suitable.
*
* 2) For models that do not have data already neatly sorted into rows and columns, such as
* QAbstractListModel based models, you can define a role from the model to map for each of row,
@@ -105,10 +108,18 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION
*/
/*!
- * \qmlproperty string ItemModelSurfaceDataProxy::valueRole
- * The value role of the mapping.
- * The value indicated by value role is set as Y-coodrinate value of the
- * QSurfaceDataItem when model data is resolved.
+ * \qmlproperty string ItemModelSurfaceDataProxy::xPosRole
+ * The X position role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::yPosRole
+ * The Y position role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::zPosRole
+ * The Z position role of the mapping.
*/
/*!
@@ -169,17 +180,17 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
/*!
* Constructs QItemModelSurfaceDataProxy 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 value role is set to \a valueRole.
+ * The yPosRole role is set to \a yPosRole.
* This constructor is meant to be used with models that have data properly sorted
* in rows and columns already, so it also sets useModelCategories property to true.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
- const QString &valueRole,
+ const QString &yPosRole,
QObject *parent)
: QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
{
dptr()->m_itemModelHandler->setItemModel(itemModel);
- dptr()->m_valueRole = valueRole;
+ dptr()->m_yPosRole = yPosRole;
dptr()->m_useModelCategories = true;
dptr()->connectItemModelHandler();
}
@@ -187,33 +198,93 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
/*!
* Constructs QItemModelSurfaceDataProxy 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.
+ * The role mappings are set with \a rowRole, \a columnRole, and \a yPosRole.
+ * The zPosRole and the xPosRole are set to \a rowRole and \a columnRole, respectively.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &yPosRole,
+ QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_xPosRole = columnRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = rowRole;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy 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 xPosRole, \a yPosRole, and
+ * \a zPosRole.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
+ QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_xPosRole = xPosRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = zPosRole;
+ dptr()->connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy 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 yPosRole.
+ * The zPosRole and the xPosRole are set to \a rowRole and \a columnRole, respectively.
+ * Row and column categories are set with \a rowCategories and \a columnCategories.
+ * This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
- const QString &valueRole,
+ const QString &yPosRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
QObject *parent)
: QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
{
dptr()->m_itemModelHandler->setItemModel(itemModel);
dptr()->m_rowRole = rowRole;
dptr()->m_columnRole = columnRole;
- dptr()->m_valueRole = valueRole;
+ dptr()->m_xPosRole = columnRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = rowRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+ dptr()->m_autoRowCategories = false;
+ dptr()->m_autoColumnCategories = false;
dptr()->connectItemModelHandler();
}
/*!
* Constructs QItemModelSurfaceDataProxy 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.
+ * The role mappings are set with \a rowRole, \a columnRole, \a xPosRole, \a yPosRole,
+ * and \a zPosRole.
* Row and column categories are set with \a rowCategories and \a columnCategories.
* This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
const QString &rowRole,
const QString &columnRole,
- const QString &valueRole,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
const QStringList &rowCategories,
const QStringList &columnCategories,
QObject *parent)
@@ -222,7 +293,9 @@ QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel
dptr()->m_itemModelHandler->setItemModel(itemModel);
dptr()->m_rowRole = rowRole;
dptr()->m_columnRole = columnRole;
- dptr()->m_valueRole = valueRole;
+ dptr()->m_xPosRole = xPosRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = zPosRole;
dptr()->m_rowCategories = rowCategories;
dptr()->m_columnCategories = columnCategories;
dptr()->m_autoRowCategories = false;
@@ -290,21 +363,57 @@ QString QItemModelSurfaceDataProxy::columnRole() const
}
/*!
- * \property QItemModelSurfaceDataProxy::valueRole
+ * \property QItemModelSurfaceDataProxy::xPosRole
+ *
+ * Defines the X position role for the mapping.
+ */
+void QItemModelSurfaceDataProxy::setXPosRole(const QString &role)
+{
+ if (dptr()->m_xPosRole != role) {
+ dptr()->m_xPosRole = role;
+ emit xPosRoleChanged(role);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::xPosRole() const
+{
+ return dptrc()->m_xPosRole;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::yPosRole
*
- * Defines the value role for the mapping.
+ * Defines the Y position role for the mapping.
*/
-void QItemModelSurfaceDataProxy::setValueRole(const QString &role)
+void QItemModelSurfaceDataProxy::setYPosRole(const QString &role)
{
- if (dptr()->m_valueRole != role) {
- dptr()->m_valueRole = role;
- emit valueRoleChanged(role);
+ if (dptr()->m_yPosRole != role) {
+ dptr()->m_yPosRole = role;
+ emit yPosRoleChanged(role);
}
}
-QString QItemModelSurfaceDataProxy::valueRole() const
+QString QItemModelSurfaceDataProxy::yPosRole() const
{
- return dptrc()->m_valueRole;
+ return dptrc()->m_yPosRole;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::zPosRole
+ *
+ * Defines the Z position role for the mapping.
+ */
+void QItemModelSurfaceDataProxy::setZPosRole(const QString &role)
+{
+ if (dptr()->m_zPosRole != role) {
+ dptr()->m_zPosRole = role;
+ emit zPosRoleChanged(role);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::zPosRole() const
+{
+ return dptrc()->m_zPosRole;
}
/*!
@@ -316,7 +425,7 @@ void QItemModelSurfaceDataProxy::setRowCategories(const QStringList &categories)
{
if (dptr()->m_rowCategories != categories) {
dptr()->m_rowCategories = categories;
- emit rowCategoriesChanged(categories);
+ emit rowCategoriesChanged();
}
}
@@ -334,7 +443,7 @@ void QItemModelSurfaceDataProxy::setColumnCategories(const QStringList &categori
{
if (dptr()->m_columnCategories != categories) {
dptr()->m_columnCategories = categories;
- emit columnCategoriesChanged(categories);
+ emit columnCategoriesChanged();
}
}
@@ -403,24 +512,28 @@ bool QItemModelSurfaceDataProxy::autoColumnCategories() const
}
/*!
- * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the
- * mapping.
+ * Changes \a rowRole, \a columnRole, \a xPosRole, \a yPosRole, \a zPosRole,
+ * \a rowCategories and \a columnCategories to the mapping.
*/
void QItemModelSurfaceDataProxy::remap(const QString &rowRole,
const QString &columnRole,
- const QString &valueRole,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
const QStringList &rowCategories,
const QStringList &columnCategories)
{
setRowRole(rowRole);
setColumnRole(columnRole);
- setValueRole(valueRole);
+ setXPosRole(xPosRole);
+ setYPosRole(yPosRole);
+ setZPosRole(zPosRole);
setRowCategories(rowCategories);
setColumnCategories(columnCategories);
}
/*!
- * /return index of the specified \a category in row categories list.
+ * \return index of the specified \a category in row categories list.
* If the row categories list is empty, -1 is returned.
* \note If the automatic row categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the first time.
@@ -431,7 +544,7 @@ int QItemModelSurfaceDataProxy::rowCategoryIndex(const QString &category)
}
/*!
- * /return index of the specified \a category in column categories list.
+ * \return index of the specified \a category in column categories list.
* If the category is not found, -1 is returned.
* \note If the automatic column categories generation is in use, this method will
* not return a valid index before the data in the model is resolved for the first time.
@@ -486,7 +599,11 @@ void QItemModelSurfaceDataProxyPrivate::connectItemModelHandler()
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelSurfaceDataProxy::columnRoleChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
- QObject::connect(qptr(), &QItemModelSurfaceDataProxy::valueRoleChanged,
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::xPosRoleChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::yPosRoleChanged,
+ m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(qptr(), &QItemModelSurfaceDataProxy::zPosRoleChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
QObject::connect(qptr(), &QItemModelSurfaceDataProxy::rowCategoriesChanged,
m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.h b/src/datavisualization/data/qitemmodelsurfacedataproxy.h
index d1e0f2b8..b1ebbeed 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy.h
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.h
@@ -20,8 +20,8 @@
#define QITEMMODELSURFACEDATAPROXY_H
#include <QtDataVisualization/qsurfacedataproxy.h>
-#include <QAbstractItemModel>
-#include <QStringList>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -33,7 +33,9 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa
Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel NOTIFY itemModelChanged)
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 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(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)
@@ -43,13 +45,22 @@ class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDa
public:
explicit QItemModelSurfaceDataProxy(QObject *parent = 0);
QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, QObject *parent = 0);
- QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &valueRole,
+ QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &yPosRole,
QObject *parent = 0);
QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
- const QString &columnRole, const QString &valueRole,
+ const QString &columnRole, const QString &yPosRole,
QObject *parent = 0);
QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
- const QString &columnRole, const QString &valueRole,
+ const QString &columnRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &zPosRole,
+ QObject *parent = 0);
+ QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ const QString &columnRole, const QString &yPosRole,
+ const QStringList &rowCategories, const QStringList &columnCategories,
+ QObject *parent = 0);
+ QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, const QString &rowRole,
+ const QString &columnRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &zPosRole,
const QStringList &rowCategories, const QStringList &columnCategories,
QObject *parent = 0);
virtual ~QItemModelSurfaceDataProxy();
@@ -61,8 +72,12 @@ public:
QString rowRole() const;
void setColumnRole(const QString &role);
QString columnRole() const;
- void setValueRole(const QString &role);
- QString valueRole() const;
+ void setXPosRole(const QString &role);
+ QString xPosRole() const;
+ void setYPosRole(const QString &role);
+ QString yPosRole() const;
+ void setZPosRole(const QString &role);
+ QString zPosRole() const;
void setRowCategories(const QStringList &categories);
QStringList rowCategories() const;
@@ -77,7 +92,8 @@ public:
bool autoColumnCategories() const;
void remap(const QString &rowRole, const QString &columnRole,
- const QString &valueRole, const QStringList &rowCategories,
+ const QString &xPosRole, const QString &yPosRole,
+ const QString &zPosRole, const QStringList &rowCategories,
const QStringList &columnCategories);
Q_INVOKABLE int rowCategoryIndex(const QString& category);
@@ -85,11 +101,13 @@ public:
signals:
void itemModelChanged(const QAbstractItemModel* itemModel);
- void rowRoleChanged(QString role);
- void columnRoleChanged(QString role);
- void valueRoleChanged(QString role);
- void rowCategoriesChanged(QStringList categories);
- void columnCategoriesChanged(QStringList categories);
+ void rowRoleChanged(const QString &role);
+ void columnRoleChanged(const QString &role);
+ void xPosRoleChanged(const QString &role);
+ void yPosRoleChanged(const QString &role);
+ void zPosRoleChanged(const QString &role);
+ void rowCategoriesChanged();
+ void columnCategoriesChanged();
void useModelCategoriesChanged(bool enable);
void autoRowCategoriesChanged(bool enable);
void autoColumnCategoriesChanged(bool enable);
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
index 5049a25e..0aaea8fd 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
@@ -52,7 +52,9 @@ private:
QString m_rowRole;
QString m_columnRole;
- QString m_valueRole;
+ QString m_xPosRole;
+ QString m_yPosRole;
+ QString m_zPosRole;
// For row/column items, sort items into these categories. Other categories are ignored.
QStringList m_rowCategories;
diff --git a/src/datavisualization/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp
index 33f8bed0..9751dfeb 100644
--- a/src/datavisualization/data/qscatterdataitem.cpp
+++ b/src/datavisualization/data/qscatterdataitem.cpp
@@ -52,6 +52,16 @@ QScatterDataItem::QScatterDataItem(const QVector3D &position)
}
/*!
+ * Constructs QScatterDataItem with \a position and \a rotation.
+ */
+QScatterDataItem::QScatterDataItem(const QVector3D &position, const QQuaternion &rotation)
+ : d_ptr(0),
+ m_position(position),
+ m_rotation(rotation)
+{
+}
+
+/*!
* Constructs a copy of \a other.
*/
QScatterDataItem::QScatterDataItem(const QScatterDataItem &other)
diff --git a/src/datavisualization/data/qscatterdataitem.h b/src/datavisualization/data/qscatterdataitem.h
index d2ef3bcc..87cc1fc5 100644
--- a/src/datavisualization/data/qscatterdataitem.h
+++ b/src/datavisualization/data/qscatterdataitem.h
@@ -20,9 +20,7 @@
#define QSCATTERDATAITEM_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QVector3D>
-#include <QQuaternion>
+#include <QtGui/QQuaternion>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -33,6 +31,7 @@ class QT_DATAVISUALIZATION_EXPORT QScatterDataItem
public:
QScatterDataItem();
QScatterDataItem(const QVector3D &position);
+ QScatterDataItem(const QVector3D &position, const QQuaternion &rotation);
QScatterDataItem(const QScatterDataItem &other);
~QScatterDataItem();
@@ -50,7 +49,7 @@ public:
inline float z() const { return m_position.z(); }
protected:
- virtual void createExtraData();
+ void createExtraData();
QScatterDataItemPrivate *d_ptr;
diff --git a/src/datavisualization/data/qscatterdataproxy.cpp b/src/datavisualization/data/qscatterdataproxy.cpp
index b5e3863d..dbbb4384 100644
--- a/src/datavisualization/data/qscatterdataproxy.cpp
+++ b/src/datavisualization/data/qscatterdataproxy.cpp
@@ -98,7 +98,7 @@ QScatterDataProxy::~QScatterDataProxy()
*
* The series this proxy is attached to.
*/
-QScatter3DSeries *QScatterDataProxy::series()
+QScatter3DSeries *QScatterDataProxy::series() const
{
return static_cast<QScatter3DSeries *>(d_ptr->series());
}
diff --git a/src/datavisualization/data/qscatterdataproxy.h b/src/datavisualization/data/qscatterdataproxy.h
index b8179166..fe561bbd 100644
--- a/src/datavisualization/data/qscatterdataproxy.h
+++ b/src/datavisualization/data/qscatterdataproxy.h
@@ -43,7 +43,7 @@ public:
explicit QScatterDataProxy(QObject *parent = 0);
virtual ~QScatterDataProxy();
- QScatter3DSeries *series();
+ QScatter3DSeries *series() const;
int itemCount() const;
const QScatterDataArray *array() const;
const QScatterDataItem *itemAt(int index) const;
diff --git a/src/datavisualization/data/qsurface3dseries.cpp b/src/datavisualization/data/qsurface3dseries.cpp
index e5f06cc6..b7e15014 100644
--- a/src/datavisualization/data/qsurface3dseries.cpp
+++ b/src/datavisualization/data/qsurface3dseries.cpp
@@ -221,7 +221,7 @@ void QSurface3DSeries::setSelectedPoint(const QPoint &position)
{
// Don't do this in private to avoid loops, as that is used for callback from controller.
if (d_ptr->m_controller)
- static_cast<Surface3DController *>(d_ptr->m_controller)->setSelectedPoint(position, this);
+ static_cast<Surface3DController *>(d_ptr->m_controller)->setSelectedPoint(position, this, true);
else
dptr()->setSelectedPoint(position);
}
diff --git a/src/datavisualization/data/qsurface3dseries.h b/src/datavisualization/data/qsurface3dseries.h
index b8a1a62b..8347104e 100644
--- a/src/datavisualization/data/qsurface3dseries.h
+++ b/src/datavisualization/data/qsurface3dseries.h
@@ -65,7 +65,7 @@ public:
signals:
void dataProxyChanged(QSurfaceDataProxy *proxy);
- void selectedPointChanged(QPoint position);
+ void selectedPointChanged(const QPoint &position);
void flatShadingEnabledChanged(bool enable);
void flatShadingSupportedChanged(bool enable);
void drawModeChanged(QSurface3DSeries::DrawFlags mode);
diff --git a/src/datavisualization/data/qsurfacedataitem.h b/src/datavisualization/data/qsurfacedataitem.h
index f305952b..1e4a384d 100644
--- a/src/datavisualization/data/qsurfacedataitem.h
+++ b/src/datavisualization/data/qsurfacedataitem.h
@@ -20,8 +20,7 @@
#define QSURFACEDATAITEM_H
#include <QtDataVisualization/qdatavisualizationglobal.h>
-
-#include <QVector3D>
+#include <QtGui/QVector3D>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -47,7 +46,7 @@ public:
inline float z() const { return m_position.z(); }
protected:
- virtual void createExtraData();
+ void createExtraData();
QSurfaceDataItemPrivate *d_ptr;
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
index 43ce40eb..34cea326 100644
--- a/src/datavisualization/data/qsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -131,7 +131,7 @@ QSurfaceDataProxy::~QSurfaceDataProxy()
*
* The series this proxy is attached to.
*/
-QSurface3DSeries *QSurfaceDataProxy::series()
+QSurface3DSeries *QSurfaceDataProxy::series() const
{
return static_cast<QSurface3DSeries *>(d_ptr->series());
}
@@ -186,6 +186,15 @@ void QSurfaceDataProxy::setItem(int rowIndex, int columnIndex, const QSurfaceDat
}
/*!
+ * Changes a single item at \a position to the \a item.
+ * The X-value of \a position indicates the row and the Y-value indicates the column.
+ */
+void QSurfaceDataProxy::setItem(const QPoint &position, const QSurfaceDataItem &item)
+{
+ setItem(position.x(), position.y(), item);
+}
+
+/*!
* Adds a new \a row to the end of array. The new \a row must have
* the same number of columns as the rows at the initial array.
*
@@ -259,6 +268,29 @@ const QSurfaceDataArray *QSurfaceDataProxy::array() const
}
/*!
+ * \return pointer to the item at \a rowIndex, \a columnIndex. It is guaranteed to be valid only
+ * until the next call that modifies data.
+ */
+const QSurfaceDataItem *QSurfaceDataProxy::itemAt(int rowIndex, int columnIndex) const
+{
+ const QSurfaceDataArray &dataArray = *dptrc()->m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
+ const QSurfaceDataRow &dataRow = *dataArray[rowIndex];
+ Q_ASSERT(columnIndex >= 0 && columnIndex < dataRow.size());
+ return &dataRow.at(columnIndex);
+}
+
+/*!
+ * \return pointer to the item at \a position. The X-value of \a position indicates the row
+ * and the Y-value indicates the column. The item is guaranteed to be valid only
+ * until the next call that modifies data.
+ */
+const QSurfaceDataItem *QSurfaceDataProxy::itemAt(const QPoint &position) const
+{
+ return itemAt(position.x(), position.y());
+}
+
+/*!
* \property QSurfaceDataProxy::rowCount
*
* \return number of rows in the data.
@@ -282,15 +314,6 @@ int QSurfaceDataProxy::columnCount() const
}
/*!
- * \return pointer to the item at \a index. It is guaranteed to be valid only until the next call that
- * modifies data.
- */
-const QSurfaceDataItem *QSurfaceDataProxy::itemAt(int index) const
-{
- return &dptrc()->m_dataArray->at(index)->at(2);
-}
-
-/*!
* \internal
*/
QSurfaceDataProxyPrivate *QSurfaceDataProxy::dptr()
diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h
index 0933faf6..475f1f2d 100644
--- a/src/datavisualization/data/qsurfacedataproxy.h
+++ b/src/datavisualization/data/qsurfacedataproxy.h
@@ -45,11 +45,12 @@ public:
explicit QSurfaceDataProxy(QObject *parent = 0);
virtual ~QSurfaceDataProxy();
- QSurface3DSeries *series();
+ QSurface3DSeries *series() const;
int rowCount() const;
int columnCount() const;
const QSurfaceDataArray *array() const;
- const QSurfaceDataItem *itemAt(int index) const;
+ const QSurfaceDataItem *itemAt(int rowIndex, int columnIndex) const;
+ const QSurfaceDataItem *itemAt(const QPoint &position) const;
void resetArray(QSurfaceDataArray *newArray);
@@ -57,6 +58,7 @@ public:
void setRows(int rowIndex, const QSurfaceDataArray &rows);
void setItem(int rowIndex, int columnIndex, const QSurfaceDataItem &item);
+ void setItem(const QPoint &position, const QSurfaceDataItem &item);
int addRow(QSurfaceDataRow *row);
int addRows(const QSurfaceDataArray &rows);
diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h
index 658abe32..7c3486d2 100644
--- a/src/datavisualization/data/qsurfacedataproxy_p.h
+++ b/src/datavisualization/data/qsurfacedataproxy_p.h
@@ -32,8 +32,6 @@
#include "qsurfacedataproxy.h"
#include "qabstractdataproxy_p.h"
-#include <QSize>
-
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class QSurfaceDataProxyPrivate : public QAbstractDataProxyPrivate
diff --git a/src/datavisualization/data/scatteritemmodelhandler.cpp b/src/datavisualization/data/scatteritemmodelhandler.cpp
index 1c936d08..08ed12f3 100644
--- a/src/datavisualization/data/scatteritemmodelhandler.cpp
+++ b/src/datavisualization/data/scatteritemmodelhandler.cpp
@@ -17,7 +17,6 @@
****************************************************************************/
#include "scatteritemmodelhandler_p.h"
-#include <QTimer>
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
@@ -92,6 +91,41 @@ 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()) {
+ bool angleAndAxis = false;
+ if (s.startsWith(QLatin1Char('@'))) {
+ angleAndAxis = true;
+ s = s.mid(1);
+ }
+ if (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) {
+ if (angleAndAxis)
+ return QQuaternion::fromAxisAndAngle(xCoord, yCoord, zCoord, sCoord);
+ else
+ return QQuaternion(sCoord, xCoord, yCoord, zCoord);
+ }
+ }
+ }
+ }
+ return QQuaternion();
+}
+
void ScatterItemModelHandler::modelPosToScatterItem(int modelRow, int modelColumn,
QScatterDataItem &item)
{
@@ -105,6 +139,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 +157,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
diff --git a/src/datavisualization/data/scatterrenderitem.cpp b/src/datavisualization/data/scatterrenderitem.cpp
index d39af816..3b2e64c5 100644
--- a/src/datavisualization/data/scatterrenderitem.cpp
+++ b/src/datavisualization/data/scatterrenderitem.cpp
@@ -33,7 +33,6 @@ ScatterRenderItem::ScatterRenderItem(const ScatterRenderItem &other)
m_visible(false)
{
m_position = other.m_position;
- m_rotation = other.m_rotation;
}
ScatterRenderItem::~ScatterRenderItem()
diff --git a/src/datavisualization/data/scatterrenderitem_p.h b/src/datavisualization/data/scatterrenderitem_p.h
index 45066dd8..eb070682 100644
--- a/src/datavisualization/data/scatterrenderitem_p.h
+++ b/src/datavisualization/data/scatterrenderitem_p.h
@@ -45,19 +45,8 @@ public:
inline const QVector3D &position() const { return m_position; }
inline void setPosition(const QVector3D &pos)
{
- if (m_position != pos) {
+ if (m_position != pos)
m_position = pos;
- // Force reformatting on next access by setting label string to null string
- if (!m_selectionLabel.isNull())
- setSelectionLabel(QString());
- }
- }
-
- inline QQuaternion rotation() const { return m_rotation; }
- inline void setRotation(const QQuaternion &rotation)
- {
- if (m_rotation != rotation)
- m_rotation = rotation;
}
inline bool isVisible() const { return m_visible; }
@@ -65,7 +54,6 @@ public:
protected:
QVector3D m_position;
- QQuaternion m_rotation;
bool m_visible;
friend class QScatterDataItem;
diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp
index 767425e9..f4383dbf 100644
--- a/src/datavisualization/data/surfaceitemmodelhandler.cpp
+++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp
@@ -20,6 +20,8 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
+static const int noRoleIndex = -1;
+
SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent)
: AbstractItemModelHandler(parent),
m_proxy(proxy),
@@ -50,7 +52,9 @@ void SurfaceItemModelHandler::resolveModel()
QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
// Default to display role if no mapping
- int valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole);
+ int xPosRole = roleHash.key(m_proxy->xPosRole().toLatin1(), noRoleIndex);
+ int yPosRole = roleHash.key(m_proxy->yPosRole().toLatin1(), Qt::DisplayRole);
+ int zPosRole = roleHash.key(m_proxy->zPosRole().toLatin1(), noRoleIndex);
int rowCount = m_itemModel->rowCount();
int columnCount = m_itemModel->columnCount();
@@ -66,15 +70,41 @@ 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 = j;
+ float zPos = i;
+ if (xPosRole != noRoleIndex) {
+ xPos = m_itemModel->index(i, j).data(xPosRole).toFloat();
+ } else {
+ QString header = m_itemModel->headerData(j, Qt::Horizontal).toString();
+ bool ok = false;
+ float headerValue = header.toFloat(&ok);
+ if (ok)
+ xPos = headerValue;
+ }
+
+ if (zPosRole != noRoleIndex) {
+ zPos = m_itemModel->index(i, j).data(zPosRole).toFloat();
+ } else {
+ QString header = m_itemModel->headerData(i, Qt::Vertical).toString();
+ bool ok = false;
+ float headerValue = header.toFloat(&ok);
+ if (ok)
+ zPos = headerValue;
+ }
+
newProxyRow[j].setPosition(
- QVector3D(m_itemModel->headerData(j, Qt::Horizontal).toFloat(),
- m_itemModel->index(i, j).data(valueRole).toFloat(),
- m_itemModel->headerData(i, Qt::Vertical).toFloat()));
+ QVector3D(xPos,
+ m_itemModel->index(i, j).data(yPosRole).toFloat(),
+ zPos));
}
}
} else {
int rowRole = roleHash.key(m_proxy->rowRole().toLatin1());
int columnRole = roleHash.key(m_proxy->columnRole().toLatin1());
+ if (xPosRole == noRoleIndex)
+ xPosRole = columnRole;
+ if (zPosRole == noRoleIndex)
+ zPosRole = rowRole;
bool generateRows = m_proxy->autoRowCategories();
bool generateColumns = m_proxy->autoColumnCategories();
@@ -87,14 +117,17 @@ void SurfaceItemModelHandler::resolveModel()
QHash<QString, bool> columnListHash;
// Sort values into rows and columns
- typedef QHash<QString, float> ColumnValueMap;
+ typedef QHash<QString, QVector3D> ColumnValueMap;
QHash <QString, ColumnValueMap> itemValueMap;
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();
+ QVector3D itemPos(index.data(xPosRole).toReal(),
+ index.data(yPosRole).toReal(),
+ index.data(zPosRole).toReal());
+ itemValueMap[rowRoleStr][columnRoleStr] = itemPos;
if (generateRows && !rowListHash.value(rowRoleStr, false)) {
rowListHash.insert(rowRoleStr, true);
rowList << rowRoleStr;
@@ -128,11 +161,8 @@ void SurfaceItemModelHandler::resolveModel()
for (int i = 0; i < rowList.size(); i++) {
QString rowKey = rowList.at(i);
QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
- for (int j = 0; j < columnList.size(); j++) {
- newProxyRow[j].setPosition(QVector3D(columnList.at(j).toFloat(),
- itemValueMap[rowKey][columnList.at(j)],
- rowList.at(i).toFloat()));
- }
+ for (int j = 0; j < columnList.size(); j++)
+ newProxyRow[j].setPosition(itemValueMap[rowKey][columnList.at(j)]);
}
}