]> sigrok.org Git - pulseview.git/commitdiff
Fix #1023 by implementing filtering channel selectors
authorSoeren Apel <redacted>
Thu, 5 Apr 2018 20:23:28 +0000 (22:23 +0200)
committerUwe Hermann <redacted>
Sun, 8 Apr 2018 17:43:03 +0000 (19:43 +0200)
pv/data/logicsegment.hpp
pv/popups/channels.cpp
pv/popups/channels.hpp

index 2e03fd55585a99f8adbe4e22e753a3aae0fcf9e5..88576118d06eb180b281d0d8ee9a9b2f1def1e2c 100644 (file)
@@ -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<int64_t, bool> 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<int64_t, bool> EdgePair;
+private:
+       struct MipMapLevel
+       {
+               uint64_t length;
+               uint64_t data_length;
+               void *data;
+       };
 
 public:
        LogicSegment(pv::data::Logic& owner, uint32_t segment_id,
index 10146741224651594086b8c514b892f2ce2c20b2..99e6376aeb5aa70351494de00238645125b061b5 100644 (file)
@@ -28,6 +28,8 @@
 
 #include <pv/session.hpp>
 #include <pv/binding/device.hpp>
+#include <pv/data/logic.hpp>
+#include <pv/data/logicsegment.hpp>
 #include <pv/data/signalbase.hpp>
 #include <pv/devices/device.hpp>
 
@@ -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<bool (const shared_ptr<data::SignalBase>)> cond_func)
+{
+       updating_channels_ = true;
+
+       for (auto entry : check_box_signal_map_) {
+               QCheckBox *cb = entry.first;
+               const shared_ptr<SignalBase> 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<ChannelGroup> group,
        const vector< shared_ptr<SignalBase> > 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<SignalBase> signal)
+               { return signal->type() == SignalBase::LogicChannel; });
+}
+
+void Channels::enable_all_analog_channels()
+{
+       set_all_channels_conditionally([](const shared_ptr<SignalBase> signal)
+               { return signal->type() == SignalBase::AnalogChannel; });
+}
+
+void Channels::enable_all_named_channels()
+{
+       set_all_channels_conditionally([](const shared_ptr<SignalBase> signal)
+               { return signal->name() != signal->internal_name(); });
+}
+
+void Channels::enable_all_changing_channels()
+{
+       set_all_channels_conditionally([](const shared_ptr<SignalBase> signal)
+               {
+                       // Non-logic channels are considered to always have a signal
+                       if (signal->type() != SignalBase::LogicChannel)
+                               return true;
+
+                       const shared_ptr<Logic> logic = signal->logic_data();
+                       assert(logic);
+
+                       // If any of the segments has edges, enable this channel
+                       for (shared_ptr<LogicSegment> segment : logic->logic_segments()) {
+                               vector<LogicSegment::EdgePair> 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
index b23af57046d808252ac7e8b6594c470926bcd87c..56a7bd1a643abf3611106afc91d3e7e42a5bd3d0 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef PULSEVIEW_PV_POPUPS_CHANNELS_HPP
 #define PULSEVIEW_PV_POPUPS_CHANNELS_HPP
 
+#include <functional>
 #include <map>
 #include <memory>
 #include <vector>
@@ -31,6 +32,7 @@
 
 #include <pv/widgets/popup.hpp>
 
+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<bool (const shared_ptr<data::SignalBase>)> cond_func);
 
        void populate_group(shared_ptr<sigrok::ChannelGroup> group,
                const vector< shared_ptr<pv::data::SignalBase> > 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<sigrok::ChannelGroup>, 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_;
 };