diff options
Diffstat (limited to 'src/datavis3d/data')
50 files changed, 4695 insertions, 0 deletions
diff --git a/src/datavis3d/data/abstractrenderitem.cpp b/src/datavis3d/data/abstractrenderitem.cpp new file mode 100644 index 00000000..004fb598 --- /dev/null +++ b/src/datavis3d/data/abstractrenderitem.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "abstractrenderitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +AbstractRenderItem::AbstractRenderItem() + : m_labelItem(0), + m_selectionLabel(0) +{ +} + +AbstractRenderItem::~AbstractRenderItem() +{ + delete m_labelItem; + delete m_selectionLabel; +} + +LabelItem &AbstractRenderItem::labelItem() +{ + if (!m_labelItem) + m_labelItem = new LabelItem; + return *m_labelItem; +} + +LabelItem &AbstractRenderItem::selectionLabel() +{ + if (!m_selectionLabel) + m_selectionLabel = new LabelItem; + return *m_selectionLabel; +} + +QString &AbstractRenderItem::label() +{ + if (m_label.isNull()) + formatLabel(); + return m_label; +} + +void AbstractRenderItem::setLabel(const QString &label) +{ + if (m_labelItem) + m_labelItem->clear(); + if (m_selectionLabel) + m_selectionLabel->clear(); + m_label = label; +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/abstractrenderitem_p.h b/src/datavis3d/data/abstractrenderitem_p.h new file mode 100644 index 00000000..4bf4df71 --- /dev/null +++ b/src/datavis3d/data/abstractrenderitem_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef ABSTRACTRENDERITEM_P_H +#define ABSTRACTRENDERITEM_P_H + +#include "datavis3dglobal_p.h" +#include "labelitem_p.h" + +#include <QOpenGLFunctions> +#include <QString> +#include <QVector3D> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class AbstractRenderItem +{ +public: + AbstractRenderItem(); + virtual ~AbstractRenderItem(); + + // Position in 3D scene + inline void setTranslation(const QVector3D &translation) { m_translation = translation; } + inline const QVector3D &translation() const {return m_translation; } + + // Label item for formatted label + LabelItem &labelItem(); + + // Selection label item (containing special selection texture, if mode is activated) + LabelItem &selectionLabel(); + + // Formatted label for item. + void setLabel(const QString &label); + QString &label(); // Formats label if not previously formatted + +protected: + virtual void formatLabel() = 0; + + QString m_label; + QVector3D m_translation; + LabelItem *m_labelItem; + LabelItem *m_selectionLabel; + + friend class QAbstractDataItem; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/barrenderitem.cpp b/src/datavis3d/data/barrenderitem.cpp new file mode 100644 index 00000000..db377aa3 --- /dev/null +++ b/src/datavis3d/data/barrenderitem.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "barrenderitem_p.h" +#include "bars3drenderer_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +BarRenderItem::BarRenderItem() + : AbstractRenderItem(), + m_renderer(0), + m_value(0) +{ +} + +BarRenderItem::~BarRenderItem() +{ +} + +void BarRenderItem::formatLabel() +{ + // Format the string on first access + QString numStr; + numStr.setNum(m_value); + // TODO actually format instead of just prepending the value + m_label.clear(); // Just in case + m_label.append(numStr); + m_label.append(m_renderer->itemLabelFormat()); // TODO format needs to be cached +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/barrenderitem_p.h b/src/datavis3d/data/barrenderitem_p.h new file mode 100644 index 00000000..babab795 --- /dev/null +++ b/src/datavis3d/data/barrenderitem_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef BARRENDERITEM_P_H +#define BARRENDERITEM_P_H + +#include "abstractrenderitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Bars3dRenderer; + +class BarRenderItem : public AbstractRenderItem +{ +public: + BarRenderItem(); + virtual ~BarRenderItem(); + + // Position relative to data window (for bar label generation) + inline void setPosition(const QPoint &pos) { m_position = pos; } + inline const QPoint &position() const { return m_position; } + + // Actual cached data value of the bar (needed to trigger label reformats) + inline void setValue(qreal value); + inline qreal value() const { return m_value; } + + // Normalized bar height + inline void setHeight(GLfloat height) { m_height = height; } + inline GLfloat height() const { return m_height; } + + // TODO should be in abstract, but currently there is no abstract renderer + inline void setRenderer(Bars3dRenderer *renderer) { m_renderer = renderer; } + +protected: + virtual void formatLabel(); + + Bars3dRenderer *m_renderer; + qreal m_value; + QPoint m_position; // x = row, y = column + GLfloat m_height; + + friend class QBarDataItem; +}; + +void BarRenderItem::setValue(qreal value) +{ + if (m_value != value) { + m_value = value; + if (!m_label.isNull()) + setLabel(QString()); // Forces reformatting on next access + } +} + +typedef QVector<BarRenderItem> BarRenderItemRow; +typedef QVector<BarRenderItemRow> BarRenderItemArray; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/data.pri b/src/datavis3d/data/data.pri new file mode 100644 index 00000000..a3b28e6e --- /dev/null +++ b/src/datavis3d/data/data.pri @@ -0,0 +1,52 @@ +HEADERS += \ + $$PWD/labelitem_p.h \ + $$PWD/qabstractdataproxy.h \ + $$PWD/qabstractdataproxy_p.h \ + $$PWD/qbardataproxy.h \ + $$PWD/qbardataproxy_p.h \ + $$PWD/abstractrenderitem_p.h \ + $$PWD/barrenderitem_p.h \ + $$PWD/qbardataitem.h \ + $$PWD/qbardataitem_p.h \ + $$PWD/qitemmodelbardatamapping.h \ + $$PWD/qitemmodelbardatamapping_p.h \ + $$PWD/qitemmodelbardataproxy_p.h \ + $$PWD/qitemmodelbardataproxy.h \ + $$PWD/maprenderitem_p.h \ + $$PWD/qmapdataitem.h \ + $$PWD/qmapdataitem_p.h \ + $$PWD/qmapdataproxy.h \ + $$PWD/qmapdataproxy_p.h \ + $$PWD/scatterrenderitem_p.h \ + $$PWD/qscatterdataitem.h \ + $$PWD/qscatterdataitem_p.h \ + $$PWD/qscatterdataproxy.h \ + $$PWD/qscatterdataproxy_p.h \ + $$PWD/qitemmodelmapdatamapping.h \ + $$PWD/qitemmodelmapdatamapping_p.h \ + $$PWD/qitemmodelmapdataproxy.h \ + $$PWD/qitemmodelmapdataproxy_p.h \ + $$PWD/qitemmodelscatterdatamapping.h \ + $$PWD/qitemmodelscatterdatamapping_p.h \ + $$PWD/qitemmodelscatterdataproxy.h \ + $$PWD/qitemmodelscatterdataproxy_p.h + +SOURCES += \ + $$PWD/labelitem.cpp \ + $$PWD/qabstractdataproxy.cpp \ + $$PWD/qbardataproxy.cpp \ + $$PWD/abstractrenderitem.cpp \ + $$PWD/barrenderitem.cpp \ + $$PWD/qbardataitem.cpp \ + $$PWD/qitemmodelbardatamapping.cpp \ + $$PWD/qitemmodelbardataproxy.cpp \ + $$PWD/maprenderitem.cpp \ + $$PWD/qmapdataitem.cpp \ + $$PWD/qmapdataproxy.cpp \ + $$PWD/scatterrenderitem.cpp \ + $$PWD/qscatterdataitem.cpp \ + $$PWD/qscatterdataproxy.cpp \ + $$PWD/qitemmodelmapdatamapping.cpp \ + $$PWD/qitemmodelmapdataproxy.cpp \ + $$PWD/qitemmodelscatterdatamapping.cpp \ + $$PWD/qitemmodelscatterdataproxy.cpp diff --git a/src/datavis3d/data/labelitem.cpp b/src/datavis3d/data/labelitem.cpp new file mode 100644 index 00000000..1d1bf6f7 --- /dev/null +++ b/src/datavis3d/data/labelitem.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "labelitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +LabelItem::LabelItem() + : m_size(QSize(0, 0)), + m_textureId(0) +{ +} + +LabelItem::~LabelItem() +{ + glDeleteTextures(1, &m_textureId); +} + +void LabelItem::setSize(const QSize &size) +{ + m_size = size; +} + +QSize LabelItem::size() const +{ + return m_size; +} + +void LabelItem::setTextureId(GLuint textureId) +{ + glDeleteTextures(1, &m_textureId); + m_textureId = textureId; +} + +GLuint LabelItem::textureId() const +{ + return m_textureId; +} + +void LabelItem::clear() +{ + if (m_textureId) { + glDeleteTextures(1, &m_textureId); + m_textureId = 0; + } + m_size = QSize(0, 0); +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/labelitem_p.h b/src/datavis3d/data/labelitem_p.h new file mode 100644 index 00000000..84625002 --- /dev/null +++ b/src/datavis3d/data/labelitem_p.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef LABELITEM_P_H +#define LABELITEM_P_H + +#include "datavis3dglobal_p.h" +#include <QOpenGLFunctions> +#include <QSize> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class LabelItem +{ +public: + explicit LabelItem(); + ~LabelItem(); + + void setSize(const QSize &size); + QSize size() const; + void setTextureId(GLuint textureId); + GLuint textureId() const; + void clear(); + +private: + Q_DISABLE_COPY(LabelItem); + + QSize m_size; + GLuint m_textureId; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/maprenderitem.cpp b/src/datavis3d/data/maprenderitem.cpp new file mode 100644 index 00000000..c7165104 --- /dev/null +++ b/src/datavis3d/data/maprenderitem.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "maprenderitem_p.h" +#include "maps3drenderer_p.h" // TODO remove when maps refactored +#include "maps3dcontroller_p.h" // TODO should be renderer +#include "qmapdataproxy.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +MapRenderItem::MapRenderItem() + : BarRenderItem() +{ +} + +MapRenderItem::~MapRenderItem() +{ +} + +void MapRenderItem::formatLabel() +{ + // TODO The label format specified in proxy should probably have additional custom formatting + // TODO specifiers in addition to standard printf specifiers for placement of item labels + // TODO and selection data (like row/column in bar selection) + + // Format the string on first access + QString numStr; + numStr.setNum(m_value); + // TODO actually format instead of just prepending the value + m_label.clear(); // Just in case + m_label.append(m_itemLabel); + m_label.append(QStringLiteral(" ")); + m_label.append(numStr); + m_label.append(m_renderer->dataProxy()->itemLabelFormat()); +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/maprenderitem_p.h b/src/datavis3d/data/maprenderitem_p.h new file mode 100644 index 00000000..f1e7290e --- /dev/null +++ b/src/datavis3d/data/maprenderitem_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef MAPRENDERITEM_P_H +#define MAPRENDERITEM_P_H + +#include "barrenderitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Maps3DRenderer; +class Maps3DController; // TODO remove when maps refactored + +class MapRenderItem : public BarRenderItem +{ +public: + MapRenderItem(); + virtual ~MapRenderItem(); + + inline const QPointF &mapPosition() const { return m_mapPosition; } + inline void setMapPosition(const QPointF &pos) { m_mapPosition = pos; } + + inline const QString &itemLabel() const { return m_itemLabel; } + inline void setItemLabel(const QString &label) { m_itemLabel = label; } + + // TODO should be in abstract, but currently there is no abstract renderer + // TODO change when maps refactored + inline void setRenderer(Maps3DController *renderer) { m_renderer = renderer; } + +protected: + virtual void formatLabel(); + + Maps3DController *m_renderer; + QPointF m_mapPosition; + QString m_itemLabel; // from QMapDataItem::label() - unformatted item label + + friend class QMapDataItem; +}; + +typedef QVector<MapRenderItem> MapRenderItemArray; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qabstractdataproxy.cpp b/src/datavis3d/data/qabstractdataproxy.cpp new file mode 100644 index 00000000..11874edb --- /dev/null +++ b/src/datavis3d/data/qabstractdataproxy.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qabstractdataproxy.h" +#include "qabstractdataproxy_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QAbstractDataProxy::QAbstractDataProxy(QAbstractDataProxyPrivate *d) : + QObject(0), + d_ptr(d) +{ +} + +QAbstractDataProxy::~QAbstractDataProxy() +{ +} + +QAbstractDataProxy::DataType QAbstractDataProxy::type() const +{ + return d_ptr->m_type; +} + +void QAbstractDataProxy::setItemLabelFormat(const QString &format) +{ + d_ptr->setItemLabelFormat(format); + emit itemLabelFormatChanged(); +} + +QString QAbstractDataProxy::itemLabelFormat() const +{ + return d_ptr->m_itemLabelFormat; +} + +// QAbstractDataProxyPrivate + +QAbstractDataProxyPrivate::QAbstractDataProxyPrivate(QAbstractDataProxy *q, QAbstractDataProxy::DataType type) + : QObject(0), + q_ptr(q), + m_type(type) +{ +} + +QAbstractDataProxyPrivate::~QAbstractDataProxyPrivate() +{ +} + +void QAbstractDataProxyPrivate::setItemLabelFormat(const QString &format) +{ + m_itemLabelFormat = format; +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qabstractdataproxy.h b/src/datavis3d/data/qabstractdataproxy.h new file mode 100644 index 00000000..0e717dbb --- /dev/null +++ b/src/datavis3d/data/qabstractdataproxy.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QABSTRACTDATAPROXY_H +#define QABSTRACTDATAPROXY_H + +#include <QtDataVis3D/qdatavis3denums.h> +#include <QObject> +#include <QScopedPointer> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QAbstractDataProxyPrivate; + +class QT_DATAVIS3D_EXPORT QAbstractDataProxy : public QObject +{ + Q_OBJECT + Q_ENUMS(DataType) + Q_PROPERTY(DataType type READ type) + +public: + enum DataType { + DataTypeNone = 0, + DataTypeBar = 1, + DataTypeMap = 2, + DataTypeScatter = 4, + DataTypeSurface = 8 + }; + +protected: + explicit QAbstractDataProxy(QAbstractDataProxyPrivate *d); +public: + virtual ~QAbstractDataProxy(); + + DataType type() const; + + // Items use this string to format single item labels, unless custom proxy initializes + // item labels with something else. + void setItemLabelFormat(const QString &format); + QString itemLabelFormat() const; + +signals: + void itemLabelFormatChanged(); + +protected: + QScopedPointer<QAbstractDataProxyPrivate> d_ptr; + +private: + Q_DISABLE_COPY(QAbstractDataProxy) +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // QABSTRACTDATAPROXY_H diff --git a/src/datavis3d/data/qabstractdataproxy_p.h b/src/datavis3d/data/qabstractdataproxy_p.h new file mode 100644 index 00000000..eda13b86 --- /dev/null +++ b/src/datavis3d/data/qabstractdataproxy_p.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#include "datavis3dglobal_p.h" +#include "qabstractdataproxy.h" +#include <QString> + +#ifndef QABSTRACTDATAPROXY_P_H +#define QABSTRACTDATAPROXY_P_H + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QAbstractDataProxyPrivate : public QObject +{ + Q_OBJECT +public: + QAbstractDataProxyPrivate(QAbstractDataProxy *q, QAbstractDataProxy::DataType type); + virtual ~QAbstractDataProxyPrivate(); + + void setItemLabelFormat(const QString &format); + +protected: + QAbstractDataProxy *q_ptr; + QAbstractDataProxy::DataType m_type; + QString m_itemLabelFormat; + +private: + friend class QAbstractDataProxy; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // QABSTRACTDATAPROXY_P_H diff --git a/src/datavis3d/data/qbardataitem.cpp b/src/datavis3d/data/qbardataitem.cpp new file mode 100644 index 00000000..1e8f3d95 --- /dev/null +++ b/src/datavis3d/data/qbardataitem.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qbardataitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +/*! + * \class QBarDataItem + * \inmodule QtDataVis3D + * \brief The QBarDataItem class provides a container for resolved data to be added to bar graphs. + * \since 1.0.0 + * + * A QBarDataItem holds data for a single rendered bar in a graph. + * Bar data proxies parse data into QBarDataItem instances for visualizing. + * + * \sa QBarDataProxy, {Qt Data Visualization 3D C++ Classes} + */ + +/*! + * Constructs QBarDataItem. + */ +QBarDataItem::QBarDataItem() + : d_ptr(0), // private data doesn't exist by default (optimization) + m_value(0.0) +{ +} + +QBarDataItem::QBarDataItem(qreal value) + : d_ptr(0), + m_value(value) +{ +} + +QBarDataItem::QBarDataItem(const QBarDataItem &other) +{ + operator=(other); +} + +/*! + * Destroys QBarDataItem. + */ +QBarDataItem::~QBarDataItem() +{ + delete d_ptr; +} + +QBarDataItem &QBarDataItem::operator=(const QBarDataItem &other) +{ + m_value = other.m_value; + if (other.d_ptr) + createExtraData(); + else + d_ptr = 0; + // TODO set extra data + return *this; +} + +void QBarDataItem::setValue(qreal value) +{ + m_value = value; +} + +qreal QBarDataItem::value() const +{ + return m_value; +} + +void QBarDataItem::createExtraData() +{ + if (!d_ptr) + d_ptr = new QBarDataItemPrivate; +} + + +QBarDataItemPrivate::QBarDataItemPrivate() +{ +} + +QBarDataItemPrivate::~QBarDataItemPrivate() +{ +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qbardataitem.h b/src/datavis3d/data/qbardataitem.h new file mode 100644 index 00000000..d7062b66 --- /dev/null +++ b/src/datavis3d/data/qbardataitem.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QBARDATAITEM_H +#define QBARDATAITEM_H + +#include <QtDataVis3D/qdatavis3denums.h> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QBarDataItemPrivate; + +class QT_DATAVIS3D_EXPORT QBarDataItem +{ +public: + QBarDataItem(); + QBarDataItem(qreal value); + QBarDataItem(const QBarDataItem &other); + ~QBarDataItem(); + + QBarDataItem &operator=(const QBarDataItem &other); + + void setValue(qreal value); + qreal value() const; + + // TODO Set color, label format, ...? + +protected: + virtual void createExtraData(); + + QBarDataItemPrivate *d_ptr; + +private: + qreal m_value; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qbardataitem_p.h b/src/datavis3d/data/qbardataitem_p.h new file mode 100644 index 00000000..e63ce787 --- /dev/null +++ b/src/datavis3d/data/qbardataitem_p.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QBARDATAITEM_P_H +#define QBARDATAITEM_P_H + +#include "datavis3dglobal_p.h" +#include "qbardataitem.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QBarDataItemPrivate +{ +public: + QBarDataItemPrivate(); + virtual ~QBarDataItemPrivate(); + + // TODO stores other data for bars besides value + +protected: + friend class QBarDataItem; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qbardataproxy.cpp b/src/datavis3d/data/qbardataproxy.cpp new file mode 100644 index 00000000..589ed37a --- /dev/null +++ b/src/datavis3d/data/qbardataproxy.cpp @@ -0,0 +1,262 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qbardataproxy.h" +#include "qbardataproxy_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QBarDataProxy::QBarDataProxy() : + QAbstractDataProxy(new QBarDataProxyPrivate(this)) +{ +} + +QBarDataProxy::QBarDataProxy(QBarDataProxyPrivate *d) : + QAbstractDataProxy(d) +{ +} + +QBarDataProxy::~QBarDataProxy() +{ +} + +void QBarDataProxy::resetArray(QBarDataArray *newArray) +{ + if (dptr()->resetArray(newArray)) + emit arrayReset(); +} + +void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row) +{ + dptr()->setRow(rowIndex, row); + emit rowsChanged(rowIndex, 1); +} + +void QBarDataProxy::setRows(int rowIndex, const QBarDataArray &rows) +{ + dptr()->setRows(rowIndex, rows); + emit rowsChanged(rowIndex, rows.size()); +} + +void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &item) +{ + dptr()->setItem(rowIndex, columnIndex, item); + emit itemChanged(rowIndex, columnIndex); +} + +int QBarDataProxy::addRow(QBarDataRow *row) +{ + int addIndex = dptr()->addRow(row); + emit rowsAdded(addIndex, 1); + return addIndex; +} + +int QBarDataProxy::addRows(const QBarDataArray &rows) +{ + int addIndex = dptr()->addRows(rows); + emit rowsAdded(addIndex, rows.size()); + return addIndex; +} + +void QBarDataProxy::insertRow(int rowIndex, QBarDataRow *row) +{ + dptr()->insertRow(rowIndex, row); + emit rowsInserted(rowIndex, 1); +} + +void QBarDataProxy::insertRows(int rowIndex, const QBarDataArray &rows) +{ + dptr()->insertRows(rowIndex, rows); + emit rowsInserted(rowIndex, rows.size()); +} + +void QBarDataProxy::removeRows(int rowIndex, int removeCount) +{ + if (rowIndex < rowCount()) { + dptr()->removeRows(rowIndex, removeCount); + emit rowsRemoved(rowIndex, removeCount); + } +} + +int QBarDataProxy::rowCount() const +{ + return dptrc()->m_dataArray->size(); +} + +const QBarDataArray *QBarDataProxy::array() const +{ + return dptrc()->m_dataArray; +} + +const QBarDataRow *QBarDataProxy::rowAt(int rowIndex) const +{ + const QBarDataArray &dataArray = *dptrc()->m_dataArray; + Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size()); + return dataArray[rowIndex]; +} + +const QBarDataItem *QBarDataProxy::itemAt(int rowIndex, int columnIndex) const +{ + const QBarDataArray &dataArray = *dptrc()->m_dataArray; + Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size()); + const QBarDataRow &dataRow = *dataArray[rowIndex]; + Q_ASSERT(columnIndex >= 0 && columnIndex < dataRow.size()); + return &dataRow.at(columnIndex); +} + +QBarDataProxyPrivate *QBarDataProxy::dptr() +{ + return static_cast<QBarDataProxyPrivate *>(d_ptr.data()); +} + +const QBarDataProxyPrivate *QBarDataProxy::dptrc() const +{ + return static_cast<const QBarDataProxyPrivate *>(d_ptr.data()); +} + +// QBarDataProxyPrivate + +QBarDataProxyPrivate::QBarDataProxyPrivate(QBarDataProxy *q) + : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeBar), + m_dataArray(new QBarDataArray) +{ +} + +QBarDataProxyPrivate::~QBarDataProxyPrivate() +{ + clearArray(); +} + +bool QBarDataProxyPrivate::resetArray(QBarDataArray *newArray) +{ + if (!m_dataArray->size() && (!newArray || !newArray->size())) + return false; + + clearArray(); + + if (newArray) + m_dataArray = newArray; + else + m_dataArray = new QBarDataArray; + + return true; +} + +void QBarDataProxyPrivate::setRow(int rowIndex, QBarDataRow *row) +{ + Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray->size()); + clearRow(rowIndex); + (*m_dataArray)[rowIndex] = row; +} + +void QBarDataProxyPrivate::setRows(int rowIndex, const QBarDataArray &rows) +{ + QBarDataArray &dataArray = *m_dataArray; + Q_ASSERT(rowIndex >= 0 && (rowIndex + rows.size()) <= dataArray.size()); + for (int i = 0; i < rows.size(); i++) { + clearRow(rowIndex); + dataArray[rowIndex] = rows.at(i); + rowIndex++; + } +} + +void QBarDataProxyPrivate::setItem(int rowIndex, int columnIndex, const QBarDataItem &item) +{ + Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray->size()); + QBarDataRow &row = *(*m_dataArray)[rowIndex]; + Q_ASSERT(columnIndex < row.size()); + row[columnIndex] = item; +} + +int QBarDataProxyPrivate::addRow(QBarDataRow *row) +{ + int currentSize = m_dataArray->size(); + m_dataArray->append(row); + return currentSize; +} + +int QBarDataProxyPrivate::addRows(const QBarDataArray &rows) +{ + int currentSize = m_dataArray->size(); + for (int i = 0; i < rows.size(); i++) + m_dataArray->append(rows.at(i)); + return currentSize; +} + +void QBarDataProxyPrivate::insertRow(int rowIndex, QBarDataRow *row) +{ + Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size()); + m_dataArray->insert(rowIndex, row); +} + +void QBarDataProxyPrivate::insertRows(int rowIndex, const QBarDataArray &rows) +{ + Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size()); + for (int i = 0; i < rows.size(); i++) + m_dataArray->insert(rowIndex++, rows.at(i)); +} + +void QBarDataProxyPrivate::removeRows(int rowIndex, int removeCount) +{ + Q_ASSERT(rowIndex >= 0); + int maxRemoveCount = m_dataArray->size() - rowIndex; + removeCount = qMin(removeCount, maxRemoveCount); + for (int i = 0; i < removeCount; i++) { + clearRow(rowIndex); + m_dataArray->removeAt(rowIndex); + } +} + +void QBarDataProxyPrivate::clearRow(int rowIndex) +{ + if (m_dataArray->at(rowIndex)) { + delete m_dataArray->at(rowIndex); + (*m_dataArray)[rowIndex] = 0; + } +} + +void QBarDataProxyPrivate::clearArray() +{ + for (int i = 0; i < m_dataArray->size(); i++) + clearRow(i); + m_dataArray->clear(); + delete m_dataArray; +} + +QPair<GLfloat, GLfloat> QBarDataProxyPrivate::limitValues(int startRow, int endRow, int startColumn, int endColumn) +{ + QPair<GLfloat, GLfloat> limits = qMakePair(0.0f, 0.0f); + endRow = qMin(endRow, m_dataArray->size() - 1); + for (int i = startRow; i <= endRow; i++) { + QBarDataRow *row = m_dataArray->at(i); + if (row) { + endColumn = qMin(endColumn, row->size() - 1); + for (int j = startColumn; j <= endColumn; j++) { + const QBarDataItem &item = m_dataArray->at(i)->at(j); + qreal itemValue = item.value(); + if (limits.second < itemValue) + limits.second = itemValue; + if (limits.first > itemValue) + limits.first = itemValue; + } + } + } + return limits; +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qbardataproxy.h b/src/datavis3d/data/qbardataproxy.h new file mode 100644 index 00000000..e28f8ff0 --- /dev/null +++ b/src/datavis3d/data/qbardataproxy.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QBARDATAPROXY_H +#define QBARDATAPROXY_H + +#include <QtDataVis3D/qabstractdataproxy.h> +#include <QtDataVis3D/qbardataitem.h> +#include <QVector> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +typedef QVector<QBarDataItem> QBarDataRow; +typedef QList<QBarDataRow *> QBarDataArray; + +class QBarDataProxyPrivate; + +class QT_DATAVIS3D_EXPORT QBarDataProxy : public QAbstractDataProxy +{ + Q_OBJECT + +public: + explicit QBarDataProxy(); + explicit QBarDataProxy(QBarDataProxyPrivate *d); + virtual ~QBarDataProxy(); + + // BarDataProxy is optimized for adding, inserting, and removing rows of data. + // Adding a column essentially means modifying every row, which is comparatively very inefficient. + // Proxy is also optimized to use cases where the only defining characteristic of an individual + // bar is its value. Modifying other data that might be added in the future such as color of + // individual bar requires allocating additional data object for the bar. + + // Row and item pointers are guaranteed to be valid only until next call that modifies data. + // Array pointer is guaranteed to be valid for lifetime of proxy. + int rowCount() const; + const QBarDataArray *array() const; + const QBarDataRow *rowAt(int rowIndex) const; + const QBarDataItem *itemAt(int rowIndex, int columnIndex) const; + + // The data array is a list of vectors (rows) of QBarDataItem instances. + // Each row can contain different amount of items or even be null. + + // QBarDataProxy takes ownership of all QBarDataRows passed to it, whether directly or + // in a QBarDataArray container. + // QBarDataRow pointers should not be used to modify data further after they have been passed to + // the proxy, as such modifications will not trigger proper signals. + + // Clears the existing array and takes ownership of the new array. + // Passing null array clears all data. + void resetArray(QBarDataArray *newArray); + + // Change existing rows + void setRow(int rowIndex, QBarDataRow *row); + void setRows(int rowIndex, const QBarDataArray &rows); + + // Setting a column is comparatively inefficient as it changes all rows. + // Can resize rows that are shorter than columnIndex. + // TODO void setColumn(int columnIndex, const QBarDataRow &column); + // TODO void setColumns(int columnIndex, const QBarDataArray &columns); + + // Change single item + void setItem(int rowIndex, int columnIndex, const QBarDataItem &item); + // Change block of items + // TODO setItems(int rowIndex, int columnIndex, QBarDataArray *items); + + int addRow(QBarDataRow *row); // returns the index of added row + int addRows(const QBarDataArray &rows); // returns the index of first added row + // TODO int addColumn(const QBarDataRow &column); // returns the index of the added column + // TODO int addColumns(const QBarDataArray &columns); // returns the index of the first added column + + // If rowIndex is equal to array size, rows are added to end of the array. + void insertRow(int rowIndex, QBarDataRow *row); + void insertRows(int rowIndex, const QBarDataArray &rows); + // TODO void insertColumn(int columnIndex, const QBarDataRow &column); + // TODO void insertColumns(int columnIndex, const QBarDataArray &columns); + + // Attempting to remove rows past the end of the array does nothing. + void removeRows(int rowIndex, int removeCount); + // TODO void removeColumns(int columnIndex, int removeCount); + +signals: + void arrayReset(); + void rowsAdded(int startIndex, int count); + void rowsChanged(int startIndex, int count); + // Index is the current array size if rows were removed from the end of the array + void rowsRemoved(int startIndex, int count); + void rowsInserted(int startIndex, int count); + // TODO void columnsChanged(int startIndex, int count); + // TODO void columnsAdded(int startIndex, int count); + // TODO void columnsRemoved(int startIndex, int count); + // TODO void columnsInserted(int startIndex, int count); + void itemChanged(int rowIndex, int columnIndex); // TODO remove once itemsChanged is added? + // TODO void itemsChanged(int rowIndex, int columnIndex, int rowCount, int columnCount); + +protected: + QBarDataProxyPrivate *dptr(); + const QBarDataProxyPrivate *dptrc() const; + +private: + Q_DISABLE_COPY(QBarDataProxy) + + friend class Bars3dController; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // QBARDATAPROXY_H diff --git a/src/datavis3d/data/qbardataproxy_p.h b/src/datavis3d/data/qbardataproxy_p.h new file mode 100644 index 00000000..fa6ccd0d --- /dev/null +++ b/src/datavis3d/data/qbardataproxy_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QBARDATAPROXY_P_H +#define QBARDATAPROXY_P_H + +#include "qbardataproxy.h" +#include "qabstractdataproxy_p.h" +#include "qbardataitem.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QBarDataProxyPrivate : public QAbstractDataProxyPrivate +{ + Q_OBJECT +public: + QBarDataProxyPrivate(QBarDataProxy *q); + virtual ~QBarDataProxyPrivate(); + + bool resetArray(QBarDataArray *newArray); + void setRow(int rowIndex, QBarDataRow *row); + void setRows(int rowIndex, const QBarDataArray &rows); + void setItem(int rowIndex, int columnIndex, const QBarDataItem &item); + int addRow(QBarDataRow *row); + int addRows(const QBarDataArray &rows); + void insertRow(int rowIndex, QBarDataRow *row); + void insertRows(int rowIndex, const QBarDataArray &rows); + void removeRows(int rowIndex, int removeCount); + + QPair<GLfloat, GLfloat> limitValues(int startRow, int startColumn, int rowCount, int columnCount); + +private: + void clearRow(int rowIndex); + void clearArray(); + + QBarDataArray *m_dataArray; + +private: + friend class QBarDataProxy; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // QBARDATAPROXY_P_H diff --git a/src/datavis3d/data/qitemmodelbardatamapping.cpp b/src/datavis3d/data/qitemmodelbardatamapping.cpp new file mode 100644 index 00000000..0aecb082 --- /dev/null +++ b/src/datavis3d/data/qitemmodelbardatamapping.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qitemmodelbardatamapping_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QItemModelBarDataMapping::QItemModelBarDataMapping() + : QObject(0), + d_ptr(new QItemModelBarDataMappingPrivate(this)) +{ +} + +QItemModelBarDataMapping::QItemModelBarDataMapping(const QItemModelBarDataMapping &other) + : QObject(0), + d_ptr(new QItemModelBarDataMappingPrivate(this)) +{ + operator=(other); +} + +QItemModelBarDataMapping::QItemModelBarDataMapping(const QString &valueRole) + : QObject(0), + d_ptr(new QItemModelBarDataMappingPrivate(this)) +{ + d_ptr->m_valueRole = valueRole; +} + +QItemModelBarDataMapping::QItemModelBarDataMapping(const QString &rowRole, + const QString &columnRole, + const QString &valueRole, + const QStringList &rowCategories, + const QStringList &columnCategories) + : QObject(0), + d_ptr(new QItemModelBarDataMappingPrivate(this)) +{ + d_ptr->m_rowRole = rowRole; + d_ptr->m_columnRole = columnRole; + d_ptr->m_valueRole = valueRole; + d_ptr->m_rowCategories = rowCategories; + d_ptr->m_columnCategories = columnCategories; +} + +QItemModelBarDataMapping::~QItemModelBarDataMapping() +{ +} + +QItemModelBarDataMapping &QItemModelBarDataMapping::operator=(const QItemModelBarDataMapping &other) +{ + d_ptr->m_rowRole = other.d_ptr->m_rowRole; + d_ptr->m_columnRole = other.d_ptr->m_columnRole; + d_ptr->m_valueRole = other.d_ptr->m_valueRole; + d_ptr->m_rowCategories = other.d_ptr->m_rowCategories; + d_ptr->m_columnCategories = other.d_ptr->m_columnCategories; + + return *this; +} + +void QItemModelBarDataMapping::setRowRole(const QString &role) +{ + d_ptr->m_rowRole = role; + emit mappingChanged(); +} + +QString QItemModelBarDataMapping::rowRole() const +{ + return d_ptr->m_rowRole; +} + +void QItemModelBarDataMapping::setColumnRole(const QString &role) +{ + d_ptr->m_columnRole = role; + emit mappingChanged(); +} + +QString QItemModelBarDataMapping::columnRole() const +{ + return d_ptr->m_columnRole; +} + +void QItemModelBarDataMapping::setValueRole(const QString &role) +{ + d_ptr->m_valueRole = role; + emit mappingChanged(); +} + +QString QItemModelBarDataMapping::valueRole() const +{ + return d_ptr->m_valueRole; +} + +void QItemModelBarDataMapping::setRowCategories(const QStringList &categories) +{ + d_ptr->m_rowCategories = categories; + emit mappingChanged(); +} + +const QStringList &QItemModelBarDataMapping::rowCategories() const +{ + return d_ptr->m_rowCategories; +} + +void QItemModelBarDataMapping::setColumnCategories(const QStringList &categories) +{ + d_ptr->m_columnCategories = categories; + emit mappingChanged(); +} + +const QStringList &QItemModelBarDataMapping::columnCategories() const +{ + return d_ptr->m_columnCategories; +} + +void QItemModelBarDataMapping::remap(const QString &rowRole, + const QString &columnRole, + const QString &valueRole, + const QStringList &rowCategories, + const QStringList &columnCategories) +{ + d_ptr->m_rowRole = rowRole; + d_ptr->m_columnRole = columnRole; + d_ptr->m_valueRole = valueRole; + d_ptr->m_rowCategories = rowCategories; + d_ptr->m_columnCategories = columnCategories; + + emit mappingChanged(); +} + +// QItemModelBarDataMappingPrivate + +QItemModelBarDataMappingPrivate::QItemModelBarDataMappingPrivate(QItemModelBarDataMapping *q) + : QObject(0), + q_ptr(q) +{ +} + +QItemModelBarDataMappingPrivate::~QItemModelBarDataMappingPrivate() +{ +} + +QT_DATAVIS3D_END_NAMESPACE + diff --git a/src/datavis3d/data/qitemmodelbardatamapping.h b/src/datavis3d/data/qitemmodelbardatamapping.h new file mode 100644 index 00000000..d9f74152 --- /dev/null +++ b/src/datavis3d/data/qitemmodelbardatamapping.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QITEMMODELBARDATAMAPPING_H +#define QITEMMODELBARDATAMAPPING_H + +#include <QtDataVis3D/qdatavis3denums.h> +#include <QStringList> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelBarDataMappingPrivate; + +class QT_DATAVIS3D_EXPORT QItemModelBarDataMapping : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole) + Q_PROPERTY(QString columnRole READ columnRole WRITE setColumnRole) + Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole) + Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories) + Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories) +public: + explicit QItemModelBarDataMapping(); + QItemModelBarDataMapping(const QItemModelBarDataMapping &other); + QItemModelBarDataMapping(const QString &valueRole); + QItemModelBarDataMapping(const QString &rowRole, const QString &columnRole, + const QString &valueRole, const QStringList &rowCategories, + const QStringList &columnCategories); + virtual ~QItemModelBarDataMapping(); + + QItemModelBarDataMapping &operator=(const QItemModelBarDataMapping &other); + + // If row categories or column categories is an empty list, use item models's rows and columns for rows and columns. + // If the categories are both defined, ignore item model's rows and columns and figure out the rows and columns from + // the values of the set roles for each item. + + void setRowRole(const QString &role); + QString rowRole() const; + void setColumnRole(const QString &role); + QString columnRole() const; + void setValueRole(const QString &role); + QString valueRole() const; + + void setRowCategories(const QStringList &categories); + const QStringList &rowCategories() const; + void setColumnCategories(const QStringList &categories); + const QStringList &columnCategories() const; + + void remap(const QString &rowRole, const QString &columnRole, + const QString &valueRole, const QStringList &rowCategories, + const QStringList &columnCategories); +signals: + void mappingChanged(); + +private: + QScopedPointer<QItemModelBarDataMappingPrivate> d_ptr; +}; + + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelbardatamapping_p.h b/src/datavis3d/data/qitemmodelbardatamapping_p.h new file mode 100644 index 00000000..fa1728e0 --- /dev/null +++ b/src/datavis3d/data/qitemmodelbardatamapping_p.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#include "qitemmodelbardatamapping.h" + +#ifndef QITEMMODELBARDATAMAPPING_P_H +#define QITEMMODELBARDATAMAPPING_P_H + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelBarDataMappingPrivate : public QObject +{ + Q_OBJECT +public: + QItemModelBarDataMappingPrivate(QItemModelBarDataMapping *q); + virtual ~QItemModelBarDataMappingPrivate(); + +private: + QString m_rowRole; + QString m_columnRole; + QString m_valueRole; + + // For row/column items, sort items into these categories. Other categories are ignored. + QStringList m_rowCategories; + QStringList m_columnCategories; + + QItemModelBarDataMapping *q_ptr; + + friend class QItemModelBarDataMapping; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelbardataproxy.cpp b/src/datavis3d/data/qitemmodelbardataproxy.cpp new file mode 100644 index 00000000..4b3ed020 --- /dev/null +++ b/src/datavis3d/data/qitemmodelbardataproxy.cpp @@ -0,0 +1,290 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qitemmodelbardataproxy_p.h" +#include <QTimer> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QItemModelBarDataProxy::QItemModelBarDataProxy() : + QBarDataProxy(new QItemModelBarDataProxyPrivate(this)) +{ +} + +QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel, + QItemModelBarDataMapping *mapping) : + QBarDataProxy(new QItemModelBarDataProxyPrivate(this)) +{ + dptr()->setItemModel(itemModel); + dptr()->setMapping(mapping); +} + +QItemModelBarDataProxy::~QItemModelBarDataProxy() +{ +} + +void QItemModelBarDataProxy::setItemModel(QAbstractItemModel *itemModel) +{ + dptr()->setItemModel(itemModel); +} + +QAbstractItemModel *QItemModelBarDataProxy::itemModel() +{ + return dptr()->m_itemModel.data(); +} + +void QItemModelBarDataProxy::setMapping(QItemModelBarDataMapping *mapping) +{ + dptr()->setMapping(mapping); +} + +QItemModelBarDataMapping *QItemModelBarDataProxy::mapping() +{ + return dptr()->m_mapping.data(); +} + +QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptr() +{ + return static_cast<QItemModelBarDataProxyPrivate *>(d_ptr.data()); +} + +// QItemModelBarDataProxyPrivate + +QItemModelBarDataProxyPrivate::QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q) + : QBarDataProxyPrivate(q), + resolvePending(0) +{ + m_resolveTimer.setSingleShot(true); + QObject::connect(&m_resolveTimer, &QTimer::timeout, this, &QItemModelBarDataProxyPrivate::handlePendingResolve); +} + +QItemModelBarDataProxyPrivate::~QItemModelBarDataProxyPrivate() +{ +} + +void QItemModelBarDataProxyPrivate::setItemModel(QAbstractItemModel *itemModel) +{ + if (!m_itemModel.isNull()) + QObject::disconnect(m_itemModel, 0, this, 0); + + m_itemModel = itemModel; + + if (!m_itemModel.isNull()) { + QObject::connect(m_itemModel, &QAbstractItemModel::columnsInserted, this, &QItemModelBarDataProxyPrivate::handleColumnsInserted); + QObject::connect(m_itemModel, &QAbstractItemModel::columnsMoved, this, &QItemModelBarDataProxyPrivate::handleColumnsMoved); + QObject::connect(m_itemModel, &QAbstractItemModel::columnsRemoved, this, &QItemModelBarDataProxyPrivate::handleColumnsRemoved); + QObject::connect(m_itemModel, &QAbstractItemModel::dataChanged, this, &QItemModelBarDataProxyPrivate::handleDataChanged); + QObject::connect(m_itemModel, &QAbstractItemModel::layoutChanged, this, &QItemModelBarDataProxyPrivate::handleLayoutChanged); + QObject::connect(m_itemModel, &QAbstractItemModel::modelReset, this, &QItemModelBarDataProxyPrivate::handleModelReset); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsInserted, this, &QItemModelBarDataProxyPrivate::handleRowsInserted); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsMoved, this, &QItemModelBarDataProxyPrivate::handleRowsMoved); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsRemoved, this, &QItemModelBarDataProxyPrivate::handleRowsRemoved); + } + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelBarDataProxyPrivate::setMapping(QItemModelBarDataMapping *mapping) +{ + if (!m_mapping.isNull()) + QObject::disconnect(m_mapping.data(), &QItemModelBarDataMapping::mappingChanged, this, &QItemModelBarDataProxyPrivate::handleMappingChanged); + + m_mapping = mapping; + + if (!m_mapping.isNull()) + QObject::connect(m_mapping.data(), &QItemModelBarDataMapping::mappingChanged, this, &QItemModelBarDataProxyPrivate::handleMappingChanged); + + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelBarDataProxyPrivate::handleColumnsInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve new items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destinationParent) + Q_UNUSED(destinationColumn) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleColumnsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Remove old items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) +{ + Q_UNUSED(topLeft) + Q_UNUSED(bottomRight) + Q_UNUSED(roles) + + // Resolve changed items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint) +{ + Q_UNUSED(parents) + Q_UNUSED(hint) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleModelReset() +{ + // Data cleared, reset array + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleRowsInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve new items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destinationParent) + Q_UNUSED(destinationRow) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleRowsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve removed items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelBarDataProxyPrivate::handleMappingChanged() +{ + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelBarDataProxyPrivate::handlePendingResolve() +{ + resolveModel(); +} + +// Resolve entire item model into QBarDataArray. +void QItemModelBarDataProxyPrivate::resolveModel() +{ + if (m_itemModel.isNull() || m_mapping.isNull()) { + qptr()->resetArray(0); + return; + } + + bool useModelRows(false); + if (!m_mapping->rowCategories().size() || !m_mapping->columnCategories().size()) { + useModelRows = true; + } else if (m_mapping->rowRole().isEmpty() || m_mapping->columnRole().isEmpty()) { + qptr()->resetArray(0); + return; + } + + QBarDataArray *newProxyArray = new QBarDataArray; + QHash<int, QByteArray> roleHash = m_itemModel->roleNames(); + // Default to display role if no mapping + int valueRole = roleHash.key(m_mapping->valueRole().toLatin1(), Qt::DisplayRole); + int rowCount = m_itemModel->rowCount(); + int columnCount = m_itemModel->columnCount(); + + if (useModelRows) { + for (int i = 0; i < rowCount; i++) { + QBarDataRow *newProxyRow = new QBarDataRow(columnCount); + for (int j = 0; j < columnCount; j++) + (*newProxyRow)[j].setValue(m_itemModel->index(i, j).data(valueRole).toReal()); + newProxyArray->append(newProxyRow); + } + } else { + int rowRole = roleHash.key(m_mapping->rowRole().toLatin1()); + int columnRole = roleHash.key(m_mapping->columnRole().toLatin1()); + const QStringList &rowList = m_mapping->rowCategories(); + const QStringList &columnList = m_mapping->columnCategories(); + + // Sort values into rows and columns + typedef QHash<QString, qreal> 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); + itemValueMap[index.data(rowRole).toString()][index.data(columnRole).toString()] + = index.data(valueRole).toReal(); + } + } + + // Create new data array from itemValueMap + foreach (QString rowKey, rowList) { + QBarDataRow *newProxyRow = new QBarDataRow(columnList.size()); + for (int i = 0; i < columnList.size(); i++) + (*newProxyRow)[i].setValue(itemValueMap[rowKey][columnList.at(i)]); + newProxyArray->append(newProxyRow); + } + } + qDebug() << __FUNCTION__ << "RowCount:" << newProxyArray->size() << "Column count:" << (newProxyArray->size() ? newProxyArray->at(0)->size() : 0); + + qptr()->resetArray(newProxyArray); +} + +QItemModelBarDataProxy *QItemModelBarDataProxyPrivate::qptr() +{ + return static_cast<QItemModelBarDataProxy *>(q_ptr); +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qitemmodelbardataproxy.h b/src/datavis3d/data/qitemmodelbardataproxy.h new file mode 100644 index 00000000..1d60bed6 --- /dev/null +++ b/src/datavis3d/data/qitemmodelbardataproxy.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QITEMMODELBARDATAPROXY_H +#define QITEMMODELBARDATAPROXY_H + +#include <QtDataVis3D/qbardataproxy.h> +#include <QtDataVis3D/qitemmodelbardatamapping.h> +#include <QAbstractItemModel> +#include <QStringList> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelBarDataProxyPrivate; + +class QT_DATAVIS3D_EXPORT QItemModelBarDataProxy : public QBarDataProxy +{ + Q_OBJECT + +public: + explicit QItemModelBarDataProxy(); + explicit QItemModelBarDataProxy(QAbstractItemModel *itemModel, QItemModelBarDataMapping *mapping); + virtual ~QItemModelBarDataProxy(); + + // Doesn't gain ownership of the model, but does connect to it to listen for data changes. + void setItemModel(QAbstractItemModel *itemModel); + QAbstractItemModel *itemModel(); + + // Map bars role (row, column, value) to role in model. + // Doesn't gain ownership of mapping, but does connect to it to listen for mapping changes. + // Modifying mapping that is set to proxy will trigger dataset re-resolving. + void setMapping(QItemModelBarDataMapping *mapping); + QItemModelBarDataMapping *mapping(); + +protected: + QItemModelBarDataProxyPrivate *dptr(); + +private: + Q_DISABLE_COPY(QItemModelBarDataProxy) +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelbardataproxy_p.h b/src/datavis3d/data/qitemmodelbardataproxy_p.h new file mode 100644 index 00000000..c69b1679 --- /dev/null +++ b/src/datavis3d/data/qitemmodelbardataproxy_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QITEMMODELBARDATAPROXY_P_H +#define QITEMMODELBARDATAPROXY_P_H + +#include "qitemmodelbardataproxy.h" +#include "qbardataproxy_p.h" +#include <QPointer> +#include <QTimer> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelBarDataProxyPrivate : public QBarDataProxyPrivate +{ + Q_OBJECT +public: + QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q); + virtual ~QItemModelBarDataProxyPrivate(); + + void setItemModel(QAbstractItemModel *itemModel); + void setMapping(QItemModelBarDataMapping *mapping); + +public slots: + void handleColumnsInserted(const QModelIndex & parent, int start, int end); + void handleColumnsMoved(const QModelIndex & sourceParent, int sourceStart, int sourceEnd, const QModelIndex & destinationParent, int destinationColumn); + void handleColumnsRemoved(const QModelIndex & parent, int start, int end); + void handleDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles = QVector<int> ()); + void handleLayoutChanged(const QList<QPersistentModelIndex> & parents = QList<QPersistentModelIndex> (), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint); + void handleModelReset(); + void handleRowsInserted(const QModelIndex & parent, int start, int end); + void handleRowsMoved(const QModelIndex & sourceParent, int sourceStart, int sourceEnd, const QModelIndex & destinationParent, int destinationRow); + void handleRowsRemoved(const QModelIndex & parent, int start, int end); + + void handleMappingChanged(); + void handlePendingResolve(); + +private: + void resolveModel(); + QItemModelBarDataProxy *qptr(); + + QPointer<QAbstractItemModel> m_itemModel; // Not owned + QPointer<QItemModelBarDataMapping> m_mapping; // Not owned + bool resolvePending; + QTimer m_resolveTimer; + + friend class QItemModelBarDataProxy; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelmapdatamapping.cpp b/src/datavis3d/data/qitemmodelmapdatamapping.cpp new file mode 100644 index 00000000..a59be94b --- /dev/null +++ b/src/datavis3d/data/qitemmodelmapdatamapping.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qitemmodelmapdatamapping_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QItemModelMapDataMapping::QItemModelMapDataMapping() + : QObject(0), + d_ptr(new QItemModelMapDataMappingPrivate(this)) +{ +} + +QItemModelMapDataMapping::QItemModelMapDataMapping(const QItemModelMapDataMapping &other) + : QObject(0), + d_ptr(new QItemModelMapDataMappingPrivate(this)) +{ + operator=(other); +} + +QItemModelMapDataMapping::QItemModelMapDataMapping(const QString &labelRole, const QString &xPosRole, + const QString &yPosRole, const QString &valueRole) + : QObject(0), + d_ptr(new QItemModelMapDataMappingPrivate(this)) +{ + d_ptr->m_labelRole = labelRole; + d_ptr->m_xPosRole = xPosRole; + d_ptr->m_yPosRole = yPosRole; + d_ptr->m_valueRole = valueRole; +} + +QItemModelMapDataMapping::~QItemModelMapDataMapping() +{ +} + +QItemModelMapDataMapping &QItemModelMapDataMapping::operator=(const QItemModelMapDataMapping &other) +{ + d_ptr->m_labelRole = other.d_ptr->m_labelRole; + d_ptr->m_xPosRole = other.d_ptr->m_xPosRole; + d_ptr->m_yPosRole = other.d_ptr->m_yPosRole; + d_ptr->m_valueRole = other.d_ptr->m_valueRole; + + return *this; +} + +void QItemModelMapDataMapping::setLabelRole(const QString &role) +{ + d_ptr->m_labelRole = role; + emit mappingChanged(); +} + +QString QItemModelMapDataMapping::labelRole() const +{ + return d_ptr->m_labelRole; +} + +void QItemModelMapDataMapping::setXPosRole(const QString &role) +{ + d_ptr->m_xPosRole = role; + emit mappingChanged(); +} + +QString QItemModelMapDataMapping::xPosRole() const +{ + return d_ptr->m_xPosRole; +} + +void QItemModelMapDataMapping::setYPosRole(const QString &role) +{ + d_ptr->m_yPosRole = role; + emit mappingChanged(); +} + +QString QItemModelMapDataMapping::yPosRole() const +{ + return d_ptr->m_yPosRole; +} + +void QItemModelMapDataMapping::setValueRole(const QString &role) +{ + d_ptr->m_valueRole = role; + emit mappingChanged(); +} + +QString QItemModelMapDataMapping::valueRole() const +{ + return d_ptr->m_valueRole; +} + + +void QItemModelMapDataMapping::remap(const QString &labelRole, const QString &xPosRole, + const QString &yPosRole, const QString &valueRole) +{ + d_ptr->m_labelRole = labelRole; + d_ptr->m_xPosRole = xPosRole; + d_ptr->m_yPosRole = yPosRole; + d_ptr->m_valueRole = valueRole; + + emit mappingChanged(); +} + +// QItemModelMapDataMappingPrivate + +QItemModelMapDataMappingPrivate::QItemModelMapDataMappingPrivate(QItemModelMapDataMapping *q) + : QObject(0), + q_ptr(q) +{ +} + +QItemModelMapDataMappingPrivate::~QItemModelMapDataMappingPrivate() +{ +} + +QT_DATAVIS3D_END_NAMESPACE + diff --git a/src/datavis3d/data/qitemmodelmapdatamapping.h b/src/datavis3d/data/qitemmodelmapdatamapping.h new file mode 100644 index 00000000..79080a65 --- /dev/null +++ b/src/datavis3d/data/qitemmodelmapdatamapping.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QITEMMODELMAPDATAMAPPING_H +#define QITEMMODELMAPDATAMAPPING_H + +#include <QtDataVis3D/qdatavis3denums.h> +#include <QStringList> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelMapDataMappingPrivate; + +class QT_DATAVIS3D_EXPORT QItemModelMapDataMapping : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString labelRole READ labelRole WRITE setLabelRole) + Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole) + Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole) + Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole) +public: + explicit QItemModelMapDataMapping(); + QItemModelMapDataMapping(const QItemModelMapDataMapping &other); + QItemModelMapDataMapping(const QString &labelRole, const QString &xPosRole, + const QString &yPosRole, const QString &valueRole); + virtual ~QItemModelMapDataMapping(); + + QItemModelMapDataMapping &operator=(const QItemModelMapDataMapping &other); + + void setLabelRole(const QString &role); + QString labelRole() const; + void setXPosRole(const QString &role); + QString xPosRole() const; + void setYPosRole(const QString &role); + QString yPosRole() const; + void setValueRole(const QString &role); + QString valueRole() const; + + void remap(const QString &labelRole, const QString &xPosRole, + const QString &yPosRole, const QString &valueRole); +signals: + void mappingChanged(); + +private: + QScopedPointer<QItemModelMapDataMappingPrivate> d_ptr; +}; + + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelmapdatamapping_p.h b/src/datavis3d/data/qitemmodelmapdatamapping_p.h new file mode 100644 index 00000000..99618942 --- /dev/null +++ b/src/datavis3d/data/qitemmodelmapdatamapping_p.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#include "qitemmodelmapdatamapping.h" + +#ifndef QITEMMODELMAPDATAMAPPING_P_H +#define QITEMMODELMAPDATAMAPPING_P_H + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelMapDataMappingPrivate : public QObject +{ + Q_OBJECT +public: + QItemModelMapDataMappingPrivate(QItemModelMapDataMapping *q); + virtual ~QItemModelMapDataMappingPrivate(); + +private: + QString m_labelRole; + QString m_xPosRole; + QString m_yPosRole; + QString m_valueRole; + + QItemModelMapDataMapping *q_ptr; + + friend class QItemModelMapDataMapping; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelmapdataproxy.cpp b/src/datavis3d/data/qitemmodelmapdataproxy.cpp new file mode 100644 index 00000000..b41384e9 --- /dev/null +++ b/src/datavis3d/data/qitemmodelmapdataproxy.cpp @@ -0,0 +1,275 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qitemmodelmapdataproxy_p.h" +#include <QTimer> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QItemModelMapDataProxy::QItemModelMapDataProxy() : + QMapDataProxy(new QItemModelMapDataProxyPrivate(this)) +{ +} + +QItemModelMapDataProxy::QItemModelMapDataProxy(QAbstractItemModel *itemModel, + QItemModelMapDataMapping *mapping) : + QMapDataProxy(new QItemModelMapDataProxyPrivate(this)) +{ + dptr()->setItemModel(itemModel); + dptr()->setMapping(mapping); +} + +QItemModelMapDataProxy::~QItemModelMapDataProxy() +{ +} + +void QItemModelMapDataProxy::setItemModel(QAbstractItemModel *itemModel) +{ + dptr()->setItemModel(itemModel); +} + +QAbstractItemModel *QItemModelMapDataProxy::itemModel() +{ + return dptr()->m_itemModel.data(); +} + +void QItemModelMapDataProxy::setMapping(QItemModelMapDataMapping *mapping) +{ + dptr()->setMapping(mapping); +} + +QItemModelMapDataMapping *QItemModelMapDataProxy::mapping() +{ + return dptr()->m_mapping.data(); +} + +QItemModelMapDataProxyPrivate *QItemModelMapDataProxy::dptr() +{ + return static_cast<QItemModelMapDataProxyPrivate *>(d_ptr.data()); +} + +// QItemModelMapDataProxyPrivate + +QItemModelMapDataProxyPrivate::QItemModelMapDataProxyPrivate(QItemModelMapDataProxy *q) + : QMapDataProxyPrivate(q), + resolvePending(0) +{ + m_resolveTimer.setSingleShot(true); + QObject::connect(&m_resolveTimer, &QTimer::timeout, this, &QItemModelMapDataProxyPrivate::handlePendingResolve); +} + +QItemModelMapDataProxyPrivate::~QItemModelMapDataProxyPrivate() +{ +} + +void QItemModelMapDataProxyPrivate::setItemModel(QAbstractItemModel *itemModel) +{ + if (!m_itemModel.isNull()) + QObject::disconnect(m_itemModel, 0, this, 0); + + m_itemModel = itemModel; + + if (!m_itemModel.isNull()) { + QObject::connect(m_itemModel, &QAbstractItemModel::columnsInserted, this, &QItemModelMapDataProxyPrivate::handleColumnsInserted); + QObject::connect(m_itemModel, &QAbstractItemModel::columnsMoved, this, &QItemModelMapDataProxyPrivate::handleColumnsMoved); + QObject::connect(m_itemModel, &QAbstractItemModel::columnsRemoved, this, &QItemModelMapDataProxyPrivate::handleColumnsRemoved); + QObject::connect(m_itemModel, &QAbstractItemModel::dataChanged, this, &QItemModelMapDataProxyPrivate::handleDataChanged); + QObject::connect(m_itemModel, &QAbstractItemModel::layoutChanged, this, &QItemModelMapDataProxyPrivate::handleLayoutChanged); + QObject::connect(m_itemModel, &QAbstractItemModel::modelReset, this, &QItemModelMapDataProxyPrivate::handleModelReset); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsInserted, this, &QItemModelMapDataProxyPrivate::handleRowsInserted); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsMoved, this, &QItemModelMapDataProxyPrivate::handleRowsMoved); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsRemoved, this, &QItemModelMapDataProxyPrivate::handleRowsRemoved); + } + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelMapDataProxyPrivate::setMapping(QItemModelMapDataMapping *mapping) +{ + if (!m_mapping.isNull()) + QObject::disconnect(m_mapping.data(), &QItemModelMapDataMapping::mappingChanged, this, &QItemModelMapDataProxyPrivate::handleMappingChanged); + + m_mapping = mapping; + + if (!m_mapping.isNull()) + QObject::connect(m_mapping.data(), &QItemModelMapDataMapping::mappingChanged, this, &QItemModelMapDataProxyPrivate::handleMappingChanged); + + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelMapDataProxyPrivate::handleColumnsInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve new items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destinationParent) + Q_UNUSED(destinationColumn) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleColumnsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Remove old items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) +{ + Q_UNUSED(topLeft) + Q_UNUSED(bottomRight) + Q_UNUSED(roles) + + // Resolve changed items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint) +{ + Q_UNUSED(parents) + Q_UNUSED(hint) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleModelReset() +{ + // Data cleared, reset array + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleRowsInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve new items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destinationParent) + Q_UNUSED(destinationRow) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleRowsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve removed items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelMapDataProxyPrivate::handleMappingChanged() +{ + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelMapDataProxyPrivate::handlePendingResolve() +{ + resolveModel(); +} + +// Resolve entire item model into QMapDataArray. +void QItemModelMapDataProxyPrivate::resolveModel() +{ + if (m_itemModel.isNull() || m_mapping.isNull()) { + qptr()->resetArray(0); + return; + } + + static const int noRoleIndex = -1; + + QHash<int, QByteArray> roleHash = m_itemModel->roleNames(); + const int labelRole = roleHash.key(m_mapping->labelRole().toLatin1(), noRoleIndex); + const int xPosRole = roleHash.key(m_mapping->xPosRole().toLatin1(), noRoleIndex); + const int yPosRole = roleHash.key(m_mapping->yPosRole().toLatin1(), noRoleIndex); + // Default valueRole to display role if no mapping + const int valueRole = roleHash.key(m_mapping->valueRole().toLatin1(), Qt::DisplayRole); + const int columnCount = m_itemModel->columnCount(); + const int rowCount = m_itemModel->rowCount(); + const int totalCount = rowCount * columnCount; + int runningCount = 0; + + // Parse data into newProxyArray + QMapDataArray *newProxyArray = new QMapDataArray(totalCount); + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < columnCount; j++) { + QModelIndex index = m_itemModel->index(i, j); + if (labelRole != noRoleIndex) + (*newProxyArray)[runningCount].setLabel(index.data(labelRole).toString()); + qreal xPos(qreal(0.0)); + qreal yPos(qreal(0.0)); + if (xPosRole != noRoleIndex) + xPos = index.data(xPosRole).toReal(); + if (yPosRole != noRoleIndex) + yPos = index.data(yPosRole).toReal(); + (*newProxyArray)[runningCount].setMapPosition(QPointF(xPos, yPos)); + (*newProxyArray)[runningCount].setValue(index.data(valueRole).toReal()); + runningCount++; + } + } + + qDebug() << __FUNCTION__ << "Total count:" << newProxyArray->size(); + + qptr()->resetArray(newProxyArray); +} + +QItemModelMapDataProxy *QItemModelMapDataProxyPrivate::qptr() +{ + return static_cast<QItemModelMapDataProxy *>(q_ptr); +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qitemmodelmapdataproxy.h b/src/datavis3d/data/qitemmodelmapdataproxy.h new file mode 100644 index 00000000..784ee162 --- /dev/null +++ b/src/datavis3d/data/qitemmodelmapdataproxy.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QITEMMODELMAPDATAPROXY_H +#define QITEMMODELMAPDATAPROXY_H + +#include <QtDataVis3D/qmapdataproxy.h> +#include <QtDataVis3D/qitemmodelmapdatamapping.h> +#include <QAbstractItemModel> +#include <QStringList> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelMapDataProxyPrivate; + +class QT_DATAVIS3D_EXPORT QItemModelMapDataProxy : public QMapDataProxy +{ + Q_OBJECT + +public: + explicit QItemModelMapDataProxy(); + explicit QItemModelMapDataProxy(QAbstractItemModel *itemModel, QItemModelMapDataMapping *mapping); + virtual ~QItemModelMapDataProxy(); + + // Doesn't gain ownership of the model, but does connect to it to listen for data changes. + void setItemModel(QAbstractItemModel *itemModel); + QAbstractItemModel *itemModel(); + + // Map maps role (label, xPos, yPos, value) to role in model + // Doesn't gain ownership of mapping, but does connect to it to listen for mapping changes. + // Modifying mapping that is set to proxy will trigger dataset re-resolving. + void setMapping(QItemModelMapDataMapping *mapping); + QItemModelMapDataMapping *mapping(); + +protected: + QItemModelMapDataProxyPrivate *dptr(); + +private: + Q_DISABLE_COPY(QItemModelMapDataProxy) +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelmapdataproxy_p.h b/src/datavis3d/data/qitemmodelmapdataproxy_p.h new file mode 100644 index 00000000..64b16c7f --- /dev/null +++ b/src/datavis3d/data/qitemmodelmapdataproxy_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QITEMMODELMAPDATAPROXY_P_H +#define QITEMMODELMAPDATAPROXY_P_H + +#include "qitemmodelmapdataproxy.h" +#include "qMapDataProxy_p.h" +#include <QPointer> +#include <QTimer> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelMapDataProxyPrivate : public QMapDataProxyPrivate +{ + Q_OBJECT +public: + QItemModelMapDataProxyPrivate(QItemModelMapDataProxy *q); + virtual ~QItemModelMapDataProxyPrivate(); + + void setItemModel(QAbstractItemModel *itemModel); + void setMapping(QItemModelMapDataMapping *mapping); + +public slots: + void handleColumnsInserted(const QModelIndex &parent, int start, int end); + void handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, int destinationColumn); + void handleColumnsRemoved(const QModelIndex &parent, int start, int end); + void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector<int> &roles = QVector<int> ()); + void handleLayoutChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex> (), + QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint); + void handleModelReset(); + void handleRowsInserted(const QModelIndex &parent, int start, int end); + void handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, int destinationRow); + void handleRowsRemoved(const QModelIndex &parent, int start, int end); + + void handleMappingChanged(); + void handlePendingResolve(); + +private: + void resolveModel(); + QItemModelMapDataProxy *qptr(); + + QPointer<QAbstractItemModel> m_itemModel; // Not owned + QPointer<QItemModelMapDataMapping> m_mapping; // Not owned + bool resolvePending; + QTimer m_resolveTimer; + + friend class QItemModelMapDataProxy; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelscatterdatamapping.cpp b/src/datavis3d/data/qitemmodelscatterdatamapping.cpp new file mode 100644 index 00000000..0b430b79 --- /dev/null +++ b/src/datavis3d/data/qitemmodelscatterdatamapping.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qitemmodelscatterdatamapping_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QItemModelScatterDataMapping::QItemModelScatterDataMapping() + : QObject(0), + d_ptr(new QItemModelScatterDataMappingPrivate(this)) +{ +} + +QItemModelScatterDataMapping::QItemModelScatterDataMapping( + const QItemModelScatterDataMapping &other) + : QObject(0), + d_ptr(new QItemModelScatterDataMappingPrivate(this)) +{ + operator=(other); +} + +QItemModelScatterDataMapping::QItemModelScatterDataMapping(const QString &labelRole, + const QString &xPosRole, + const QString &yPosRole, + const QString &zPosRole, + const QString &valueRole) + : QObject(0), + d_ptr(new QItemModelScatterDataMappingPrivate(this)) +{ + Q_UNUSED(labelRole); + Q_UNUSED(valueRole); + //d_ptr->m_labelRole = labelRole; + d_ptr->m_xPosRole = xPosRole; + d_ptr->m_yPosRole = yPosRole; + d_ptr->m_zPosRole = zPosRole; + //d_ptr->m_valueRole = valueRole; +} + +QItemModelScatterDataMapping::~QItemModelScatterDataMapping() +{ +} + +QItemModelScatterDataMapping &QItemModelScatterDataMapping::operator=( + const QItemModelScatterDataMapping &other) +{ + //d_ptr->m_labelRole = other.d_ptr->m_labelRole; + d_ptr->m_xPosRole = other.d_ptr->m_xPosRole; + d_ptr->m_yPosRole = other.d_ptr->m_yPosRole; + d_ptr->m_zPosRole = other.d_ptr->m_zPosRole; + //d_ptr->m_valueRole = other.d_ptr->m_valueRole; + + return *this; +} + +//void QItemModelScatterDataMapping::setLabelRole(const QString &role) +//{ +// d_ptr->m_labelRole = role; +// emit mappingChanged(); +//} + +//QString QItemModelScatterDataMapping::labelRole() const +//{ +// return d_ptr->m_labelRole; +//} + +void QItemModelScatterDataMapping::setXPosRole(const QString &role) +{ + d_ptr->m_xPosRole = role; + emit mappingChanged(); +} + +QString QItemModelScatterDataMapping::xPosRole() const +{ + return d_ptr->m_xPosRole; +} + +void QItemModelScatterDataMapping::setYPosRole(const QString &role) +{ + d_ptr->m_yPosRole = role; + emit mappingChanged(); +} + +QString QItemModelScatterDataMapping::yPosRole() const +{ + return d_ptr->m_yPosRole; +} + +void QItemModelScatterDataMapping::setZPosRole(const QString &role) +{ + d_ptr->m_zPosRole = role; + emit mappingChanged(); +} + +QString QItemModelScatterDataMapping::zPosRole() const +{ + return d_ptr->m_zPosRole; +} + +//void QItemModelScatterDataMapping::setValueRole(const QString &role) +//{ +// d_ptr->m_valueRole = role; +// emit mappingChanged(); +//} + +//QString QItemModelScatterDataMapping::valueRole() const +//{ +// return d_ptr->m_valueRole; +//} + +void QItemModelScatterDataMapping::remap(const QString &labelRole, const QString &xPosRole, + const QString &yPosRole, const QString &zPosRole, + const QString &valueRole) +{ + Q_UNUSED(labelRole); + Q_UNUSED(valueRole); + //d_ptr->m_labelRole = labelRole; + d_ptr->m_xPosRole = xPosRole; + d_ptr->m_yPosRole = yPosRole; + d_ptr->m_zPosRole = zPosRole; + //d_ptr->m_valueRole = valueRole; + + emit mappingChanged(); +} + +// QItemModelScatterDataMappingPrivate + +QItemModelScatterDataMappingPrivate::QItemModelScatterDataMappingPrivate( + QItemModelScatterDataMapping *q) + : QObject(0), + q_ptr(q) +{ +} + +QItemModelScatterDataMappingPrivate::~QItemModelScatterDataMappingPrivate() +{ +} + +QT_DATAVIS3D_END_NAMESPACE + diff --git a/src/datavis3d/data/qitemmodelscatterdatamapping.h b/src/datavis3d/data/qitemmodelscatterdatamapping.h new file mode 100644 index 00000000..f4a2cfe6 --- /dev/null +++ b/src/datavis3d/data/qitemmodelscatterdatamapping.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QITEMMODELSCATTERDATAMAPPING_H +#define QITEMMODELSCATTERDATAMAPPING_H + +#include <QtDataVis3D/qdatavis3denums.h> +#include <QObject> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelScatterDataMappingPrivate; + +class QT_DATAVIS3D_EXPORT QItemModelScatterDataMapping : public QObject +{ + Q_OBJECT + //Q_PROPERTY(QString labelRole READ labelRole WRITE setLabelRole) + Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole) + Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole) + Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole) + //Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole) +public: + explicit QItemModelScatterDataMapping(); + QItemModelScatterDataMapping(const QItemModelScatterDataMapping &other); + QItemModelScatterDataMapping(const QString &labelRole, const QString &xPosRole, + const QString &yPosRole, const QString &zPosRole, + const QString &valueRole); + virtual ~QItemModelScatterDataMapping(); + + QItemModelScatterDataMapping &operator=(const QItemModelScatterDataMapping &other); + + //void setLabelRole(const QString &role); + //QString labelRole() 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 setValueRole(const QString &role); + //QString valueRole() const; + + void remap(const QString &labelRole, const QString &xPosRole, + const QString &yPosRole, const QString &zPosRole, const QString &valueRole); +signals: + void mappingChanged(); + +private: + QScopedPointer<QItemModelScatterDataMappingPrivate> d_ptr; +}; + + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelscatterdatamapping_p.h b/src/datavis3d/data/qitemmodelscatterdatamapping_p.h new file mode 100644 index 00000000..90a826c0 --- /dev/null +++ b/src/datavis3d/data/qitemmodelscatterdatamapping_p.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#include "qitemmodelscatterdatamapping.h" + +#ifndef QITEMMODELSCATTERDATAMAPPING_P_H +#define QITEMMODELSCATTERDATAMAPPING_P_H + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelScatterDataMappingPrivate : public QObject +{ + Q_OBJECT +public: + QItemModelScatterDataMappingPrivate(QItemModelScatterDataMapping *q); + virtual ~QItemModelScatterDataMappingPrivate(); + +private: + //QString m_labelRole; + QString m_xPosRole; + QString m_yPosRole; + QString m_zPosRole; + //QString m_valueRole; + + QItemModelScatterDataMapping *q_ptr; + + friend class QItemModelScatterDataMapping; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelscatterdataproxy.cpp b/src/datavis3d/data/qitemmodelscatterdataproxy.cpp new file mode 100644 index 00000000..c4f4f0a7 --- /dev/null +++ b/src/datavis3d/data/qitemmodelscatterdataproxy.cpp @@ -0,0 +1,305 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qitemmodelscatterdataproxy_p.h" +#include <QTimer> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QItemModelScatterDataProxy::QItemModelScatterDataProxy() : + QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this)) +{ +} + +QItemModelScatterDataProxy::QItemModelScatterDataProxy(QAbstractItemModel *itemModel, + QItemModelScatterDataMapping *mapping) : + QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this)) +{ + dptr()->setItemModel(itemModel); + dptr()->setMapping(mapping); +} + +QItemModelScatterDataProxy::~QItemModelScatterDataProxy() +{ +} + +void QItemModelScatterDataProxy::setItemModel(QAbstractItemModel *itemModel) +{ + dptr()->setItemModel(itemModel); +} + +QAbstractItemModel *QItemModelScatterDataProxy::itemModel() +{ + return dptr()->m_itemModel.data(); +} + +void QItemModelScatterDataProxy::setMapping(QItemModelScatterDataMapping *mapping) +{ + dptr()->setMapping(mapping); +} + +QItemModelScatterDataMapping *QItemModelScatterDataProxy::mapping() +{ + return dptr()->m_mapping.data(); +} + +QItemModelScatterDataProxyPrivate *QItemModelScatterDataProxy::dptr() +{ + return static_cast<QItemModelScatterDataProxyPrivate *>(d_ptr.data()); +} + +// QItemModelScatterDataProxyPrivate + +QItemModelScatterDataProxyPrivate::QItemModelScatterDataProxyPrivate(QItemModelScatterDataProxy *q) + : QScatterDataProxyPrivate(q), + resolvePending(0) +{ + m_resolveTimer.setSingleShot(true); + QObject::connect(&m_resolveTimer, &QTimer::timeout, this, + &QItemModelScatterDataProxyPrivate::handlePendingResolve); +} + +QItemModelScatterDataProxyPrivate::~QItemModelScatterDataProxyPrivate() +{ +} + +void QItemModelScatterDataProxyPrivate::setItemModel(QAbstractItemModel *itemModel) +{ + if (!m_itemModel.isNull()) + QObject::disconnect(m_itemModel, 0, this, 0); + + m_itemModel = itemModel; + + if (!m_itemModel.isNull()) { + QObject::connect(m_itemModel, &QAbstractItemModel::columnsInserted, this, + &QItemModelScatterDataProxyPrivate::handleColumnsInserted); + QObject::connect(m_itemModel, &QAbstractItemModel::columnsMoved, this, + &QItemModelScatterDataProxyPrivate::handleColumnsMoved); + QObject::connect(m_itemModel, &QAbstractItemModel::columnsRemoved, this, + &QItemModelScatterDataProxyPrivate::handleColumnsRemoved); + QObject::connect(m_itemModel, &QAbstractItemModel::dataChanged, this, + &QItemModelScatterDataProxyPrivate::handleDataChanged); + QObject::connect(m_itemModel, &QAbstractItemModel::layoutChanged, this, + &QItemModelScatterDataProxyPrivate::handleLayoutChanged); + QObject::connect(m_itemModel, &QAbstractItemModel::modelReset, this, + &QItemModelScatterDataProxyPrivate::handleModelReset); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsInserted, this, + &QItemModelScatterDataProxyPrivate::handleRowsInserted); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsMoved, this, + &QItemModelScatterDataProxyPrivate::handleRowsMoved); + QObject::connect(m_itemModel, &QAbstractItemModel::rowsRemoved, this, + &QItemModelScatterDataProxyPrivate::handleRowsRemoved); + } + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelScatterDataProxyPrivate::setMapping(QItemModelScatterDataMapping *mapping) +{ + if (!m_mapping.isNull()) + QObject::disconnect(m_mapping.data(), &QItemModelScatterDataMapping::mappingChanged, this, + &QItemModelScatterDataProxyPrivate::handleMappingChanged); + + m_mapping = mapping; + + if (!m_mapping.isNull()) + QObject::connect(m_mapping.data(), &QItemModelScatterDataMapping::mappingChanged, this, + &QItemModelScatterDataProxyPrivate::handleMappingChanged); + + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelScatterDataProxyPrivate::handleColumnsInserted(const QModelIndex &parent, + int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve new items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleColumnsMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, + int destinationColumn) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destinationParent) + Q_UNUSED(destinationColumn) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleColumnsRemoved(const QModelIndex &parent, + int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Remove old items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleDataChanged(const QModelIndex &topLeft, + const QModelIndex &bottomRight, + const QVector<int> &roles) +{ + Q_UNUSED(topLeft) + Q_UNUSED(bottomRight) + Q_UNUSED(roles) + + // Resolve changed items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleLayoutChanged( + const QList<QPersistentModelIndex> &parents, + QAbstractItemModel::LayoutChangeHint hint) +{ + Q_UNUSED(parents) + Q_UNUSED(hint) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleModelReset() +{ + // Data cleared, reset array + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleRowsInserted(const QModelIndex &parent, + int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve new items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleRowsMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, + int destinationRow) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destinationParent) + Q_UNUSED(destinationRow) + + // Resolve moved items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleRowsRemoved(const QModelIndex &parent, + int start, int end) +{ + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + + // Resolve removed items + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); // TODO Resolving entire model is inefficient +} + +void QItemModelScatterDataProxyPrivate::handleMappingChanged() +{ + if (!m_resolveTimer.isActive()) + m_resolveTimer.start(0); +} + +void QItemModelScatterDataProxyPrivate::handlePendingResolve() +{ + resolveModel(); +} + +// Resolve entire item model into QScatterDataArray. +void QItemModelScatterDataProxyPrivate::resolveModel() +{ + if (m_itemModel.isNull() || m_mapping.isNull()) { + qptr()->resetArray(0); + return; + } + + static const int noRoleIndex = -1; + + QHash<int, QByteArray> roleHash = m_itemModel->roleNames(); + //const int labelRole = roleHash.key(m_mapping->labelRole().toLatin1(), noRoleIndex); + const int xPosRole = roleHash.key(m_mapping->xPosRole().toLatin1(), noRoleIndex); + const int yPosRole = roleHash.key(m_mapping->yPosRole().toLatin1(), noRoleIndex); + const int zPosRole = roleHash.key(m_mapping->zPosRole().toLatin1(), noRoleIndex); + // Default valueRole to display role if no mapping + //const int valueRole = roleHash.key(m_mapping->valueRole().toLatin1(), Qt::DisplayRole); + const int columnCount = m_itemModel->columnCount(); + const int rowCount = m_itemModel->rowCount(); + const int totalCount = rowCount * columnCount; + int runningCount = 0; + + // Parse data into newProxyArray + QScatterDataArray *newProxyArray = new QScatterDataArray(totalCount); + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < columnCount; j++) { + QModelIndex index = m_itemModel->index(i, j); + //if (labelRole != noRoleIndex) + // (*newProxyArray)[runningCount].setLabel(index.data(labelRole).toString()); + float xPos(0.0f); + float yPos(0.0f); + float zPos(0.0f); + if (xPosRole != noRoleIndex) + xPos = index.data(xPosRole).toFloat(); + if (yPosRole != noRoleIndex) + yPos = index.data(yPosRole).toFloat(); + if (zPosRole != noRoleIndex) + zPos = index.data(zPosRole).toFloat(); + (*newProxyArray)[runningCount].setPosition(QVector3D(xPos, yPos, zPos)); + //(*newProxyArray)[runningCount].setValue(index.data(valueRole).toReal()); + runningCount++; + } + } + + qDebug() << __FUNCTION__ << "Total count:" << newProxyArray->size(); + + qptr()->resetArray(newProxyArray); +} + +QItemModelScatterDataProxy *QItemModelScatterDataProxyPrivate::qptr() +{ + return static_cast<QItemModelScatterDataProxy *>(q_ptr); +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qitemmodelscatterdataproxy.h b/src/datavis3d/data/qitemmodelscatterdataproxy.h new file mode 100644 index 00000000..f609e84b --- /dev/null +++ b/src/datavis3d/data/qitemmodelscatterdataproxy.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QITEMMODELSCATTERDATAPROXY_H +#define QITEMMODELSCATTERDATAPROXY_H + +#include <QtDataVis3D/qscatterdataproxy.h> +#include <QtDataVis3D/qitemmodelscatterdatamapping.h> +#include <QAbstractItemModel> +#include <QStringList> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelScatterDataProxyPrivate; + +class QT_DATAVIS3D_EXPORT QItemModelScatterDataProxy : public QScatterDataProxy +{ + Q_OBJECT + +public: + explicit QItemModelScatterDataProxy(); + explicit QItemModelScatterDataProxy(QAbstractItemModel *itemModel, + QItemModelScatterDataMapping *mapping); + virtual ~QItemModelScatterDataProxy(); + + // Doesn't gain ownership of the model, but does connect to it to listen for data changes. + void setItemModel(QAbstractItemModel *itemModel); + QAbstractItemModel *itemModel(); + + // Map scatter role (xPos, yPos, zPos) to role in model + // Doesn't gain ownership of mapping, but does connect to it to listen for mapping changes. + // Modifying mapping that is set to proxy will trigger dataset re-resolving. + void setMapping(QItemModelScatterDataMapping *mapping); + QItemModelScatterDataMapping *mapping(); + +protected: + QItemModelScatterDataProxyPrivate *dptr(); + +private: + Q_DISABLE_COPY(QItemModelScatterDataProxy) +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qitemmodelscatterdataproxy_p.h b/src/datavis3d/data/qitemmodelscatterdataproxy_p.h new file mode 100644 index 00000000..aed3d974 --- /dev/null +++ b/src/datavis3d/data/qitemmodelscatterdataproxy_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QITEMMODELSCATTERDATAPROXY_P_H +#define QITEMMODELSCATTERDATAPROXY_P_H + +#include "qitemmodelscatterdataproxy.h" +#include "qscatterdataproxy_p.h" +#include <QPointer> +#include <QTimer> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QItemModelScatterDataProxyPrivate : public QScatterDataProxyPrivate +{ + Q_OBJECT +public: + QItemModelScatterDataProxyPrivate(QItemModelScatterDataProxy *q); + virtual ~QItemModelScatterDataProxyPrivate(); + + void setItemModel(QAbstractItemModel *itemModel); + void setMapping(QItemModelScatterDataMapping *mapping); + +public slots: + void handleColumnsInserted(const QModelIndex &parent, int start, int end); + void handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, int destinationColumn); + void handleColumnsRemoved(const QModelIndex &parent, int start, int end); + void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector<int> &roles = QVector<int> ()); + void handleLayoutChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex> (), + QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint); + void handleModelReset(); + void handleRowsInserted(const QModelIndex &parent, int start, int end); + void handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, int destinationRow); + void handleRowsRemoved(const QModelIndex &parent, int start, int end); + + void handleMappingChanged(); + void handlePendingResolve(); + +private: + void resolveModel(); + QItemModelScatterDataProxy *qptr(); + + QPointer<QAbstractItemModel> m_itemModel; // Not owned + QPointer<QItemModelScatterDataMapping> m_mapping; // Not owned + bool resolvePending; + QTimer m_resolveTimer; + + friend class QItemModelScatterDataProxy; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qmapdataitem.cpp b/src/datavis3d/data/qmapdataitem.cpp new file mode 100644 index 00000000..2fe9b6e8 --- /dev/null +++ b/src/datavis3d/data/qmapdataitem.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qmapdataitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +/*! + * \class QMapDataItem + * \inmodule QtDataVis3D + * \brief The QMapDataItem class provides a container for resolved data to be added to maps graphs. + * \since 1.0.0 + * + * A QMapDataItem holds data for a single rendered bar in a maps graph. + * Maps data proxies parse data into QMapDataItem instances for visualizing. + * + * \sa QMapDataProxy, {Qt Data Visualization 3D C++ Classes} + */ + +/*! + * Constructs QMapDataItem. + */ +QMapDataItem::QMapDataItem() + : QBarDataItem() +{ +} + +QMapDataItem::QMapDataItem(const QMapDataItem &other) + : QBarDataItem(other) +{ + operator=(other); +} + +/*! + * Destroys QMapDataItem. + */ +QMapDataItem::~QMapDataItem() +{ +} + +QMapDataItem &QMapDataItem::operator=(const QMapDataItem &other) +{ + QBarDataItem::operator =(other); + m_mapPosition = other.m_mapPosition; + m_label = other.m_label; + + return *this; +} + +void QMapDataItem::setMapPosition(const QPointF &position) +{ + m_mapPosition = position; +} + +QPointF QMapDataItem::mapPosition() const +{ + return m_mapPosition; +} + +void QMapDataItem::setLabel(const QString &label) +{ + m_label = label; +} + +QString QMapDataItem::label() const +{ + return m_label; +} + +void QMapDataItem::createExtraData() +{ + if (!d_ptr) + d_ptr = new QMapDataItemPrivate; +} + +QMapDataItemPrivate::QMapDataItemPrivate() + : QBarDataItemPrivate() +{ +} + +QMapDataItemPrivate::~QMapDataItemPrivate() +{ +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qmapdataitem.h b/src/datavis3d/data/qmapdataitem.h new file mode 100644 index 00000000..240b03dd --- /dev/null +++ b/src/datavis3d/data/qmapdataitem.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QMAPDATAITEM_H +#define QMAPDATAITEM_H + +#include <QtDataVis3D/qdatavis3denums.h> +#include <QtDataVis3D/qbardataitem.h> +#include <QPointF> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QMapDataItemPrivate; + +class QT_DATAVIS3D_EXPORT QMapDataItem : public QBarDataItem +{ +public: + QMapDataItem(); + QMapDataItem(const QMapDataItem &other); + ~QMapDataItem(); + + QMapDataItem &operator=(const QMapDataItem &other); + + void setMapPosition(const QPointF &position); + QPointF mapPosition() const; + + void setLabel(const QString &label); + QString label() const; + +protected: + virtual void createExtraData(); + + QMapDataItemPrivate *d_ptr; + +private: + QPointF m_mapPosition; + QString m_label; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qmapdataitem_p.h b/src/datavis3d/data/qmapdataitem_p.h new file mode 100644 index 00000000..2926e3ef --- /dev/null +++ b/src/datavis3d/data/qmapdataitem_p.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QMAPDATAITEM_P_H +#define QMAPDATAITEM_P_H + +#include "datavis3dglobal_p.h" +#include "qmapdataitem.h" +#include "qbardataitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QMapDataItemPrivate : public QBarDataItemPrivate +{ +public: + QMapDataItemPrivate(); + virtual ~QMapDataItemPrivate(); + + // TODO stores other data for map items besides position + +protected: + friend class QMapDataItem; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qmapdataproxy.cpp b/src/datavis3d/data/qmapdataproxy.cpp new file mode 100644 index 00000000..a7a0e9d5 --- /dev/null +++ b/src/datavis3d/data/qmapdataproxy.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qmapdataproxy.h" +#include "qmapdataproxy_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QMapDataProxy::QMapDataProxy() : + QAbstractDataProxy(new QMapDataProxyPrivate(this)) +{ +} + +QMapDataProxy::QMapDataProxy(QMapDataProxyPrivate *d) : + QAbstractDataProxy(d) +{ +} + +QMapDataProxy::~QMapDataProxy() +{ +} + +void QMapDataProxy::resetArray(QMapDataArray *newArray) +{ + if (dptr()->resetArray(newArray)) + emit arrayReset(); +} + + +int QMapDataProxy::itemCount() const +{ + return dptrc()->m_dataArray.size(); +} + +const QMapDataArray *QMapDataProxy::array() const +{ + return &dptrc()->m_dataArray; +} + +const QMapDataItem *QMapDataProxy::itemAt(int index) const +{ + return &dptrc()->m_dataArray.at(index); +} + +QMapDataProxyPrivate *QMapDataProxy::dptr() +{ + return static_cast<QMapDataProxyPrivate *>(d_ptr.data()); +} + +const QMapDataProxyPrivate *QMapDataProxy::dptrc() const +{ + return static_cast<const QMapDataProxyPrivate *>(d_ptr.data()); +} + +// QBarDataProxyPrivate + +QMapDataProxyPrivate::QMapDataProxyPrivate(QMapDataProxy *q) + : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeMap) +{ +} + +QMapDataProxyPrivate::~QMapDataProxyPrivate() +{ + m_dataArray.clear(); +} + +bool QMapDataProxyPrivate::resetArray(QMapDataArray *newArray) +{ + if (!m_dataArray.size() && (!newArray || !newArray->size())) + return false; + + m_dataArray.clear(); + + if (newArray) { + m_dataArray = *newArray; + delete newArray; + } + + return true; +} + +QPair<GLfloat, GLfloat> QMapDataProxyPrivate::limitValues() +{ + QPair<GLfloat, GLfloat> limits = qMakePair(0.0f, 0.0f); + for (int i = 0; i < m_dataArray.size(); i++) { + const QMapDataItem &item = m_dataArray.at(i); + qreal itemValue = item.value(); + if (limits.second < itemValue) + limits.second = itemValue; + if (limits.first > itemValue) + limits.first = itemValue; + } + return limits; +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qmapdataproxy.h b/src/datavis3d/data/qmapdataproxy.h new file mode 100644 index 00000000..45bb95d5 --- /dev/null +++ b/src/datavis3d/data/qmapdataproxy.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QMAPDATAPROXY_H +#define QMAPDATAPROXY_H + +#include <QtDataVis3D/qabstractdataproxy.h> +#include <QtDataVis3D/qmapdataitem.h> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +typedef QVector<QMapDataItem> QMapDataArray; + +class QMapDataProxyPrivate; + +class QT_DATAVIS3D_EXPORT QMapDataProxy : public QAbstractDataProxy +{ + Q_OBJECT + +public: + explicit QMapDataProxy(); + explicit QMapDataProxy(QMapDataProxyPrivate *d); + virtual ~QMapDataProxy(); + + // QMapDataProxy is also optimized to use cases where the only defining characteristics of an individual + // map item are it's value and position. Modifying other data such as color or mesh of individual bar + // requires allocating additional data object for the bar. + + // Item pointers are guaranteed to be valid only until next call that modifies data. + // Array pointer is guaranteed to be valid for lifetime of proxy. + int itemCount() const; + const QMapDataArray *array() const; + const QMapDataItem *itemAt(int index) const; // Index needs to exist or this crashes + + // TODO Should data manipulation/access methods be protected rather than public to enforce subclassing use of proxy? + // TODO Leaving them public gives user more options. + + // QMapDataProxy takes ownership of all QMapDataArrays and QMapDataItems passed to it. + + // Clears the existing array and sets it data to new array. + void resetArray(QMapDataArray *newArray); + + // TODO void setItem(int index, QMapDataItem *item); + // TODO void setItems(int index, QMapDataArray *items); + + // TODO int addItem(QMapDataItem *item); // returns the index of added item + // TODO int addItems(QMapDataArray *items); // returns the index of added item + + // TODO void insertItem(int index, QMapDataItem *item); + // TODO void insertItems(int index, QMapDataArray *items); + + // TODO void removeItems(int index, int removeCount); + +signals: + void arrayReset(); + void itemsAdded(int startIndex, int count); + void itemsChanged(int startIndex, int count); + void itemsRemoved(int startIndex, int count); // Index may be over current array size if removed from end + void itemsInserted(int startIndex, int count); + +protected: + QMapDataProxyPrivate *dptr(); + const QMapDataProxyPrivate *dptrc() const; + +private: + Q_DISABLE_COPY(QMapDataProxy) + + friend class Maps3DController; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qmapdataproxy_p.h b/src/datavis3d/data/qmapdataproxy_p.h new file mode 100644 index 00000000..bf3d1d2c --- /dev/null +++ b/src/datavis3d/data/qmapdataproxy_p.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QMAPDATAPROXY_P_H +#define QMAPDATAPROXY_P_H + +#include "qmapdataproxy.h" +#include "qabstractdataproxy_p.h" +#include "qmapdataitem.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QMapDataProxyPrivate : public QAbstractDataProxyPrivate +{ + Q_OBJECT +public: + QMapDataProxyPrivate(QMapDataProxy *q); + virtual ~QMapDataProxyPrivate(); + + bool resetArray(QMapDataArray *newArray); + + QPair<GLfloat, GLfloat> limitValues(); + +private: + QMapDataArray m_dataArray; + +private: + friend class QMapDataProxy; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // QBARDATAPROXY_P_H diff --git a/src/datavis3d/data/qscatterdataitem.cpp b/src/datavis3d/data/qscatterdataitem.cpp new file mode 100644 index 00000000..e2580339 --- /dev/null +++ b/src/datavis3d/data/qscatterdataitem.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qscatterdataitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +/*! + * \class QScatterDataItem + * \inmodule QtDataVis3D + * \brief The QScatterDataItem class provides a container for resolved data to be added to scatter + * graphs. + * \since 1.0.0 + * + * A QScatterDataItem holds data for a single rendered item in a scatter graph. + * Scatter data proxies parse data into QScatterDataItem instances for visualizing. + * + * \sa QScatterDataProxy, {Qt Data Visualization 3D C++ Classes} + */ + +/*! + * Constructs QScatterDataItem. + */ +QScatterDataItem::QScatterDataItem() + : d_ptr(0) // private data doesn't exist by default (optimization) + +{ +} + +QScatterDataItem::QScatterDataItem(const QVector3D &position) + : d_ptr(0), + m_position(position) +{ +} + +QScatterDataItem::QScatterDataItem(const QScatterDataItem &other) +{ + operator=(other); +} + +/*! + * Destroys QScatterDataItem. + */ +QScatterDataItem::~QScatterDataItem() +{ +} + +QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other) +{ + m_position = other.m_position; + //m_size = other.m_size; + + if (other.d_ptr) + createExtraData(); + else + d_ptr = 0; + // TODO set extra data + + return *this; +} + +void QScatterDataItem::setPosition(const QVector3D &position) +{ + m_position = position; +} + +const QVector3D &QScatterDataItem::position() const +{ + return m_position; +} + +//void QScatterDataItem::setSize(qreal size) +//{ +// m_size = size; +//} + +//const qreal &QScatterDataItem::size() const +//{ +// return m_size; +//} + +void QScatterDataItem::createExtraData() +{ + if (!d_ptr) + d_ptr = new QScatterDataItemPrivate; +} + +QScatterDataItemPrivate::QScatterDataItemPrivate() +{ +} + +QScatterDataItemPrivate::~QScatterDataItemPrivate() +{ +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qscatterdataitem.h b/src/datavis3d/data/qscatterdataitem.h new file mode 100644 index 00000000..82383ae6 --- /dev/null +++ b/src/datavis3d/data/qscatterdataitem.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QSCATTERDATAITEM_H +#define QSCATTERDATAITEM_H + +#include <QtDataVis3D/qdatavis3denums.h> +#include <QVector3D> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QScatterDataItemPrivate; + +class QT_DATAVIS3D_EXPORT QScatterDataItem +{ +public: + QScatterDataItem(); + QScatterDataItem(const QVector3D &position); + QScatterDataItem(const QScatterDataItem &other); + ~QScatterDataItem(); + + QScatterDataItem &operator=(const QScatterDataItem &other); + + void setPosition(const QVector3D &position); + const QVector3D &position() const; + + //void setSize(qreal size); + //qreal size() const; + +protected: + virtual void createExtraData(); + + QScatterDataItemPrivate *d_ptr; + +private: + QVector3D m_position; + //qreal m_size; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qscatterdataitem_p.h b/src/datavis3d/data/qscatterdataitem_p.h new file mode 100644 index 00000000..3718a185 --- /dev/null +++ b/src/datavis3d/data/qscatterdataitem_p.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QSCATTERDATAITEM_P_H +#define QSCATTERDATAITEM_P_H + +#include "datavis3dglobal_p.h" +#include "qscatterdataitem.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QScatterDataItemPrivate +{ +public: + QScatterDataItemPrivate(); + virtual ~QScatterDataItemPrivate(); + + // TODO stores other data for scatter items besides position + +protected: + friend class QScatterDataItem; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qscatterdataproxy.cpp b/src/datavis3d/data/qscatterdataproxy.cpp new file mode 100644 index 00000000..d2f544ef --- /dev/null +++ b/src/datavis3d/data/qscatterdataproxy.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "qscatterdataproxy.h" +#include "qscatterdataproxy_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +QScatterDataProxy::QScatterDataProxy() : + QAbstractDataProxy(new QScatterDataProxyPrivate(this)) +{ +} + +QScatterDataProxy::QScatterDataProxy(QScatterDataProxyPrivate *d) : + QAbstractDataProxy(d) +{ +} + +QScatterDataProxy::~QScatterDataProxy() +{ +} + +void QScatterDataProxy::resetArray(QScatterDataArray *newArray) +{ + if (dptr()->resetArray(newArray)) + emit arrayReset(); +} + +void QScatterDataProxy::setItem(int index, const QScatterDataItem &item) +{ + dptr()->setItem(index, item); + emit itemsChanged(index, 1); +} + +void QScatterDataProxy::setItems(int index, const QScatterDataArray &items) +{ + dptr()->setItems(index, items); + emit itemsChanged(index, items.size()); +} + +int QScatterDataProxy::addItem(const QScatterDataItem &item) +{ + int addIndex = dptr()->addItem(item); + emit itemsAdded(addIndex, 1); + return addIndex; +} + +int QScatterDataProxy::addItems(const QScatterDataArray &items) +{ + int addIndex = dptr()->addItems(items); + emit itemsAdded(addIndex, items.size()); + return addIndex; +} + +void QScatterDataProxy::insertItem(int index, const QScatterDataItem &item) +{ + dptr()->insertItem(index, item); + emit itemsInserted(index, 1); +} + +void QScatterDataProxy::insertItems(int index, const QScatterDataArray &items) +{ + dptr()->insertItems(index, items); + emit itemsInserted(index, items.size()); +} + +void QScatterDataProxy::removeItems(int index, int removeCount) +{ + dptr()->removeItems(index, removeCount); + emit itemsRemoved(index, removeCount); +} + +int QScatterDataProxy::itemCount() const +{ + return dptrc()->m_dataArray->size(); +} + +const QScatterDataArray *QScatterDataProxy::array() const +{ + return dptrc()->m_dataArray; +} + +const QScatterDataItem *QScatterDataProxy::itemAt(int index) const +{ + return &dptrc()->m_dataArray->at(index); +} + +QScatterDataProxyPrivate *QScatterDataProxy::dptr() +{ + return static_cast<QScatterDataProxyPrivate *>(d_ptr.data()); +} + +const QScatterDataProxyPrivate *QScatterDataProxy::dptrc() const +{ + return static_cast<const QScatterDataProxyPrivate *>(d_ptr.data()); +} + +// QScatterDataProxyPrivate + +QScatterDataProxyPrivate::QScatterDataProxyPrivate(QScatterDataProxy *q) + : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeScatter), + m_dataArray(new QScatterDataArray) +{ +} + +QScatterDataProxyPrivate::~QScatterDataProxyPrivate() +{ + m_dataArray->clear(); + delete m_dataArray; +} + +bool QScatterDataProxyPrivate::resetArray(QScatterDataArray *newArray) +{ + if (!m_dataArray->size() && (!newArray || !newArray->size())) + return false; + + m_dataArray->clear(); + delete m_dataArray; + + if (newArray) + m_dataArray = newArray; + else + m_dataArray = new QScatterDataArray; + + return true; +} + +void QScatterDataProxyPrivate::setItem(int index, const QScatterDataItem &item) +{ + Q_ASSERT(index >= 0 && index < m_dataArray->size()); + (*m_dataArray)[index] = item; +} + +void QScatterDataProxyPrivate::setItems(int index, const QScatterDataArray &items) +{ + Q_ASSERT(index >= 0 && (index + items.size()) <= m_dataArray->size()); + for (int i = 0; i < items.size(); i++) + (*m_dataArray)[index++] = items[i]; +} + +int QScatterDataProxyPrivate::addItem(const QScatterDataItem &item) +{ + int currentSize = m_dataArray->size(); + m_dataArray->append(item); + return currentSize; +} + +int QScatterDataProxyPrivate::addItems(const QScatterDataArray &items) +{ + int currentSize = m_dataArray->size(); + (*m_dataArray) += items; + return currentSize; +} + +void QScatterDataProxyPrivate::insertItem(int index, const QScatterDataItem &item) +{ + Q_ASSERT(index >= 0 && index <= m_dataArray->size()); + m_dataArray->insert(index, item); +} + +void QScatterDataProxyPrivate::insertItems(int index, const QScatterDataArray &items) +{ + Q_ASSERT(index >= 0 && index <= m_dataArray->size()); + for (int i = 0; i < items.size(); i++) + m_dataArray->insert(index++, items.at(i)); +} + +void QScatterDataProxyPrivate::removeItems(int index, int removeCount) +{ + Q_ASSERT(index >= 0); + int maxRemoveCount = m_dataArray->size() - index; + removeCount = qMin(removeCount, maxRemoveCount); + m_dataArray->remove(index, removeCount); +} + +QVector3D QScatterDataProxyPrivate::limitValues() +{ + QVector3D limits; + for (int i = 0; i < m_dataArray->size(); i++) { + const QScatterDataItem &item = m_dataArray->at(i); + float xValue = qAbs(item.position().x()); + if (limits.x() < xValue) + limits.setX(xValue); + float yValue = qAbs(item.position().y()); + if (limits.y() < yValue) + limits.setY(yValue); + float zValue = qAbs(item.position().z()); + if (limits.z() < zValue) + limits.setZ(zValue); + } + //qDebug() << __FUNCTION__ << limits << m_dataArray.size(); + return limits; +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/qscatterdataproxy.h b/src/datavis3d/data/qscatterdataproxy.h new file mode 100644 index 00000000..9e139c00 --- /dev/null +++ b/src/datavis3d/data/qscatterdataproxy.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef QSCATTERDATAPROXY_H +#define QSCATTERDATAPROXY_H + +#include <QtDataVis3D/qabstractdataproxy.h> +#include <QtDataVis3D/qscatterdataitem.h> + +QT_DATAVIS3D_BEGIN_NAMESPACE + +typedef QVector<QScatterDataItem> QScatterDataArray; + +class QScatterDataProxyPrivate; + +class QT_DATAVIS3D_EXPORT QScatterDataProxy : public QAbstractDataProxy +{ + Q_OBJECT + +public: + explicit QScatterDataProxy(); + explicit QScatterDataProxy(QScatterDataProxyPrivate *d); + virtual ~QScatterDataProxy(); + + // QScatterDataProxy is optimized to use cases where the only defining characteristics of an + // individual scatter item are it's position and size. Modifying other data that might be + // added in the future such as color requires allocating additional data object for the bar. + + // Item pointers are guaranteed to be valid only until next call that modifies data. + // Array pointer is guaranteed to be valid for lifetime of proxy. + int itemCount() const; + const QScatterDataArray *array() const; + const QScatterDataItem *itemAt(int index) const; + + // Clears the existing array and takes ownership of the new array. + // Passing null array clears all data. + void resetArray(QScatterDataArray *newArray); + + // Change existing items + void setItem(int index, const QScatterDataItem &item); + void setItems(int index, const QScatterDataArray &items); + + int addItem(const QScatterDataItem &item); // returns the index of added item + int addItems(const QScatterDataArray &items); // returns the index of first added item + + // If index is equal to data array size, item(s) are added to the array. + void insertItem(int index, const QScatterDataItem &item); + void insertItems(int index, const QScatterDataArray &items); + + // Attempting to remove items past the end of the array does nothing. + void removeItems(int index, int removeCount); + +signals: + void arrayReset(); + void itemsAdded(int startIndex, int count); + void itemsChanged(int startIndex, int count); + void itemsRemoved(int startIndex, int count); // Index may be over current array size if removed from end + void itemsInserted(int startIndex, int count); + +protected: + QScatterDataProxyPrivate *dptr(); + const QScatterDataProxyPrivate *dptrc() const; + +private: + Q_DISABLE_COPY(QScatterDataProxy) + + friend class Scatter3DController; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/data/qscatterdataproxy_p.h b/src/datavis3d/data/qscatterdataproxy_p.h new file mode 100644 index 00000000..526845fd --- /dev/null +++ b/src/datavis3d/data/qscatterdataproxy_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QSCATTERDATAPROXY_P_H +#define QSCATTERDATAPROXY_P_H + +#include "qscatterdataproxy.h" +#include "qabstractdataproxy_p.h" +#include "qscatterdataitem.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class QScatterDataProxyPrivate : public QAbstractDataProxyPrivate +{ + Q_OBJECT +public: + QScatterDataProxyPrivate(QScatterDataProxy *q); + virtual ~QScatterDataProxyPrivate(); + + bool resetArray(QScatterDataArray *newArray); + void setItem(int index, const QScatterDataItem &item); + void setItems(int index, const QScatterDataArray &items); + int addItem(const QScatterDataItem &item); + int addItems(const QScatterDataArray &items); + void insertItem(int index, const QScatterDataItem &item); + void insertItems(int index, const QScatterDataArray &items); + void removeItems(int index, int removeCount); + + QVector3D limitValues(); + +private: + QScatterDataArray *m_dataArray; + QString m_itemLabelFormat; + + friend class QScatterDataProxy; +}; + +QT_DATAVIS3D_END_NAMESPACE + +#endif // QBARDATAPROXY_P_H diff --git a/src/datavis3d/data/scatterrenderitem.cpp b/src/datavis3d/data/scatterrenderitem.cpp new file mode 100644 index 00000000..15281c0a --- /dev/null +++ b/src/datavis3d/data/scatterrenderitem.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "scatterrenderitem_p.h" +#include "scatter3drenderer_p.h" +#include "qscatterdataproxy.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +ScatterRenderItem::ScatterRenderItem() + : BarRenderItem() +{ +} + +ScatterRenderItem::~ScatterRenderItem() +{ +} + +void ScatterRenderItem::formatLabel() +{ + // TODO The label format specified in proxy should probably have additional custom formatting + // TODO specifiers in addition to standard printf specifiers for placement of item labels + // TODO and selection data (like row/column in bar selection) + + // Format the string on first access + QString numStr; + numStr.setNum(m_value); + // TODO actually format instead of just prepending the value + m_label.clear(); // Just in case + //m_label.append(m_itemLabel); + //m_label.append(QStringLiteral(" ")); + m_label.append(numStr); + m_label.append(m_renderer->itemLabelFormat()); +} + +QT_DATAVIS3D_END_NAMESPACE diff --git a/src/datavis3d/data/scatterrenderitem_p.h b/src/datavis3d/data/scatterrenderitem_p.h new file mode 100644 index 00000000..47cfeed2 --- /dev/null +++ b/src/datavis3d/data/scatterrenderitem_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVis3D module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the QtDataVis3D API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef SCATTERRENDERITEM_P_H +#define SCATTERRENDERITEM_P_H + +#include "barrenderitem_p.h" + +QT_DATAVIS3D_BEGIN_NAMESPACE + +class Scatter3DRenderer; + +class ScatterRenderItem : public BarRenderItem +{ +public: + ScatterRenderItem(); + virtual ~ScatterRenderItem(); + + inline const QVector3D &position() const { return m_position; } + inline void setPosition(const QVector3D &pos) { m_position = pos; } + + //inline void setSize(qreal size); + //inline qreal size() const { return m_size; } + + // TODO should be in abstract, but currently there is no abstract renderer + // TODO change when maps refactored + inline void setRenderer(Scatter3DRenderer *renderer) { m_renderer = renderer; } + +protected: + virtual void formatLabel(); + + Scatter3DRenderer *m_renderer; + QVector3D m_position; + //qreal m_size; // TODO in case we need a fourth variable that adjusts scatter item size + + friend class QScatterDataItem; +}; + +typedef QVector<ScatterRenderItem> ScatterRenderItemArray; + +QT_DATAVIS3D_END_NAMESPACE + +#endif |