From: Soeren Apel Date: Fri, 25 May 2018 14:07:24 +0000 (+0200) Subject: Add imported files to the session save/restore mechanism X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=1325ce422f1b49ab1f693125105b8c373c2965e5 Add imported files to the session save/restore mechanism This commit also makes the file loading more robust by improving the handling of cases where files can't be loaded. --- diff --git a/pv/devices/file.hpp b/pv/devices/file.hpp index d8e9ae9a..23234caa 100644 --- a/pv/devices/file.hpp +++ b/pv/devices/file.hpp @@ -36,7 +36,7 @@ protected: public: /** - * Builds the full name. It only contains all the fields. + * Builds the full name. It contains all the fields. */ string full_name() const; @@ -46,7 +46,7 @@ public: string display_name(const DeviceManager&) const; protected: - const string file_name_; + string file_name_; }; } // namespace devices diff --git a/pv/devices/inputfile.cpp b/pv/devices/inputfile.cpp index 4ffd2dfa..8e973f05 100644 --- a/pv/devices/inputfile.cpp +++ b/pv/devices/inputfile.cpp @@ -21,11 +21,18 @@ #include #include +#include #include +#include + #include "inputfile.hpp" +using sigrok::InputFormat; + using std::map; +using std::out_of_range; +using std::pair; using std::shared_ptr; using std::streamsize; using std::string; @@ -53,6 +60,56 @@ InputFile::InputFile(const shared_ptr &context, { } +InputFile::InputFile(const shared_ptr &context, + QSettings &settings): + File(""), + context_(context), + interrupt_(false) +{ + file_name_ = settings.value("filename").toString().toStdString(); + + QString format_name = settings.value("format").toString(); + + // Find matching format + const map > formats = context->input_formats(); + + try { + format_ = formats.at(format_name.toStdString()); + + // Restore all saved options + 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(); + options_[name.toStdString()] = GlobalSettings::restore_variantbase(settings); + settings.endGroup(); + } + + } catch (out_of_range) { + qWarning() << "Could not find input format" << format_name << + "needed to restore session input file"; + } +} + +void InputFile::save_meta_to_settings(QSettings &settings) +{ + settings.setValue("filename", QString::fromStdString(file_name_)); + + settings.setValue("format", QString::fromStdString(format_->name())); + + settings.setValue("options", (int)options_.size()); + + int i = 0; + for (pair option : options_) { + settings.beginGroup("option" + QString::number(i)); + settings.setValue("name", QString::fromStdString(option.first)); + GlobalSettings::store_variantbase(settings, option.second); + settings.endGroup(); + i++; + } +} + void InputFile::open() { if (session_) @@ -60,6 +117,9 @@ void InputFile::open() else session_ = context_->create_session(); + if (!format_) + return; + input_ = format_->create_input(options_); if (!input_) @@ -99,6 +159,9 @@ void InputFile::start() void InputFile::run() { + if (!input_) + return; + if (!f) { // Previous call to run() processed the entire file already f = new ifstream(file_name_, ios::binary); diff --git a/pv/devices/inputfile.hpp b/pv/devices/inputfile.hpp index 41698e6d..e08832f6 100644 --- a/pv/devices/inputfile.hpp +++ b/pv/devices/inputfile.hpp @@ -26,6 +26,8 @@ #include "file.hpp" +#include + using std::atomic; using std::ifstream; using std::map; @@ -47,6 +49,15 @@ public: shared_ptr format, const map &options); + /** + * Constructor that loads a file using the metadata saved by + * save_meta_to_settings() before. + */ + InputFile(const shared_ptr &context, + QSettings &settings); + + void save_meta_to_settings(QSettings &settings); + void open(); void close(); @@ -59,8 +70,8 @@ public: private: const shared_ptr context_; - const shared_ptr format_; - const map options_; + shared_ptr format_; + map options_; shared_ptr input_; ifstream *f; diff --git a/pv/globalsettings.cpp b/pv/globalsettings.cpp index c77327c3..cd356ae6 100644 --- a/pv/globalsettings.cpp +++ b/pv/globalsettings.cpp @@ -25,6 +25,7 @@ #include using std::map; +using std::string; using std::vector; namespace pv { @@ -169,5 +170,33 @@ GVariant* GlobalSettings::restore_gvariant(QSettings &settings) return value; } +void GlobalSettings::store_variantbase(QSettings &settings, Glib::VariantBase v) +{ + const QByteArray var_data = QByteArray((const char*)v.get_data(), v.get_size()); + + settings.setValue("value", var_data); + settings.setValue("type", QString::fromStdString(v.get_type_string())); +} + +Glib::VariantBase GlobalSettings::restore_variantbase(QSettings &settings) +{ + QString raw_type = settings.value("type").toString(); + GVariantType *var_type = g_variant_type_new(raw_type.toUtf8()); + + QByteArray data = settings.value("value").toByteArray(); + + gpointer var_data = g_memdup((gconstpointer)data.constData(), + (guint)data.size()); + + GVariant *value = g_variant_new_from_data(var_type, var_data, + data.size(), false, g_free, var_data); + + Glib::VariantBase ret_val = Glib::VariantBase(value, true); + + g_variant_type_free(var_type); + g_variant_unref(value); + + return ret_val; +} } // namespace pv diff --git a/pv/globalsettings.hpp b/pv/globalsettings.hpp index b7f7af06..276a9682 100644 --- a/pv/globalsettings.hpp +++ b/pv/globalsettings.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -97,6 +98,10 @@ public: static GVariant* restore_gvariant(QSettings &settings); + static void store_variantbase(QSettings &settings, Glib::VariantBase v); + + static Glib::VariantBase restore_variantbase(QSettings &settings); + private: static vector callbacks_; diff --git a/pv/session.cpp b/pv/session.cpp index 4aba385b..7df73d63 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -207,7 +207,7 @@ void Session::save_settings(QSettings &settings) const } shared_ptr sessionfile_device = - dynamic_pointer_cast< devices::SessionFile >(device_); + dynamic_pointer_cast(device_); if (sessionfile_device) { settings.setValue("device_type", "sessionfile"); @@ -217,6 +217,16 @@ void Session::save_settings(QSettings &settings) const settings.endGroup(); } + 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(); + } + // Save channels and decoders for (shared_ptr base : signalbases_) { #ifdef ENABLE_DECODE @@ -290,21 +300,34 @@ void Session::restore_settings(QSettings &settings) settings.endGroup(); } - if (device_type == "sessionfile") { - settings.beginGroup("device"); - QString filename = settings.value("filename").toString(); - settings.endGroup(); + if ((device_type == "sessionfile") || (device_type == "inputfile")) { + if (device_type == "sessionfile") { + settings.beginGroup("device"); + QString filename = settings.value("filename").toString(); + settings.endGroup(); + + if (QFileInfo(filename).isReadable()) { + device = make_shared(device_manager_.context(), + filename.toStdString()); + } + } + + if (device_type == "inputfile") { + settings.beginGroup("device"); + device = make_shared(device_manager_.context(), + settings); + settings.endGroup(); + } - if (QFileInfo(filename).isReadable()) { - device = make_shared(device_manager_.context(), - filename.toStdString()); + if (device) { set_device(device); start_capture([](QString infoMessage) { // TODO Emulate noquote() qDebug() << "Session error:" << infoMessage; }); - set_name(QFileInfo(filename).fileName()); + set_name(QString::fromStdString( + dynamic_pointer_cast(device)->display_name(device_manager_))); } }