Save/restore view states and signal settings
authorSoeren Apel <soeren@apelpie.net>
Wed, 31 Aug 2016 06:19:02 +0000 (08:19 +0200)
committerSoeren Apel <soeren@apelpie.net>
Wed, 31 Aug 2016 06:19:02 +0000 (08:19 +0200)
CMakeLists.txt
pv/mainwindow.cpp
pv/mainwindow.hpp
pv/session.cpp
pv/session.hpp
pv/view/analogsignal.cpp
pv/view/analogsignal.hpp
pv/view/signal.cpp
pv/view/signal.hpp
pv/view/view.cpp
pv/view/view.hpp

index 0b28850258cdb88d56a1eab520a0d6500a7bdeb1..69e62ee5e4dd3bed6757c1e20a1a3756ab66c377 100644 (file)
@@ -98,9 +98,9 @@ else()
 endif()
 
 if(ENABLE_TESTS)
 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()
 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).
 endif()
 
 # Find the platform's thread library (needed for C++11 threads).
index 77dc946213ef20850247fc0b5acf15f51b820df3..874f66ce7c2cd8e0fb07d326affa837b7d976d9f 100644 (file)
@@ -218,6 +218,9 @@ shared_ptr<Session> MainWindow::add_session()
 
        shared_ptr<Session> session = make_shared<Session>(device_manager_, name);
 
 
        shared_ptr<Session> session = make_shared<Session>(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<view::View> main_view =
        sessions_.push_back(session);
 
        shared_ptr<view::View> main_view =
@@ -334,6 +337,15 @@ bool MainWindow::restoreState(const QByteArray &state, int version)
        return false;
 }
 
        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<Session> s : sessions_)
+               if (s.get() == session)
+                       add_view(title, type, *s);
+}
+
 void MainWindow::on_actionViewStickyScrolling_triggered()
 {
        shared_ptr<pv::view::View> view = get_active_view();
 void MainWindow::on_actionViewStickyScrolling_triggered()
 {
        shared_ptr<pv::view::View> view = get_active_view();
index 2e4c6bbdcd5e5d00f921acdb741016fb2a581f37..87e8755b8f8a6264e19f4c9b863dbb735a26e384 100644 (file)
@@ -91,6 +91,9 @@ private:
        virtual bool restoreState(const QByteArray &state, int version = 0);
 
 private Q_SLOTS:
        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();
        void on_actionViewStickyScrolling_triggered();
 
        void on_actionViewColouredBg_triggered();
index 38e862cf30fff42732c3396a26eebd6e07ae914d..b53360fcd9508bbbc559978181a33cfe88ecad71 100644 (file)
@@ -167,7 +167,7 @@ void Session::save_settings(QSettings &settings) const
 {
        map<string, string> dev_info;
        list<string> key_list;
 {
        map<string, string> dev_info;
        list<string> key_list;
-       int stacks = 0;
+       int stacks = 0, views = 0;
 
        if (device_) {
                shared_ptr<devices::HardwareDevice> hw_device =
 
        if (device_) {
                shared_ptr<devices::HardwareDevice> hw_device =
@@ -230,6 +230,22 @@ void Session::save_settings(QSettings &settings) const
                }
 
                settings.setValue("decoder_stacks", stacks);
                }
 
                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::View> 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
                        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<pv::view::View> view)
                main_view_ = view;
        }
 
                main_view_ = view;
        }
 
-       views_.insert(view);
+       views_.push_back(view);
 }
 
 void Session::deregister_view(std::shared_ptr<pv::view::View> view)
 {
 }
 
 void Session::deregister_view(std::shared_ptr<pv::view::View> view)
 {
-       views_.erase(view);
+       views_.remove_if([&](std::shared_ptr<pv::view::View> v) {
+               return v == view; });
 
        if (views_.empty()) {
                main_view_.reset();
 
        if (views_.empty()) {
                main_view_.reset();
@@ -456,7 +489,11 @@ void Session::deregister_view(std::shared_ptr<pv::view::View> view)
 
 bool Session::has_view(std::shared_ptr<pv::view::View> view)
 {
 
 bool Session::has_view(std::shared_ptr<pv::view::View> view)
 {
-       return views_.find(view) != views_.end();
+       for (std::shared_ptr<pv::view::View> v : views_)
+               if (v == view)
+                       return true;
+
+       return false;
 }
 
 double Session::get_samplerate() const
 }
 
 double Session::get_samplerate() const
index e7a90ae9c720707f97a3796f8a588257a240e42d..79ec42cd4956354be4c12d08df776c40cddba1b9 100644 (file)
@@ -42,6 +42,7 @@
 #include <QString>
 
 #include "util.hpp"
 #include <QString>
 
 #include "util.hpp"
+#include "view/viewwidget.hpp"
 
 struct srd_decoder;
 struct srd_channel;
 
 struct srd_decoder;
 struct srd_channel;
@@ -180,7 +181,7 @@ private:
        std::shared_ptr<devices::Device> device_;
        QString default_name_, name_;
 
        std::shared_ptr<devices::Device> device_;
        QString default_name_, name_;
 
-       std::unordered_set< std::shared_ptr<pv::view::View> > views_;
+       std::list< std::shared_ptr<pv::view::View> > views_;
        std::shared_ptr<pv::view::View> main_view_;
 
        std::shared_ptr<pv::toolbars::MainBar> main_bar_;
        std::shared_ptr<pv::view::View> main_view_;
 
        std::shared_ptr<pv::toolbars::MainBar> main_bar_;
@@ -217,6 +218,9 @@ Q_SIGNALS:
        void data_received();
 
        void frame_ended();
        void data_received();
 
        void frame_ended();
+
+       void add_view(const QString &title, view::ViewType type,
+               Session *session);
 };
 
 } // namespace pv
 };
 
 } // namespace pv
index fbffb2ebb0061b7a05af272d5647fe45c37b229b..0d38314dfa270e95cdbcb906a01b4f0d025f5004 100644 (file)
@@ -88,6 +88,23 @@ shared_ptr<pv::data::SignalData> AnalogSignal::data() const
        return base_->analog_data();
 }
 
        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<int, int> AnalogSignal::v_extents() const
 {
        const int h = vdivs_ * div_height_;
 std::pair<int, int> AnalogSignal::v_extents() const
 {
        const int h = vdivs_ * div_height_;
index 81fdf393abb16aab3e633582a5c83060d83df0c7..1369a76cf24f2c7852cb27d7683cef103b26287e 100644 (file)
@@ -59,6 +59,10 @@ public:
 
        std::shared_ptr<pv::data::SignalData> data() const;
 
 
        std::shared_ptr<pv::data::SignalData> 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.
        /**
         * Computes the vertical extents of the contents of this row item.
         * @return A pair containing the minimum and maximum y-values.
index 8dd329e0f7fd947c08717068e58dd4999307c827..ad139f7e4ad21cbbb79a03355aa1917fdfbd2d03 100644 (file)
@@ -91,6 +91,16 @@ shared_ptr<data::SignalBase> Signal::base() const
        return base_;
 }
 
        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_;
 const ViewItemOwner::item_list& Signal::child_items() const
 {
        return items_;
index a449382faf080d31e21ff33a383fd20ff3c38a34..5bac1f44d83c821a5dd107d3818bad53ceeef167 100644 (file)
@@ -66,6 +66,10 @@ public:
 
        std::shared_ptr<data::SignalBase> base() const;
 
 
        std::shared_ptr<data::SignalBase> 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.
         */
        /**
         * Returns a list of row items owned by this object.
         */
index 3f832474cebdf9415df879dc3592a7de27a25f7d..c69e75caec10594ba3122aa31a8344a2e5dd5b3a 100644 (file)
 #include <cassert>
 #include <climits>
 #include <cmath>
 #include <cassert>
 #include <climits>
 #include <cmath>
+#include <iostream>
 #include <iterator>
 #include <mutex>
 #include <unordered_set>
 
 #include <iterator>
 #include <mutex>
 #include <unordered_set>
 
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/serialization/serialization.hpp>
 #include <boost/thread/locks.hpp>
 
 #include <QApplication>
 #include <boost/thread/locks.hpp>
 
 #include <QApplication>
@@ -245,6 +249,45 @@ const Viewport* View::viewport() const
        return viewport_;
 }
 
        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<view::Signal> 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<view::Signal> signal : signals_) {
+               settings.beginGroup(signal->base()->internal_name());
+               signal->restore_settings(settings);
+               settings.endGroup();
+       }
+}
+
 vector< shared_ptr<TimeItem> > View::time_items() const
 {
        const vector<shared_ptr<Flag>> f(flags());
 vector< shared_ptr<TimeItem> > View::time_items() const
 {
        const vector<shared_ptr<Flag>> f(flags());
index eeb43ec88303a79ed55f5a93107afe113cc7d143..cb1035c4c93ea202c240e6e42128565f54df419b 100644 (file)
@@ -114,6 +114,10 @@ public:
 
        const Viewport* viewport() const;
 
 
        const Viewport* viewport() const;
 
+       void save_settings(QSettings &settings) const;
+
+       void restore_settings(QSettings &settings);
+
        /**
         * Gets a list of time markers.
         */
        /**
         * Gets a list of time markers.
         */