]> sigrok.org Git - pulseview.git/blobdiff - pv/views/trace/logicsignal.cpp
Really fix #1125 (and maybe #1139)
[pulseview.git] / pv / views / trace / logicsignal.cpp
index 9913d6873ddfd28639c36d1348203c1a921f9ddd..10a5bd4ae70bb2c1f95503fc8ec2b52c17d4f0d5 100644 (file)
@@ -46,6 +46,7 @@ using std::max;
 using std::make_pair;
 using std::min;
 using std::none_of;
+using std::out_of_range;
 using std::pair;
 using std::shared_ptr;
 using std::vector;
@@ -101,7 +102,6 @@ LogicSignal::LogicSignal(
        shared_ptr<devices::Device> device,
        shared_ptr<data::SignalBase> base) :
        Signal(session, base),
-       signal_height_(QFontMetrics(QApplication::font()).height() * 2),
        device_(device),
        trigger_none_(nullptr),
        trigger_rising_(nullptr),
@@ -114,6 +114,9 @@ LogicSignal::LogicSignal(
 
        base_->set_colour(SignalColours[base->index() % countof(SignalColours)]);
 
+       GlobalSettings gs;
+       signal_height_ = gs.value(GlobalSettings::Key_View_DefaultLogicHeight).toInt();
+
        /* Populate this channel's trigger setting with whatever we
         * find in the current session trigger, if anything. */
        trigger_match_ = nullptr;
@@ -134,6 +137,25 @@ shared_ptr<pv::data::Logic> LogicSignal::logic_data() const
        return base_->logic_data();
 }
 
+void LogicSignal::save_settings(QSettings &settings) const
+{
+       settings.setValue("trace_height", signal_height_);
+}
+
+void LogicSignal::restore_settings(QSettings &settings)
+{
+       if (settings.contains("trace_height")) {
+               const int old_height = signal_height_;
+               signal_height_ = settings.value("trace_height").toInt();
+
+               if ((signal_height_ != old_height) && owner_) {
+                       // Call order is important, otherwise the lazy event handler won't work
+                       owner_->extents_changed(false, true);
+                       owner_->row_item_appearance_changed(false, true);
+               }
+       }
+}
+
 pair<int, int> LogicSignal::v_extents() const
 {
        const int signal_margin =
@@ -170,13 +192,10 @@ void LogicSignal::paint_mid(QPainter &p, ViewItemPaintParams &pp)
        const float high_offset = y - signal_height_ + 0.5f;
        const float low_offset = y + 0.5f;
 
-       const deque< shared_ptr<pv::data::LogicSegment> > &segments =
-               base_->logic_data()->logic_segments();
-       if (segments.empty())
+       shared_ptr<pv::data::LogicSegment> segment = get_logic_segment_to_paint();
+       if (!segment || (segment->get_sample_count() == 0))
                return;
 
-       const shared_ptr<pv::data::LogicSegment> &segment = segments.front();
-
        double samplerate = segment->samplerate();
 
        // Show sample rate as 1Hz when it is unknown
@@ -185,7 +204,7 @@ void LogicSignal::paint_mid(QPainter &p, ViewItemPaintParams &pp)
 
        const double pixels_offset = pp.pixels_offset();
        const pv::util::Timestamp& start_time = segment->start_time();
-       const int64_t last_sample = segment->get_sample_count() - 1;
+       const int64_t last_sample = (int64_t)segment->get_sample_count() - 1;
        const double samples_per_pixel = samplerate * pp.scale();
        const double pixels_per_sample = 1 / samples_per_pixel;
        const pv::util::Timestamp start = samplerate * (pp.offset() - start_time);
@@ -327,6 +346,31 @@ void LogicSignal::paint_caps(QPainter &p, QLineF *const lines,
        p.drawLines(lines, line - lines);
 }
 
+shared_ptr<pv::data::LogicSegment> LogicSignal::get_logic_segment_to_paint() const
+{
+       shared_ptr<pv::data::LogicSegment> segment;
+
+       const deque< shared_ptr<pv::data::LogicSegment> > &segments =
+               base_->logic_data()->logic_segments();
+
+       if (!segments.empty()) {
+               if (segment_display_mode_ == ShowLastSegmentOnly) {
+                       segment = segments.back();
+               }
+
+       if ((segment_display_mode_ == ShowSingleSegmentOnly) ||
+               (segment_display_mode_ == ShowLastCompleteSegmentOnly)) {
+                       try {
+                               segment = segments.at(current_segment_);
+                       } catch (out_of_range&) {
+                               qDebug() << "Current logic segment out of range for signal" << base_->name() << ":" << current_segment_;
+                       }
+               }
+       }
+
+       return segment;
+}
+
 void LogicSignal::init_trigger_actions(QWidget *parent)
 {
        trigger_none_ = new QAction(*get_icon(":/icons/trigger-none.svg"),
@@ -439,6 +483,16 @@ void LogicSignal::populate_popup_form(QWidget *parent, QFormLayout *form)
 {
        Signal::populate_popup_form(parent, form);
 
+       signal_height_sb_ = new QSpinBox(parent);
+       signal_height_sb_->setRange(5, 1000);
+       signal_height_sb_->setSingleStep(5);
+       signal_height_sb_->setSuffix(tr(" pixels"));
+       signal_height_sb_->setValue(signal_height_);
+       connect(signal_height_sb_, SIGNAL(valueChanged(int)),
+               this, SLOT(on_signal_height_changed(int)));
+       form->addRow(tr("Trace height"), signal_height_sb_);
+
+       // Trigger settings
        const vector<int32_t> trig_types = get_trigger_types();
 
        if (!trig_types.empty()) {
@@ -531,6 +585,17 @@ void LogicSignal::on_trigger()
        modify_trigger();
 }
 
+void LogicSignal::on_signal_height_changed(int height)
+{
+       signal_height_ = height;
+
+       if (owner_) {
+               // Call order is important, otherwise the lazy event handler won't work
+               owner_->extents_changed(false, true);
+               owner_->row_item_appearance_changed(false, true);
+       }
+}
+
 } // namespace trace
 } // namespace views
 } // namespace pv