summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data/qitemmodelbardataproxy.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/qitemmodelbardataproxy.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/qitemmodelbardataproxy.cpp')
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.cpp374
1 files changed, 334 insertions, 40 deletions
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp
index a28e05e1..71bb6c75 100644
--- a/src/datavisualization/data/qitemmodelbardataproxy.cpp
+++ b/src/datavisualization/data/qitemmodelbardataproxy.cpp
@@ -29,13 +29,36 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
* \since Qt Data Visualization 1.0
*
* QItemModelBarDataProxy allows you to use QAbstractItemModel derived models as a data source
- * for Q3DBars. It uses QItemModelBarDataMapping instance to map data from the model to Q3DBars
- * graph.
+ * for Q3DBars. It uses the defined mappings to map data from the model to rows, columns, and
+ * values of Q3DBars graph.
*
- * The data is resolved asynchronously whenever the mapping or the model changes.
+ * The data is resolved asynchronously whenever mappings or the model changes.
* QBarDataProxy::arrayReset() is emitted when the data has been resolved.
*
- * \sa QItemModelBarDataMapping, {Qt Data Visualization Data Handling}
+ * There are three ways to use mappings:
+ *
+ * 1) If useModelCategories property is set to true, this proxy will map rows and
+ * columns of QAbstractItemModel directly to rows and columns of Q3DBars, 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 for storing various monthly values
+ * related to a business.
+ * Each item in the model has the roles "year", "month", "income", and "expenses".
+ * You could do the following to display the data in a bar graph:
+ *
+ * \snippet doc_src_qtdatavisualization.cpp 3
+ *
+ * \sa {Qt Data Visualization Data Handling}
*/
/*!
@@ -52,11 +75,13 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
* Data is resolved asynchronously whenever the mapping or the model changes.
* QBarDataProxy::arrayReset() is emitted when the data has been resolved.
*
+ * For more details, see QItemModelBarDataProxy documentation.
+ *
* Usage example:
*
* \snippet doc_src_qmldatavisualization.cpp 7
*
- * \sa BarDataProxy, BarDataMapping, {Qt Data Visualization Data Handling}
+ * \sa BarDataProxy, {Qt Data Visualization Data Handling}
*/
/*!
@@ -65,30 +90,133 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
*/
/*!
- * \qmlproperty list ItemModelBarDataProxy::activeMapping
- * The active mapping. Modifying a mapping that is set to the proxy will trigger data set
- * re-resolving.
+ * \qmlproperty string ItemModelBarDataProxy::rowRole
+ * The row role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string ItemModelBarDataProxy::columnRole
+ * The column role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string ItemModelBarDataProxy::valueRole
+ * The value role of the mapping.
+ */
+
+/*!
+ * \qmlproperty list ItemModelBarDataProxy::rowCategories
+ * The row categories of the mapping. Only items with row roles that are found in this list are
+ * included when the data is resolved. The rows are ordered in the same order as they are in this list.
+ */
+
+/*!
+ * \qmlproperty list ItemModelBarDataProxy::columnCategories
+ * The column categories of the mapping. Only items with column roles that are found in this list are
+ * included when the data is resolved. The columns are ordered in the same order as they are in this list.
+ */
+
+/*!
+ * \qmlproperty list ItemModelBarDataProxy::useModelCategories
+ * When set to true, the mapping ignores row and column roles and categories, and uses
+ * the rows and columns from the model instead. Row and column headers are used for row and column
+ * labels. Defaults to false.
+ */
+
+/*!
+ * \qmlproperty list ItemModelBarDataProxy::autoRowCategories
+ * When set to true, the mapping ignores any explicitly set row categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from the model is resolved. Defaults to true.
+ */
+
+/*!
+ * \qmlproperty list ItemModelBarDataProxy::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.
*/
/*!
- * Constructs QItemModelBarDataProxy.
+ * Constructs QItemModelBarDataProxy with optional \a parent.
*/
-QItemModelBarDataProxy::QItemModelBarDataProxy() :
- QBarDataProxy(new QItemModelBarDataProxyPrivate(this))
+QItemModelBarDataProxy::QItemModelBarDataProxy(QObject *parent)
+ : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
{
+ connectItemModelHandler();
}
/*!
- * Constructs QItemModelBarDataProxy with \a itemModel and \a mapping. Proxy takes ownership of the
- * \a mapping, but doesn't take ownership of the \a itemModel, as typically item models are owned
- * by other controls.
+ * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ */
+QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel, QObject *parent)
+ : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
+{
+ setItemModel(itemModel);
+ connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The 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.
+ */
+QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+ const QString &valueRole, QObject *parent)
+ : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_useModelCategories = true;
+ connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
+ */
+QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole, QObject *parent)
+ : QBarDataProxy(new QItemModelBarDataProxyPrivate(this), parent)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ connectItemModelHandler();
+}
+
+/*!
+ * Constructs QItemModelBarDataProxy with \a itemModel and optional \a parent. Proxy doesn't take
+ * ownership of the \a itemModel, as typically item models are owned by other controls.
+ * The role mappings are set with \a rowRole, \a columnRole, and \a valueRole.
+ * Row and column categories are set with \a rowCategories and \a columnCategories.
+ * This constructor also sets autoRowCategories and autoColumnCategories to false.
*/
QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
- QItemModelBarDataMapping *mapping) :
- QBarDataProxy(new QItemModelBarDataProxyPrivate(this))
+ const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
+ QObject *parent)
+ : QBarDataProxy(new QItemModelBarDataProxyPrivate(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 +243,191 @@ const QAbstractItemModel *QItemModelBarDataProxy::itemModel() const
}
/*!
- * \property QItemModelBarDataProxy::activeMapping
+ * \property QItemModelBarDataProxy::rowRole
+ *
+ * Defines the row role for the mapping.
+ */
+void QItemModelBarDataProxy::setRowRole(const QString &role)
+{
+ if (dptr()->m_rowRole != role) {
+ dptr()->m_rowRole = role;
+ emit rowRoleChanged(role);
+ }
+}
+
+QString QItemModelBarDataProxy::rowRole() const
+{
+ return dptrc()->m_rowRole;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::columnRole
*
- * 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 column role for the mapping.
*/
-void QItemModelBarDataProxy::setActiveMapping(QItemModelBarDataMapping *mapping)
+void QItemModelBarDataProxy::setColumnRole(const QString &role)
{
- dptr()->m_itemModelHandler->setActiveMapping(mapping);
+ if (dptr()->m_columnRole != role) {
+ dptr()->m_columnRole = role;
+ emit columnRoleChanged(role);
+ }
}
-QItemModelBarDataMapping *QItemModelBarDataProxy::activeMapping() const
+QString QItemModelBarDataProxy::columnRole() const
{
- return static_cast<QItemModelBarDataMapping *>(dptrc()->m_itemModelHandler->activeMapping());
+ return dptrc()->m_columnRole;
}
/*!
- * Transfers the ownership of the \a mapping to this proxy. The mapping is not taken to use yet.
- * \sa setActiveMapping(), releaseMapping()
+ * \property QItemModelBarDataProxy::valueRole
+ *
+ * Defines the value role for the mapping.
+ */
+void QItemModelBarDataProxy::setValueRole(const QString &role)
+{
+ if (dptr()->m_valueRole != role) {
+ dptr()->m_valueRole = role;
+ emit valueRoleChanged(role);
+ }
+}
+
+QString QItemModelBarDataProxy::valueRole() const
+{
+ return dptrc()->m_valueRole;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::rowCategories
+ *
+ * Defines the row categories for the mapping.
+ */
+void QItemModelBarDataProxy::setRowCategories(const QStringList &categories)
+{
+ if (dptr()->m_rowCategories != categories) {
+ dptr()->m_rowCategories = categories;
+ emit rowCategoriesChanged(categories);
+ }
+}
+
+QStringList QItemModelBarDataProxy::rowCategories() const
+{
+ return dptrc()->m_rowCategories;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::columnCategories
+ *
+ * Defines the column categories for the mapping.
+ */
+void QItemModelBarDataProxy::setColumnCategories(const QStringList &categories)
+{
+ if (dptr()->m_columnCategories != categories) {
+ dptr()->m_columnCategories = categories;
+ emit columnCategoriesChanged(categories);
+ }
+}
+
+QStringList QItemModelBarDataProxy::columnCategories() const
+{
+ return dptrc()->m_columnCategories;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::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 QItemModelBarDataProxy::addMapping(QItemModelBarDataMapping *mapping)
+void QItemModelBarDataProxy::setUseModelCategories(bool enable)
{
- dptr()->m_itemModelHandler->addMapping(mapping);
+ if (dptr()->m_useModelCategories != enable) {
+ dptr()->m_useModelCategories = enable;
+ emit useModelCategoriesChanged(enable);
+ }
+}
+
+bool QItemModelBarDataProxy::useModelCategories() const
+{
+ return dptrc()->m_useModelCategories;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::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 QItemModelBarDataProxy::setAutoRowCategories(bool enable)
+{
+ if (dptr()->m_autoRowCategories != enable) {
+ dptr()->m_autoRowCategories = enable;
+ emit autoRowCategoriesChanged(enable);
+ }
+}
+
+bool QItemModelBarDataProxy::autoRowCategories() const
+{
+ return dptrc()->m_autoRowCategories;
+}
+
+/*!
+ * \property QItemModelBarDataProxy::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 QItemModelBarDataProxy::setAutoColumnCategories(bool enable)
+{
+ if (dptr()->m_autoColumnCategories != enable) {
+ dptr()->m_autoColumnCategories = enable;
+ emit autoColumnCategoriesChanged(enable);
+ }
+}
+
+bool QItemModelBarDataProxy::autoColumnCategories() const
+{
+ return dptrc()->m_autoColumnCategories;
}
/*!
- * 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.
+ * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the
+ * mapping.
*/
-void QItemModelBarDataProxy::releaseMapping(QItemModelBarDataMapping *mapping)
+void QItemModelBarDataProxy::remap(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
{
- dptr()->m_itemModelHandler->releaseMapping(mapping);
+ setRowRole(rowRole);
+ setColumnRole(columnRole);
+ setValueRole(valueRole);
+ setRowCategories(rowCategories);
+ setColumnCategories(columnCategories);
}
/*!
- * \return list of mappings owned by the proxy.
+ * /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.
*/
-QList<QItemModelBarDataMapping *> QItemModelBarDataProxy::mappings() const
+int QItemModelBarDataProxy::rowCategoryIndex(const QString &category)
{
- QList<QItemModelBarDataMapping *> retList;
- QList<QAbstractDataMapping *> abstractList = dptrc()->m_itemModelHandler->mappings();
- foreach (QAbstractDataMapping *mapping, abstractList)
- retList.append(static_cast<QItemModelBarDataMapping *>(mapping));
+ return dptr()->m_rowCategories.indexOf(category);
+}
- return retList;
+/*!
+ * /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 QItemModelBarDataProxy::columnCategoryIndex(const QString &category)
+{
+ return dptr()->m_columnCategories.indexOf(category);
}
/*!
@@ -177,11 +446,36 @@ const QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptrc() const
return static_cast<const QItemModelBarDataProxyPrivate *>(d_ptr.data());
}
+void QItemModelBarDataProxy::connectItemModelHandler()
+{
+ QObject::connect(dptr()->m_itemModelHandler, &BarItemModelHandler::itemModelChanged,
+ this, &QItemModelBarDataProxy::itemModelChanged);
+ QObject::connect(this, &QItemModelBarDataProxy::rowRoleChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelBarDataProxy::columnRoleChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelBarDataProxy::valueRoleChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelBarDataProxy::rowCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelBarDataProxy::columnCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelBarDataProxy::useModelCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelBarDataProxy::autoRowCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+ QObject::connect(this, &QItemModelBarDataProxy::autoColumnCategoriesChanged,
+ dptr()->m_itemModelHandler, &AbstractItemModelHandler::handleMappingChanged);
+}
+
// QItemModelBarDataProxyPrivate
QItemModelBarDataProxyPrivate::QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q)
: QBarDataProxyPrivate(q),
- m_itemModelHandler(new BarItemModelHandler(q))
+ m_itemModelHandler(new BarItemModelHandler(q)),
+ m_useModelCategories(false),
+ m_autoRowCategories(true),
+ m_autoColumnCategories(true)
{
}