From 323715c41a09a1aba08f4b716e9d93da58f0f3a8 Mon Sep 17 00:00:00 2001 From: Soeren Apel Date: Sat, 23 Feb 2019 14:33:22 +0100 Subject: [PATCH] Fix #971: Allow saving/restoring of session setups --- pv/session.cpp | 138 ++++++++++++++++++++------------------ pv/session.hpp | 4 ++ pv/toolbars/mainbar.cpp | 65 ++++++++++++++++-- pv/toolbars/mainbar.hpp | 7 ++ pv/widgets/importmenu.cpp | 16 +++-- pv/widgets/importmenu.hpp | 3 +- 6 files changed, 159 insertions(+), 74 deletions(-) diff --git a/pv/session.cpp b/pv/session.cpp index d406b9f..99bd748 100644 --- a/pv/session.cpp +++ b/pv/session.cpp @@ -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& 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& 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 dev_info; list key_list; - int decode_signals = 0, views = 0; if (device_) { shared_ptr hw_device = @@ -241,39 +279,45 @@ void Session::save_settings(QSettings &settings) const settings.endGroup(); } - // Save channels and decoders - for (const shared_ptr& base : signalbases_) { + save_setup(settings); + } +} + +void Session::restore_setup(QSettings &settings) +{ + // Restore channels + for (shared_ptr 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 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& 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 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 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 device) diff --git a/pv/session.hpp b/pv/session.hpp index 9566b4a..e8e2dd5 100644 --- a/pv/session.hpp +++ b/pv/session.hpp @@ -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); /** diff --git a/pv/toolbars/mainbar.cpp b/pv/toolbars/mainbar.cpp index e517ff7..4eaf5c2 100644 --- a/pv/toolbars/mainbar.cpp +++ b/pv/toolbars/mainbar.cpp @@ -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 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)), this, SLOT(import_file(shared_ptr))); @@ -170,12 +187,16 @@ MainBar::MainBar(Session &session, QWidget *parent, pv::views::trace::View *view open_button_->setPopupMode(QToolButton::MenuButtonPopup); // Save button - vector open_actions; - open_actions.push_back(action_save_as_); - open_actions.push_back(action_save_selection_as_); + vector 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)), this, SLOT(export_file(shared_ptr))); @@ -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 diff --git a/pv/toolbars/mainbar.hpp b/pv/toolbars/mainbar.hpp index e938dbb..c79837e 100644 --- a/pv/toolbars/mainbar.hpp +++ b/pv/toolbars/mainbar.hpp @@ -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: diff --git a/pv/widgets/importmenu.cpp b/pv/widgets/importmenu.cpp index 1a45aa6..e303424 100644 --- a/pv/widgets/importmenu.cpp +++ b/pv/widgets/importmenu.cpp @@ -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, - QAction *open_action) : + vectoropen_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(); } diff --git a/pv/widgets/importmenu.hpp b/pv/widgets/importmenu.hpp index d1d5231..c70962a 100644 --- a/pv/widgets/importmenu.hpp +++ b/pv/widgets/importmenu.hpp @@ -26,6 +26,7 @@ #include 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 context, - QAction *open_action = nullptr); + vectoropen_actions = vector()); private Q_SLOTS: void on_action(QObject *action); -- 2.30.2