+ // Restore decoder stack
+ GSList *dec_list = g_slist_copy((GSList*)srd_decoder_list());
+
+ int decoders = settings.value("decoders").toInt();
+
+ for (int decoder_idx = 0; decoder_idx < decoders; decoder_idx++) {
+ settings.beginGroup("decoder" + QString::number(decoder_idx));
+
+ QString id = settings.value("id").toString();
+
+ for (GSList *entry = dec_list; entry; entry = entry->next) {
+ const srd_decoder *dec = (srd_decoder*)entry->data;
+ if (!dec)
+ continue;
+
+ 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());
+
+ // Restore decoder options that differ from their default
+ int options = settings.value("options").toInt();
+
+ for (int i = 0; i < options; i++) {
+ settings.beginGroup("option" + QString::number(i));
+ QString name = settings.value("name").toString();
+ GVariant *value = GlobalSettings::restore_gvariant(settings);
+ decoder->set_option(name.toUtf8(), value);
+ settings.endGroup();
+ }
+
+ // Include the newly created decode channels in the channel lists
+ update_channel_list();
+
+ // Restore row properties
+ int i = 0;
+ for (Row* row : decoder->get_rows()) {
+ settings.beginGroup("row" + QString::number(i));
+ row->set_visible(settings.value("visible", true).toBool());
+ settings.endGroup();
+ i++;
+ }
+
+ // Restore class properties
+ i = 0;
+ for (AnnotationClass* ann_class : decoder->ann_classes()) {
+ settings.beginGroup("ann_class" + QString::number(i));
+ ann_class->set_visible(settings.value("visible", true).toBool());
+ settings.endGroup();
+ i++;
+ }
+
+ break;
+ }
+ }
+
+ settings.endGroup();
+ channels_updated();
+ }
+
+ // Restore channel mapping
+ unsigned int channels = settings.value("channels").toInt();
+
+ const vector< shared_ptr<data::SignalBase> > signalbases =
+ session_.signalbases();
+
+ for (unsigned int channel_id = 0; channel_id < channels; channel_id++) {
+ auto channel = find_if(channels_.begin(), channels_.end(),
+ [&](decode::DecodeChannel ch) { return ch.id == channel_id; });
+
+ if (channel == channels_.end()) {
+ qDebug() << "ERROR: Non-existant channel index:" << channel_id;
+ continue;
+ }
+
+ settings.beginGroup("channel" + QString::number(channel_id));
+
+ QString assigned_signal_name = settings.value("assigned_signal_name").toString();
+
+ for (const shared_ptr<data::SignalBase>& signal : signalbases)
+ if ((signal->name() == assigned_signal_name) && (signal->type() != SignalBase::DecodeChannel))
+ channel->assigned_signal = signal;
+
+ channel->initial_pin_state = settings.value("initial_pin_state").toInt();
+
+ settings.endGroup();
+ }
+
+ connect_input_notifiers();
+
+ // Update the internal structures
+ stack_config_changed_ = true;
+ update_channel_list();
+ commit_decoder_channels();
+ update_output_signals();
+
+ // TODO Restore logic output signal settings
+
+ begin_decode();
+}
+
+bool DecodeSignal::all_input_segments_complete(uint32_t segment_id) const
+{
+ bool all_complete = true;
+
+ for (const decode::DecodeChannel& ch : channels_)
+ if (ch.assigned_signal) {
+ if (!ch.assigned_signal->logic_data())
+ continue;
+
+ const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
+ if (logic_data->logic_segments().empty())
+ return false;
+
+ if (segment_id >= logic_data->logic_segments().size())
+ return false;
+
+ const shared_ptr<const LogicSegment> segment = logic_data->logic_segments()[segment_id]->get_shared_ptr();
+ if (segment && !segment->is_complete())
+ all_complete = false;
+ }
+
+ return all_complete;
+}
+
+uint32_t DecodeSignal::get_input_segment_count() const
+{
+ uint64_t count = std::numeric_limits<uint64_t>::max();
+ bool no_signals_assigned = true;
+
+ for (const decode::DecodeChannel& ch : channels_)
+ if (ch.assigned_signal) {
+ no_signals_assigned = false;
+
+ const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
+ if (!logic_data || logic_data->logic_segments().empty())
+ return 0;
+
+ // Find the min value of all segment counts
+ if ((uint64_t)(logic_data->logic_segments().size()) < count)
+ count = logic_data->logic_segments().size();
+ }
+
+ return (no_signals_assigned ? 0 : count);
+}
+
+double DecodeSignal::get_input_samplerate(uint32_t segment_id) const
+{
+ double samplerate = 0;
+
+ for (const decode::DecodeChannel& ch : channels_)
+ if (ch.assigned_signal) {
+ const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
+ if (!logic_data || logic_data->logic_segments().empty())
+ continue;
+
+ try {
+ const shared_ptr<const LogicSegment> segment =
+ logic_data->logic_segments().at(segment_id)->get_shared_ptr();
+ if (segment)
+ samplerate = segment->samplerate();
+ } catch (out_of_range&) {
+ // Do nothing
+ }
+ break;
+ }
+
+ return samplerate;
+}
+
+Decoder* DecodeSignal::get_decoder_by_instance(const srd_decoder *const srd_dec)
+{
+ for (shared_ptr<Decoder>& d : stack_)
+ if (d->get_srd_decoder() == srd_dec)
+ return d.get();
+
+ return nullptr;