Channels: Make channel enable/disable options symmetric
authorSoeren Apel <soeren@apelpie.net>
Tue, 16 Oct 2018 19:01:35 +0000 (21:01 +0200)
committerUwe Hermann <uwe@hermann-uwe.de>
Tue, 16 Oct 2018 21:53:10 +0000 (23:53 +0200)
pv/popups/channels.cpp
pv/popups/channels.hpp

index ffe42fd..8aca292 100644 (file)
@@ -61,9 +61,13 @@ Channels::Channels(Session &session, QWidget *parent) :
        enable_all_channels_(tr("All"), this),
        disable_all_channels_(tr("All"), this),
        enable_all_logic_channels_(tr("Logic"), this),
+       disable_all_logic_channels_(tr("Logic"), this),
        enable_all_analog_channels_(tr("Analog"), this),
+       disable_all_analog_channels_(tr("Analog"), this),
        enable_all_named_channels_(tr("Named"), this),
+       disable_all_unnamed_channels_(tr("Unnamed"), this),
        enable_all_changing_channels_(tr("Changing"), this),
+       disable_all_non_changing_channels_(tr("Non-changing"), this),
        check_box_mapper_(this)
 {
        // Create the layout
@@ -123,24 +127,34 @@ Channels::Channels(Session &session, QWidget *parent) :
        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(&disable_all_logic_channels_, SIGNAL(clicked()), this, SLOT(disable_all_logic_channels()));
        connect(&enable_all_analog_channels_, SIGNAL(clicked()), this, SLOT(enable_all_analog_channels()));
+       connect(&disable_all_analog_channels_, SIGNAL(clicked()), this, SLOT(disable_all_analog_channels()));
        connect(&enable_all_named_channels_, SIGNAL(clicked()), this, SLOT(enable_all_named_channels()));
+       connect(&disable_all_unnamed_channels_, SIGNAL(clicked()), this, SLOT(disable_all_unnamed_channels()));
        connect(&enable_all_changing_channels_, SIGNAL(clicked()),
                this, SLOT(enable_all_changing_channels()));
+       connect(&disable_all_non_changing_channels_, SIGNAL(clicked()),
+               this, SLOT(disable_all_non_changing_channels()));
 
        QLabel *label1 = new QLabel(tr("Disable: "));
-       buttons_bar_.addWidget(label1);
-       buttons_bar_.addWidget(&disable_all_channels_);
+       filter_buttons_bar_.addWidget(label1, 0, 0);
+       filter_buttons_bar_.addWidget(&disable_all_channels_, 0, 1);
+       filter_buttons_bar_.addWidget(&disable_all_logic_channels_, 0, 2);
+       filter_buttons_bar_.addWidget(&disable_all_analog_channels_, 0, 3);
+       filter_buttons_bar_.addWidget(&disable_all_unnamed_channels_, 0, 4);
+       filter_buttons_bar_.addWidget(&disable_all_non_changing_channels_, 0, 5);
+
        QLabel *label2 = new QLabel(tr("Enable: "));
-       buttons_bar_.addWidget(label2);
-       buttons_bar_.addWidget(&enable_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();
+       filter_buttons_bar_.addWidget(label2, 1, 0);
+       filter_buttons_bar_.addWidget(&enable_all_channels_, 1, 1);
+       filter_buttons_bar_.addWidget(&enable_all_logic_channels_, 1, 2);
+       filter_buttons_bar_.addWidget(&enable_all_analog_channels_, 1, 3);
+       filter_buttons_bar_.addWidget(&enable_all_named_channels_, 1, 4);
+       filter_buttons_bar_.addWidget(&enable_all_changing_channels_, 1, 5);
 
-       layout_.addRow(&buttons_bar_);
+       layout_.addItem(new QSpacerItem(0, 15, QSizePolicy::Expanding, QSizePolicy::Expanding));
+       layout_.addRow(&filter_buttons_bar_);
 
        // Connect the check-box signal mapper
        connect(&check_box_mapper_, SIGNAL(mapped(QWidget*)),
@@ -173,10 +187,28 @@ void Channels::enable_channels_conditionally(
                const shared_ptr<SignalBase> sig = entry.second;
                assert(sig);
 
-               const bool state = cond_func(sig);
-               if (state) {
-                       sig->set_enabled(state);
-                       cb->setChecked(state);
+               if (cond_func(sig)) {
+                       sig->set_enabled(true);
+                       cb->setChecked(true);
+               }
+       }
+
+       updating_channels_ = false;
+}
+
+void Channels::disable_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);
+
+               if (cond_func(sig)) {
+                       sig->set_enabled(false);
+                       cb->setChecked(false);
                }
        }
 
@@ -309,18 +341,36 @@ void Channels::enable_all_logic_channels()
                { return signal->type() == SignalBase::LogicChannel; });
 }
 
+void Channels::disable_all_logic_channels()
+{
+       disable_channels_conditionally([](const shared_ptr<SignalBase> signal)
+               { return signal->type() == SignalBase::LogicChannel; });
+}
+
 void Channels::enable_all_analog_channels()
 {
        enable_channels_conditionally([](const shared_ptr<SignalBase> signal)
                { return signal->type() == SignalBase::AnalogChannel; });
 }
 
+void Channels::disable_all_analog_channels()
+{
+       disable_channels_conditionally([](const shared_ptr<SignalBase> signal)
+               { return signal->type() == SignalBase::AnalogChannel; });
+}
+
 void Channels::enable_all_named_channels()
 {
        enable_channels_conditionally([](const shared_ptr<SignalBase> signal)
                { return signal->name() != signal->internal_name(); });
 }
 
+void Channels::disable_all_unnamed_channels()
+{
+       disable_channels_conditionally([](const shared_ptr<SignalBase> signal)
+               { return signal->name() == signal->internal_name(); });
+}
+
 void Channels::enable_all_changing_channels()
 {
        enable_channels_conditionally([](const shared_ptr<SignalBase> signal)
@@ -354,5 +404,38 @@ void Channels::enable_all_changing_channels()
                });
 }
 
+void Channels::disable_all_non_changing_channels()
+{
+       disable_channels_conditionally([](const shared_ptr<SignalBase> signal)
+               {
+                       // Always disable channels without sample data
+                       if (!signal->has_samples())
+                               return true;
+
+                       // Non-logic channels are considered to always have a signal
+                       if (signal->type() != SignalBase::LogicChannel)
+                               return false;
+
+                       const shared_ptr<Logic> logic = signal->logic_data();
+                       assert(logic);
+
+                       // If any of the segments has edges, leave this channel enabled
+                       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 false;
+                       }
+
+                       // No edges detected in any of the segments
+                       return true;
+               });
+}
+
 }  // namespace popups
 }  // namespace pv
index 344d21a..54d2434 100644 (file)
@@ -28,7 +28,6 @@
 #include <QCheckBox>
 #include <QFormLayout>
 #include <QGridLayout>
-#include <QHBoxLayout>
 #include <QLabel>
 #include <QPushButton>
 #include <QSignalMapper>
@@ -71,8 +70,11 @@ public:
 
 private:
        void set_all_channels(bool set);
+
        void enable_channels_conditionally(
                function<bool (const shared_ptr<data::SignalBase>)> cond_func);
+       void disable_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);
@@ -80,7 +82,6 @@ private:
        QGridLayout* create_channel_group_grid(
                const vector< shared_ptr<pv::data::SignalBase> > sigs);
 
-private:
        void showEvent(QShowEvent *event);
 
 private Q_SLOTS:
@@ -89,9 +90,13 @@ private Q_SLOTS:
        void enable_all_channels();
        void disable_all_channels();
        void enable_all_logic_channels();
+       void disable_all_logic_channels();
        void enable_all_analog_channels();
+       void disable_all_analog_channels();
        void enable_all_named_channels();
+       void disable_all_unnamed_channels();
        void enable_all_changing_channels();
+       void disable_all_non_changing_channels();
 
 private:
        pv::Session &session_;
@@ -105,10 +110,12 @@ private:
                check_box_signal_map_;
        map< shared_ptr<sigrok::ChannelGroup>, QLabel*> group_label_map_;
 
-       QHBoxLayout buttons_bar_;
+       QGridLayout filter_buttons_bar_;
        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_;
+       QPushButton enable_all_logic_channels_, disable_all_logic_channels_;
+       QPushButton enable_all_analog_channels_, disable_all_analog_channels_;
+       QPushButton enable_all_named_channels_, disable_all_unnamed_channels_;
+       QPushButton enable_all_changing_channels_, disable_all_non_changing_channels_;
 
        QSignalMapper check_box_mapper_;
 };