From eb852ca7e5800577762663bc72b1f9d009cf7e51 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 8 Nov 2018 10:28:52 +0100 Subject: Fix access to bar sets instantiated inside the module The QBarModelMapper allocates QBarSet instances during initialization. While this works for pure C++ applications, on the QML side these need to be of type DeclarativeBarSet to be accessible, but also expose additional properties. The C++ module is not aware of QML, also the QBarModelMapper cannot expose a dynamic allocator without breaking binary compatibility. Hence, the approach is to create a custom allocator function and export it from the C++ module. In case a declarative chart is created, the allocator is replaced with the QML one. Fixes: QTBUG-71013 Change-Id: I1864d637df37f8cd38d28fdba75da0c5608a612c Reviewed-by: hjk Reviewed-by: Maurice Kalinowski --- src/charts/barchart/qbarmodelmapper.cpp | 9 ++++++++- src/chartsqml2/declarativechart.cpp | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/charts/barchart/qbarmodelmapper.cpp b/src/charts/barchart/qbarmodelmapper.cpp index 966d719f..6a7e18d7 100644 --- a/src/charts/barchart/qbarmodelmapper.cpp +++ b/src/charts/barchart/qbarmodelmapper.cpp @@ -540,6 +540,13 @@ void QBarModelMapperPrivate::barValueChanged(int index) initializeBarFromModel(); } +QBarSet *qt_allocate_bar_set_cpp(const QString &label) +{ + return new QBarSet(label); +} + +QT_CHARTS_EXPORT QBarSet *(*qt_allocate_bar_set)(const QString &label) = &qt_allocate_bar_set_cpp; + void QBarModelMapperPrivate::initializeBarFromModel() { if (m_model == 0 || m_series == 0) @@ -556,7 +563,7 @@ void QBarModelMapperPrivate::initializeBarFromModel() QModelIndex barIndex = barModelIndex(i, posInBar); // check if there is such model index if (barIndex.isValid()) { - QBarSet *barSet = new QBarSet(m_model->headerData(i, m_orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical).toString()); + QBarSet *barSet = qt_allocate_bar_set(m_model->headerData(i, m_orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical).toString()); while (barIndex.isValid()) { barSet->append(m_model->data(barIndex, Qt::DisplayRole).toDouble()); posInBar++; diff --git a/src/chartsqml2/declarativechart.cpp b/src/chartsqml2/declarativechart.cpp index 11677667..2437d4d5 100644 --- a/src/chartsqml2/declarativechart.cpp +++ b/src/chartsqml2/declarativechart.cpp @@ -441,6 +441,23 @@ DeclarativeChart::DeclarativeChart(QChart::ChartType type, QQuickItem *parent) initChart(type); } +// QTBUG-71013 +// The symbol resides in qbarmodelmapper.cpp#548 in the C++ module. +// Here, it gets imported and reset to the DeclarativeBarSet allocator +#ifdef Q_OS_WIN +QT_CHARTS_EXPORT +#else +extern +#endif +QBarSet *(*qt_allocate_bar_set)(const QString &label); + +QBarSet *qt_allocate_bar_set_qml(const QString &label) +{ + auto bar = new DeclarativeBarSet(); + bar->setLabel(label); + return bar; +} + void DeclarativeChart::initChart(QChart::ChartType type) { m_sceneImage = 0; @@ -452,6 +469,10 @@ void DeclarativeChart::initChart(QChart::ChartType type) setFlag(ItemHasContents, true); + // Reset allocator for QBarSet to create + // Declarative BarSets by default + qt_allocate_bar_set = &qt_allocate_bar_set_qml; + if (type == QChart::ChartTypePolar) m_chart = new QPolarChart(); else -- cgit v1.2.3