X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=pv%2Fsession.cpp;h=31ca328deca53bf1c9cfd90d426fb228da228af6;hb=HEAD;hp=ea3fe07b4e312c8bece64035967edf4e6e5c692f;hpb=e23d7aa0d9980c3c269cbddb4cfbb32350d7425c;p=pulseview.git diff --git a/pv/session.cpp b/pv/session.cpp index ea3fe07b..b4ecc6a8 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include "devicemanager.hpp" @@ -37,6 +38,7 @@ #include "data/decode/decoder.hpp" #include "data/logic.hpp" #include "data/logicsegment.hpp" +#include "data/mathsignal.hpp" #include "data/signalbase.hpp" #include "devices/hardwaredevice.hpp" @@ -124,6 +126,8 @@ Session::Session(DeviceManager &device_manager, QString name) : cur_samplerate_(0), data_saved_(true) { + // Use this name also for the QObject instance + setObjectName(name_); } Session::~Session() @@ -173,9 +177,22 @@ void Session::set_name(QString name) name_ = name; + // Use this name also for the QObject instance + setObjectName(name_); + name_changed(); } +QString Session::save_path() const +{ + return save_path_; +} + +void Session::set_save_path(QString path) +{ + save_path_ = path; +} + const vector< shared_ptr > Session::views() const { return views_; @@ -203,25 +220,33 @@ bool Session::data_saved() const void Session::save_setup(QSettings &settings) const { - int i = 0; + int i; + int decode_signal_count = 0; + int gen_signal_count = 0; // Save channels and decoders for (const shared_ptr& base : signalbases_) { #ifdef ENABLE_DECODE if (base->is_decode_signal()) { - settings.beginGroup("decode_signal" + QString::number(i++)); + settings.beginGroup("decode_signal" + QString::number(decode_signal_count++)); base->save_settings(settings); settings.endGroup(); } else #endif - { + if (base->is_generated()) { + settings.beginGroup("generated_signal" + QString::number(gen_signal_count++)); + settings.setValue("type", base->type()); + base->save_settings(settings); + settings.endGroup(); + } else { settings.beginGroup(base->internal_name()); base->save_settings(settings); settings.endGroup(); } } - settings.setValue("decode_signals", i); + settings.setValue("decode_signals", decode_signal_count); + settings.setValue("generated_signals", gen_signal_count); // Save view states and their signal settings // Note: main_view must be saved as view0 @@ -312,25 +337,36 @@ void Session::save_settings(QSettings &settings) const settings.endGroup(); } - shared_ptr sessionfile_device = - dynamic_pointer_cast(device_); - - if (sessionfile_device) { + // Having saved the data to srzip overrides the current device. This is + // a crappy hack around the fact that saving e.g. an imported file to + // srzip would require changing the underlying libsigrok device + if (!save_path_.isEmpty()) { + QFileInfo fi = QFileInfo(QDir(save_path_), name_); settings.setValue("device_type", "sessionfile"); settings.beginGroup("device"); - settings.setValue("filename", QString::fromStdString( - sessionfile_device->full_name())); + settings.setValue("filename", fi.absoluteFilePath()); settings.endGroup(); - } + } else { + shared_ptr sessionfile_device = + dynamic_pointer_cast(device_); + + if (sessionfile_device) { + settings.setValue("device_type", "sessionfile"); + settings.beginGroup("device"); + settings.setValue("filename", QString::fromStdString( + sessionfile_device->full_name())); + settings.endGroup(); + } - shared_ptr inputfile_device = - dynamic_pointer_cast(device_); + shared_ptr inputfile_device = + dynamic_pointer_cast(device_); - if (inputfile_device) { - settings.setValue("device_type", "inputfile"); - settings.beginGroup("device"); - inputfile_device->save_meta_to_settings(settings); - settings.endGroup(); + if (inputfile_device) { + settings.setValue("device_type", "inputfile"); + settings.beginGroup("device"); + inputfile_device->save_meta_to_settings(settings); + settings.endGroup(); + } } save_setup(settings); @@ -346,11 +382,34 @@ void Session::restore_setup(QSettings &settings) settings.endGroup(); } + // Restore generated signals + int gen_signal_count = settings.value("generated_signals").toInt(); + + for (int i = 0; i < gen_signal_count; i++) { + settings.beginGroup("generated_signal" + QString::number(i)); + SignalBase::ChannelType type = (SignalBase::ChannelType)settings.value("type").toInt(); + shared_ptr signal; + + if (type == SignalBase::MathChannel) + signal = make_shared(*this); + else + qWarning() << tr("Can't restore generated signal of unknown type %1 (%2)") \ + .arg((int)type) \ + .arg(settings.value("name").toString()); + + if (signal) { + add_generated_signal(signal); + signal->restore_settings(settings); + } + + settings.endGroup(); + } + // Restore decoders #ifdef ENABLE_DECODE - int decode_signals = settings.value("decode_signals").toInt(); + int decode_signal_count = settings.value("decode_signals").toInt(); - for (int i = 0; i < decode_signals; i++) { + for (int i = 0; i < decode_signal_count; i++) { settings.beginGroup("decode_signal" + QString::number(i)); shared_ptr signal = add_decode_signal(); signal->restore_settings(settings); @@ -442,18 +501,21 @@ void Session::restore_settings(QSettings &settings) set_device(device); settings.endGroup(); + + if (device) + restore_setup(settings); } + QString filename; if ((device_type == "sessionfile") || (device_type == "inputfile")) { if (device_type == "sessionfile") { settings.beginGroup("device"); - const QString filename = settings.value("filename").toString(); + filename = settings.value("filename").toString(); settings.endGroup(); - if (QFileInfo(filename).isReadable()) { + if (QFileInfo(filename).isReadable()) device = make_shared(device_manager_.context(), filename.toStdString()); - } } if (device_type == "inputfile") { @@ -463,8 +525,10 @@ void Session::restore_settings(QSettings &settings) settings.endGroup(); } + if (device) { set_device(device); + restore_setup(settings); start_capture([](QString infoMessage) { // TODO Emulate noquote() @@ -472,11 +536,16 @@ void Session::restore_settings(QSettings &settings) set_name(QString::fromStdString( dynamic_pointer_cast(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 device) @@ -545,6 +614,9 @@ void Session::set_device(shared_ptr device) } catch (const QString &e) { device_.reset(); MainWindow::show_session_error(tr("Failed to open device"), e); + } catch (const sigrok::Error &e) { + device_.reset(); + MainWindow::show_session_error(tr("Failed to open device"), QString(e.what())); } if (device_) { @@ -687,8 +759,11 @@ void Session::load_file(QString file_name, QString setup_file_name, file_name.toStdString()))); } catch (Error& e) { MainWindow::show_session_error(tr("Failed to load %1").arg(file_name), e.what()); - set_default_device(); - main_bar_->update_device_list(); + return; + } + + if (!device_) { + MainWindow::show_session_error(errorMessage, ""); return; } @@ -707,7 +782,11 @@ void Session::load_file(QString file_name, QString setup_file_name, main_bar_->update_device_list(); start_capture([&, errorMessage](QString infoMessage) { - MainWindow::show_session_error(errorMessage, infoMessage); }); + Q_EMIT session_error_raised(errorMessage, infoMessage); }); + + // Only set save path if we loaded an srzip file + if (dynamic_pointer_cast(device_)) + set_save_path(QFileInfo(file_name).absolutePath()); set_name(QFileInfo(file_name).fileName()); } @@ -744,6 +823,7 @@ void Session::start_capture(function error_handler) d->clear(); trigger_list_.clear(); + segment_sample_count_.clear(); // Revert name back to default name (e.g. "Session 1") for real devices // as the (possibly saved) data is gone. File devices keep their name. @@ -755,9 +835,10 @@ void Session::start_capture(function error_handler) name_changed(); } + acq_start_time_ = Glib::DateTime::create_now_local(); + // Begin the session - sampling_thread_ = std::thread( - &Session::sample_thread_proc, this, error_handler); + sampling_thread_ = std::thread(&Session::sample_thread_proc, this, error_handler); } void Session::stop_capture() @@ -850,16 +931,22 @@ double Session::get_samplerate() const return samplerate; } -uint32_t Session::get_segment_count() const +Glib::DateTime Session::get_acquisition_start_time() const { - uint32_t value = 0; + return acq_start_time_; +} - // Find the highest number of segments - for (const shared_ptr& data : all_signal_data_) - if (data->get_segment_count() > value) - value = data->get_segment_count(); +uint32_t Session::get_highest_segment_id() const +{ + return highest_segment_id_; +} - return value; +uint64_t Session::get_segment_sample_count(uint32_t segment_id) const +{ + if (segment_id < segment_sample_count_.size()) + return segment_sample_count_[segment_id]; + else + return 0; } vector Session::get_triggers(uint32_t segment_id) const @@ -878,6 +965,18 @@ const vector< shared_ptr > Session::signalbases() const return signalbases_; } +uint32_t Session::get_signal_count(data::SignalBase::ChannelType type) const +{ + return count_if(signalbases_.begin(), signalbases_.end(), + [&] (shared_ptr sb) { return sb->type() == type; }); +} + +uint32_t Session::get_next_signal_index(data::SignalBase::ChannelType type) +{ + next_index_list_[type]++; + return next_index_list_[type]; +} + void Session::add_generated_signal(shared_ptr signal) { signalbases_.push_back(signal); @@ -961,7 +1060,8 @@ MetadataObjManager* Session::metadata_obj_manager() void Session::set_capture_state(capture_state state) { - bool changed; + if (state == capture_state_) + return; if (state == Running) acq_time_.restart(); @@ -970,12 +1070,10 @@ void Session::set_capture_state(capture_state state) { lock_guard lock(sampling_mutex_); - changed = capture_state_ != state; capture_state_ = state; } - if (changed) - capture_state_changed(state); + capture_state_changed(state); } void Session::update_signals() @@ -1262,6 +1360,7 @@ void Session::signal_new_segment() if (new_segment_id > highest_segment_id_) { highest_segment_id_ = new_segment_id; + segment_sample_count_.emplace_back(0); new_segment(highest_segment_id_); } } @@ -1462,6 +1561,9 @@ void Session::feed_in_logic(shared_ptr logic) cur_logic_segment_->append_payload(logic); + segment_sample_count_[highest_segment_id_] = + max(segment_sample_count_[highest_segment_id_], cur_logic_segment_->get_sample_count()); + data_received(); } @@ -1528,6 +1630,9 @@ void Session::feed_in_analog(shared_ptr analog) // Append the samples in the segment segment->append_interleaved_samples(channel_data++, analog->num_samples(), channels.size()); + + segment_sample_count_[highest_segment_id_] = + max(segment_sample_count_[highest_segment_id_], segment->get_sample_count()); } if (sweep_beginning) {