diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-04-28 03:00:26 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-04-28 03:00:26 +0200 |
commit | 8b4ad5a108b53e6964815856b37cf004099ce505 (patch) | |
tree | 095bcb952882ddd26868ce241aa21c2c21dcfc80 | |
parent | 0e37ed7adebe68b65fe6b923617a543f1ebb30cc (diff) | |
parent | 1448df4988763d163b6753f9afddbec7999aedd8 (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Change-Id: Ib7c1f07ccaf6eac51303984b39c21d099ca0706a
-rw-r--r-- | src/charts/legend/qlegend.cpp | 125 | ||||
-rw-r--r-- | src/charts/legend/qlegend_p.h | 5 | ||||
-rw-r--r-- | tests/auto/qpieslice/tst_qpieslice.cpp | 12 |
3 files changed, 106 insertions, 36 deletions
diff --git a/src/charts/legend/qlegend.cpp b/src/charts/legend/qlegend.cpp index 219d790e..dd75db1b 100644 --- a/src/charts/legend/qlegend.cpp +++ b/src/charts/legend/qlegend.cpp @@ -707,70 +707,124 @@ void QLegendPrivate::handleSeriesVisibleChanged() m_layout->invalidate(); } +QObject *QLegendPrivate::relatedObject(const QLegendMarker *l) +{ + return l->d_ptr->relatedObject(); +} + +// Find equivalent QLegendMarker by checking for relatedObject() +static int indexOfEquivalent(const QLegendMarker *needle, + const QList<QLegendMarker *> &hayStack) +{ + const QObject *needleObject = QLegendPrivate::relatedObject(needle); + for (int i = 0, size = hayStack.size(); i < size; ++i) { + if (QLegendPrivate::relatedObject(hayStack.at(i)) == needleObject) + return i; + } + return -1; +} + +// Find QLegendMarker for series +static int indexOfSeries(const QAbstractSeries *series, + const QList<QLegendMarker *> &hayStack) +{ + for (int i = 0, size = hayStack.size(); i < size; ++i) { + if (hayStack.at(i)->series() == series) + return i; + } + return -1; +} + void QLegendPrivate::handleCountChanged() { // Here we handle the changes in marker count. // Can happen for example when pieslice(s) have been added to or removed from pieseries. - QAbstractSeriesPrivate *series = qobject_cast<QAbstractSeriesPrivate *> (sender()); - QList<QLegendMarker *> createdMarkers = series->createLegendMarkers(q_ptr); - - // Find out removed markers and created markers - QList<QLegendMarker *> removedMarkers; - foreach (QLegendMarker *oldMarker, m_markers) { - // we have marker, which is related to sender. - if (oldMarker->series() == series->q_ptr) { - bool found = false; - foreach(QLegendMarker *newMarker, createdMarkers) { - // New marker considered existing if: - // - d_ptr->relatedObject() is same for both markers. - if (newMarker->d_ptr->relatedObject() == oldMarker->d_ptr->relatedObject()) { - // Delete the new marker, since we already have existing marker, that might be connected on user side. - found = true; - createdMarkers.removeOne(newMarker); - delete newMarker; - } - } - if (!found) { - // No related object found for marker, add to removedMarkers list - removedMarkers << oldMarker; + QAbstractSeriesPrivate *seriesP = qobject_cast<QAbstractSeriesPrivate *>(sender()); + QAbstractSeries *series = seriesP->q_ptr; + QList<QLegendMarker *> createdMarkers = seriesP->createLegendMarkers(q_ptr); + QVector<bool> isNew(createdMarkers.size(), true); + + const int pos = indexOfSeries(series, m_markers); + // Remove markers of the series from m_markers and check against the newly + // created ones. + if (pos != -1) { + while (pos < m_markers.size() && m_markers.at(pos)->series() == series) { + QLegendMarker *oldMarker = m_markers.takeAt(pos); + const int newIndex = indexOfEquivalent(oldMarker, createdMarkers); + if (newIndex == -1) { + removeMarkerHelper(oldMarker); // no longer exists + } else { + // Replace newly created marker by its equivalent + delete createdMarkers[newIndex]; + createdMarkers[newIndex] = oldMarker; + isNew[newIndex] = false; } } } - removeMarkers(removedMarkers); - decorateMarkers(createdMarkers); - addMarkers(createdMarkers); + for (int i = 0, size = createdMarkers.size(); i < size; ++i) { + if (isNew.at(i)) { + insertMarkerHelper(createdMarkers.at(i)); + decorateMarker(createdMarkers.at(i)); + } + } + + // Re-insert createdMarkers into m_markers in correct order. + if (pos != -1 || pos == m_markers.size()) { + m_markers.append(createdMarkers); + } else { + for (int c = createdMarkers.size() - 1; c >= 0; --c) + m_markers.insert(pos, createdMarkers.at(c)); + } q_ptr->layout()->invalidate(); } +// Helper function for marker insertion except m_markers handling +void QLegendPrivate::insertMarkerHelper(QLegendMarker *marker) +{ + LegendMarkerItem *item = marker->d_ptr->item(); + m_items->addToGroup(item); + m_markerHash.insert(item, marker); +} + void QLegendPrivate::addMarkers(QList<QLegendMarker *> markers) { foreach (QLegendMarker *marker, markers) { - m_items->addToGroup(marker->d_ptr.data()->item()); + insertMarkerHelper(marker); m_markers << marker; - m_markerHash.insert(marker->d_ptr->item(), marker); } } +// Helper function for marker removal except m_markers handling +void QLegendPrivate::removeMarkerHelper(QLegendMarker *marker) +{ + LegendMarkerItem *item = marker->d_ptr->item(); + item->setVisible(false); + m_items->removeFromGroup(item); + m_markerHash.remove(item); + delete marker; +} + void QLegendPrivate::removeMarkers(QList<QLegendMarker *> markers) { foreach (QLegendMarker *marker, markers) { - marker->d_ptr->item()->setVisible(false); - m_items->removeFromGroup(marker->d_ptr->item()); m_markers.removeOne(marker); - m_markerHash.remove(marker->d_ptr->item()); - delete marker; + removeMarkerHelper(marker); } } +void QLegendPrivate::decorateMarker(QLegendMarker *marker) +{ + marker->setFont(m_font); + marker->setLabelBrush(m_labelBrush); +} + void QLegendPrivate::decorateMarkers(QList<QLegendMarker *> markers) { - foreach (QLegendMarker *marker, markers) { - marker->setFont(m_font); - marker->setLabelBrush(m_labelBrush); - } + for (QLegendMarker *marker : markers) + decorateMarker(marker); } void QLegendPrivate::updateToolTips() @@ -786,3 +840,4 @@ void QLegendPrivate::updateToolTips() #include "moc_qlegend_p.cpp" QT_CHARTS_END_NAMESPACE + diff --git a/src/charts/legend/qlegend_p.h b/src/charts/legend/qlegend_p.h index 0f69004c..3ffff23d 100644 --- a/src/charts/legend/qlegend_p.h +++ b/src/charts/legend/qlegend_p.h @@ -66,6 +66,8 @@ public: QList<QLegendMarker*> markers(QAbstractSeries *series = 0); qreal maxMarkerWidth() const; + static QObject *relatedObject(const QLegendMarker *l); + public Q_SLOTS: void handleSeriesAdded(QAbstractSeries *series); void handleSeriesRemoved(QAbstractSeries *series); @@ -74,8 +76,11 @@ public Q_SLOTS: private: // Internal helpers + void insertMarkerHelper(QLegendMarker *marker); void addMarkers(QList<QLegendMarker *> markers); + void removeMarkerHelper(QLegendMarker *marker); void removeMarkers(QList<QLegendMarker *> markers); + void decorateMarker(QLegendMarker *marker); void decorateMarkers(QList<QLegendMarker *> markers); void updateToolTips(); diff --git a/tests/auto/qpieslice/tst_qpieslice.cpp b/tests/auto/qpieslice/tst_qpieslice.cpp index 19d838f5..977ed35b 100644 --- a/tests/auto/qpieslice/tst_qpieslice.cpp +++ b/tests/auto/qpieslice/tst_qpieslice.cpp @@ -31,6 +31,8 @@ #include <tst_definitions.h> #include <QtCharts/QChartView> #include <QtCharts/QChart> +#include <QtCharts/QLegend> +#include <QtCharts/QLegendMarker> #include <QtCharts/QPieSlice> #include <QtCharts/QPieSeries> @@ -217,12 +219,20 @@ void tst_qpieslice::customize() QCOMPARE(s1->labelFont(), f1); // insert a slice - series->insert(0, new QPieSlice("slice 5", 5)); + series->insert(0, new QPieSlice("slice 0", 5)); QCOMPARE(s1->pen(), p1); QCOMPARE(s1->brush(), b1); QCOMPARE(s1->labelBrush(), b1); QCOMPARE(s1->labelFont(), f1); + // QTBUG-62082, verify correct insertion at 0. + const QStringList expectedLabels{"slice 0", "slice 1", "slice 3", "slice 4"}; + const auto legendMarkers = view.chart()->legend()->markers(); + const int legendMarkersSize = legendMarkers.size(); + QCOMPARE(legendMarkersSize, expectedLabels.size()); + for (int m = 0; m < legendMarkersSize; ++m) + QCOMPARE(legendMarkers.at(m)->label(), expectedLabels.at(m)); + // change theme // theme will overwrite customizations view.chart()->setTheme(QChart::ChartThemeHighContrast); |