+ // Restore channels
+ for (shared_ptr<data::SignalBase> base : signalbases_) {
+ settings.beginGroup(base->internal_name());
+ base->restore_settings(settings);
+ settings.endGroup();
+ }
+
+ // Restore decoders
+#ifdef ENABLE_DECODE
+ int decode_signals = settings.value("decode_signals").toInt();
+
+ for (int i = 0; i < decode_signals; i++) {
+ settings.beginGroup("decode_signal" + QString::number(i));
+ shared_ptr<data::DecodeSignal> signal = add_decode_signal();
+ signal->restore_settings(settings);
+ settings.endGroup();
+ }
+#endif
+
+ // Restore views
+ int views = settings.value("views").toInt();
+
+ for (int i = 0; i < views; i++) {
+ settings.beginGroup("view" + QString::number(i));
+
+ if (i > 0) {
+ views::ViewType type = (views::ViewType)settings.value("type").toInt();
+ add_view(type, this);
+ views_.back()->restore_settings(settings);
+ } else
+ main_view_->restore_settings(settings);
+
+ settings.endGroup();
+ }
+
+ // Restore meta objects like markers and cursors
+ int meta_objs = settings.value("meta_objs").toInt();
+
+ for (int i = 0; i < meta_objs; i++) {
+ settings.beginGroup("meta_obj" + QString::number(i));
+
+ shared_ptr<views::ViewBase> vb;
+ shared_ptr<views::trace::View> tv;
+ if (settings.contains("assoc_view"))
+ vb = views_.at(settings.value("assoc_view").toInt());
+
+ if (vb)
+ tv = dynamic_pointer_cast<views::trace::View>(vb);
+
+ const QString type = settings.value("type").toString();
+
+ if ((type == "time_marker") && tv) {
+ Timestamp ts = GlobalSettings::restore_timestamp(settings, "time");
+ shared_ptr<views::trace::Flag> flag = tv->add_flag(ts);
+ flag->set_text(settings.value("text").toString());
+ }
+
+ if ((type == "selection") && tv) {
+ Timestamp start = GlobalSettings::restore_timestamp(settings, "start_time");
+ Timestamp end = GlobalSettings::restore_timestamp(settings, "end_time");
+ tv->set_cursors(start, end);
+ tv->show_cursors();
+ }
+
+ settings.endGroup();
+ }
+}
+
+void Session::restore_settings(QSettings &settings)
+{
+ shared_ptr<devices::Device> device;
+
+ const QString device_type = settings.value("device_type").toString();
+
+ if (device_type == "hardware") {
+ map<string, string> dev_info;
+ list<string> key_list;
+
+ // Re-select last used device if possible but only if it's not demo
+ settings.beginGroup("device");
+ key_list.emplace_back("vendor");
+ key_list.emplace_back("model");
+ key_list.emplace_back("version");
+ key_list.emplace_back("serial_num");
+ key_list.emplace_back("connection_id");
+
+ for (string key : key_list) {
+ const QString k = QString::fromStdString(key);
+ if (!settings.contains(k))
+ continue;
+
+ const string value = settings.value(k).toString().toStdString();
+ if (!value.empty())
+ dev_info.insert(make_pair(key, value));
+ }
+
+ if (dev_info.count("model") > 0)
+ device = device_manager_.find_device_from_info(dev_info);
+
+ if (device)
+ set_device(device);
+
+ settings.endGroup();
+ }
+
+
+ QString filename;
+ if ((device_type == "sessionfile") || (device_type == "inputfile")) {
+ if (device_type == "sessionfile") {
+ settings.beginGroup("device");
+ filename = settings.value("filename").toString();
+ settings.endGroup();
+
+ if (QFileInfo(filename).isReadable())
+ device = make_shared<devices::SessionFile>(device_manager_.context(),
+ filename.toStdString());
+ }
+
+ if (device_type == "inputfile") {
+ settings.beginGroup("device");
+ device = make_shared<devices::InputFile>(device_manager_.context(),
+ settings);
+ settings.endGroup();
+ }
+
+ if (device) {
+ set_device(device);
+
+ start_capture([](QString infoMessage) {
+ // TODO Emulate noquote()
+ qDebug() << "Session error:" << infoMessage; });
+
+ set_name(QString::fromStdString(
+ dynamic_pointer_cast<devices::File>(device)->display_name(device_manager_)));
+
+ if (!filename.isEmpty()) {
+ // Only set the save path if we load an srzip file
+ if (device_type == "sessionfile")
+ set_save_path(QFileInfo(filename).absolutePath());
+
+ set_name(QFileInfo(filename).fileName());
+ }
+ }
+ }
+
+ if (device)
+ restore_setup(settings);
+}
+
+void Session::select_device(shared_ptr<devices::Device> device)
+{
+ try {
+ if (device)
+ set_device(device);
+ else
+ set_default_device();
+ } catch (const QString &e) {
+ MainWindow::show_session_error(tr("Failed to select device"), e);
+ }
+}
+
+void Session::set_device(shared_ptr<devices::Device> device)
+{
+ assert(device);
+
+ // Ensure we are not capturing before setting the device
+ stop_capture();
+
+ if (device_)
+ device_->close();
+
+ device_.reset();
+
+ // Revert name back to default name (e.g. "Session 1") as the data is gone
+ name_ = default_name_;
+ name_changed();
+
+ // Remove all stored data and reset all views
+ for (shared_ptr<views::ViewBase> view : views_) {
+ view->clear_signalbases();
+#ifdef ENABLE_DECODE
+ view->clear_decode_signals();
+#endif
+ view->reset_view_state();
+ }
+
+ for (SignalGroup* group : signal_groups_) {
+ group->clear();
+ delete group;
+ }
+ signal_groups_.clear();
+
+ for (const shared_ptr<data::SignalData>& d : all_signal_data_)
+ d->clear();
+
+ all_signal_data_.clear();
+ signalbases_.clear();
+ cur_logic_segment_.reset();
+
+ for (auto& entry : cur_analog_segments_) {
+ shared_ptr<sigrok::Channel>(entry.first).reset();
+ shared_ptr<data::AnalogSegment>(entry.second).reset();
+ }
+
+ logic_data_.reset();
+
+ signals_changed();
+
+ device_ = move(device);
+
+ try {
+ device_->open();
+ } catch (const QString &e) {
+ device_.reset();
+ MainWindow::show_session_error(tr("Failed to open device"), e);
+ }
+
+ if (device_) {
+ device_->session()->add_datafeed_callback([=]
+ (shared_ptr<sigrok::Device> device, shared_ptr<Packet> packet) {
+ data_feed_in(device, packet);
+ });
+
+ update_signals();
+ }
+
+ device_changed();