]> sigrok.org Git - pulseview.git/blobdiff - pv/views/trace/view.cpp
Make sure get_time_extents() uses a signal that data was acquired for
[pulseview.git] / pv / views / trace / view.cpp
index 46bae5d8b27755287fe17a187ded3ea31e79cb59..df58967523e2e692b9b64b60df0a2564f10cc2ad 100644 (file)
@@ -54,6 +54,7 @@
 #include "pv/metadata_obj.hpp"
 #include "pv/data/logic.hpp"
 #include "pv/data/logicsegment.hpp"
+#include "pv/data/signalbase.hpp"
 #include "pv/devices/device.hpp"
 #include "pv/globalsettings.hpp"
 #include "pv/session.hpp"
@@ -63,6 +64,7 @@
 #include "decodetrace.hpp"
 #endif
 
+using pv::data::SignalBase;
 using pv::data::SignalData;
 using pv::data::Segment;
 using pv::util::TimeUnit;
@@ -284,7 +286,7 @@ void View::reset_view_state()
        zero_offset_ = 0;
        custom_zero_offset_set_ = false;
        updating_scroll_ = false;
-       settings_restored_ = false;
+       restoring_state_ = false;
        always_zoom_to_fit_ = false;
        tick_period_ = 0;
        tick_prefix_ = pv::util::SIPrefix::yocto;
@@ -298,10 +300,8 @@ void View::reset_view_state()
        grabbed_widget_ = nullptr;
        hover_point_ = QPoint(-1, -1);
        scroll_needs_defaults_ = true;
-       saved_v_offset_ = 0;
        scale_at_acq_start_ = 0;
        offset_at_acq_start_ = 0;
-       suppress_zoom_to_fit_after_acq_ = false;
 
        show_cursors_ = false;
        cursor_state_changed(show_cursors_);
@@ -312,6 +312,8 @@ void View::reset_view_state()
 
        // Make sure the standard bar's segment selector is in sync
        set_segment_display_mode(segment_display_mode_);
+
+       scrollarea_->verticalScrollBar()->setRange(-100000000, 100000000);
 }
 
 Session& View::session()
@@ -389,6 +391,11 @@ void View::add_signalbase(const shared_ptr<data::SignalBase> signalbase)
 void View::remove_signalbase(const shared_ptr<data::SignalBase> signalbase)
 {
        ViewBase::remove_signalbase(signalbase);
+
+       shared_ptr<Signal> signal = get_signal_by_signalbase(signalbase);
+
+       if (signal)
+               remove_trace(signal);
 }
 
 #ifdef ENABLE_DECODE
@@ -418,14 +425,34 @@ void View::remove_decode_signal(shared_ptr<data::DecodeSignal> signal)
        for (auto i = decode_traces_.begin(); i != decode_traces_.end(); i++)
                if ((*i)->base() == signal) {
                        decode_traces_.erase(i);
-                       signals_changed();
-                       return;
+                       break;
                }
 
        ViewBase::remove_decode_signal(signal);
 }
 #endif
 
+void View::remove_trace(shared_ptr<Trace> trace)
+{
+       TraceTreeItemOwner *const owner = trace->owner();
+       assert(owner);
+       owner->remove_child_item(trace);
+
+       for (auto i = signals_.begin(); i != signals_.end(); i++)
+               if ((*i) == trace) {
+                       signals_.erase(i);
+                       break;
+               }
+
+       if (!header_was_shrunk_)
+               resize_header_to_fit();
+
+       update_layout();
+
+       header_->update();
+       viewport_->update();
+}
+
 shared_ptr<Signal> View::get_signal_under_mouse_cursor() const
 {
        return signal_under_mouse_cursor_;
@@ -514,14 +541,12 @@ void View::restore_settings(QSettings &settings)
        }
 
        if (settings.contains("v_offset")) {
+               // Note: see eventFilter() for additional information
                saved_v_offset_ = settings.value("v_offset").toInt();
-               set_v_offset(saved_v_offset_);
                scroll_needs_defaults_ = false;
-               // Note: see eventFilter() for additional information
        }
 
-       settings_restored_ = true;
-       suppress_zoom_to_fit_after_acq_ = true;
+       restoring_state_ = true;
 
        // Update the ruler so that it uses the new scale
        calculate_tick_spacing();
@@ -861,7 +886,7 @@ void View::set_scale_offset(double scale, const Timestamp& offset)
        // Disable sticky scrolling / always zoom to fit when acquisition runs
        // and user drags the viewport
        if ((scale_ == scale) && (offset_ != offset) &&
-                       (session_.get_capture_state() == Session::Running)) {
+               (session_.get_capture_state() == Session::Running)) {
 
                if (sticky_scrolling_) {
                        sticky_scrolling_ = false;
@@ -903,7 +928,9 @@ pair<Timestamp, Timestamp> View::get_time_extents() const
        if (signals_.size() == 0)
                return make_pair(0, 0);
 
-       data.push_back(signals_.front()->data());
+       for (shared_ptr<Signal> s : signals_)
+               if (s->data()->segments().size() > 0)
+                       data.push_back(s->data());
 
        for (const shared_ptr<SignalData>& d : data) {
                const vector< shared_ptr<Segment> > segments = d->segments();
@@ -1538,7 +1565,7 @@ bool View::eventFilter(QObject *object, QEvent *event)
                // resized to their final sizes.
                update_layout();
 
-               if (settings_restored_)
+               if (restoring_state_)
                        determine_if_header_was_shrunk();
                else
                        resize_header_to_fit();
@@ -1548,10 +1575,8 @@ bool View::eventFilter(QObject *object, QEvent *event)
                        scroll_needs_defaults_ = false;
                }
 
-               if (saved_v_offset_) {
+               if (restoring_state_)
                        set_v_offset(saved_v_offset_);
-                       saved_v_offset_ = 0;
-               }
        }
 
        return QObject::eventFilter(object, event);
@@ -1773,7 +1798,6 @@ void View::signals_changed()
 #ifdef ENABLE_DECODE
        traces.insert(decode_traces_.begin(), decode_traces_.end());
 #endif
-
        set< shared_ptr<Trace> > add_traces;
        set_difference(traces.begin(), traces.end(),
                prev_traces.begin(), prev_traces.end(),
@@ -1887,6 +1911,10 @@ void View::signals_changed()
        // Add and position the pending top levels items
        int offset = v_extents().second;
        for (shared_ptr<TraceTreeItem> item : new_top_level_items) {
+               // items may already have gained an owner when they were added to a group above
+               if (item->owner())
+                       continue;
+
                add_child_item(item);
 
                // Position the item after the last item or at the top if there is none
@@ -1933,13 +1961,14 @@ void View::capture_state_updated(int state)
                // the main view of this session (other trace views may be used for
                // zooming and we don't want to mess them up)
                bool state = settings.value(GlobalSettings::Key_View_ZoomToFitDuringAcq).toBool();
-               if (is_main_view_ && state) {
+               if (is_main_view_ && state && !restoring_state_) {
                        always_zoom_to_fit_ = true;
                        always_zoom_to_fit_changed(always_zoom_to_fit_);
                }
 
                // Enable sticky scrolling if the setting is enabled
-               sticky_scrolling_ = settings.value(GlobalSettings::Key_View_StickyScrolling).toBool();
+               sticky_scrolling_ = !restoring_state_ &&
+                       settings.value(GlobalSettings::Key_View_StickyScrolling).toBool();
 
                // Reset all traces to segment 0
                current_segment_ = 0;
@@ -1965,12 +1994,13 @@ void View::capture_state_updated(int state)
                // Only perform zoom-to-fit if the user hasn't altered the viewport and
                // we didn't restore settings in the meanwhile
                if (zoom_to_fit_after_acq &&
-                       !suppress_zoom_to_fit_after_acq_ &&
+                       !restoring_state_ &&
                        (scale_ == scale_at_acq_start_) &&
-                       (offset_ == offset_at_acq_start_))
+                       (sticky_scrolling_ || (offset_ == offset_at_acq_start_))) {
                        zoom_fit(false);  // We're stopped, so the GUI state doesn't matter
+               }
 
-               suppress_zoom_to_fit_after_acq_ = false;
+               restoring_state_ = false;
        }
 }