ソースを参照

Fix ctkSliderWidget assert when changing decimals with Ctrl+'+'

For the test to work, ctkDoubleSpinBox::keyPressEvent had to be written.
The test values come from a real case where ctkSliderWidget asserted.
Other values were not triggering asserts.
Julien Finet 12 年 前
コミット
5f4e49f4e6
共有3 個のファイルを変更した22 個の追加3 個の削除を含む
  1. 8 0
      Libs/Widgets/ctkDoubleSpinBox.cpp
  2. 4 1
      Libs/Widgets/ctkDoubleSpinBox.h
  3. 10 2
      Libs/Widgets/ctkSliderWidget.cpp

+ 8 - 0
Libs/Widgets/ctkDoubleSpinBox.cpp

@@ -1001,6 +1001,14 @@ bool ctkDoubleSpinBox::invertedControls() const
 }
 
 //-----------------------------------------------------------------------------
+void ctkDoubleSpinBox::keyPressEvent(QKeyEvent* event)
+{
+  Q_D(ctkDoubleSpinBox);
+  const bool accept = this->eventFilter(d->SpinBox, event);
+  event->setAccepted(accept);
+}
+
+//-----------------------------------------------------------------------------
 bool ctkDoubleSpinBox::eventFilter(QObject* obj, QEvent* event)
 {
   Q_D(ctkDoubleSpinBox);

+ 4 - 1
Libs/Widgets/ctkDoubleSpinBox.h

@@ -274,7 +274,10 @@ Q_SIGNALS:
 protected:
   ctkDoubleSpinBoxPrivate* const d_ptr;
 
-  bool eventFilter(QObject *obj, QEvent *event);
+  /// Reimplemented to support shortcuts.
+  virtual void keyPressEvent(QKeyEvent* event);
+  /// Reimplemented to support shortcuts on the double spinbox.
+  virtual bool eventFilter(QObject *obj, QEvent *event);
 
 private:
   Q_DECLARE_PRIVATE(ctkDoubleSpinBox);

+ 10 - 2
Libs/Widgets/ctkSliderWidget.cpp

@@ -279,6 +279,8 @@ double ctkSliderWidget::value()const
 {
   Q_D(const ctkSliderWidget);
   Q_ASSERT(d->equal(d->SpinBox->value(), d->Slider->value()));
+  // The slider is the most precise as it does not round the value with the
+  // decimals number.
   return d->Changing ? d->ValueBeforeChange : d->Slider->value();
 }
 
@@ -433,12 +435,18 @@ void ctkSliderWidget::setDecimals(int newDecimals)
   d->SpinBox->setDecimals(newDecimals);
   // The number of decimals can change the range values
   // i.e. 50.55 with 2 decimals -> 51 with 0 decimals
-  // As the SpinBox range change doesn't fire signals, 
+  // As the SpinBox range change doesn't fire signals,
   // we have to do the synchronization manually here
   d->Slider->setRange(d->SpinBox->minimum(), d->SpinBox->maximum());
   Q_ASSERT(d->equal(d->SpinBox->minimum(),d->Slider->minimum()));
-  Q_ASSERT(d->equal(d->SpinBox->value(),d->Slider->value()));
   Q_ASSERT(d->equal(d->SpinBox->maximum(),d->Slider->maximum()));
+  // Last time the value was set on the spinbox, the value might have been
+  // rounded by the previous number of decimals. The slider however never rounds
+  // the value. Now, if the number of decimals is higher, such rounding is lost
+  // precision. The "true" value must be set again to the spinbox to "recover"
+  // the precision.
+  this->setSpinBoxValue(d->Slider->value());
+  Q_ASSERT(d->equal(d->SpinBox->value(),d->Slider->value()));
   d->updateSpinBoxDecimals();
 }