From 3a21afa6a5dfc06c17f127960bb0038fd322f213 Mon Sep 17 00:00:00 2001 From: Soeren Apel Date: Wed, 31 Aug 2016 08:19:02 +0200 Subject: [PATCH] Save/restore view states and signal settings --- CMakeLists.txt | 4 ++-- pv/mainwindow.cpp | 12 +++++++++++ pv/mainwindow.hpp | 3 +++ pv/session.cpp | 45 ++++++++++++++++++++++++++++++++++++---- pv/session.hpp | 6 +++++- pv/view/analogsignal.cpp | 17 +++++++++++++++ pv/view/analogsignal.hpp | 4 ++++ pv/view/signal.cpp | 10 +++++++++ pv/view/signal.hpp | 4 ++++ pv/view/view.cpp | 43 ++++++++++++++++++++++++++++++++++++++ pv/view/view.hpp | 4 ++++ 11 files changed, 145 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b288502..69e62ee5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,9 +98,9 @@ else() endif() if(ENABLE_TESTS) - find_package(Boost 1.53 COMPONENTS filesystem system thread unit_test_framework REQUIRED) + find_package(Boost 1.53 COMPONENTS filesystem serialization system thread unit_test_framework REQUIRED) else() - find_package(Boost 1.53 COMPONENTS filesystem system thread REQUIRED) + find_package(Boost 1.53 COMPONENTS filesystem serialization system thread REQUIRED) endif() # Find the platform's thread library (needed for C++11 threads). diff --git a/pv/mainwindow.cpp b/pv/mainwindow.cpp index 77dc9462..874f66ce 100644 --- a/pv/mainwindow.cpp +++ b/pv/mainwindow.cpp @@ -218,6 +218,9 @@ shared_ptr MainWindow::add_session() shared_ptr session = make_shared(device_manager_, name); + connect(session.get(), SIGNAL(add_view(const QString&, view::ViewType, Session*)), + this, SLOT(on_add_view(const QString&, view::ViewType, Session*))); + sessions_.push_back(session); shared_ptr main_view = @@ -334,6 +337,15 @@ bool MainWindow::restoreState(const QByteArray &state, int version) return false; } +void MainWindow::on_add_view(const QString &title, view::ViewType type, + Session *session) +{ + // We get a pointer and need a reference + for (std::shared_ptr s : sessions_) + if (s.get() == session) + add_view(title, type, *s); +} + void MainWindow::on_actionViewStickyScrolling_triggered() { shared_ptr view = get_active_view(); diff --git a/pv/mainwindow.hpp b/pv/mainwindow.hpp index 2e4c6bbd..87e8755b 100644 --- a/pv/mainwindow.hpp +++ b/pv/mainwindow.hpp @@ -91,6 +91,9 @@ private: virtual bool restoreState(const QByteArray &state, int version = 0); private Q_SLOTS: + void on_add_view(const QString &title, view::ViewType type, + Session *session); + void on_actionViewStickyScrolling_triggered(); void on_actionViewColouredBg_triggered(); diff --git a/pv/session.cpp b/pv/session.cpp index 38e862cf..b53360fc 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -167,7 +167,7 @@ void Session::save_settings(QSettings &settings) const { map dev_info; list key_list; - int stacks = 0; + int stacks = 0, views = 0; if (device_) { shared_ptr hw_device = @@ -230,6 +230,22 @@ void Session::save_settings(QSettings &settings) const } settings.setValue("decoder_stacks", stacks); + + // Save view states and their signal settings + // Note: main_view must be saved as view0 + settings.beginGroup("view" + QString::number(views++)); + main_view_->save_settings(settings); + settings.endGroup(); + + for (shared_ptr view : views_) { + if (view != main_view_) { + settings.beginGroup("view" + QString::number(views++)); + view->save_settings(settings); + settings.endGroup(); + } + } + + settings.setValue("views", views); } } @@ -307,6 +323,22 @@ void Session::restore_settings(QSettings &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) { + view::ViewType type = (view::ViewType)settings.value("type").toInt(); + add_view(name_, type, this); + views_.back()->restore_settings(settings); + } else + main_view_->restore_settings(settings); + + settings.endGroup(); + } } } @@ -439,12 +471,13 @@ void Session::register_view(std::shared_ptr view) main_view_ = view; } - views_.insert(view); + views_.push_back(view); } void Session::deregister_view(std::shared_ptr view) { - views_.erase(view); + views_.remove_if([&](std::shared_ptr v) { + return v == view; }); if (views_.empty()) { main_view_.reset(); @@ -456,7 +489,11 @@ void Session::deregister_view(std::shared_ptr view) bool Session::has_view(std::shared_ptr view) { - return views_.find(view) != views_.end(); + for (std::shared_ptr v : views_) + if (v == view) + return true; + + return false; } double Session::get_samplerate() const diff --git a/pv/session.hpp b/pv/session.hpp index e7a90ae9..79ec42cd 100644 --- a/pv/session.hpp +++ b/pv/session.hpp @@ -42,6 +42,7 @@ #include #include "util.hpp" +#include "view/viewwidget.hpp" struct srd_decoder; struct srd_channel; @@ -180,7 +181,7 @@ private: std::shared_ptr device_; QString default_name_, name_; - std::unordered_set< std::shared_ptr > views_; + std::list< std::shared_ptr > views_; std::shared_ptr main_view_; std::shared_ptr main_bar_; @@ -217,6 +218,9 @@ Q_SIGNALS: void data_received(); void frame_ended(); + + void add_view(const QString &title, view::ViewType type, + Session *session); }; } // namespace pv diff --git a/pv/view/analogsignal.cpp b/pv/view/analogsignal.cpp index fbffb2eb..0d38314d 100644 --- a/pv/view/analogsignal.cpp +++ b/pv/view/analogsignal.cpp @@ -88,6 +88,23 @@ shared_ptr AnalogSignal::data() const return base_->analog_data(); } +void AnalogSignal::save_settings(QSettings &settings) const +{ + settings.setValue("vdivs", vdivs_); + settings.setValue("scale_index", scale_index_); +} + +void AnalogSignal::restore_settings(QSettings &settings) +{ + if (settings.contains("vdivs")) + vdivs_ = settings.value("vdivs").toInt(); + + if (settings.contains("scale_index")) { + scale_index_ = settings.value("scale_index").toInt(); + update_scale(); + } +} + std::pair AnalogSignal::v_extents() const { const int h = vdivs_ * div_height_; diff --git a/pv/view/analogsignal.hpp b/pv/view/analogsignal.hpp index 81fdf393..1369a76c 100644 --- a/pv/view/analogsignal.hpp +++ b/pv/view/analogsignal.hpp @@ -59,6 +59,10 @@ public: std::shared_ptr data() const; + virtual void save_settings(QSettings &settings) const; + + virtual void restore_settings(QSettings &settings); + /** * Computes the vertical extents of the contents of this row item. * @return A pair containing the minimum and maximum y-values. diff --git a/pv/view/signal.cpp b/pv/view/signal.cpp index 8dd329e0..ad139f7e 100644 --- a/pv/view/signal.cpp +++ b/pv/view/signal.cpp @@ -91,6 +91,16 @@ shared_ptr Signal::base() const return base_; } +void Signal::save_settings(QSettings &settings) const +{ + (void)settings; +} + +void Signal::restore_settings(QSettings &settings) +{ + (void)settings; +} + const ViewItemOwner::item_list& Signal::child_items() const { return items_; diff --git a/pv/view/signal.hpp b/pv/view/signal.hpp index a449382f..5bac1f44 100644 --- a/pv/view/signal.hpp +++ b/pv/view/signal.hpp @@ -66,6 +66,10 @@ public: std::shared_ptr base() const; + virtual void save_settings(QSettings &settings) const; + + virtual void restore_settings(QSettings &settings); + /** * Returns a list of row items owned by this object. */ diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 3f832474..c69e75ca 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -28,10 +28,14 @@ #include #include #include +#include #include #include #include +#include +#include +#include #include #include @@ -245,6 +249,45 @@ const Viewport* View::viewport() const return viewport_; } +void View::save_settings(QSettings &settings) const +{ + settings.setValue("scale", scale_); + + std::stringstream ss; + boost::archive::text_oarchive oa(ss); + oa << boost::serialization::make_nvp("offset", offset_); + settings.setValue("offset", QString::fromStdString(ss.str())); + + for (shared_ptr signal : signals_) { + settings.beginGroup(signal->base()->internal_name()); + signal->save_settings(settings); + settings.endGroup(); + } +} + +void View::restore_settings(QSettings &settings) +{ + if (settings.contains("scale")) + set_scale(settings.value("scale").toDouble()); + + if (settings.contains("offset")) { + util::Timestamp offset; + std::stringstream ss; + ss << settings.value("offset").toString().toStdString(); + + boost::archive::text_iarchive ia(ss); + ia >> boost::serialization::make_nvp("offset", offset); + + set_offset(offset); + } + + for (shared_ptr signal : signals_) { + settings.beginGroup(signal->base()->internal_name()); + signal->restore_settings(settings); + settings.endGroup(); + } +} + vector< shared_ptr > View::time_items() const { const vector> f(flags()); diff --git a/pv/view/view.hpp b/pv/view/view.hpp index eeb43ec8..cb1035c4 100644 --- a/pv/view/view.hpp +++ b/pv/view/view.hpp @@ -114,6 +114,10 @@ public: const Viewport* viewport() const; + void save_settings(QSettings &settings) const; + + void restore_settings(QSettings &settings); + /** * Gets a list of time markers. */ -- 2.30.2