aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-04-24 07:51:12 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-04-24 07:29:35 +0000
commit49423c18f5fa7f26b1a02a79055a05b67f322a6a (patch)
tree5c70c213db96403d9109b5398f0734fd2e9b01d0
parent7faafa470eee71c51255e276e7b9df5beed2dd5b (diff)
QQuickRangeSlider: don't crash on press with null handles
The handle visuals should be optional. There were a few missing checks for null pointers. Change-Id: I13e38f373428dbe0c8e338442370fbe7bb02c15a Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r--src/quicktemplates2/qquickrangeslider.cpp20
-rw-r--r--tests/auto/controls/data/tst_rangeslider.qml27
2 files changed, 38 insertions, 9 deletions
diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp
index 99815d36..5b03de88 100644
--- a/src/quicktemplates2/qquickrangeslider.cpp
+++ b/src/quicktemplates2/qquickrangeslider.cpp
@@ -435,16 +435,15 @@ void QQuickRangeSliderPrivate::handlePress(const QPointF &point)
otherNode = first;
} else {
// find the nearest
- const qreal firstDistance = QLineF(firstHandle->boundingRect().center(),
- q->mapToItem(firstHandle, point)).length();
- const qreal secondDistance = QLineF(secondHandle->boundingRect().center(),
- q->mapToItem(secondHandle, point)).length();
+ const qreal firstPos = positionAt(q, firstHandle, point);
+ const qreal secondPos = positionAt(q, secondHandle, point);
+ const qreal firstDistance = qAbs(firstPos - first->position());
+ const qreal secondDistance = qAbs(secondPos - second->position());
if (qFuzzyCompare(firstDistance, secondDistance)) {
// same distance => choose the one that can be moved towards the press position
const bool inverted = from > to;
- const qreal pos = positionAt(q, firstHandle, point);
- if ((!inverted && pos < first->position()) || (inverted && pos > first->position())) {
+ if ((!inverted && firstPos < first->position()) || (inverted && firstPos > first->position())) {
hitNode = first;
otherNode = second;
} else {
@@ -462,11 +461,14 @@ void QQuickRangeSliderPrivate::handlePress(const QPointF &point)
if (hitNode) {
hitNode->setPressed(true);
- hitNode->handle()->setZ(1);
+ if (QQuickItem *handle = hitNode->handle())
+ handle->setZ(1);
QQuickRangeSliderNodePrivate::get(hitNode)->touchId = touchId;
}
- if (otherNode)
- otherNode->handle()->setZ(0);
+ if (otherNode) {
+ if (QQuickItem *handle = otherNode->handle())
+ handle->setZ(0);
+ }
}
void QQuickRangeSliderPrivate::handleMove(const QPointF &point)
diff --git a/tests/auto/controls/data/tst_rangeslider.qml b/tests/auto/controls/data/tst_rangeslider.qml
index 69ec6218..da6e24a1 100644
--- a/tests/auto/controls/data/tst_rangeslider.qml
+++ b/tests/auto/controls/data/tst_rangeslider.qml
@@ -896,4 +896,31 @@ TestCase {
mouseMove(control, node.handle.x - 1, node.handle.y - 1)
compare(node.hovered, false)
}
+
+ function test_nullHandles() {
+ var control = createTemporaryObject(sliderComponent, testCase, {"second.value": 1})
+ verify(control)
+
+ verify(control.first.handle)
+ verify(control.second.handle)
+
+ control.first.handle = null
+ control.second.handle = null
+
+ mousePress(control, control.leftPadding, control.height / 2)
+ verify(control.first.pressed, true)
+ compare(control.second.pressed, false)
+
+ mouseRelease(control, control.leftPadding, control.height / 2)
+ compare(control.first.pressed, false)
+ compare(control.second.pressed, false)
+
+ mousePress(control, control.width - control.rightPadding, control.height / 2)
+ compare(control.first.pressed, false)
+ compare(control.second.pressed, true)
+
+ mouseRelease(control, control.width - control.rightPadding, control.height / 2)
+ compare(control.first.pressed, false)
+ compare(control.second.pressed, false)
+ }
}