Fix #940 by updating the div spin boxes when needed
authorSoeren Apel <soeren@apelpie.net>
Wed, 24 May 2017 11:44:43 +0000 (13:44 +0200)
committerSoeren Apel <soeren@apelpie.net>
Fri, 26 May 2017 17:36:04 +0000 (19:36 +0200)
Also, prevent the autoranging algo from changing the div
assigment when the user is in the process of changing it.
This way, we only change the div assignment during
acquisition, which is when we actually need this feature.

pv/view/analogsignal.cpp
pv/view/analogsignal.hpp

index 5777628747cd550b8b3624567b3a65407c8fe07f..8f6027b7a52f990135fc54cbe0881b93fc4d1c0a 100644 (file)
@@ -31,7 +31,6 @@
 #include <QFormLayout>
 #include <QGridLayout>
 #include <QLabel>
-#include <QSpinBox>
 #include <QString>
 
 #include "analogsignal.hpp"
@@ -569,7 +568,7 @@ void AnalogSignal::update_conversion_type()
                owner_->row_item_appearance_changed(false, true);
 }
 
-void AnalogSignal::perform_autoranging(bool force_update)
+void AnalogSignal::perform_autoranging(bool keep_divs, bool force_update)
 {
        const deque< shared_ptr<pv::data::AnalogSegment> > &segments =
                base_->analog_data()->analog_segments();
@@ -592,18 +591,31 @@ void AnalogSignal::perform_autoranging(bool force_update)
        prev_min = min;
        prev_max = max;
 
-       // Use all divs for the positive range if there are no negative values
-       if ((min == 0) && (neg_vdivs_ > 0)) {
-               pos_vdivs_ += neg_vdivs_;
-               neg_vdivs_ = 0;
-       }
+       // If we're allowed to alter the div assignment...
+       if (!keep_divs) {
+               // Use all divs for the positive range if there are no negative values
+               if ((min == 0) && (neg_vdivs_ > 0)) {
+                       pos_vdivs_ += neg_vdivs_;
+                       neg_vdivs_ = 0;
+               }
 
-       // Split up the divs if there are negative values but no negative divs
-       if ((min < 0) && (neg_vdivs_ == 0)) {
-               neg_vdivs_ = pos_vdivs_ / 2;
-               pos_vdivs_ -= neg_vdivs_;
+               // Split up the divs if there are negative values but no negative divs
+               if ((min < 0) && (neg_vdivs_ == 0)) {
+                       neg_vdivs_ = pos_vdivs_ / 2;
+                       pos_vdivs_ -= neg_vdivs_;
+               }
        }
 
+       // If there is still no positive div when we need it, add one
+       // (this can happen when pos_vdivs==neg_vdivs==0)
+       if ((max > 0) && (pos_vdivs_ == 0))
+               pos_vdivs_ = 1;
+
+       // If there is still no negative div when we need it, add one
+       // (this can happen when pos_vdivs was 0 or 1 when trying to split)
+       if ((min < 0) && (neg_vdivs_ == 0))
+               neg_vdivs_ = 1;
+
        double min_value_per_div;
        if ((pos_vdivs_ > 0) && (neg_vdivs_ >  0))
                min_value_per_div = std::max(max / pos_vdivs_, -min / neg_vdivs_);
@@ -630,19 +642,19 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form)
        QFormLayout *const layout = new QFormLayout;
 
        // Add the number of vdivs
-       QSpinBox *pvdiv_sb = new QSpinBox(parent);
-       pvdiv_sb->setRange(0, MaximumVDivs);
-       pvdiv_sb->setValue(pos_vdivs_);
-       connect(pvdiv_sb, SIGNAL(valueChanged(int)),
+       pvdiv_sb_ = new QSpinBox(parent);
+       pvdiv_sb_->setRange(0, MaximumVDivs);
+       pvdiv_sb_->setValue(pos_vdivs_);
+       connect(pvdiv_sb_, SIGNAL(valueChanged(int)),
                this, SLOT(on_pos_vdivs_changed(int)));
-       layout->addRow(tr("Number of pos vertical divs"), pvdiv_sb);
+       layout->addRow(tr("Number of pos vertical divs"), pvdiv_sb_);
 
-       QSpinBox *nvdiv_sb = new QSpinBox(parent);
-       nvdiv_sb->setRange(0, MaximumVDivs);
-       nvdiv_sb->setValue(neg_vdivs_);
-       connect(nvdiv_sb, SIGNAL(valueChanged(int)),
+       nvdiv_sb_ = new QSpinBox(parent);
+       nvdiv_sb_->setRange(0, MaximumVDivs);
+       nvdiv_sb_->setValue(neg_vdivs_);
+       connect(nvdiv_sb_, SIGNAL(valueChanged(int)),
                this, SLOT(on_neg_vdivs_changed(int)));
-       layout->addRow(tr("Number of neg vertical divs"), nvdiv_sb);
+       layout->addRow(tr("Number of neg vertical divs"), nvdiv_sb_);
 
        // Add the vertical resolution
        resolution_cb_ = new QComboBox(parent);
@@ -709,7 +721,7 @@ void AnalogSignal::populate_popup_form(QWidget *parent, QFormLayout *form)
 
 void AnalogSignal::on_samples_added()
 {
-       perform_autoranging();
+       perform_autoranging(false, false);
 
        if (owner_) {
                // Call order is important, otherwise the lazy event handler won't work
@@ -720,10 +732,20 @@ void AnalogSignal::on_samples_added()
 
 void AnalogSignal::on_pos_vdivs_changed(int vdivs)
 {
+       if (vdivs == pos_vdivs_)
+               return;
+
        pos_vdivs_ = vdivs;
 
-       if (autoranging_)
-               perform_autoranging(true);
+       if (autoranging_) {
+               perform_autoranging(true, true);
+
+               // It could be that a positive or negative div was added, so update
+               if (pvdiv_sb_) {
+                       pvdiv_sb_->setValue(pos_vdivs_);
+                       nvdiv_sb_->setValue(neg_vdivs_);
+               }
+       }
 
        if (owner_) {
                // Call order is important, otherwise the lazy event handler won't work
@@ -734,10 +756,20 @@ void AnalogSignal::on_pos_vdivs_changed(int vdivs)
 
 void AnalogSignal::on_neg_vdivs_changed(int vdivs)
 {
+       if (vdivs == neg_vdivs_)
+               return;
+
        neg_vdivs_ = vdivs;
 
-       if (autoranging_)
-               perform_autoranging(true);
+       if (autoranging_) {
+               perform_autoranging(true, true);
+
+               // It could be that a positive or negative div was added, so update
+               if (pvdiv_sb_) {
+                       pvdiv_sb_->setValue(pos_vdivs_);
+                       nvdiv_sb_->setValue(neg_vdivs_);
+               }
+       }
 
        if (owner_) {
                // Call order is important, otherwise the lazy event handler won't work
@@ -760,7 +792,7 @@ void AnalogSignal::on_autoranging_changed(int state)
        autoranging_ = (state == Qt::Checked);
 
        if (autoranging_)
-               perform_autoranging(true);
+               perform_autoranging(false, true);
 
        if (owner_) {
                // Call order is important, otherwise the lazy event handler won't work
index eef424d5bafb1f871381476998b2e1c02830d648..109cdd374782a906d34ed558403b8e0a9d00f94b 100644 (file)
@@ -25,6 +25,7 @@
 #include <memory>
 
 #include <QComboBox>
+#include <QSpinBox>
 
 using std::pair;
 using std::shared_ptr;
@@ -145,7 +146,7 @@ private:
 
        void update_conversion_type();
 
-       void perform_autoranging(bool force_update = false);
+       void perform_autoranging(bool keep_divs, bool force_update);
 
 protected:
        void populate_popup_form(QWidget *parent, QFormLayout *form);
@@ -166,6 +167,7 @@ private Q_SLOTS:
 
 private:
        QComboBox *resolution_cb_, *conversion_cb_, *display_type_cb_;
+       QSpinBox *pvdiv_sb_, *nvdiv_sb_;
 
        float scale_;
        int scale_index_;