summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-11-26 14:53:50 +0200
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-11-27 11:29:30 +0200
commit7c942cc0f497fe7e61ce6a10fce45771c0858e09 (patch)
treeaab5d2285b8e583f3565e305e0818a49503cf95c /src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
parente029d0ea1d486dd3dbbfa4519a2125da202f22e4 (diff)
Integrated item model mappings to item model proxies
Separate mapping object was redundant. Task-number: QTRD-2564 Change-Id: I6b1a23ba52dbb184f46df0fdd64184eeb145c0c3 Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavisualization/data/qitemmodelsurfacedataproxy.cpp')
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.cpp376
1 files changed, 340 insertions, 36 deletions
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
index 75032930..920878d5 100644
--- a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
@@ -31,11 +31,36 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
* \since Qt Data Visualization 1.0
*
* QItemModelSurfaceDataProxy allows you to use QAbstractItemModel derived models as a data source
- * for Q3DSurface. It maps roles defined in QItemModelSurfaceDataMapping to roles in the model.
+ * for Q3DSurface. It uses the defined mappings to map data from the model to rows, columns, and
+ * values of Q3DSurface graph.
*
* Data is resolved asynchronously whenever the mapping or the model changes.
* QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved.
*
+ * There are three ways to use mappings:
+ *
+ * 1) If useModelCategories property is set to true, this proxy will map rows and
+ * columns of QAbstractItemModel to rows and columns of Q3DSurface, and uses the value returned for
+ * Qt::DisplayRole as bar value by default.
+ * The value role to be used can be redefined if Qt::DisplayRole is not suitable.
+ *
+ * 2) For models that do not have data already neatly sorted into rows and columns, such as
+ * QAbstractListModel based models, you can define a role from the model to map for each of row,
+ * column and value.
+ *
+ * 3) If you do not want to include all data contained in the model, or the autogenerated rows and
+ * columns are not ordered as you wish, you can specify which rows and columns should be included
+ * and in which order by defining an explicit list of categories for either or both of rows and
+ * columns.
+ *
+ * For example, assume that you have a custom QAbstractItemModel storing surface topography data.
+ * Each item in the model has the roles "longitude", "latitude", and "height". The item model already
+ * contains the data properly sorted so that longitudes and latitudes are first encountered in
+ * correct order, which enables us to utilize the row and column category autogeneration.
+ * You could do the following to display the data in a surface graph:
+ *
+ * \snippet doc_src_qtdatavisualization.cpp 5
+ *
* \sa {Qt Data Visualization Data Handling}
*/
@@ -53,11 +78,13 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
* Data is resolved asynchronously whenever the mapping or the model changes.
* QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved.
*
+ * For more details, see QItemModelSurfaceDataProxy documentation.
+ *
* Usage example:
*
* \snippet doc_src_qmldatavisualization.cpp 9
*
- * \sa SurfaceDataProxy, SurfaceDataMapping, {Qt Data Visualization Data Handling}
+ * \sa SurfaceDataProxy, {Qt Data Visualization Data Handling}
*/
/*!
@@ -66,29 +93,140 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
*/
/*!
- * \qmlproperty list ItemModelSurfaceDataProxy::activeMapping
- * The active mapping. Modifying a mapping that is set to the proxy will trigger data set
- * re-resolving.
+ * \qmlproperty string ItemModelSurfaceDataProxy::rowRole
+ * The row role of the mapping.
+ * In addition to defining which row the data belongs to, the value indicated by row role
+ * is also set as the Z-coordinate value of the QSurfaceDataItem when model data is resolved.
*/
/*!
- * Constructs QItemModelSurfaceDataProxy.
+ * \qmlproperty string ItemModelSurfaceDataProxy::columnRole
+ * The column role of the mapping.
+ * In addition to defining which column the data belongs to, the value indicated by column role
+ * is also set as the X-coordinate value of the QSurfaceDataItem when model data is resolved.
*/
-QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy() :
- QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this))
+
+/*!
+ * \qmlproperty string ItemModelSurfaceDataProxy::valueRole
+ * The value role of the mapping.
+ * The value indicated by value role is set as Y-coodrinate value of the
+ * QSurfaceDataItem when model data is resolved.
+ */
+
+/*!
+ * \qmlproperty list ItemModelSurfaceDataProxy::rowCategories
+ * The row categories of the mapping. Only items with row roles that are found in this list are
+ * included when data is resolved. The rows are ordered in the same order as they are in this list.
+ */
+
+/*!
+ * \qmlproperty list ItemModelSurfaceDataProxy::columnCategories
+ * The column categories of the mapping. Only items with column roles that are found in this list are
+ * included when data is resolved. The columns are ordered in the same order as they are in this list.
+ */
+
+/*!
+ * \qmlproperty list ItemModelSurfaceDataProxy::useModelCategories
+ * When set to true, the mapping ignores row and column roles and categories, and uses
+ * the rows and columns from the model instead. Defaults to false.
+ */
+
+/*!
+ * \qmlproperty list ItemModelSurfaceDataProxy::autoRowCategories
+ * When set to true, the mapping ignores any explicitly set row categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Proxy minimum and maximum row values are also
+ * autogenerated from data when this is set to true. Defaults to true.
+ */
+
+/*!
+ * \qmlproperty list ItemModelSurfaceDataProxy::autoColumnCategories
+ * When set to true, the mapping ignores any explicitly set column categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Proxy minimum and maximum column values are also
+ * autogenerated from data when this is set to true. Defaults to true.
+ */
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy with optional \a parent.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
{
+ connectItemModelHandler();
}
/*!
- * Constructs QItemModelSurfaceDataProxy with \a itemModel and \a mapping. Does not take ownership
- * of the model or the mapping, but does connect to them to listen for changes.
+ * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel, QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The value role is set to \a valueRole.
+ * This constructor is meant to be used with models that have data properly sorted
+ * in rows and columns already, so it also sets useModelCategories property to true.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+ const QString &valueRole, QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_useModelCategories = true;
+ connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole, QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
+ * Row and column categories are set with \a rowCategories and \a columnCategories.
+ * This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
- QItemModelSurfaceDataMapping *mapping) :
- QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this))
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
+ QObject *parent)
+ : QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this), parent)
{
dptr()->m_itemModelHandler->setItemModel(itemModel);
- dptr()->m_itemModelHandler->setActiveMapping(mapping);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+ dptr()->m_autoRowCategories = false;
+ dptr()->m_autoColumnCategories = false;
+ connectItemModelHandler();
}
/*!
@@ -115,50 +253,191 @@ const QAbstractItemModel *QItemModelSurfaceDataProxy::itemModel() const
}
/*!
- * \property QItemModelSurfaceDataProxy::activeMapping
+ * \property QItemModelSurfaceDataProxy::rowRole
*
- * Defines data mapping. Proxy takes ownership of the \a mapping.
- * Modifying a mapping that is set to the proxy will trigger data set re-resolving.
+ * Defines the row role for the mapping.
*/
-void QItemModelSurfaceDataProxy::setActiveMapping(QItemModelSurfaceDataMapping *mapping)
+void QItemModelSurfaceDataProxy::setRowRole(const QString &role)
{
- dptr()->m_itemModelHandler->setActiveMapping(mapping);
+ if (dptr()->m_rowRole != role) {
+ dptr()->m_rowRole = role;
+ emit rowRoleChanged(role);
+ }
}
-QItemModelSurfaceDataMapping *QItemModelSurfaceDataProxy::activeMapping() const
+QString QItemModelSurfaceDataProxy::rowRole() const
{
- return static_cast<QItemModelSurfaceDataMapping *>(dptrc()->m_itemModelHandler->activeMapping());
+ return dptrc()->m_rowRole;
}
/*!
- * Transfers the ownership of the \a mapping to this proxy. The mapping is not taken to use yet.
- * \sa setActiveMapping(), releaseMapping()
+ * \property QItemModelSurfaceDataProxy::columnRole
+ *
+ * Defines the column role for the mapping.
*/
-void QItemModelSurfaceDataProxy::addMapping(QItemModelSurfaceDataMapping *mapping)
+void QItemModelSurfaceDataProxy::setColumnRole(const QString &role)
+{
+ if (dptr()->m_columnRole != role) {
+ dptr()->m_columnRole = role;
+ emit columnRoleChanged(role);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::columnRole() const
{
- dptr()->m_itemModelHandler->addMapping(mapping);
+ return dptrc()->m_columnRole;
}
/*!
- * Releases the ownership of the \a mapping back to the caller. If the mapping was the currently
- * active one, no mapping remains active after this call.
+ * \property QItemModelSurfaceDataProxy::valueRole
+ *
+ * Defines the value role for the mapping.
*/
-void QItemModelSurfaceDataProxy::releaseMapping(QItemModelSurfaceDataMapping *mapping)
+void QItemModelSurfaceDataProxy::setValueRole(const QString &role)
{
- dptr()->m_itemModelHandler->releaseMapping(mapping);
+ if (dptr()->m_valueRole != role) {
+ dptr()->m_valueRole = role;
+ emit valueRoleChanged(role);
+ }
+}
+
+QString QItemModelSurfaceDataProxy::valueRole() const
+{
+ return dptrc()->m_valueRole;
}
/*!
- * \return list of mappings owned by the proxy.
+ * \property QItemModelSurfaceDataProxy::rowCategories
+ *
+ * Defines the row categories for the mapping.
*/
-QList<QItemModelSurfaceDataMapping *> QItemModelSurfaceDataProxy::mappings() const
+void QItemModelSurfaceDataProxy::setRowCategories(const QStringList &categories)
{
- QList<QItemModelSurfaceDataMapping *> retList;
- QList<QAbstractDataMapping *> abstractList = dptrc()->m_itemModelHandler->mappings();
- foreach (QAbstractDataMapping *mapping, abstractList)
- retList.append(static_cast<QItemModelSurfaceDataMapping *>(mapping));
+ if (dptr()->m_rowCategories != categories) {
+ dptr()->m_rowCategories = categories;
+ emit rowCategoriesChanged(categories);
+ }
+}
+
+QStringList QItemModelSurfaceDataProxy::rowCategories() const
+{
+ return dptrc()->m_rowCategories;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::columnCategories
+ *
+ * Defines the column categories for the mapping.
+ */
+void QItemModelSurfaceDataProxy::setColumnCategories(const QStringList &categories)
+{
+ if (dptr()->m_columnCategories != categories) {
+ dptr()->m_columnCategories = categories;
+ emit columnCategoriesChanged(categories);
+ }
+}
+
+QStringList QItemModelSurfaceDataProxy::columnCategories() const
+{
+ return dptrc()->m_columnCategories;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::useModelCategories
+ *
+ * When set to true, the mapping ignores row and column roles and categories, and uses
+ * the rows and columns from the model instead. Defaults to false.
+ */
+void QItemModelSurfaceDataProxy::setUseModelCategories(bool enable)
+{
+ if (dptr()->m_useModelCategories != enable) {
+ dptr()->m_useModelCategories = enable;
+ emit useModelCategoriesChanged(enable);
+ }
+}
+
+bool QItemModelSurfaceDataProxy::useModelCategories() const
+{
+ return dptrc()->m_useModelCategories;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::autoRowCategories
+ *
+ * When set to true, the mapping ignores any explicitly set row categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Defaults to true.
+ */
+void QItemModelSurfaceDataProxy::setAutoRowCategories(bool enable)
+{
+ if (dptr()->m_autoRowCategories != enable) {
+ dptr()->m_autoRowCategories = enable;
+ emit autoRowCategoriesChanged(enable);
+ }
+}
- return retList;
+bool QItemModelSurfaceDataProxy::autoRowCategories() const
+{
+ return dptrc()->m_autoRowCategories;
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::autoColumnCategories
+ *
+ * When set to true, the mapping ignores any explicitly set column categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Defaults to true.
+ */
+void QItemModelSurfaceDataProxy::setAutoColumnCategories(bool enable)
+{
+ if (dptr()->m_autoColumnCategories != enable) {
+ dptr()->m_autoColumnCategories = enable;
+ emit autoColumnCategoriesChanged(enable);
+ }
+}
+
+bool QItemModelSurfaceDataProxy::autoColumnCategories() const
+{
+ return dptrc()->m_autoColumnCategories;
+}
+
+/*!
+ * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the
+ * mapping.
+ */
+void QItemModelSurfaceDataProxy::remap(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
+{
+ setRowRole(rowRole);
+ setColumnRole(columnRole);
+ setValueRole(valueRole);
+ setRowCategories(rowCategories);
+ setColumnCategories(columnCategories);
+}
+
+/*!
+ * /return index of the specified \a category in row categories list.
+ * If the row categories list is empty, -1 is returned.
+ * \note If the automatic row categories generation is in use, this method will
+ * not return a valid index before the data in the model is resolved for the first time.
+ */
+int QItemModelSurfaceDataProxy::rowCategoryIndex(const QString &category)
+{
+ return dptr()->m_rowCategories.indexOf(category);
+}
+
+/*!
+ * /return index of the specified \a category in column categories list.
+ * If the category is not found, -1 is returned.
+ * \note If the automatic column categories generation is in use, this method will
+ * not return a valid index before the data in the model is resolved for the first time.
+ */
+int QItemModelSurfaceDataProxy::columnCategoryIndex(const QString &category)
+{
+ return dptr()->m_columnCategories.indexOf(category);
}
/*!
@@ -177,11 +456,36 @@ const QItemModelSurfaceDataProxyPrivate *QItemModelSurfaceDataProxy::dptrc() con
return static_cast<const QItemModelSurfaceDataProxyPrivate *>(d_ptr.data());
}
+void QItemModelSurfaceDataProxy::connectItemModelHandler()
+{
+ QObject::connect(dptr()->m_itemModelHandler, &SurfaceItemModelHandler::itemModelChanged,
+ this, &QItemModelSurfaceDataProxy::itemModelChanged);
+ QObject::connect(this, &QItemModelSurfaceDataProxy::rowRoleChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelSurfaceDataProxy::columnRoleChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelSurfaceDataProxy::valueRoleChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelSurfaceDataProxy::rowCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelSurfaceDataProxy::columnCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelSurfaceDataProxy::useModelCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelSurfaceDataProxy::autoRowCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelSurfaceDataProxy::autoColumnCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+}
+
// QItemModelSurfaceDataProxyPrivate
QItemModelSurfaceDataProxyPrivate::QItemModelSurfaceDataProxyPrivate(QItemModelSurfaceDataProxy *q)
: QSurfaceDataProxyPrivate(q),
- m_itemModelHandler(new SurfaceItemModelHandler(q))
+ m_itemModelHandler(new SurfaceItemModelHandler(q)),
+ m_useModelCategories(false),
+ m_autoRowCategories(true),
+ m_autoColumnCategories(true)
{
}