Introduce DecodeSignal::annotation_visibility_changed and use it
authorSoeren Apel <soeren@apelpie.net>
Thu, 30 Apr 2020 14:01:56 +0000 (16:01 +0200)
committerUwe Hermann <uwe@hermann-uwe.de>
Sun, 3 May 2020 15:20:55 +0000 (17:20 +0200)
pv/data/decode/annotation.cpp
pv/data/decode/decoder.cpp
pv/data/decode/decoder.hpp
pv/data/decode/row.cpp
pv/data/decode/row.hpp
pv/data/decode/rowdata.cpp
pv/data/decodesignal.cpp
pv/data/decodesignal.hpp
pv/views/tabular_decoder/model.cpp
pv/views/tabular_decoder/view.hpp
pv/views/trace/decodetrace.cpp

index 1a331b3e143aeb46e0969b5936dac60e7fa314aa..b1dc6ef66c17efa6f44bd416bf546261380f2636 100644 (file)
@@ -126,7 +126,8 @@ bool Annotation::visible() const
 {
        const Row* row = data_->row();
 
-       return (row->visible() && row->class_is_visible(ann_class_id_));
+       return (row->visible() && row->class_is_visible(ann_class_id_)
+               && row->decoder()->visible());
 }
 
 const QColor Annotation::color() const
index 600382feddb576346f9c835b44934a1cd049670b..f644b8af3a3356e03db91af8b948119e2cb4be17 100644 (file)
@@ -36,6 +36,28 @@ namespace pv {
 namespace data {
 namespace decode {
 
+AnnotationClass::AnnotationClass(size_t _id, char* _name, char* _description, Row* _row) :
+       id(_id),
+       name(_name),
+       description(_description),
+       row(_row),
+       visible_(true)
+{
+}
+
+bool AnnotationClass::visible() const
+{
+       return visible_;
+}
+
+void AnnotationClass::set_visible(bool visible)
+{
+       visible_ = visible;
+
+       visibility_changed();
+}
+
+
 Decoder::Decoder(const srd_decoder *const dec, uint8_t stack_level) :
        srd_decoder_(dec),
        stack_level_(stack_level),
@@ -48,7 +70,10 @@ Decoder::Decoder(const srd_decoder *const dec, uint8_t stack_level) :
                char **ann_class = (char**)l->data;
                char *name = ann_class[0];
                char *desc = ann_class[1];
-               ann_classes_.push_back({i++, name, desc, nullptr, true}); // Visible by default
+               ann_classes_.emplace_back(i++, name, desc, nullptr);
+
+               connect(&(ann_classes_.back()), SIGNAL(visibility_changed()),
+                       this, SLOT(on_class_visibility_changed()));
        }
 
        // Query the binary output classes
@@ -64,7 +89,6 @@ Decoder::Decoder(const srd_decoder *const dec, uint8_t stack_level) :
        uint32_t row_count = 0;
        for (const GSList *rl = srd_decoder_->annotation_rows; rl; rl = rl->next)
                row_count++;
-       rows_.reserve(row_count);
 
        i = 0;
        for (const GSList *rl = srd_decoder_->annotation_rows; rl; rl = rl->next) {
@@ -75,6 +99,9 @@ Decoder::Decoder(const srd_decoder *const dec, uint8_t stack_level) :
                // FIXME PV can crash from .at() if a PD's ann classes are defined incorrectly
                for (const GSList *cl = srd_row->ann_classes; cl; cl = cl->next)
                        ann_classes_.at((size_t)cl->data).row = &(rows_.back());
+
+               connect(&(rows_.back()), SIGNAL(visibility_changed()),
+                       this, SLOT(on_row_visibility_changed()));
        }
 
        if (rows_.empty()) {
@@ -115,6 +142,8 @@ bool Decoder::visible() const
 void Decoder::set_visible(bool visible)
 {
        visible_ = visible;
+
+       annotation_visibility_changed();
 }
 
 const vector<DecodeChannel*>& Decoder::channels() const
@@ -288,6 +317,16 @@ const DecodeBinaryClassInfo* Decoder::get_binary_class(uint32_t id) const
        return &(bin_classes_.at(id));
 }
 
+void Decoder::on_row_visibility_changed()
+{
+       annotation_visibility_changed();
+}
+
+void Decoder::on_class_visibility_changed()
+{
+       annotation_visibility_changed();
+}
+
 }  // namespace decode
 }  // namespace data
 }  // namespace pv
index 7b1a20134acaccd7ce4adec6462d11a02c11ffcb..2c4337478135fdc40d63c82c63316a59617f188e 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef PULSEVIEW_PV_DATA_DECODE_DECODER_HPP
 #define PULSEVIEW_PV_DATA_DECODE_DECODER_HPP
 
+#include <deque>
 #include <map>
 #include <memory>
 #include <set>
 
 #include <glib.h>
 
+#include <QObject>
+
 #include <pv/data/signalbase.hpp>
 #include <pv/data/decode/row.hpp>
 
+using std::deque;
 using std::map;
 using std::string;
 using std::vector;
@@ -50,13 +54,27 @@ namespace decode {
 
 class Decoder;
 
-struct AnnotationClass
+class AnnotationClass: public QObject
 {
+       Q_OBJECT
+
+public:
+       AnnotationClass(size_t _id, char* _name, char* _description, Row* _row);
+
+       bool visible() const;
+       void set_visible(bool visible);
+
+Q_SIGNALS:
+       void visibility_changed();
+
+public:
        size_t id;
        char* name;
        char* description;
        Row* row;
-       bool visible;
+
+private:
+       bool visible_;
 };
 
 struct DecodeChannel
@@ -79,8 +97,10 @@ struct DecodeBinaryClassInfo
 };
 
 
-class Decoder
+class Decoder : public QObject
 {
+       Q_OBJECT
+
 public:
        Decoder(const srd_decoder *const dec, uint8_t stack_level);
 
@@ -119,6 +139,13 @@ public:
        uint32_t get_binary_class_count() const;
        const DecodeBinaryClassInfo* get_binary_class(uint32_t id) const;
 
+Q_SIGNALS:
+       void annotation_visibility_changed();
+
+private Q_SLOTS:
+       void on_row_visibility_changed();
+       void on_class_visibility_changed();
+
 private:
        const srd_decoder* const srd_decoder_;
        uint8_t stack_level_;
@@ -126,8 +153,8 @@ private:
        bool visible_;
 
        vector<DecodeChannel*> channels_;
-       vector<Row> rows_;
-       vector<AnnotationClass> ann_classes_;
+       deque<Row> rows_;
+       deque<AnnotationClass> ann_classes_;
        vector<DecodeBinaryClassInfo> bin_classes_;
        map<string, GVariant*> options_;
        srd_decoder_inst *decoder_inst_;
index 4f0e245fc65c359528a7cf3e5a5d8c3760671740..d127a2eadaf3045180452a148777f33cb30c9f08 100644 (file)
@@ -110,6 +110,8 @@ bool Row::visible() const
 void Row::set_visible(bool visible)
 {
        visible_ = visible;
+
+       visibility_changed();
 }
 
 void Row::set_base_color(QColor base_color)
@@ -163,7 +165,7 @@ const QColor Row::get_dark_class_color(uint32_t ann_class_id) const
 bool Row::has_hidden_classes() const
 {
        for (const AnnotationClass* c : ann_classes())
-               if (!c->visible)
+               if (!c->visible())
                        return true;
 
        return false;
@@ -171,7 +173,7 @@ bool Row::has_hidden_classes() const
 
 bool Row::class_is_visible(uint32_t ann_class_id) const
 {
-       return decoder_->get_ann_class_by_id(ann_class_id)->visible;
+       return decoder_->get_ann_class_by_id(ann_class_id)->visible();
 }
 
 bool Row::operator<(const Row& other) const
index 71945f2e0cf0899ffc911001ef5beff0e4f17bb4..8e76dfa0b64d9a10ac555419cc752cbbbce16b88 100644 (file)
@@ -37,11 +37,13 @@ namespace decode {
 #define DECODE_COLOR_SATURATION (180) /* 0-255 */
 #define DECODE_COLOR_VALUE (170) /* 0-255 */
 
-struct AnnotationClass;
+class AnnotationClass;
 class Decoder;
 
-class Row
+class Row: public QObject
 {
+       Q_OBJECT
+
 public:
        Row();
 
@@ -71,6 +73,9 @@ public:
        bool operator<(const Row& other) const;
        bool operator==(const Row& other) const;
 
+Q_SIGNALS:
+       void visibility_changed();
+
 private:
        uint32_t index_;
        Decoder* decoder_;
index 0434e1c0d8aad7a2d93e2ecf26555377ff6fb62f..a9c2e2a883b8eee89dbc518e8bb18aae25bb8607 100644 (file)
@@ -63,7 +63,7 @@ void RowData::get_annotation_subset(
 
        uint32_t max_ann_class_id = 0;
        for (AnnotationClass* c : row_->ann_classes()) {
-               if (!c->visible)
+               if (!c->visible())
                        all_ann_classes_enabled = false;
                else
                        all_ann_classes_disabled = false;
@@ -83,7 +83,7 @@ void RowData::get_annotation_subset(
                        vector<size_t> class_visible;
                        class_visible.resize(max_ann_class_id + 1, 0);
                        for (AnnotationClass* c : row_->ann_classes())
-                               if (c->visible)
+                               if (c->visible())
                                        class_visible[c->id] = 1;
 
                        for (const auto& annotation : annotations_)
index 811aff65589529887d8b57b7924c6df05b5024f2..ff7a27640fb597c4aed12863da5d6bf0ff9f2dd7 100644 (file)
@@ -86,6 +86,9 @@ void DecodeSignal::stack_decoder(const srd_decoder *decoder, bool restart_decode
        const shared_ptr<Decoder> dec = make_shared<Decoder>(decoder, stack_.size());
        stack_.push_back(dec);
 
+       connect(dec.get(), SIGNAL(annotation_visibility_changed()),
+               this, SLOT(on_annotation_visibility_changed()));
+
        // Include the newly created decode channels in the channel lists
        update_channel_list();
 
@@ -698,7 +701,7 @@ void DecodeSignal::save_settings(QSettings &settings) const
                i = 0;
                for (const AnnotationClass* ann_class : decoder->ann_classes()) {
                        settings.beginGroup("ann_class" + QString::number(i));
-                       settings.setValue("visible", ann_class->visible);
+                       settings.setValue("visible", ann_class->visible());
                        settings.endGroup();
                        i++;
                }
@@ -752,6 +755,9 @@ void DecodeSignal::restore_settings(QSettings &settings)
                        if (QString::fromUtf8(dec->id) == id) {
                                shared_ptr<Decoder> decoder = make_shared<Decoder>(dec, stack_.size());
 
+                               connect(decoder.get(), SIGNAL(annotation_visibility_changed()),
+                                       this, SLOT(on_annotation_visibility_changed()));
+
                                stack_.push_back(decoder);
                                decoder->set_visible(settings.value("visible", true).toBool());
 
@@ -782,7 +788,7 @@ void DecodeSignal::restore_settings(QSettings &settings)
                                i = 0;
                                for (AnnotationClass* ann_class : decoder->ann_classes()) {
                                        settings.beginGroup("ann_class" + QString::number(i));
-                                       ann_class->visible = settings.value("visible", true).toBool();
+                                       ann_class->set_visible(settings.value("visible", true).toBool());
                                        settings.endGroup();
                                        i++;
                                }
@@ -1591,5 +1597,10 @@ void DecodeSignal::on_data_received()
                logic_mux_cond_.notify_one();
 }
 
+void DecodeSignal::on_annotation_visibility_changed()
+{
+       annotation_visibility_changed();
+}
+
 } // namespace data
 } // namespace pv
index 3adcbb93102c5b05b65b58340de491857fdefaf9..2a6d125f06024dd14494097f834a00d6f44bd8fc 100644 (file)
@@ -226,12 +226,15 @@ Q_SIGNALS:
        void decode_reset();
        void decode_finished();
        void channels_updated();
+       void annotation_visibility_changed();
 
 private Q_SLOTS:
        void on_capture_state_changed(int state);
        void on_data_cleared();
        void on_data_received();
 
+       void on_annotation_visibility_changed();
+
 private:
        pv::Session &session_;
 
index b0632f7ad35b5d3d2be9e6084cd930baa9a2a7d0..6037cf3e8171745caa67191999b6a967914edd8b 100644 (file)
@@ -189,9 +189,15 @@ void AnnotationCollectionModel::set_signal_and_segment(data::DecodeSignal* signa
                return;
        }
 
+       disconnect(this, SLOT(on_annotation_visibility_changed()));
+
        all_annotations_ = signal->get_all_annotations_by_segment(current_segment);
        signal_ = signal;
 
+       for (const shared_ptr<Decoder>& dec : signal_->decoder_stack())
+               connect(dec.get(), SIGNAL(annotation_visibility_changed()),
+                       this, SLOT(on_annotation_visibility_changed()));
+
        if (hide_hidden_)
                update_annotations_without_hidden();
        else
@@ -334,6 +340,24 @@ void AnnotationCollectionModel::on_setting_changed(const QString &key, const QVa
        theme_is_dark_ = GlobalSettings::current_theme_is_dark();
 }
 
+void AnnotationCollectionModel::on_annotation_visibility_changed()
+{
+       if (!hide_hidden_)
+               return;
+
+       update_annotations_without_hidden();
+
+       // Re-apply the requested sample range
+       set_sample_range(start_sample_, end_sample_);
+
+       if (dataset_)
+               dataChanged(index(0, 0), index(dataset_->size(), 0));
+       else
+               dataChanged(QModelIndex(), QModelIndex());
+
+       layoutChanged();
+}
+
 } // namespace tabular_decoder
 } // namespace views
 } // namespace pv
index 6bb89c86616e33ab680b60bd86488ef4eaa0b28f..ae2d5276de2a6a46cf54f12c9951f79a4b30a104 100644 (file)
@@ -86,6 +86,9 @@ public:
 
        void on_setting_changed(const QString &key, const QVariant &value) override;
 
+private Q_SLOTS:
+       void on_annotation_visibility_changed();
+
 private:
        vector<QVariant> header_data_;
        const deque<const Annotation*>* all_annotations_;
index e9b046c2d86bb088389f53682b6d8f6732248ffe..52ba83d64ddb94a4063bd46d5973d22591fd67f5 100644 (file)
@@ -1340,7 +1340,7 @@ void DecodeTrace::initialize_row_widgets(DecodeTraceRow* r, unsigned int row_id)
        for (const AnnotationClass* ann_class : ann_classes) {
                cb = new QCheckBox();
                cb->setText(tr(ann_class->description));
-               cb->setChecked(ann_class->visible);
+               cb->setChecked(ann_class->visible());
 
                int dim = ViewItemPaintParams::text_height() - 2;
                QPixmap pixmap(dim, dim);
@@ -1621,7 +1621,7 @@ void DecodeTrace::on_show_hide_class(QWidget* sender)
        assert(ann_class_ptr);
        AnnotationClass* ann_class = (AnnotationClass*)ann_class_ptr;
 
-       ann_class->visible = !ann_class->visible;
+       ann_class->set_visible(!ann_class->visible());
 
        void* row_ptr = sender->property("decode_trace_row_ptr").value<void*>();
        assert(row_ptr);