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();
assert(index < (int)stack_.size());
// Find the decoder in the stack
- auto iter = stack_.begin();
- for (int i = 0; i < index; i++, iter++)
- assert(iter != stack_.end());
+ auto iter = stack_.begin() + index;
+ assert(iter != stack_.end());
- decoder_removed(iter->get());
+ shared_ptr<Decoder> dec = *iter;
+
+ decoder_removed(dec.get());
// Delete the element
stack_.erase(iter);
begin_decode();
}
-double DecodeSignal::samplerate() const
+double DecodeSignal::get_samplerate() const
{
double result = 0;
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++;
}
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());
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++;
}
QString assigned_signal_name = settings.value("assigned_signal_name").toString();
for (const shared_ptr<data::SignalBase>& signal : signalbases)
- if (signal->name() == assigned_signal_name)
+ if ((signal->name() == assigned_signal_name) && (signal->type() != SignalBase::DecodeChannel))
channel->assigned_signal = signal.get();
channel->initial_pin_state = settings.value("initial_pin_state").toInt();
// Add the annotation to the row
const Annotation* ann = row_data.emplace_annotation(pdata);
- // Add the annotation to the global annotation list
+ // We insert the annotation into the global annotation list in a way so that
+ // the annotation list is sorted by start sample and length. Otherwise, we'd
+ // have to sort the model, which is expensive
deque<const Annotation*>& all_annotations =
ds->segments_[ds->current_segment_id_].all_annotations;
- all_annotations.emplace_back(ann);
+
+ if (all_annotations.empty()) {
+ all_annotations.emplace_back(ann);
+ } else {
+ const uint64_t new_ann_len = (pdata->end_sample - pdata->start_sample);
+ bool ann_has_earlier_start = (pdata->start_sample < all_annotations.back()->start_sample());
+ bool ann_is_longer = (new_ann_len >
+ (all_annotations.back()->end_sample() - all_annotations.back()->start_sample()));
+
+ if (ann_has_earlier_start && ann_is_longer) {
+ bool ann_has_same_start;
+ auto it = all_annotations.end();
+
+ do {
+ it--;
+ ann_has_earlier_start = (pdata->start_sample < (*it)->start_sample());
+ ann_has_same_start = (pdata->start_sample == (*it)->start_sample());
+ ann_is_longer = (new_ann_len > (*it)->length());
+ } while ((ann_has_earlier_start || (ann_has_same_start && ann_is_longer)) && (it != all_annotations.begin()));
+
+ // Allow inserting at the front
+ if (it != all_annotations.begin())
+ it++;
+
+ all_annotations.emplace(it, ann);
+ } else
+ all_annotations.emplace_back(ann);
+ }
+
+ // When emplace_annotation() inserts instead of appends an annotation,
+ // the pointers in all_annotations that follow the inserted annotation and
+ // point to annotations for this row are off by one and must be updated
+ if (&(row_data.annotations().back()) != ann) {
+ // Search backwards until we find the annotation we just added
+ auto row_it = row_data.annotations().end();
+ auto all_it = all_annotations.end();
+ do {
+ all_it--;
+ if ((*all_it)->row_data() == &row_data)
+ row_it--;
+ } while (&(*row_it) != ann);
+
+ // Update the annotation addresses for this row's annotations until the end
+ do {
+ if ((*all_it)->row_data() == &row_data) {
+ *all_it = &(*row_it);
+ row_it++;
+ }
+ all_it++;
+ } while (all_it != all_annotations.end());
+ }
}
void DecodeSignal::binary_callback(srd_proto_data *pdata, void *decode_signal)
logic_mux_cond_.notify_one();
}
+void DecodeSignal::on_annotation_visibility_changed()
+{
+ annotation_visibility_changed();
+}
+
} // namespace data
} // namespace pv