diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-04-24 07:51:12 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-04-24 07:29:35 +0000 |
commit | 49423c18f5fa7f26b1a02a79055a05b67f322a6a (patch) | |
tree | 5c70c213db96403d9109b5398f0734fd2e9b01d0 | |
parent | 7faafa470eee71c51255e276e7b9df5beed2dd5b (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.cpp | 20 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_rangeslider.qml | 27 |
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) + } } |