summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-04-28 03:00:26 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-04-28 03:00:26 +0200
commit8b4ad5a108b53e6964815856b37cf004099ce505 (patch)
tree095bcb952882ddd26868ce241aa21c2c21dcfc80
parent0e37ed7adebe68b65fe6b923617a543f1ebb30cc (diff)
parent1448df4988763d163b6753f9afddbec7999aedd8 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
-rw-r--r--src/charts/legend/qlegend.cpp125
-rw-r--r--src/charts/legend/qlegend_p.h5
-rw-r--r--tests/auto/qpieslice/tst_qpieslice.cpp12
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);