Fix #971: Allow saving/restoring of session setups
authorSoeren Apel <soeren@apelpie.net>
Sat, 23 Feb 2019 13:33:22 +0000 (14:33 +0100)
committerSoeren Apel <soeren@apelpie.net>
Sat, 2 Mar 2019 13:42:42 +0000 (14:42 +0100)
pv/session.cpp
pv/session.hpp
pv/toolbars/mainbar.cpp
pv/toolbars/mainbar.hpp
pv/widgets/importmenu.cpp
pv/widgets/importmenu.hpp

index d406b9f..99bd748 100644 (file)
@@ -187,11 +187,49 @@ bool Session::data_saved() const
        return data_saved_;
 }
 
+void Session::save_setup(QSettings &settings) const
+{
+       int decode_signals = 0, views = 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(decode_signals++));
+                       base->save_settings(settings);
+                       settings.endGroup();
+               } else
+#endif
+               {
+                       settings.beginGroup(base->internal_name());
+                       base->save_settings(settings);
+                       settings.endGroup();
+               }
+       }
+
+       settings.setValue("decode_signals", decode_signals);
+
+       // 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 (const shared_ptr<views::ViewBase>& view : views_) {
+               if (view != main_view_) {
+                       settings.beginGroup("view" + QString::number(views++));
+                       view->save_settings(settings);
+                       settings.endGroup();
+               }
+       }
+
+       settings.setValue("views", views);
+}
+
 void Session::save_settings(QSettings &settings) const
 {
        map<string, string> dev_info;
        list<string> key_list;
-       int decode_signals = 0, views = 0;
 
        if (device_) {
                shared_ptr<devices::HardwareDevice> hw_device =
@@ -241,39 +279,45 @@ void Session::save_settings(QSettings &settings) const
                        settings.endGroup();
                }
 
-               // Save channels and decoders
-               for (const shared_ptr<data::SignalBase>& base : signalbases_) {
+               save_setup(settings);
+       }
+}
+
+void Session::restore_setup(QSettings &settings)
+{
+       // 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
-                       if (base->is_decode_signal()) {
-                               settings.beginGroup("decode_signal" + QString::number(decode_signals++));
-                               base->save_settings(settings);
-                               settings.endGroup();
-                       } else
+       int decode_signals = settings.value("decode_signals").toInt();
+
+       for (int i = 0; i < decode_signals; i++) {
+               settings.beginGroup("decode_signal" + QString::number(i));
+               shared_ptr<data::DecodeSignal> signal = add_decode_signal();
+               signal->restore_settings(settings);
+               settings.endGroup();
+       }
 #endif
-                       {
-                               settings.beginGroup(base->internal_name());
-                               base->save_settings(settings);
-                               settings.endGroup();
-                       }
-               }
 
-               settings.setValue("decode_signals", decode_signals);
+       // Restore views
+       int views = settings.value("views").toInt();
 
-               // 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 (int i = 0; i < views; i++) {
+               settings.beginGroup("view" + QString::number(i));
 
-               for (const shared_ptr<views::ViewBase>& view : views_) {
-                       if (view != main_view_) {
-                               settings.beginGroup("view" + QString::number(views++));
-                               view->save_settings(settings);
-                               settings.endGroup();
-                       }
-               }
+               if (i > 0) {
+                       views::ViewType type = (views::ViewType)settings.value("type").toInt();
+                       add_view(name_, type, this);
+                       views_.back()->restore_settings(settings);
+               } else
+                       main_view_->restore_settings(settings);
 
-               settings.setValue("views", views);
+               settings.endGroup();
        }
 }
 
@@ -345,42 +389,8 @@ void Session::restore_settings(QSettings &settings)
                }
        }
 
-       if (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 decode_signals = settings.value("decode_signals").toInt();
-
-               for (int i = 0; i < decode_signals; i++) {
-                       settings.beginGroup("decode_signal" + QString::number(i));
-                       shared_ptr<data::DecodeSignal> signal = add_decode_signal();
-                       signal->restore_settings(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) {
-                               views::ViewType type = (views::ViewType)settings.value("type").toInt();
-                               add_view(name_, type, this);
-                               views_.back()->restore_settings(settings);
-                       } else
-                               main_view_->restore_settings(settings);
-
-                       settings.endGroup();
-               }
-       }
+       if (device)
+               restore_setup(settings);
 }
 
 void Session::select_device(shared_ptr<devices::Device> device)
index 9566b4a..e8e2dd5 100644 (file)
@@ -151,8 +151,12 @@ public:
         */
        bool data_saved() const;
 
+       void save_setup(QSettings &settings) const;
+
        void save_settings(QSettings &settings) const;
 
+       void restore_setup(QSettings &settings);
+
        void restore_settings(QSettings &settings);
 
        /**
index e517ff7..4eaf5c2 100644 (file)
@@ -93,6 +93,8 @@ MainBar::MainBar(Session &session, QWidget *parent, pv::views::trace::View *view
        action_open_(new QAction(this)),
        action_save_as_(new QAction(this)),
        action_save_selection_as_(new QAction(this)),
+       action_restore_setup_(new QAction(this)),
+       action_save_setup_(new QAction(this)),
        action_connect_(new QAction(this)),
        open_button_(new QToolButton()),
        save_button_(new QToolButton()),
@@ -129,6 +131,10 @@ MainBar::MainBar(Session &session, QWidget *parent, pv::views::trace::View *view
        connect(action_open_, SIGNAL(triggered(bool)),
                this, SLOT(on_actionOpen_triggered()));
 
+       action_restore_setup_->setText(tr("Restore Session Setu&p..."));
+       connect(action_restore_setup_, SIGNAL(triggered(bool)),
+               this, SLOT(on_actionRestoreSetup_triggered()));
+
        action_save_as_->setText(tr("&Save As..."));
        action_save_as_->setIcon(QIcon::fromTheme("document-save-as",
                QIcon(":/icons/document-save-as.png")));
@@ -143,6 +149,10 @@ MainBar::MainBar(Session &session, QWidget *parent, pv::views::trace::View *view
        connect(action_save_selection_as_, SIGNAL(triggered(bool)),
                this, SLOT(on_actionSaveSelectionAs_triggered()));
 
+       action_save_setup_->setText(tr("Save Session Setu&p..."));
+       connect(action_save_setup_, SIGNAL(triggered(bool)),
+               this, SLOT(on_actionSaveSetup_triggered()));
+
        widgets::ExportMenu *menu_file_export = new widgets::ExportMenu(this,
                session.device_manager().context());
        menu_file_export->setTitle(tr("&Export"));
@@ -160,8 +170,15 @@ MainBar::MainBar(Session &session, QWidget *parent, pv::views::trace::View *view
                this, SLOT(on_actionConnect_triggered()));
 
        // Open button
+       vector<QAction*> open_actions;
+       open_actions.push_back(action_open_);
+       QAction* separator_o = new QAction(this);
+       separator_o->setSeparator(true);
+       open_actions.push_back(separator_o);
+       open_actions.push_back(action_restore_setup_);
+
        widgets::ImportMenu *import_menu = new widgets::ImportMenu(this,
-               session.device_manager().context(), action_open_);
+               session.device_manager().context(), open_actions);
        connect(import_menu, SIGNAL(format_selected(shared_ptr<sigrok::InputFormat>)),
                this, SLOT(import_file(shared_ptr<sigrok::InputFormat>)));
 
@@ -170,12 +187,16 @@ MainBar::MainBar(Session &session, QWidget *parent, pv::views::trace::View *view
        open_button_->setPopupMode(QToolButton::MenuButtonPopup);
 
        // Save button
-       vector<QAction*> open_actions;
-       open_actions.push_back(action_save_as_);
-       open_actions.push_back(action_save_selection_as_);
+       vector<QAction*> save_actions;
+       save_actions.push_back(action_save_as_);
+       save_actions.push_back(action_save_selection_as_);
+       QAction* separator_s = new QAction(this);
+       separator_s->setSeparator(true);
+       save_actions.push_back(separator_s);
+       save_actions.push_back(action_save_setup_);
 
        widgets::ExportMenu *export_menu = new widgets::ExportMenu(this,
-               session.device_manager().context(), open_actions);
+               session.device_manager().context(), save_actions);
        connect(export_menu, SIGNAL(format_selected(shared_ptr<sigrok::OutputFormat>)),
                this, SLOT(export_file(shared_ptr<sigrok::OutputFormat>)));
 
@@ -783,6 +804,40 @@ void MainBar::on_actionSaveSelectionAs_triggered()
        export_file(session_.device_manager().context()->output_formats()["srzip"], true);
 }
 
+void MainBar::on_actionSaveSetup_triggered()
+{
+       QSettings settings;
+       const QString dir = settings.value(SettingSaveDirectory).toString();
+
+       const QString file_name = QFileDialog::getSaveFileName(
+               this, tr("Save File"), dir, tr(
+                               "PulseView Session Setups (*.pvs);;"
+                               "All Files (*)"));
+
+       if (file_name.isEmpty())
+               return;
+
+       QSettings settings_storage(file_name, QSettings::IniFormat);
+       session_.save_setup(settings_storage);
+}
+
+void MainBar::on_actionRestoreSetup_triggered()
+{
+       QSettings settings;
+       const QString dir = settings.value(SettingSaveDirectory).toString();
+
+       const QString file_name = QFileDialog::getOpenFileName(
+               this, tr("Open File"), dir, tr(
+                               "PulseView Session Setups (*.pvs);;"
+                               "All Files (*)"));
+
+       if (file_name.isEmpty())
+               return;
+
+       QSettings settings_storage(file_name, QSettings::IniFormat);
+       session_.restore_setup(settings_storage);
+}
+
 void MainBar::on_actionConnect_triggered()
 {
        // Stop any currently running capture session
index e938dbb..c79837e 100644 (file)
@@ -98,6 +98,8 @@ public:
        QAction* action_open() const;
        QAction* action_save_as() const;
        QAction* action_save_selection_as() const;
+       QAction* action_restore_setup() const;
+       QAction* action_save_setup() const;
        QAction* action_connect() const;
 
 private:
@@ -118,6 +120,8 @@ private:
        QAction *const action_open_;
        QAction *const action_save_as_;
        QAction *const action_save_selection_as_;
+       QAction *const action_restore_setup_;
+       QAction *const action_save_setup_;
        QAction *const action_connect_;
 
 private Q_SLOTS:
@@ -143,6 +147,9 @@ private Q_SLOTS:
        void on_actionSaveAs_triggered();
        void on_actionSaveSelectionAs_triggered();
 
+       void on_actionSaveSetup_triggered();
+       void on_actionRestoreSetup_triggered();
+
        void on_actionConnect_triggered();
 
 protected:
index 1a45aa6..e303424 100644 (file)
@@ -31,6 +31,7 @@ using std::map;
 using std::pair;
 using std::string;
 using std::shared_ptr;
+using std::vector;
 
 using sigrok::Context;
 using sigrok::InputFormat;
@@ -39,16 +40,23 @@ namespace pv {
 namespace widgets {
 
 ImportMenu::ImportMenu(QWidget *parent, shared_ptr<Context> context,
-       QAction *open_action) :
+       vector<QAction *>open_actions) :
        QMenu(parent),
        context_(context),
        mapper_(this)
 {
        assert(context);
 
-       if (open_action) {
-               addAction(open_action);
-               setDefaultAction(open_action);
+       if (!open_actions.empty()) {
+               bool first_action = true;
+               for (auto open_action : open_actions) {
+                       addAction(open_action);
+
+                       if (first_action) {
+                               first_action = false;
+                               setDefaultAction(open_action);
+                       }
+               }
                addSeparator();
        }
 
index d1d5231..c70962a 100644 (file)
@@ -26,6 +26,7 @@
 #include <QSignalMapper>
 
 using std::shared_ptr;
+using std::vector;
 
 namespace sigrok {
 class Context;
@@ -41,7 +42,7 @@ class ImportMenu : public QMenu
 
 public:
        ImportMenu(QWidget *parent, shared_ptr<sigrok::Context> context,
-               QAction *open_action = nullptr);
+               vector<QAction *>open_actions = vector<QAction *>());
 
 private Q_SLOTS:
        void on_action(QObject *action);