/**************************************************************************** ** ** Copyright (C) 2014 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 QtDataVisualization 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 "surfaceitemmodelhandler_p.h" QT_BEGIN_NAMESPACE_DATAVISUALIZATION SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent) : AbstractItemModelHandler(parent), m_proxy(proxy), m_proxyArray(0) { } SurfaceItemModelHandler::~SurfaceItemModelHandler() { } // Resolve entire item model into QSurfaceDataArray. void SurfaceItemModelHandler::resolveModel() { if (m_itemModel.isNull()) { m_proxy->resetArray(0); m_proxyArray = 0; return; } if (!m_proxy->useModelCategories() && (m_proxy->rowRole().isEmpty() || m_proxy->columnRole().isEmpty())) { m_proxy->resetArray(0); m_proxyArray = 0; return; } QHash roleHash = m_itemModel->roleNames(); // Default to display role if no mapping int valueRole = roleHash.key(m_proxy->valueRole().toLatin1(), Qt::DisplayRole); int rowCount = m_itemModel->rowCount(); int columnCount = m_itemModel->columnCount(); if (m_proxy->useModelCategories()) { // If dimensions have changed, recreate the array if (m_proxyArray != m_proxy->array() || columnCount != m_proxy->columnCount() || rowCount != m_proxyArray->size()) { m_proxyArray = new QSurfaceDataArray; m_proxyArray->reserve(rowCount); for (int i = 0; i < rowCount; i++) m_proxyArray->append(new QSurfaceDataRow(columnCount)); } for (int i = 0; i < rowCount; i++) { QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i); for (int j = 0; j < columnCount; j++) { newProxyRow[j].setPosition( QVector3D(m_itemModel->headerData(j, Qt::Horizontal).toFloat(), m_itemModel->index(i, j).data(valueRole).toFloat(), m_itemModel->headerData(i, Qt::Vertical).toFloat())); } } } else { int rowRole = roleHash.key(m_proxy->rowRole().toLatin1()); int columnRole = roleHash.key(m_proxy->columnRole().toLatin1()); bool generateRows = m_proxy->autoRowCategories(); bool generateColumns = m_proxy->autoColumnCategories(); QStringList rowList; QStringList columnList; // For detecting duplicates in categories generation, using QHashes should be faster than // simple QStringList::contains() check. QHash rowListHash; QHash columnListHash; // Sort values into rows and columns typedef QHash ColumnValueMap; QHash itemValueMap; for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { QModelIndex index = m_itemModel->index(i, j); QString rowRoleStr = index.data(rowRole).toString(); QString columnRoleStr = index.data(columnRole).toString(); itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal(); if (generateRows && !rowListHash.value(rowRoleStr, false)) { rowListHash.insert(rowRoleStr, true); rowList << rowRoleStr; } if (generateColumns && !columnListHash.value(columnRoleStr, false)) { columnListHash.insert(columnRoleStr, true); columnList << columnRoleStr; } } } if (generateRows) m_proxy->dptr()->m_rowCategories = rowList; else rowList = m_proxy->rowCategories(); if (generateColumns) m_proxy->dptr()->m_columnCategories = columnList; else columnList = m_proxy->columnCategories(); // If dimensions have changed, recreate the array if (m_proxyArray != m_proxy->array() || columnList.size() != m_proxy->columnCount() || rowList.size() != m_proxyArray->size()) { m_proxyArray = new QSurfaceDataArray; m_proxyArray->reserve(rowList.size()); for (int i = 0; i < rowList.size(); i++) m_proxyArray->append(new QSurfaceDataRow(columnList.size())); } // Create data array from itemValueMap for (int i = 0; i < rowList.size(); i++) { QString rowKey = rowList.at(i); QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i); for (int j = 0; j < columnList.size(); j++) { newProxyRow[j].setPosition(QVector3D(columnList.at(j).toFloat(), itemValueMap[rowKey][columnList.at(j)], rowList.at(i).toFloat())); } } } m_proxy->resetArray(m_proxyArray); } QT_END_NAMESPACE_DATAVISUALIZATION