From: Soeren Apel Date: Thu, 5 Apr 2018 20:23:28 +0000 (+0200) Subject: Fix #1023 by implementing filtering channel selectors X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=5b35d18ccf2e5a8949d1b4b37d06bf527480e547 Fix #1023 by implementing filtering channel selectors --- diff --git a/pv/data/logicsegment.hpp b/pv/data/logicsegment.hpp index 2e03fd55..88576118 100644 --- a/pv/data/logicsegment.hpp +++ b/pv/data/logicsegment.hpp @@ -58,23 +58,22 @@ class LogicSegment : public Segment { Q_OBJECT -private: - struct MipMapLevel - { - uint64_t length; - uint64_t data_length; - void *data; - }; +public: + typedef pair EdgePair; -private: static const unsigned int ScaleStepCount = 10; static const int MipMapScalePower; static const int MipMapScaleFactor; static const float LogMipMapScaleFactor; static const uint64_t MipMapDataUnit; -public: - typedef pair EdgePair; +private: + struct MipMapLevel + { + uint64_t length; + uint64_t data_length; + void *data; + }; public: LogicSegment(pv::data::Logic& owner, uint32_t segment_id, diff --git a/pv/popups/channels.cpp b/pv/popups/channels.cpp index 10146741..99e6376a 100644 --- a/pv/popups/channels.cpp +++ b/pv/popups/channels.cpp @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -39,6 +41,8 @@ using std::unordered_set; using std::vector; using pv::data::SignalBase; +using pv::data::Logic; +using pv::data::LogicSegment; using sigrok::Channel; using sigrok::ChannelGroup; @@ -53,6 +57,10 @@ Channels::Channels(Session &session, QWidget *parent) : updating_channels_(false), enable_all_channels_(tr("Enable All"), this), disable_all_channels_(tr("Disable All"), this), + enable_all_logic_channels_(tr("Enable only logic"), this), + enable_all_analog_channels_(tr("Enable only analog"), this), + enable_all_named_channels_(tr("Enable only named"), this), + enable_all_changing_channels_(tr("Enable only changing"), this), check_box_mapper_(this) { // Create the layout @@ -102,16 +110,27 @@ Channels::Channels(Session &session, QWidget *parent) : populate_group(nullptr, global_sigs); // Create the enable/disable all buttons - connect(&enable_all_channels_, SIGNAL(clicked()), - this, SLOT(enable_all_channels())); - connect(&disable_all_channels_, SIGNAL(clicked()), - this, SLOT(disable_all_channels())); + connect(&enable_all_channels_, SIGNAL(clicked()), this, SLOT(enable_all_channels())); + connect(&disable_all_channels_, SIGNAL(clicked()), this, SLOT(disable_all_channels())); + connect(&enable_all_logic_channels_, SIGNAL(clicked()), this, SLOT(enable_all_logic_channels())); + connect(&enable_all_analog_channels_, SIGNAL(clicked()), this, SLOT(enable_all_analog_channels())); + connect(&enable_all_named_channels_, SIGNAL(clicked()), this, SLOT(enable_all_named_channels())); + connect(&enable_all_changing_channels_, SIGNAL(clicked()), + this, SLOT(enable_all_changing_channels())); enable_all_channels_.setFlat(true); disable_all_channels_.setFlat(true); + enable_all_logic_channels_.setFlat(true); + enable_all_analog_channels_.setFlat(true); + enable_all_named_channels_.setFlat(true); + enable_all_changing_channels_.setFlat(true); buttons_bar_.addWidget(&enable_all_channels_); buttons_bar_.addWidget(&disable_all_channels_); + buttons_bar_.addWidget(&enable_all_logic_channels_); + buttons_bar_.addWidget(&enable_all_analog_channels_); + buttons_bar_.addWidget(&enable_all_named_channels_); + buttons_bar_.addWidget(&enable_all_changing_channels_); buttons_bar_.addStretch(1); layout_.addRow(&buttons_bar_); @@ -137,6 +156,24 @@ void Channels::set_all_channels(bool set) updating_channels_ = false; } +void Channels::set_all_channels_conditionally( + function)> cond_func) +{ + updating_channels_ = true; + + for (auto entry : check_box_signal_map_) { + QCheckBox *cb = entry.first; + const shared_ptr sig = entry.second; + assert(sig); + + const bool state = cond_func(sig); + sig->set_enabled(state); + cb->setChecked(state); + } + + updating_channels_ = false; +} + void Channels::populate_group(shared_ptr group, const vector< shared_ptr > sigs) { @@ -257,5 +294,52 @@ void Channels::disable_all_channels() set_all_channels(false); } +void Channels::enable_all_logic_channels() +{ + set_all_channels_conditionally([](const shared_ptr signal) + { return signal->type() == SignalBase::LogicChannel; }); +} + +void Channels::enable_all_analog_channels() +{ + set_all_channels_conditionally([](const shared_ptr signal) + { return signal->type() == SignalBase::AnalogChannel; }); +} + +void Channels::enable_all_named_channels() +{ + set_all_channels_conditionally([](const shared_ptr signal) + { return signal->name() != signal->internal_name(); }); +} + +void Channels::enable_all_changing_channels() +{ + set_all_channels_conditionally([](const shared_ptr signal) + { + // Non-logic channels are considered to always have a signal + if (signal->type() != SignalBase::LogicChannel) + return true; + + const shared_ptr logic = signal->logic_data(); + assert(logic); + + // If any of the segments has edges, enable this channel + for (shared_ptr segment : logic->logic_segments()) { + vector edges; + + segment->get_subsampled_edges(edges, + 0, segment->get_sample_count() - 1, + LogicSegment::MipMapScaleFactor, + signal->index()); + + if (edges.size() > 2) + return true; + } + + // No edges detected in any of the segments + return false; + }); +} + } // namespace popups } // namespace pv diff --git a/pv/popups/channels.hpp b/pv/popups/channels.hpp index b23af570..56a7bd1a 100644 --- a/pv/popups/channels.hpp +++ b/pv/popups/channels.hpp @@ -20,6 +20,7 @@ #ifndef PULSEVIEW_PV_POPUPS_CHANNELS_HPP #define PULSEVIEW_PV_POPUPS_CHANNELS_HPP +#include #include #include #include @@ -31,6 +32,7 @@ #include +using std::function; using std::map; using std::shared_ptr; using std::vector; @@ -69,6 +71,8 @@ public: private: void set_all_channels(bool set); + void set_all_channels_conditionally( + function)> cond_func); void populate_group(shared_ptr group, const vector< shared_ptr > sigs); @@ -84,6 +88,10 @@ private Q_SLOTS: void enable_all_channels(); void disable_all_channels(); + void enable_all_logic_channels(); + void enable_all_analog_channels(); + void enable_all_named_channels(); + void enable_all_changing_channels(); private: pv::Session &session_; @@ -98,8 +106,9 @@ private: map< shared_ptr, QLabel*> group_label_map_; QHBoxLayout buttons_bar_; - QPushButton enable_all_channels_; - QPushButton disable_all_channels_; + QPushButton enable_all_channels_, disable_all_channels_; + QPushButton enable_all_logic_channels_, enable_all_analog_channels_; + QPushButton enable_all_named_channels_, enable_all_changing_channels_; QSignalMapper check_box_mapper_; };