Kaynağa Gözat

ctkRangeWidget: set a range outside of values crashed

Typical case
range = 0 99
values =  0 99
setRange (-10, -1)
->crash
Julien Finet 14 yıl önce
ebeveyn
işleme
43e4b9059d

+ 2 - 0
Libs/Widgets/Testing/Cpp/CMakeLists.txt

@@ -32,6 +32,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cxx
   ctkMenuButtonTest1.cpp
   ctkRangeSliderTest1.cpp
   ctkRangeWidgetTest1.cpp
+  ctkRangeWidgetTest2.cpp
   ctkDateRangeWidgetTest1.cpp
   ctkSettingsPanelTest1.cpp
   ctkSettingsTest1.cpp
@@ -110,6 +111,7 @@ SIMPLE_TEST( ctkMatrixWidgetTest2 )
 SIMPLE_TEST( ctkMenuButtonTest1 )
 SIMPLE_TEST( ctkRangeSliderTest1 )
 SIMPLE_TEST( ctkRangeWidgetTest1 )
+SIMPLE_TEST( ctkRangeWidgetTest2 )
 SIMPLE_TEST( ctkDateRangeWidgetTest1 )
 SIMPLE_TEST( ctkSettingsPanelTest1 )
 SIMPLE_TEST( ctkSettingsTest1 )

+ 62 - 0
Libs/Widgets/Testing/Cpp/ctkRangeWidgetTest2.cpp

@@ -0,0 +1,62 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QTimer>
+
+// CTK includes
+#include "ctkRangeWidget.h"
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkRangeWidgetTest2(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkRangeWidget sliderSpinBox;
+  sliderSpinBox.setDecimals(2);
+  sliderSpinBox.setRange(0, 99);
+  
+  sliderSpinBox.setValues(1., 10.);
+  sliderSpinBox.setRange(-10., -0.10);
+
+  sliderSpinBox.setMaximum(-11.);
+  
+  sliderSpinBox.setMinimum(101.);
+  
+  sliderSpinBox.setValues(0., 1000.);
+  
+  sliderSpinBox.setRange(-2002, 2002);
+
+  sliderSpinBox.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I" )
+    {
+    QTimer::singleShot(200, &app, SLOT(quit()));
+    }
+
+  return app.exec();
+
+}
+

+ 25 - 13
Libs/Widgets/ctkRangeWidget.cpp

@@ -44,7 +44,7 @@ public:
 
   bool          Tracking;
   bool          Changing;
-  bool          SettingRange;
+  bool          SettingSliderRange;
   double        MinimumValueBeforeChange;
   double        MaximumValueBeforeChange;
   bool          AutoSpinBoxWidth;
@@ -63,7 +63,7 @@ ctkRangeWidgetPrivate::ctkRangeWidgetPrivate(ctkRangeWidget& object)
 {
   this->Tracking = true;
   this->Changing = false;
-  this->SettingRange = false;
+  this->SettingSliderRange = false;
   this->MinimumValueBeforeChange = 0.;
   this->MaximumValueBeforeChange = 0.;
   this->AutoSpinBoxWidth = true;
@@ -236,12 +236,17 @@ double ctkRangeWidget::maximum()const
 void ctkRangeWidget::setMinimum(double min)
 {
   Q_D(ctkRangeWidget);
+  bool blocked = d->MinimumSpinBox->blockSignals(true);
+  blocked = d->MaximumSpinBox->blockSignals(true);
   d->MinimumSpinBox->setMinimum(min);
+  d->MaximumSpinBox->setMinimum(min);
+  d->MinimumSpinBox->blockSignals(blocked);
+  d->MaximumSpinBox->blockSignals(blocked);
   // SpinBox can truncate min (depending on decimals).
   // use Spinbox's min to set Slider's min
-  d->SettingRange = true;
+  d->SettingSliderRange = true;
   d->Slider->setMinimum(d->MinimumSpinBox->minimum());
-  d->SettingRange = false;
+  d->SettingSliderRange = false;
   Q_ASSERT(d->equal(d->MinimumSpinBox->minimum(),d->Slider->minimum()));
   d->updateSpinBoxWidth();
 }
@@ -250,12 +255,17 @@ void ctkRangeWidget::setMinimum(double min)
 void ctkRangeWidget::setMaximum(double max)
 {
   Q_D(ctkRangeWidget);
+  bool blocked = d->MinimumSpinBox->blockSignals(true);
+  blocked = d->MaximumSpinBox->blockSignals(true);
+  d->MinimumSpinBox->setMaximum(max);
   d->MaximumSpinBox->setMaximum(max);
+  d->MinimumSpinBox->blockSignals(blocked);
+  d->MaximumSpinBox->blockSignals(blocked);
   // SpinBox can truncate max (depending on decimals).
   // use Spinbox's max to set Slider's max
-  d->SettingRange = true;
+  d->SettingSliderRange = true;
   d->Slider->setMaximum(d->MaximumSpinBox->maximum());
-  d->SettingRange = false;
+  d->SettingSliderRange = false;
   Q_ASSERT(d->equal(d->MaximumSpinBox->maximum(), d->Slider->maximum()));
   d->updateSpinBoxWidth();
 }
@@ -267,15 +277,17 @@ void ctkRangeWidget::setRange(double min, double max)
   
   double oldMin = d->MinimumSpinBox->minimum();
   double oldMax = d->MaximumSpinBox->maximum();
-  d->MinimumSpinBox->setMinimum(qMin(min,max));
-  d->MinimumSpinBox->setMaximum(qMax(min,max));
-  d->MaximumSpinBox->setMinimum(qMin(min,max));
-  d->MaximumSpinBox->setMaximum(qMax(min,max));
+  bool blocked = d->MinimumSpinBox->blockSignals(true);
+  d->MinimumSpinBox->setRange(qMin(min,max), qMax(min,max));
+  d->MinimumSpinBox->blockSignals(blocked);
+  blocked = d->MaximumSpinBox->blockSignals(true);
+  d->MaximumSpinBox->setRange(qMin(min,max), qMax(min,max));
+  d->MaximumSpinBox->blockSignals(blocked);
   // SpinBox can truncate the range (depending on decimals).
   // use Spinbox's range to set Slider's range
-  d->SettingRange = true;
+  d->SettingSliderRange = true;
   d->Slider->setRange(d->MinimumSpinBox->minimum(), d->MaximumSpinBox->maximum());
-  d->SettingRange = false;
+  d->SettingSliderRange = false;
   Q_ASSERT(d->equal(d->MinimumSpinBox->minimum(), d->Slider->minimum()));
   Q_ASSERT(d->equal(d->MaximumSpinBox->maximum(), d->Slider->maximum()));
   d->updateSpinBoxWidth();
@@ -290,7 +302,7 @@ void ctkRangeWidget::setRange(double min, double max)
 void ctkRangeWidget::onSliderRangeChanged(double min, double max)
 {
   Q_D(ctkRangeWidget);
-  if (!d->SettingRange)
+  if (!d->SettingSliderRange)
     {
     this->setRange(min, max);
     }