#include <boost/thread/locks.hpp>
#include <boost/thread/shared_mutex.hpp>
-#ifdef ENABLE_DECODE
-#include <libsigrokdecode/libsigrokdecode.h>
-#endif
+#include <cassert>
+#include <mutex>
+#include <stdexcept>
-#include "session.hpp"
+#include <sys/stat.h>
+#include "session.hpp"
#include "devicemanager.hpp"
#include "data/analog.hpp"
#include "devices/hardwaredevice.hpp"
#include "devices/sessionfile.hpp"
+#include "toolbars/mainbar.hpp"
+
#include "view/analogsignal.hpp"
#include "view/decodetrace.hpp"
#include "view/logicsignal.hpp"
#include "view/signal.hpp"
#include "view/view.hpp"
-#include <cassert>
-#include <mutex>
-#include <stdexcept>
-
-#include <sys/stat.h>
-
-#include <QDebug>
-
#include <libsigrokcxx/libsigrokcxx.hpp>
+#ifdef ENABLE_DECODE
+#include <libsigrokdecode/libsigrokdecode.h>
+#endif
+
using boost::shared_lock;
using boost::shared_mutex;
using boost::unique_lock;
using Glib::Variant;
namespace pv {
-Session::Session(DeviceManager &device_manager) :
+Session::Session(DeviceManager &device_manager, QString name) :
device_manager_(device_manager),
+ name_(name),
capture_state_(Stopped),
cur_samplerate_(0)
{
return device_;
}
+QString Session::name() const
+{
+ return name_;
+}
+
+void Session::set_name(QString name)
+{
+ if (default_name_.isEmpty())
+ default_name_ = name;
+
+ name_ = name;
+
+ name_changed();
+}
+
+std::shared_ptr<pv::view::View> Session::main_view() const
+{
+ return main_view_;
+}
+
+void Session::set_main_bar(std::shared_ptr<pv::toolbars::MainBar> main_bar)
+{
+ main_bar_ = main_bar;
+}
+
+shared_ptr<pv::toolbars::MainBar> Session::main_bar() const
+{
+ return main_bar_;
+}
+
+void Session::save_settings(QSettings &settings) const
+{
+ map<string, string> dev_info;
+ list<string> key_list;
+ int stacks = 0;
+
+ if (device_) {
+ settings.beginGroup("Device");
+ key_list.push_back("vendor");
+ key_list.push_back("model");
+ key_list.push_back("version");
+ key_list.push_back("serial_num");
+ key_list.push_back("connection_id");
+
+ dev_info = device_manager_.get_device_info(device_);
+
+ for (string key : key_list) {
+ if (dev_info.count(key))
+ settings.setValue(QString::fromUtf8(key.c_str()),
+ QString::fromUtf8(dev_info.at(key).c_str()));
+ else
+ settings.remove(QString::fromUtf8(key.c_str()));
+ }
+
+ // Save channels and decoders
+ for (shared_ptr<data::SignalBase> base : signalbases_) {
+#ifdef ENABLE_DECODE
+ if (base->is_decode_signal()) {
+ shared_ptr<pv::data::DecoderStack> decoder_stack =
+ base->decoder_stack();
+ std::shared_ptr<data::decode::Decoder> top_decoder =
+ decoder_stack->stack().front();
+
+ settings.beginGroup("decoder_stack" + QString::number(stacks++));
+ settings.setValue("id", top_decoder->decoder()->id);
+ settings.setValue("name", top_decoder->decoder()->name);
+ settings.endGroup();
+ } else
+#endif
+ {
+ settings.beginGroup(base->internal_name());
+ base->save_settings(settings);
+ settings.endGroup();
+ }
+ }
+
+ settings.setValue("decoder_stacks", stacks);
+ settings.endGroup();
+ }
+}
+
+void Session::restore_settings(QSettings &settings)
+{
+ map<string, string> dev_info;
+ list<string> key_list;
+ shared_ptr<devices::HardwareDevice> device;
+
+ // Re-select last used device if possible but only if it's not demo
+ settings.beginGroup("Device");
+ key_list.push_back("vendor");
+ key_list.push_back("model");
+ key_list.push_back("version");
+ key_list.push_back("serial_num");
+ key_list.push_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(std::make_pair(key, value));
+ }
+
+ if (dev_info.count("model") > 0)
+ device = device_manager_.find_device_from_info(dev_info);
+
+ if (device) {
+ set_device(device);
+
+ // 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 stacks = settings.value("decoder_stacks").toInt();
+
+ for (int i = 0; i < stacks; i++) {
+ settings.beginGroup("decoder_stack" + QString::number(i++));
+
+ QString id = settings.value("id").toString();
+ add_decoder(srd_decoder_get_by_id(id.toStdString().c_str()));
+
+ settings.endGroup();
+ }
+#endif
+ }
+
+ settings.endGroup();
+}
+
void Session::set_device(shared_ptr<devices::Device> device)
{
assert(device);
device_.reset();
+ // Revert name back to default name (e.g. "Untitled-1") as the data is gone
+ name_ = default_name_;
+ name_changed();
+
// Remove all stored data
for (std::shared_ptr<pv::view::View> view : views_) {
view->clear_signals();
device_->open();
} catch (const QString &e) {
device_.reset();
- device_selected();
+ device_changed();
throw;
}
});
update_signals();
- device_selected();
+ device_changed();
}
void Session::set_default_device()
for (const shared_ptr<data::SignalData> d : all_signal_data_)
d->clear();
+ // Revert name back to default name (e.g. "Untitled-1") as the data is gone
+ name_ = default_name_;
+ name_changed();
+
// Begin the session
sampling_thread_ = std::thread(
&Session::sample_thread_proc, this, error_handler);
void Session::register_view(std::shared_ptr<pv::view::View> view)
{
+ if (views_.empty()) {
+ main_view_ = view;
+ }
+
views_.insert(view);
}
void Session::deregister_view(std::shared_ptr<pv::view::View> view)
{
views_.erase(view);
+
+ if (views_.empty()) {
+ main_view_.reset();
+
+ // Without a view there can be no main bar
+ main_bar_.reset();
+ }
+}
+
+bool Session::has_view(std::shared_ptr<pv::view::View> view)
+{
+ return views_.find(view) != views_.end();
}
double Session::get_samplerate() const
shared_ptr<data::SignalBase>(new data::SignalBase(nullptr));
signalbase->set_decoder_stack(decoder_stack);
+ signalbases_.insert(signalbase);
for (std::shared_ptr<pv::view::View> view : views_)
view->add_decode_trace(signalbase);