+ // 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<decode::Decoder> decoder =
+ make_shared<decode::Decoder>(dec);
+
+ stack_.push_back(decoder);
+
+ // 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();
+ break;
+ }
+ }
+
+ settings.endGroup();
+ channels_updated();
+ }
+
+ // Restore channel mapping
+ unsigned int channels = settings.value("channels").toInt();
+
+ const unordered_set< 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(),
+ [&](data::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 (shared_ptr<data::SignalBase> signal : signalbases)
+ if (signal->name() == assigned_signal_name)
+ channel->assigned_signal = signal.get();
+
+ channel->initial_pin_state = settings.value("initial_pin_state").toInt();
+
+ settings.endGroup();
+ }
+
+ // Update the internal structures
+ update_channel_list();
+ commit_decoder_channels();
+
+ begin_decode();
+}
+
+uint32_t DecodeSignal::get_input_segment_count() const
+{
+ uint64_t count = std::numeric_limits<uint64_t>::max();
+ bool no_signals_assigned = true;
+
+ for (const data::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);
+}
+
+uint32_t DecodeSignal::get_input_samplerate(uint32_t segment_id) const
+{
+ double samplerate = 0;
+
+ for (const data::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<LogicSegment> segment = logic_data->logic_segments().at(segment_id);
+ samplerate = segment->samplerate();
+ } catch (out_of_range) {
+ // Do nothing
+ }
+ break;
+ }
+
+ return samplerate;