From: Soeren Apel Date: Thu, 30 Apr 2020 14:01:56 +0000 (+0200) Subject: Introduce DecodeSignal::annotation_visibility_changed and use it X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=02078aa15a4747b8ab7a91d54e2e141c3acb5628;p=pulseview.git Introduce DecodeSignal::annotation_visibility_changed and use it --- diff --git a/pv/data/decode/annotation.cpp b/pv/data/decode/annotation.cpp index 1a331b3e..b1dc6ef6 100644 --- a/pv/data/decode/annotation.cpp +++ b/pv/data/decode/annotation.cpp @@ -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 diff --git a/pv/data/decode/decoder.cpp b/pv/data/decode/decoder.cpp index 600382fe..f644b8af 100644 --- a/pv/data/decode/decoder.cpp +++ b/pv/data/decode/decoder.cpp @@ -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& 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 diff --git a/pv/data/decode/decoder.hpp b/pv/data/decode/decoder.hpp index 7b1a2013..2c433747 100644 --- a/pv/data/decode/decoder.hpp +++ b/pv/data/decode/decoder.hpp @@ -20,6 +20,7 @@ #ifndef PULSEVIEW_PV_DATA_DECODE_DECODER_HPP #define PULSEVIEW_PV_DATA_DECODE_DECODER_HPP +#include #include #include #include @@ -27,9 +28,12 @@ #include +#include + #include #include +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 channels_; - vector rows_; - vector ann_classes_; + deque rows_; + deque ann_classes_; vector bin_classes_; map options_; srd_decoder_inst *decoder_inst_; diff --git a/pv/data/decode/row.cpp b/pv/data/decode/row.cpp index 4f0e245f..d127a2ea 100644 --- a/pv/data/decode/row.cpp +++ b/pv/data/decode/row.cpp @@ -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 diff --git a/pv/data/decode/row.hpp b/pv/data/decode/row.hpp index 71945f2e..8e76dfa0 100644 --- a/pv/data/decode/row.hpp +++ b/pv/data/decode/row.hpp @@ -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_; diff --git a/pv/data/decode/rowdata.cpp b/pv/data/decode/rowdata.cpp index 0434e1c0..a9c2e2a8 100644 --- a/pv/data/decode/rowdata.cpp +++ b/pv/data/decode/rowdata.cpp @@ -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 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_) diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index 811aff65..ff7a2764 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -86,6 +86,9 @@ void DecodeSignal::stack_decoder(const srd_decoder *decoder, bool restart_decode const shared_ptr dec = make_shared(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 = make_shared(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 diff --git a/pv/data/decodesignal.hpp b/pv/data/decodesignal.hpp index 3adcbb93..2a6d125f 100644 --- a/pv/data/decodesignal.hpp +++ b/pv/data/decodesignal.hpp @@ -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_; diff --git a/pv/views/tabular_decoder/model.cpp b/pv/views/tabular_decoder/model.cpp index b0632f7a..6037cf3e 100644 --- a/pv/views/tabular_decoder/model.cpp +++ b/pv/views/tabular_decoder/model.cpp @@ -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& 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 diff --git a/pv/views/tabular_decoder/view.hpp b/pv/views/tabular_decoder/view.hpp index 6bb89c86..ae2d5276 100644 --- a/pv/views/tabular_decoder/view.hpp +++ b/pv/views/tabular_decoder/view.hpp @@ -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 header_data_; const deque* all_annotations_; diff --git a/pv/views/trace/decodetrace.cpp b/pv/views/trace/decodetrace.cpp index e9b046c2..52ba83d6 100644 --- a/pv/views/trace/decodetrace.cpp +++ b/pv/views/trace/decodetrace.cpp @@ -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(); assert(row_ptr);