diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-11-26 14:53:50 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2013-11-27 11:29:30 +0200 |
commit | 7c942cc0f497fe7e61ce6a10fce45771c0858e09 (patch) | |
tree | aab5d2285b8e583f3565e305e0818a49503cf95c /src/datavisualization/data/qitemmodelbardataproxy.cpp | |
parent | e029d0ea1d486dd3dbbfa4519a2125da202f22e4 (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.cpp | 374 |
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) { } |