#include <sys/stat.h>
#include <QDebug>
+#include <QDir>
#include <QFileInfo>
#include "devicemanager.hpp"
#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"
cur_samplerate_(0),
data_saved_(true)
{
+ // Use this name also for the QObject instance
+ setObjectName(name_);
}
Session::~Session()
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<views::ViewBase> > Session::views() const
{
return views_;
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<data::SignalBase>& 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
settings.endGroup();
}
- shared_ptr<devices::SessionFile> sessionfile_device =
- dynamic_pointer_cast<devices::SessionFile>(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<devices::SessionFile> sessionfile_device =
+ dynamic_pointer_cast<devices::SessionFile>(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<devices::InputFile> inputfile_device =
- dynamic_pointer_cast<devices::InputFile>(device_);
+ shared_ptr<devices::InputFile> inputfile_device =
+ dynamic_pointer_cast<devices::InputFile>(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);
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<data::SignalBase> signal;
+
+ if (type == SignalBase::MathChannel)
+ signal = make_shared<data::MathSignal>(*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<data::DecodeSignal> signal = add_decode_signal();
signal->restore_settings(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<devices::SessionFile>(device_manager_.context(),
filename.toStdString());
- }
}
if (device_type == "inputfile") {
settings.endGroup();
}
+
if (device) {
set_device(device);
+ restore_setup(settings);
start_capture([](QString infoMessage) {
// TODO Emulate noquote()
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)
* data type.
*/
auto found = fmt_opts.find(key);
- if (found == fmt_opts.end())
+ if (found == fmt_opts.end()) {
+ qCritical() << "Supplied input option" << QString::fromStdString(key) <<
+ "is not a valid option for this input module, it will be ignored!";
continue;
+ }
+
shared_ptr<Option> opt = found->second;
result[key] = opt->parse_string(val);
}
return f.first == user_name; });
if (iter == formats.end()) {
MainWindow::show_session_error(tr("Error"),
- tr("Unexpected input format: %s").arg(QString::fromStdString(format)));
+ tr("Unexpected input format: %1").arg(QString::fromStdString(format)));
return;
}
input_format = (*iter).second;
start_capture([&, errorMessage](QString infoMessage) {
MainWindow::show_session_error(errorMessage, infoMessage); });
+ // Only set save path if we loaded an srzip file
+ if (dynamic_pointer_cast<devices::SessionFile>(device_))
+ set_save_path(QFileInfo(file_name).absolutePath());
+
set_name(QFileInfo(file_name).fileName());
}
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.
}
// 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()
return samplerate;
}
-uint32_t Session::get_segment_count() const
+uint32_t Session::get_highest_segment_id() const
{
- uint32_t value = 0;
-
- // Find the highest number of segments
- for (const shared_ptr<data::SignalData>& data : all_signal_data_)
- if (data->get_segment_count() > value)
- value = data->get_segment_count();
+ 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<util::Timestamp> Session::get_triggers(uint32_t segment_id) const
return signalbases_;
}
+uint32_t Session::get_signal_count(data::SignalBase::ChannelType type) const
+{
+ return count_if(signalbases_.begin(), signalbases_.end(),
+ [&] (shared_ptr<SignalBase> 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<data::SignalBase> signal)
{
signalbases_.push_back(signal);
void Session::set_capture_state(capture_state state)
{
- bool changed;
+ if (state == capture_state_)
+ return;
if (state == Running)
acq_time_.restart();
{
lock_guard<mutex> lock(sampling_mutex_);
- changed = capture_state_ != state;
capture_state_ = state;
}
- if (changed)
- capture_state_changed(state);
+ capture_state_changed(state);
}
void Session::update_signals()
if (new_segment_id > highest_segment_id_) {
highest_segment_id_ = new_segment_id;
+ segment_sample_count_.emplace_back(0);
new_segment(highest_segment_id_);
}
}
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();
}
// 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) {