From 7a0e6da706a57b633bdbf59b22b4379f99ddfa40 Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Sat, 2 Jul 2022 10:01:43 -0500 Subject: [PATCH 1/9] mode/app: decouple mode creation from gui components Signed-off-by: Kiara Navarro --- Software/PC_Application/LibreVNA-GUI.pro | 7 ++ Software/PC_Application/appwindow.cpp | 104 +++++++--------- Software/PC_Application/appwindow.h | 3 +- Software/PC_Application/mode.cpp | 135 +-------------------- Software/PC_Application/mode.h | 9 +- Software/PC_Application/modehandler.cpp | 138 ++++++++++++++++++++++ Software/PC_Application/modehandler.h | 50 ++++++++ Software/PC_Application/modetabwidget.cpp | 14 +++ Software/PC_Application/modetabwidget.h | 18 +++ Software/PC_Application/modewindow.cpp | 99 ++++++++++++++++ Software/PC_Application/modewindow.h | 28 +++++ Software/PC_Application/modewindow.ui | 45 +++++++ 12 files changed, 454 insertions(+), 196 deletions(-) create mode 100644 Software/PC_Application/modehandler.cpp create mode 100644 Software/PC_Application/modehandler.h create mode 100644 Software/PC_Application/modetabwidget.cpp create mode 100644 Software/PC_Application/modetabwidget.h create mode 100644 Software/PC_Application/modewindow.cpp create mode 100644 Software/PC_Application/modewindow.h create mode 100644 Software/PC_Application/modewindow.ui diff --git a/Software/PC_Application/LibreVNA-GUI.pro b/Software/PC_Application/LibreVNA-GUI.pro index bd60738..5665ce2 100644 --- a/Software/PC_Application/LibreVNA-GUI.pro +++ b/Software/PC_Application/LibreVNA-GUI.pro @@ -123,7 +123,10 @@ HEADERS += \ averaging.h \ csv.h \ json.hpp \ + modehandler.h \ mode.h \ + modetabwidget.h \ + modewindow.h \ preferences.h \ savable.h \ scpi.h \ @@ -242,7 +245,10 @@ SOURCES += \ averaging.cpp \ csv.cpp \ main.cpp \ + modehandler.cpp \ mode.cpp \ + modetabwidget.cpp \ + modewindow.cpp \ preferences.cpp \ scpi.cpp \ tcpserver.cpp \ @@ -306,6 +312,7 @@ FORMS += \ VNA/s2pImportOptions.ui \ aboutdialog.ui \ main.ui \ + modewindow.ui \ preferencesdialog.ui DISTFILES += diff --git a/Software/PC_Application/appwindow.cpp b/Software/PC_Application/appwindow.cpp index 305960c..7cb3f28 100644 --- a/Software/PC_Application/appwindow.cpp +++ b/Software/PC_Application/appwindow.cpp @@ -27,12 +27,14 @@ #include "CustomWidgets/informationbox.h" #include "Util/app_common.h" #include "about.h" +#include "mode.h" +#include "modehandler.h" +#include "modewindow.h" #include #include #include #include -#include #include #include #include @@ -168,6 +170,7 @@ AppWindow::AppWindow(QWidget *parent) , appVersion(APP_VERSION) , appGitHash(APP_GIT_HASH) { + // qDebug().setVerbosity(0); qDebug() << "Application start"; @@ -186,6 +189,7 @@ AppWindow::AppWindow(QWidget *parent) Preferences::getInstance().load(); device = nullptr; + modeHandler = nullptr; if(parser.isSet("port")) { bool OK; @@ -222,12 +226,19 @@ AppWindow::AppWindow(QWidget *parent) ui->menuToolbars->addAction(t->toggleViewAction()); } - // Create GUI modes - central = new QStackedWidget; - setCentralWidget(central); - auto vna = new VNA(this); - auto generator = new Generator(this); - auto spectrumAnalyzer = new SpectrumAnalyzer(this); + modeHandler = new ModeHandler(this); + auto modeWindow = new ModeWindow(modeHandler, this); + + setCentralWidget(modeWindow); + modeHandler->createMode("Vector Network Analyzer", Mode::Type::VNA); + modeHandler->createMode("Spectrum Analyzer", Mode::Type::SA); + modeHandler->createMode("Signal Generator", Mode::Type::SG); + + auto setModeStatusbar = [=](const QString &msg) { + lModeInfo.setText(msg); + }; + + connect(modeHandler, &ModeHandler::StatusBarMessageChanged, setModeStatusbar); // UI connections connect(ui->actionUpdate_Device_List, &QAction::triggered, this, &AppWindow::UpdateDeviceList); @@ -271,32 +282,10 @@ AppWindow::AppWindow(QWidget *parent) } } - // averaging mode may have changed, update for all relevant modes - for (auto m : Mode::getModes()) - { - switch (m->getType()) - { - case Mode::Type::VNA: - if(p.Acquisition.useMedianAveraging) { - static_cast(m)->setAveragingMode(Averaging::Mode::Median); - } - else { - static_cast(m)->setAveragingMode(Averaging::Mode::Mean); - } - break; - case Mode::Type::SA: - if(p.Acquisition.useMedianAveraging) { - static_cast(m)->setAveragingMode(Averaging::Mode::Median); - } - else { - static_cast(m)->setAveragingMode(Averaging::Mode::Mean); - } - break; - case Mode::Type::SG: - case Mode::Type::Last: - default: - break; - } + if(p.Acquisition.useMedianAveraging) { + modeHandler->setAveragingMode(Averaging::Mode::Median); + } else { + modeHandler->setAveragingMode(Averaging::Mode::Mean); } // acquisition frequencies may have changed, update @@ -333,9 +322,6 @@ AppWindow::AppWindow(QWidget *parent) SetupSCPI(); - // Set default mode - vna->activate(); - auto pref = Preferences::getInstance(); if(pref.Startup.UseSetupFile) { LoadSetup(pref.Startup.SetupFile); @@ -351,7 +337,8 @@ AppWindow::AppWindow(QWidget *parent) LoadSetup(parser.value("setup")); } if(parser.isSet("cal")) { - vna->LoadCalibration(parser.value("cal")); + VNA* mode = static_cast(modeHandler->findFirstOfType(Mode::Type::VNA)); + mode->LoadCalibration(parser.value("cal")); } if(!parser.isSet("no-gui")) { InformationBox::setGUI(true); @@ -375,9 +362,7 @@ void AppWindow::closeEvent(QCloseEvent *event) if(pref.Startup.UseSetupFile && pref.Startup.AutosaveSetupFile) { SaveSetup(pref.Startup.SetupFile); } - for(auto m : Mode::getModes()) { - m->shutdown(); - } + modeHandler->shutdown(); QSettings settings; settings.setValue("geometry", saveGeometry()); // deactivate currently used mode (stores mode state in settings) @@ -385,6 +370,8 @@ void AppWindow::closeEvent(QCloseEvent *event) Mode::getActiveMode()->deactivate(); } delete device; + delete modeHandler; + modeHandler = nullptr; pref.store(); QMainWindow::closeEvent(event); } @@ -586,11 +573,11 @@ void AppWindow::SetupSCPI() } Mode *mode = nullptr; if (params[0] == "VNA") { - mode = Mode::findFirstOfType(Mode::Type::VNA); + mode = modeHandler->findFirstOfType(Mode::Type::VNA); } else if(params[0] == "GEN") { - mode = Mode::findFirstOfType(Mode::Type::SG); + mode = modeHandler->findFirstOfType(Mode::Type::SG); } else if(params[0] == "SA") { - mode = Mode::findFirstOfType(Mode::Type::SA); + mode = modeHandler->findFirstOfType(Mode::Type::SA); } else { return "INVALID MDOE"; } @@ -1082,7 +1069,7 @@ nlohmann::json AppWindow::SaveSetup() { nlohmann::json j; nlohmann::json jm; - for(auto m : Mode::getModes()) { + for(auto m : modeHandler->getModes()) { nlohmann::json jmode; jmode["type"] = Mode::TypeToName(m->getType()).toStdString(); jmode["name"] = m->getName().toStdString(); @@ -1138,28 +1125,31 @@ void AppWindow::LoadSetup(nlohmann::json j) toolbars.reference.type->setCurrentIndex(index); toolbars.reference.outFreq->setCurrentText(QString::fromStdString(j["Reference"].value("Output", "Off"))); } - while(Mode::getModes().size() > 0) { - delete Mode::getModes()[0]; - } + + modeHandler->closeModes(); // old style VNA/Generator/Spectrum Analyzer settings if(j.contains("VNA")) { - auto vna = new VNA(this); + modeHandler->createMode("Vector Network Analyzer", Mode::Type::VNA); + auto * vna = static_cast(modeHandler->findFirstOfType(Mode::Type::VNA)); vna->fromJSON(j["VNA"]); } if(j.contains("Generator")) { - auto generator = new Generator(this); + modeHandler->createMode("Generator", Mode::Type::SG); + auto * generator = static_cast(modeHandler->findFirstOfType(Mode::Type::SG)); generator->fromJSON(j["Generator"]); } if(j.contains("SpectrumAnalyzer")) { - auto spectrumAnalyzer = new SpectrumAnalyzer(this); + modeHandler->createMode("Spectrum Analyzer", Mode::Type::SA); + auto * spectrumAnalyzer = static_cast(modeHandler->findFirstOfType(Mode::Type::SA)); spectrumAnalyzer->fromJSON(j["SpectrumAnalyzer"]); } if(j.contains("Modes")) { for(auto jm : j["Modes"]) { auto type = Mode::TypeFromName(QString::fromStdString(jm.value("type", "Invalid"))); if(type != Mode::Type::Last && jm.contains("settings")) { - auto m = Mode::createNew(this, QString::fromStdString(jm.value("name", "")), type); + modeHandler->createMode(QString::fromStdString(jm.value("name", "")), type); + auto m = modeHandler->getMode(modeHandler->getCurrentIndex()); m->fromJSON(jm["settings"]); } } @@ -1167,15 +1157,15 @@ void AppWindow::LoadSetup(nlohmann::json j) // activate the correct mode QString modeName = QString::fromStdString(j.value("activeMode", "")); - for(auto m : Mode::getModes()) { + for(auto m : modeHandler->getModes()) { if(m->getName() == modeName) { m->activate(); break; } } // if no mode is activated, there might have been a problem with the setup file. Activate the first mode anyway, to prevent invalid GUI state - if(!Mode::getActiveMode() && Mode::getModes().size() > 0) { - Mode::getModes()[0]->activate(); + if(!Mode::getActiveMode() && modeHandler->getModes().size() > 0) { + modeHandler->getModes()[0]->activate(); } } @@ -1184,11 +1174,6 @@ Device *&AppWindow::getDevice() return device; } -QStackedWidget *AppWindow::getCentral() const -{ - return central; -} - Ui::MainWindow *AppWindow::getUi() const { return ui; @@ -1268,3 +1253,4 @@ void AppWindow::UpdateStatusBar(DeviceStatusBar status) break; } } + diff --git a/Software/PC_Application/appwindow.h b/Software/PC_Application/appwindow.h index 90b18f2..d3ec2b1 100644 --- a/Software/PC_Application/appwindow.h +++ b/Software/PC_Application/appwindow.h @@ -31,6 +31,7 @@ class MainWindow; class VNA; class Generator; class SpectrumAnalyzer; +class ModeHandler; class AppWindow : public QMainWindow { @@ -40,7 +41,6 @@ public: ~AppWindow(); Ui::MainWindow *getUi() const; - QStackedWidget *getCentral() const; Device*&getDevice(); const QString& getAppVersion() const; @@ -98,6 +98,7 @@ private: } reference; } toolbars; + ModeHandler *modeHandler; Device *device; DeviceLog deviceLog; QString deviceSerial; diff --git a/Software/PC_Application/mode.cpp b/Software/PC_Application/mode.cpp index 163f203..787163f 100644 --- a/Software/PC_Application/mode.cpp +++ b/Software/PC_Application/mode.cpp @@ -13,10 +13,7 @@ #include #include -std::vector Mode::modes; Mode* Mode::activeMode = nullptr; -QTabBar* Mode::tabbar = nullptr; -QWidget* Mode::cornerWidget = nullptr; //QButtonGroup* Mode::modeButtonGroup = nullptr; Mode::Mode(AppWindow *window, QString name, QString SCPIname) @@ -26,80 +23,6 @@ Mode::Mode(AppWindow *window, QString name, QString SCPIname) name(name), central(nullptr) { - if(!nameAllowed(name)) { - throw std::runtime_error("Unable to create mode, name already taken"); - } - // Create mode switch button - if(!cornerWidget) { - // this is the first created mode, initialize corner widget and set this mode as active - cornerWidget = new QWidget(); - cornerWidget->setLayout(new QHBoxLayout); - cornerWidget->layout()->setSpacing(0); - cornerWidget->layout()->setMargin(0); - cornerWidget->layout()->setContentsMargins(0,0,0,0); - cornerWidget->setMaximumHeight(window->menuBar()->height()); - - tabbar = new QTabBar; - tabbar->setTabsClosable(true); - tabbar->setStyleSheet("QTabBar::tab { height: "+QString::number(window->menuBar()->height())+"px;}"); - cornerWidget->layout()->addWidget(tabbar); - - auto bAdd = new QPushButton(); - QIcon icon; - QString iconThemeName = QString::fromUtf8("list-add"); - if (QIcon::hasThemeIcon(iconThemeName)) { - icon = QIcon::fromTheme(iconThemeName); - } else { - icon.addFile(QString::fromUtf8(":/icons/add.png"), QSize(), QIcon::Normal, QIcon::Off); - } - bAdd->setIcon(icon); - - auto mAdd = new QMenu(); - for(unsigned int i=0;i<(int) Type::Last;i++) { - auto type = (Type) i; - auto action = new QAction(TypeToName(type)); - mAdd->addAction(action); - connect(action, &QAction::triggered, [=](){ - bool ok; - QString text = QInputDialog::getText(window, "Create new "+TypeToName(type)+" tab", - "Name:", QLineEdit::Normal, - TypeToName(type), &ok); - if(ok) { - if(!nameAllowed(text)) { - InformationBox::ShowError("Name collision", "Unable to create tab, no duplicate names allowed"); - } else { - auto mode = Mode::createNew(window, text, type); - mode->activate(); - } - } - }); - } - bAdd->setMenu(mAdd); - bAdd->setMaximumHeight(window->menuBar()->height()); - bAdd->setMaximumWidth(40); - cornerWidget->layout()->addWidget(bAdd); - - window->menuBar()->setCornerWidget(cornerWidget); - - connect(tabbar, &QTabBar::currentChanged, [=](int index){ - modes[index]->activate(); - }); - connect(tabbar, &QTabBar::tabCloseRequested, [=](int index){ - delete modes[index]; - }); - connect(tabbar, &QTabBar::tabMoved, [=](int from, int to){ - auto modeFrom = modes.at(from); - auto modeTo = modes.at(to); - modes[from] = modeTo; - modes[to] = modeFrom; - }); - } - connect(this, &Mode::statusbarMessage, window, &AppWindow::setModeStatus); - modes.push_back(this); - tabbar->blockSignals(true); - tabbar->insertTab(tabbar->count(), name); - tabbar->blockSignals(false); - tabbar->setMovable(true); window->getSCPI()->add(this); } @@ -109,16 +32,6 @@ Mode::~Mode() if(activeMode == this) { deactivate(); } - auto index = findTabIndex(); - tabbar->blockSignals(true); - tabbar->removeTab(index); - tabbar->blockSignals(false); - modes.erase(modes.begin() + index); - if(modes.size() > 0) { - modes[tabbar->currentIndex()]->activate(); - } - window->getCentral()->removeWidget(central); - delete central; for(auto d : docks) { delete d; } @@ -151,7 +64,6 @@ void Mode::activate() } QSettings settings; - window->getCentral()->setCurrentWidget(central); // restore dock and toolbar positions window->restoreState(settings.value("windowState_"+name).toByteArray()); @@ -175,10 +87,6 @@ void Mode::activate() } activeMode = this; - // force activation of correct tab in case the mode switch was done via script/setup load. - // This will trigger a second activation of this mode in the signal of the tab bar, but since it is - // already the active mode, this function will just return -> no recursion - tabbar->setCurrentIndex(findTabIndex()); if(window->getDevice()) { initializeDevice(); @@ -268,21 +176,9 @@ Mode *Mode::createNew(AppWindow *window, QString name, Mode::Type t) } } -bool Mode::nameAllowed(QString name) -{ - for(auto m : modes) { - if(m->getName() == name) { - // name already taken, no duplicates allowed - return false; - } - } - return true; -} - void Mode::finalize(QWidget *centralWidget) { central = centralWidget; - window->getCentral()->addWidget(central); // Set ObjectName for toolbars and docks for(auto d : docks) { d->setObjectName(d->windowTitle()+name); @@ -302,27 +198,6 @@ void Mode::finalize(QWidget *centralWidget) } } -int Mode::findTabIndex() -{ - auto it = std::find(modes.begin(), modes.end(), this); - return it - modes.begin(); -} - -std::vector Mode::getModes() -{ - return modes; -} - -Mode *Mode::findFirstOfType(Mode::Type t) -{ - for(auto m : modes) { - if(m->getType() == t) { - return m; - } - } - return nullptr; -} - void Mode::setStatusbarMessage(QString msg) { statusbarMsg = msg; @@ -338,12 +213,7 @@ QString Mode::getName() const void Mode::setName(const QString &value) { - if(!nameAllowed(value)) { - // unable to use this name - return; - } name = value; - tabbar->setTabText(findTabIndex(), name); } void Mode::updateGraphColors() @@ -354,3 +224,8 @@ void Mode::updateGraphColors() } } } + +QWidget *Mode::getCentral() const +{ + return central; +} diff --git a/Software/PC_Application/mode.h b/Software/PC_Application/mode.h index 038cc53..a031d75 100644 --- a/Software/PC_Application/mode.h +++ b/Software/PC_Application/mode.h @@ -44,9 +44,8 @@ public: virtual void saveSreenshot(); static Mode *createNew(AppWindow *window, QString name, Type t); - static bool nameAllowed(QString name); - static std::vector getModes(); - static Mode* findFirstOfType(Type t); + + virtual QWidget *getCentral() const; signals: void statusbarMessage(QString msg); @@ -60,14 +59,12 @@ protected: std::set docks; private: - int findTabIndex(); static std::vector modes; static Mode *activeMode; - static QTabBar *tabbar; - static QWidget *cornerWidget; // static QButtonGroup *modeButtonGroup; QString name; QString statusbarMsg; + QWidget *central; }; diff --git a/Software/PC_Application/modehandler.cpp b/Software/PC_Application/modehandler.cpp new file mode 100644 index 0000000..61357c7 --- /dev/null +++ b/Software/PC_Application/modehandler.cpp @@ -0,0 +1,138 @@ +#include "modehandler.h" + +#include "VNA/vna.h" +#include "SpectrumAnalyzer/spectrumanalyzer.h" +#include "Generator/generator.h" +#include "mode.h" +#include "averaging.h" + +ModeHandler::ModeHandler(AppWindow *aw): + QObject(), + aw(aw) +{} + +void ModeHandler::shutdown() +{ + for(auto m : modes) { + m->shutdown(); + } +} + +void ModeHandler::createMode(QString name, Mode::Type t) +{ + auto mode = Mode::createNew(aw, name, t); + createMode(mode); +} + +void ModeHandler::createMode(Mode *mode) +{ + modes.push_back(mode); + currentModeIndex = int(modes.size()); + connect(mode, &Mode::statusbarMessage, this, &ModeHandler::setStatusBarMessageChanged); + emit ModeCreated(currentModeIndex - 1); + +} + +Mode* ModeHandler::getMode(int index) +{ + return modes.at(index); +} + +std::vector ModeHandler::getModes() +{ + return modes; +} + +void ModeHandler::setCurrentIndex(int index) +{ + if ( (currentModeIndex != index) && (index >= 0)) { + currentModeIndex = index; + auto * mode = modes.at(currentModeIndex); + mode->activate(); + } +} + +int ModeHandler::getCurrentIndex() +{ + return currentModeIndex; +} + +void ModeHandler::closeMode(int index) +{ + disconnect(modes.at(index), &Mode::statusbarMessage, this, &ModeHandler::setStatusBarMessageChanged); + delete modes.at(index); + modes.erase(modes.begin() + index); + if (currentModeIndex > int(modes.size()) ) { + setCurrentIndex(currentModeIndex - 1); // Select bar before one deleted + auto vna = modes.at(currentModeIndex); + vna->activate(); + } + emit ModeClosed(index); +} + +void ModeHandler::closeModes() +{ + while(modes.size() > 0) { + closeMode(0); + } +} + +void ModeHandler::setStatusBarMessageChanged(const QString &msg) +{ + emit StatusBarMessageChanged(msg); +} + +bool ModeHandler::nameAllowed(const QString &name) +{ + for(auto m : modes) { + if(m->getName() == name) { + /* name already taken, no duplicates allowed + * when importing, name is used as value + */ + return false; + } + } + return true; +} + +Mode* ModeHandler::findFirstOfType(Mode::Type t) +{ + for(auto m : modes) { + if(m->getType() == t) { + return m; + } + } + return nullptr; +} + +void ModeHandler::setAveragingMode(Averaging::Mode value) +{ + + + // averaging mode may have changed, update for all relevant modes + for (auto m : getModes()) + { + switch (m->getType()) + { + case Mode::Type::VNA: + static_cast(m)->setAveragingMode(value); + break; + case Mode::Type::SA: + static_cast(m)->setAveragingMode(value); + break; + case Mode::Type::SG: + case Mode::Type::Last: + default: + break; + } + } + + for(auto m : modes) { + if (m->getType() == Mode::Type::SA) { + static_cast(m)->setAveragingMode(value); + } + else if (m->getType() == Mode::Type::VNA) { + static_cast(m)->setAveragingMode(value); + } + } +} diff --git a/Software/PC_Application/modehandler.h b/Software/PC_Application/modehandler.h new file mode 100644 index 0000000..b41c758 --- /dev/null +++ b/Software/PC_Application/modehandler.h @@ -0,0 +1,50 @@ +#ifndef MODEHANDLER_H +#define MODEHANDLER_H + +#include "mode.h" +#include "appwindow.h" + +#include +#include + +class ModeHandler: public QObject +{ + Q_OBJECT +public: + ModeHandler(AppWindow *window); + ~ModeHandler() = default; + + void shutdown(); + void createMode(QString name, Mode::Type t); + void closeMode(int index); + void closeModes(); + int getCurrentIndex(); + + Mode* getMode(int index); + std::vector getModes(); + + bool nameAllowed(const QString &name); + Mode* findFirstOfType(Mode::Type t); + + void setAveragingMode(Averaging::Mode m); + +signals: + void StatusBarMessageChanged(const QString &msg); + + void ModeCreated(int modeIndex); + void ModeClosed(int modeIndex); + +public slots: + void setCurrentIndex(int modeIndex); + +private: + std::vector modes; + int currentModeIndex; + void createMode(Mode *mode); + AppWindow *aw; + +private slots: + void setStatusBarMessageChanged(const QString &msg); +}; + +#endif // MODEHANDLER_H diff --git a/Software/PC_Application/modetabwidget.cpp b/Software/PC_Application/modetabwidget.cpp new file mode 100644 index 0000000..e2170b9 --- /dev/null +++ b/Software/PC_Application/modetabwidget.cpp @@ -0,0 +1,14 @@ +#include "modetabwidget.h" + +#include +#include + +ModeTabWidget::ModeTabWidget(QWidget* parent): + QTabWidget(parent) +{ + tabBar = new QTabBar; + tabBar->setStyleSheet("QTabBar::tab { height: " + QString::number(parent->height()) + "px;}"); + this->setTabBar(tabBar); + this->setTabsClosable(true); + this->setMovable(true); +} diff --git a/Software/PC_Application/modetabwidget.h b/Software/PC_Application/modetabwidget.h new file mode 100644 index 0000000..0e1e786 --- /dev/null +++ b/Software/PC_Application/modetabwidget.h @@ -0,0 +1,18 @@ +#ifndef MODETABWIDGET_H +#define MODETABWIDGET_H + +#include +#include + +class ModeTabWidget: public QTabWidget +{ + Q_OBJECT +public: + explicit ModeTabWidget(QWidget* parent = nullptr); + ~ModeTabWidget() = default; + +private: + QTabBar * tabBar = nullptr; +}; + +#endif // MODETABWIDGET_H diff --git a/Software/PC_Application/modewindow.cpp b/Software/PC_Application/modewindow.cpp new file mode 100644 index 0000000..cacbb38 --- /dev/null +++ b/Software/PC_Application/modewindow.cpp @@ -0,0 +1,99 @@ +#include "modewindow.h" + +#include "mode.h" +#include "ui_modewindow.h" +#include "appwindow.h" +#include "CustomWidgets/informationbox.h" + +#include +#include +#include + +ModeWindow::ModeWindow(ModeHandler* handler, AppWindow* aw, QWidget* parent): + QWidget(parent), + handler(handler), + aw(aw) +{ + ui = new Ui::ModeWindow; + ui->setupUi(this); + + SetupUi(); + + connect(handler, &ModeHandler::ModeCreated, this, &ModeWindow::ModeCreated); + connect(handler, &ModeHandler::ModeClosed, this, &ModeWindow::ModeClosed); + + connect(ui->tabwidgetModes, &ModeTabWidget::currentChanged, handler, &ModeHandler::setCurrentIndex); + connect(ui->tabwidgetModes, &ModeTabWidget::tabCloseRequested, handler, &ModeHandler::closeMode); + +} + +ModeWindow::~ModeWindow() +{ + delete ui; + ui = nullptr; +} + +void ModeWindow::SetupUi() +{ + ui->horizontalLayout->setSpacing(0); + ui->horizontalLayout->setMargin(0); + ui->horizontalLayout->setContentsMargins(0,0,0,0); + ui->tabwidgetModes->setUsesScrollButtons(true); + + auto bAdd = new QPushButton(); + QIcon icon; + QString iconThemeName = QString::fromUtf8("list-add"); + + if (QIcon::hasThemeIcon(iconThemeName)) + icon = QIcon::fromTheme(iconThemeName); + else + icon.addFile(QString::fromUtf8(":/icons/add.png"), QSize(), QIcon::Normal, QIcon::Off); + + bAdd->setIcon(icon); + bAdd->setMaximumHeight(450); + bAdd->setMaximumWidth(40); + + auto mAdd = new QMenu(); + for(unsigned int i=0;i<(int) Mode::Type::Last;i++) { + auto type = (Mode::Type) i; + auto action = new QAction(Mode::TypeToName(type)); + mAdd->addAction(action); + connect(action, &QAction::triggered, [=](){ + bool ok; + QString text = QInputDialog::getText(this, + "Create new "+Mode::TypeToName(type)+" tab", + "Name:", QLineEdit::Normal, + Mode::TypeToName(type), &ok); + if(ok) { + if(!handler->nameAllowed(text)) { + InformationBox::ShowError("Name collision", "Unable to create tab, " \ + "no duplicate names allowed"); + } else { + handler->createMode(text, type); + } + } + }); + } + bAdd->setMenu(mAdd); + aw->menuBar()->setCornerWidget(bAdd); +} + +void ModeWindow::ModeCreated(int modeIndex) +{ + auto mode = handler->getMode(modeIndex); + + if (mode) + { + const auto name = mode->getName(); + auto central = mode->getCentral(); + const auto tabIndex = ui->tabwidgetModes->insertTab(modeIndex, central, name); + ui->tabwidgetModes->setCurrentIndex(tabIndex); + } +} + +void ModeWindow::ModeClosed(int modeIndex) +{ + auto modeWidget = ui->tabwidgetModes->widget(modeIndex); + ui->tabwidgetModes->removeTab(modeIndex); + delete modeWidget; +} diff --git a/Software/PC_Application/modewindow.h b/Software/PC_Application/modewindow.h new file mode 100644 index 0000000..4a31286 --- /dev/null +++ b/Software/PC_Application/modewindow.h @@ -0,0 +1,28 @@ +#ifndef MODEWINDOW_H +#define MODEWINDOW_H + +#include "modehandler.h" + +namespace Ui { + class ModeWindow; +} + +class ModeWindow: public QWidget +{ + Q_OBJECT +public: + explicit ModeWindow(ModeHandler* handler, AppWindow* aw, QWidget *parent = nullptr); + ~ModeWindow(); + +private: + ModeHandler* handler; + Ui::ModeWindow *ui; + void SetupUi(); + AppWindow* aw; + +private slots: + void ModeCreated(int modeIndex); + void ModeClosed(int modeIndex); +}; + +#endif // MODEWINDOW_H diff --git a/Software/PC_Application/modewindow.ui b/Software/PC_Application/modewindow.ui new file mode 100644 index 0000000..4f9e2d3 --- /dev/null +++ b/Software/PC_Application/modewindow.ui @@ -0,0 +1,45 @@ + + + ModeWindow + + + + 0 + 0 + 22 + 29 + + + + Form + + + + + + Qt::LeftToRight + + + -1 + + + false + + + true + + + + + + + + ModeTabWidget + QTabWidget +
modetabwidget.h
+ 1 +
+
+ + +
From cb9b03e418a80ba65e713846ddd42739f9252743 Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Sun, 3 Jul 2022 10:22:50 -0500 Subject: [PATCH 2/9] app/mode: place tabs in menu corner Signed-off-by: Kiara Navarro --- Software/PC_Application/LibreVNA-GUI.pro | 3 -- Software/PC_Application/appwindow.cpp | 36 ++++++++------ Software/PC_Application/appwindow.h | 1 + Software/PC_Application/mode.cpp | 10 ++-- Software/PC_Application/mode.h | 2 - Software/PC_Application/modehandler.cpp | 36 +++++++++----- Software/PC_Application/modehandler.h | 6 ++- Software/PC_Application/modetabwidget.cpp | 14 ------ Software/PC_Application/modetabwidget.h | 18 ------- Software/PC_Application/modewindow.cpp | 57 +++++++++++++++-------- Software/PC_Application/modewindow.h | 7 +-- Software/PC_Application/modewindow.ui | 45 ------------------ 12 files changed, 95 insertions(+), 140 deletions(-) delete mode 100644 Software/PC_Application/modetabwidget.cpp delete mode 100644 Software/PC_Application/modetabwidget.h delete mode 100644 Software/PC_Application/modewindow.ui diff --git a/Software/PC_Application/LibreVNA-GUI.pro b/Software/PC_Application/LibreVNA-GUI.pro index 5665ce2..b12ef96 100644 --- a/Software/PC_Application/LibreVNA-GUI.pro +++ b/Software/PC_Application/LibreVNA-GUI.pro @@ -125,7 +125,6 @@ HEADERS += \ json.hpp \ modehandler.h \ mode.h \ - modetabwidget.h \ modewindow.h \ preferences.h \ savable.h \ @@ -247,7 +246,6 @@ SOURCES += \ main.cpp \ modehandler.cpp \ mode.cpp \ - modetabwidget.cpp \ modewindow.cpp \ preferences.cpp \ scpi.cpp \ @@ -312,7 +310,6 @@ FORMS += \ VNA/s2pImportOptions.ui \ aboutdialog.ui \ main.ui \ - modewindow.ui \ preferencesdialog.ui DISTFILES += diff --git a/Software/PC_Application/appwindow.cpp b/Software/PC_Application/appwindow.cpp index 7cb3f28..9e157fa 100644 --- a/Software/PC_Application/appwindow.cpp +++ b/Software/PC_Application/appwindow.cpp @@ -227,12 +227,15 @@ AppWindow::AppWindow(QWidget *parent) } modeHandler = new ModeHandler(this); - auto modeWindow = new ModeWindow(modeHandler, this); + new ModeWindow(modeHandler, this); - setCentralWidget(modeWindow); - modeHandler->createMode("Vector Network Analyzer", Mode::Type::VNA); + central = new QStackedWidget; + setCentralWidget(central); + + auto vnaIndex = modeHandler->createMode("Vector Network Analyzer", Mode::Type::VNA); modeHandler->createMode("Spectrum Analyzer", Mode::Type::SA); modeHandler->createMode("Signal Generator", Mode::Type::SG); + modeHandler->setCurrentIndex(vnaIndex); auto setModeStatusbar = [=](const QString &msg) { lModeInfo.setText(msg); @@ -1128,28 +1131,29 @@ void AppWindow::LoadSetup(nlohmann::json j) modeHandler->closeModes(); - // old style VNA/Generator/Spectrum Analyzer settings + /* old style VNA/Generator/Spectrum Analyzer settings, + * no more than one instance in each mode running */ if(j.contains("VNA")) { - modeHandler->createMode("Vector Network Analyzer", Mode::Type::VNA); - auto * vna = static_cast(modeHandler->findFirstOfType(Mode::Type::VNA)); + auto vnaIndex = modeHandler->createMode("Vector Network Analyzer", Mode::Type::VNA); + auto *vna = static_cast(modeHandler->getMode(vnaIndex)); vna->fromJSON(j["VNA"]); } if(j.contains("Generator")) { - modeHandler->createMode("Generator", Mode::Type::SG); - auto * generator = static_cast(modeHandler->findFirstOfType(Mode::Type::SG)); + auto sgIndex = modeHandler->createMode("Generator", Mode::Type::SG); + auto *generator = static_cast(modeHandler->getMode(sgIndex)); generator->fromJSON(j["Generator"]); } if(j.contains("SpectrumAnalyzer")) { - modeHandler->createMode("Spectrum Analyzer", Mode::Type::SA); - auto * spectrumAnalyzer = static_cast(modeHandler->findFirstOfType(Mode::Type::SA)); + auto saIndex = modeHandler->createMode("Spectrum Analyzer", Mode::Type::SA); + auto *spectrumAnalyzer = static_cast(modeHandler->getMode(saIndex)); spectrumAnalyzer->fromJSON(j["SpectrumAnalyzer"]); } if(j.contains("Modes")) { for(auto jm : j["Modes"]) { auto type = Mode::TypeFromName(QString::fromStdString(jm.value("type", "Invalid"))); if(type != Mode::Type::Last && jm.contains("settings")) { - modeHandler->createMode(QString::fromStdString(jm.value("name", "")), type); - auto m = modeHandler->getMode(modeHandler->getCurrentIndex()); + auto index = modeHandler->createMode(QString::fromStdString(jm.value("name", "")), type); + auto m = modeHandler->getMode(index); m->fromJSON(jm["settings"]); } } @@ -1159,7 +1163,8 @@ void AppWindow::LoadSetup(nlohmann::json j) QString modeName = QString::fromStdString(j.value("activeMode", "")); for(auto m : modeHandler->getModes()) { if(m->getName() == modeName) { - m->activate(); + auto index = modeHandler->findIndex(m); + modeHandler->setCurrentIndex(index); break; } } @@ -1174,6 +1179,11 @@ Device *&AppWindow::getDevice() return device; } +QStackedWidget *AppWindow::getCentral() const +{ + return central; +} + Ui::MainWindow *AppWindow::getUi() const { return ui; diff --git a/Software/PC_Application/appwindow.h b/Software/PC_Application/appwindow.h index d3ec2b1..8b1269e 100644 --- a/Software/PC_Application/appwindow.h +++ b/Software/PC_Application/appwindow.h @@ -41,6 +41,7 @@ public: ~AppWindow(); Ui::MainWindow *getUi() const; + QStackedWidget *getCentral() const; Device*&getDevice(); const QString& getAppVersion() const; diff --git a/Software/PC_Application/mode.cpp b/Software/PC_Application/mode.cpp index 787163f..998b0db 100644 --- a/Software/PC_Application/mode.cpp +++ b/Software/PC_Application/mode.cpp @@ -32,6 +32,8 @@ Mode::~Mode() if(activeMode == this) { deactivate(); } + window->getCentral()->removeWidget(central); + delete central; for(auto d : docks) { delete d; } @@ -64,7 +66,7 @@ void Mode::activate() } QSettings settings; - + window->getCentral()->setCurrentWidget(central); // restore dock and toolbar positions window->restoreState(settings.value("windowState_"+name).toByteArray()); @@ -179,6 +181,7 @@ Mode *Mode::createNew(AppWindow *window, QString name, Mode::Type t) void Mode::finalize(QWidget *centralWidget) { central = centralWidget; + window->getCentral()->addWidget(central); // Set ObjectName for toolbars and docks for(auto d : docks) { d->setObjectName(d->windowTitle()+name); @@ -224,8 +227,3 @@ void Mode::updateGraphColors() } } } - -QWidget *Mode::getCentral() const -{ - return central; -} diff --git a/Software/PC_Application/mode.h b/Software/PC_Application/mode.h index a031d75..ce1627c 100644 --- a/Software/PC_Application/mode.h +++ b/Software/PC_Application/mode.h @@ -45,8 +45,6 @@ public: static Mode *createNew(AppWindow *window, QString name, Type t); - virtual QWidget *getCentral() const; - signals: void statusbarMessage(QString msg); protected: diff --git a/Software/PC_Application/modehandler.cpp b/Software/PC_Application/modehandler.cpp index 61357c7..b565e2b 100644 --- a/Software/PC_Application/modehandler.cpp +++ b/Software/PC_Application/modehandler.cpp @@ -18,19 +18,23 @@ void ModeHandler::shutdown() } } -void ModeHandler::createMode(QString name, Mode::Type t) +int ModeHandler::createMode(QString name, Mode::Type t) { auto mode = Mode::createNew(aw, name, t); - createMode(mode); + return createMode(mode); } -void ModeHandler::createMode(Mode *mode) +int ModeHandler::createMode(Mode *mode) { modes.push_back(mode); - currentModeIndex = int(modes.size()); + currentModeIndex = int(modes.size()) - 1; connect(mode, &Mode::statusbarMessage, this, &ModeHandler::setStatusBarMessageChanged); - emit ModeCreated(currentModeIndex - 1); + auto * m = getMode(currentModeIndex); + m->activate(); + + emit ModeCreated(currentModeIndex); + return (currentModeIndex); } Mode* ModeHandler::getMode(int index) @@ -45,10 +49,12 @@ std::vector ModeHandler::getModes() void ModeHandler::setCurrentIndex(int index) { - if ( (currentModeIndex != index) && (index >= 0)) { +// if ( (getCurrentIndex() != index) && (index >= 0)) { + if ( (getCurrentIndex() != index) && (index >= 0)) { currentModeIndex = index; - auto * mode = modes.at(currentModeIndex); - mode->activate(); + auto * m = getMode(getCurrentIndex()); + m->activate(); + emit CurrentModeChanged(getCurrentIndex()); } } @@ -62,10 +68,10 @@ void ModeHandler::closeMode(int index) disconnect(modes.at(index), &Mode::statusbarMessage, this, &ModeHandler::setStatusBarMessageChanged); delete modes.at(index); modes.erase(modes.begin() + index); - if (currentModeIndex > int(modes.size()) ) { - setCurrentIndex(currentModeIndex - 1); // Select bar before one deleted - auto vna = modes.at(currentModeIndex); - vna->activate(); + if (int(modes.size()) > 0) { + if (getCurrentIndex() == index) { + setCurrentIndex(getCurrentIndex()-1); // Select bar before one deleted + } } emit ModeClosed(index); } @@ -95,6 +101,12 @@ bool ModeHandler::nameAllowed(const QString &name) return true; } +int ModeHandler::findIndex(Mode *targetMode) +{ + auto it = std::find(modes.begin(), modes.end(), targetMode); + return it - modes.begin(); +} + Mode* ModeHandler::findFirstOfType(Mode::Type t) { for(auto m : modes) { diff --git a/Software/PC_Application/modehandler.h b/Software/PC_Application/modehandler.h index b41c758..683701b 100644 --- a/Software/PC_Application/modehandler.h +++ b/Software/PC_Application/modehandler.h @@ -15,7 +15,7 @@ public: ~ModeHandler() = default; void shutdown(); - void createMode(QString name, Mode::Type t); + int createMode(QString name, Mode::Type t); void closeMode(int index); void closeModes(); int getCurrentIndex(); @@ -24,6 +24,7 @@ public: std::vector getModes(); bool nameAllowed(const QString &name); + int findIndex(Mode *targetMode); Mode* findFirstOfType(Mode::Type t); void setAveragingMode(Averaging::Mode m); @@ -33,6 +34,7 @@ signals: void ModeCreated(int modeIndex); void ModeClosed(int modeIndex); + void CurrentModeChanged(int modeIndex); public slots: void setCurrentIndex(int modeIndex); @@ -40,7 +42,7 @@ public slots: private: std::vector modes; int currentModeIndex; - void createMode(Mode *mode); + int createMode(Mode *mode); AppWindow *aw; private slots: diff --git a/Software/PC_Application/modetabwidget.cpp b/Software/PC_Application/modetabwidget.cpp deleted file mode 100644 index e2170b9..0000000 --- a/Software/PC_Application/modetabwidget.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "modetabwidget.h" - -#include -#include - -ModeTabWidget::ModeTabWidget(QWidget* parent): - QTabWidget(parent) -{ - tabBar = new QTabBar; - tabBar->setStyleSheet("QTabBar::tab { height: " + QString::number(parent->height()) + "px;}"); - this->setTabBar(tabBar); - this->setTabsClosable(true); - this->setMovable(true); -} diff --git a/Software/PC_Application/modetabwidget.h b/Software/PC_Application/modetabwidget.h deleted file mode 100644 index 0e1e786..0000000 --- a/Software/PC_Application/modetabwidget.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MODETABWIDGET_H -#define MODETABWIDGET_H - -#include -#include - -class ModeTabWidget: public QTabWidget -{ - Q_OBJECT -public: - explicit ModeTabWidget(QWidget* parent = nullptr); - ~ModeTabWidget() = default; - -private: - QTabBar * tabBar = nullptr; -}; - -#endif // MODETABWIDGET_H diff --git a/Software/PC_Application/modewindow.cpp b/Software/PC_Application/modewindow.cpp index cacbb38..0e4c94a 100644 --- a/Software/PC_Application/modewindow.cpp +++ b/Software/PC_Application/modewindow.cpp @@ -1,7 +1,6 @@ #include "modewindow.h" #include "mode.h" -#include "ui_modewindow.h" #include "appwindow.h" #include "CustomWidgets/informationbox.h" @@ -14,31 +13,34 @@ ModeWindow::ModeWindow(ModeHandler* handler, AppWindow* aw, QWidget* parent): handler(handler), aw(aw) { - ui = new Ui::ModeWindow; - ui->setupUi(this); SetupUi(); connect(handler, &ModeHandler::ModeCreated, this, &ModeWindow::ModeCreated); connect(handler, &ModeHandler::ModeClosed, this, &ModeWindow::ModeClosed); + connect(handler, &ModeHandler::CurrentModeChanged, this, &ModeWindow::CurrentModeChanged); - connect(ui->tabwidgetModes, &ModeTabWidget::currentChanged, handler, &ModeHandler::setCurrentIndex); - connect(ui->tabwidgetModes, &ModeTabWidget::tabCloseRequested, handler, &ModeHandler::closeMode); - + connect(tabBar, &QTabBar::currentChanged, handler, &ModeHandler::setCurrentIndex); + connect(tabBar, &QTabBar::tabCloseRequested, handler, &ModeHandler::closeMode); } ModeWindow::~ModeWindow() { - delete ui; - ui = nullptr; } void ModeWindow::SetupUi() { - ui->horizontalLayout->setSpacing(0); - ui->horizontalLayout->setMargin(0); - ui->horizontalLayout->setContentsMargins(0,0,0,0); - ui->tabwidgetModes->setUsesScrollButtons(true); + auto cornerWidget = new QWidget(); + cornerWidget->setLayout(new QHBoxLayout); + cornerWidget->layout()->setSpacing(0); + cornerWidget->layout()->setMargin(0); + cornerWidget->layout()->setContentsMargins(0,0,0,0); + cornerWidget->setMaximumHeight(aw->menuBar()->height()); + + tabBar = new QTabBar; + tabBar->setStyleSheet("QTabBar::tab { height: " + QString::number(aw->menuBar()->height()) + "px;}"); + tabBar->setTabsClosable(true); + cornerWidget->layout()->addWidget(tabBar); auto bAdd = new QPushButton(); QIcon icon; @@ -50,7 +52,7 @@ void ModeWindow::SetupUi() icon.addFile(QString::fromUtf8(":/icons/add.png"), QSize(), QIcon::Normal, QIcon::Off); bAdd->setIcon(icon); - bAdd->setMaximumHeight(450); + bAdd->setMaximumHeight(aw->menuBar()->height()); bAdd->setMaximumWidth(40); auto mAdd = new QMenu(); @@ -75,7 +77,10 @@ void ModeWindow::SetupUi() }); } bAdd->setMenu(mAdd); - aw->menuBar()->setCornerWidget(bAdd); + + cornerWidget->layout()->addWidget(bAdd); + + aw->menuBar()->setCornerWidget(cornerWidget); } void ModeWindow::ModeCreated(int modeIndex) @@ -85,15 +90,27 @@ void ModeWindow::ModeCreated(int modeIndex) if (mode) { const auto name = mode->getName(); - auto central = mode->getCentral(); - const auto tabIndex = ui->tabwidgetModes->insertTab(modeIndex, central, name); - ui->tabwidgetModes->setCurrentIndex(tabIndex); + + tabBar->blockSignals(true); + tabBar->insertTab(modeIndex, name); + tabBar->blockSignals(false); + + tabBar->setCurrentIndex(modeIndex); } } void ModeWindow::ModeClosed(int modeIndex) { - auto modeWidget = ui->tabwidgetModes->widget(modeIndex); - ui->tabwidgetModes->removeTab(modeIndex); - delete modeWidget; + tabBar->blockSignals(true); + tabBar->removeTab(modeIndex); + tabBar->blockSignals(false); +} + + +void ModeWindow::CurrentModeChanged(int modeIndex) +{ + if (modeIndex != tabBar->currentIndex()) + { + tabBar->setCurrentIndex(modeIndex); + } } diff --git a/Software/PC_Application/modewindow.h b/Software/PC_Application/modewindow.h index 4a31286..c4a8139 100644 --- a/Software/PC_Application/modewindow.h +++ b/Software/PC_Application/modewindow.h @@ -3,10 +3,6 @@ #include "modehandler.h" -namespace Ui { - class ModeWindow; -} - class ModeWindow: public QWidget { Q_OBJECT @@ -16,13 +12,14 @@ public: private: ModeHandler* handler; - Ui::ModeWindow *ui; void SetupUi(); AppWindow* aw; + QTabBar* tabBar; private slots: void ModeCreated(int modeIndex); void ModeClosed(int modeIndex); + void CurrentModeChanged(int modeIndex); }; #endif // MODEWINDOW_H diff --git a/Software/PC_Application/modewindow.ui b/Software/PC_Application/modewindow.ui deleted file mode 100644 index 4f9e2d3..0000000 --- a/Software/PC_Application/modewindow.ui +++ /dev/null @@ -1,45 +0,0 @@ - - - ModeWindow - - - - 0 - 0 - 22 - 29 - - - - Form - - - - - - Qt::LeftToRight - - - -1 - - - false - - - true - - - - - - - - ModeTabWidget - QTabWidget -
modetabwidget.h
- 1 -
-
- - -
From 77e0d156d044e122865a4e872d545af112df4ba9 Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Mon, 4 Jul 2022 13:06:08 -0500 Subject: [PATCH 3/9] mode: set tabs moveable --- Software/PC_Application/modehandler.cpp | 9 +++++++++ Software/PC_Application/modehandler.h | 1 + Software/PC_Application/modewindow.cpp | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Software/PC_Application/modehandler.cpp b/Software/PC_Application/modehandler.cpp index b565e2b..db8b797 100644 --- a/Software/PC_Application/modehandler.cpp +++ b/Software/PC_Application/modehandler.cpp @@ -58,6 +58,15 @@ void ModeHandler::setCurrentIndex(int index) } } +void ModeHandler::currentModeMoved(int from, int to) +{ + auto modeFrom = modes.at(from); + auto modeTo = modes.at(to); + modes[from] = modeTo; + modes[to] = modeFrom; + setCurrentIndex(to); +} + int ModeHandler::getCurrentIndex() { return currentModeIndex; diff --git a/Software/PC_Application/modehandler.h b/Software/PC_Application/modehandler.h index 683701b..de4e1d0 100644 --- a/Software/PC_Application/modehandler.h +++ b/Software/PC_Application/modehandler.h @@ -17,6 +17,7 @@ public: void shutdown(); int createMode(QString name, Mode::Type t); void closeMode(int index); + void currentModeMoved(int from, int to); void closeModes(); int getCurrentIndex(); diff --git a/Software/PC_Application/modewindow.cpp b/Software/PC_Application/modewindow.cpp index 0e4c94a..1fe89d4 100644 --- a/Software/PC_Application/modewindow.cpp +++ b/Software/PC_Application/modewindow.cpp @@ -22,6 +22,7 @@ ModeWindow::ModeWindow(ModeHandler* handler, AppWindow* aw, QWidget* parent): connect(tabBar, &QTabBar::currentChanged, handler, &ModeHandler::setCurrentIndex); connect(tabBar, &QTabBar::tabCloseRequested, handler, &ModeHandler::closeMode); + connect(tabBar, &QTabBar::tabMoved, handler, &ModeHandler::currentModeMoved); } ModeWindow::~ModeWindow() @@ -94,7 +95,7 @@ void ModeWindow::ModeCreated(int modeIndex) tabBar->blockSignals(true); tabBar->insertTab(modeIndex, name); tabBar->blockSignals(false); - + tabBar->setMovable(true); tabBar->setCurrentIndex(modeIndex); } } From 287ee3757ff524af1483ca5a51f6f13642c7dc17 Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Fri, 8 Jul 2022 23:16:59 -0500 Subject: [PATCH 4/9] mode: refactor next selected mode when a tab is closed --- Software/PC_Application/modehandler.cpp | 50 ++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/Software/PC_Application/modehandler.cpp b/Software/PC_Application/modehandler.cpp index db8b797..2fed964 100644 --- a/Software/PC_Application/modehandler.cpp +++ b/Software/PC_Application/modehandler.cpp @@ -49,8 +49,7 @@ std::vector ModeHandler::getModes() void ModeHandler::setCurrentIndex(int index) { -// if ( (getCurrentIndex() != index) && (index >= 0)) { - if ( (getCurrentIndex() != index) && (index >= 0)) { + if (index >= 0) { currentModeIndex = index; auto * m = getMode(getCurrentIndex()); m->activate(); @@ -75,13 +74,51 @@ int ModeHandler::getCurrentIndex() void ModeHandler::closeMode(int index) { disconnect(modes.at(index), &Mode::statusbarMessage, this, &ModeHandler::setStatusBarMessageChanged); - delete modes.at(index); - modes.erase(modes.begin() + index); + + std::vector idx; + for(int i=0; i < int(modes.size()); i++) + { + idx.push_back(i); + } + + auto left = std::find(idx.begin(), idx.end(), getCurrentIndex()-1); + auto right = std::find(idx.begin(), idx.end(), getCurrentIndex()+1); + auto foundLeft = false; + auto foundRight = false; + + if ( left != idx.end() ) + { + foundLeft = true; + } + + if ( right != idx.end() ) + { + foundRight = true; + } + + auto lastIndex = getCurrentIndex(); + if (int(modes.size()) > 0) { - if (getCurrentIndex() == index) { - setCurrentIndex(getCurrentIndex()-1); // Select bar before one deleted + if (getCurrentIndex() == index) + { + if (foundLeft) + { + setCurrentIndex(getCurrentIndex()-1); + } + else if (foundRight) + { + setCurrentIndex(getCurrentIndex()+1); + } } } + + delete modes.at(index); + modes.erase(modes.begin() + index); + + if (getCurrentIndex() == 1 && lastIndex == 0) { + setCurrentIndex(0); + } + emit ModeClosed(index); } @@ -157,3 +194,4 @@ void ModeHandler::setAveragingMode(Averaging::Mode value) } } } + From 0b7c3d5416625c3e18f164d1e67a70d773af3d1d Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Sat, 9 Jul 2022 18:55:12 -0500 Subject: [PATCH 5/9] mode: do not re activate current tab when is moved --- Software/PC_Application/modehandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Software/PC_Application/modehandler.cpp b/Software/PC_Application/modehandler.cpp index 2fed964..d456e5c 100644 --- a/Software/PC_Application/modehandler.cpp +++ b/Software/PC_Application/modehandler.cpp @@ -63,7 +63,6 @@ void ModeHandler::currentModeMoved(int from, int to) auto modeTo = modes.at(to); modes[from] = modeTo; modes[to] = modeFrom; - setCurrentIndex(to); } int ModeHandler::getCurrentIndex() From f56e32488ebda8b11b7fc96ba41951235c3146fb Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Sun, 10 Jul 2022 10:45:56 -0500 Subject: [PATCH 6/9] app: activate mode from scpi Fix missing activation of gui mode components --- Software/PC_Application/appwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Software/PC_Application/appwindow.cpp b/Software/PC_Application/appwindow.cpp index 9e157fa..12c788b 100644 --- a/Software/PC_Application/appwindow.cpp +++ b/Software/PC_Application/appwindow.cpp @@ -586,6 +586,8 @@ void AppWindow::SetupSCPI() } if(mode) { mode->activate(); + int index = modeHandler->findIndex(mode); + modeHandler->setCurrentIndex(index); return SCPI::getResultName(SCPI::Result::Empty); } else { return SCPI::getResultName(SCPI::Result::Error); From 2fbe6e84bea909bb5790d00ab1cd6fde4f8fa504 Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Sun, 10 Jul 2022 19:55:10 -0500 Subject: [PATCH 7/9] mode: move responsabilities from mode to modehandler - Pass the following responsabilities from mode to mode handler: - active / deactive target mode - get active mode - create new modes - Move back setting averaging mode when settings are updated using getModes() method instead of handling logic in mode handler. --- .../Calibration/amplitudecaldialog.cpp | 10 ++- .../Calibration/amplitudecaldialog.h | 5 +- .../Calibration/frequencycaldialog.cpp | 8 +- .../Calibration/frequencycaldialog.h | 3 +- .../Calibration/receivercaldialog.cpp | 4 +- .../Calibration/receivercaldialog.h | 3 +- .../Calibration/sourcecaldialog.cpp | 4 +- .../Calibration/sourcecaldialog.h | 3 +- .../PC_Application/Generator/generator.cpp | 3 +- .../SpectrumAnalyzer/spectrumanalyzer.cpp | 5 +- Software/PC_Application/VNA/vna.cpp | 7 +- Software/PC_Application/appwindow.cpp | 72 +++++++++++----- Software/PC_Application/appwindow.h | 1 + Software/PC_Application/mode.cpp | 33 +------ Software/PC_Application/mode.h | 12 ++- Software/PC_Application/modehandler.cpp | 86 ++++++++++--------- Software/PC_Application/modehandler.h | 9 +- 17 files changed, 142 insertions(+), 126 deletions(-) diff --git a/Software/PC_Application/Calibration/amplitudecaldialog.cpp b/Software/PC_Application/Calibration/amplitudecaldialog.cpp index 3c4c3dc..9425aa3 100644 --- a/Software/PC_Application/Calibration/amplitudecaldialog.cpp +++ b/Software/PC_Application/Calibration/amplitudecaldialog.cpp @@ -17,15 +17,16 @@ using namespace std; using namespace nlohmann; -AmplitudeCalDialog::AmplitudeCalDialog(Device *dev, QWidget *parent) : +AmplitudeCalDialog::AmplitudeCalDialog(Device *dev, ModeHandler *handler, QWidget *parent) : QDialog(parent), ui(new Ui::AmplitudeCalDialog), dev(dev), + modeHandler(handler), model(this), mode(CalibrationMode::BothPorts) { - activeMode = Mode::getActiveMode(); - activeMode->deactivate(); + auto activeMode = modeHandler->getActiveMode(); + modeHandler->deactivate(activeMode); dev->SetIdle(); ui->setupUi(this); ui->view->setModel(&model); @@ -137,7 +138,8 @@ AmplitudeCalDialog::AmplitudeCalDialog(Device *dev, QWidget *parent) : AmplitudeCalDialog::~AmplitudeCalDialog() { delete ui; - activeMode->activate(); + auto activeMode = modeHandler->getActiveMode(); + modeHandler->activate(activeMode); } void AmplitudeCalDialog::reject() diff --git a/Software/PC_Application/Calibration/amplitudecaldialog.h b/Software/PC_Application/Calibration/amplitudecaldialog.h index 0abcbd8..d36516d 100644 --- a/Software/PC_Application/Calibration/amplitudecaldialog.h +++ b/Software/PC_Application/Calibration/amplitudecaldialog.h @@ -2,6 +2,7 @@ #define AMPLITUDECALDIALOG_H #include "mode.h" +#include "modehandler.h" #include "Device/device.h" #include @@ -42,7 +43,7 @@ class AmplitudeCalDialog : public QDialog Q_OBJECT public: - explicit AmplitudeCalDialog(Device *dev, QWidget *parent = nullptr); + explicit AmplitudeCalDialog(Device *dev, ModeHandler *handler, QWidget *parent = nullptr); ~AmplitudeCalDialog(); void reject() override; @@ -100,7 +101,7 @@ protected: std::vector points; Ui::AmplitudeCalDialog *ui; Device *dev; - Mode *activeMode; + ModeHandler *modeHandler; AmplitudeModel model; bool edited; CalibrationMode mode; diff --git a/Software/PC_Application/Calibration/frequencycaldialog.cpp b/Software/PC_Application/Calibration/frequencycaldialog.cpp index df2d403..abd04f8 100644 --- a/Software/PC_Application/Calibration/frequencycaldialog.cpp +++ b/Software/PC_Application/Calibration/frequencycaldialog.cpp @@ -2,7 +2,7 @@ #include "ui_frequencycaldialog.h" -FrequencyCalDialog::FrequencyCalDialog(Device *dev, QWidget *parent) : +FrequencyCalDialog::FrequencyCalDialog(Device *dev, ModeHandler *handler, QWidget *parent) : QDialog(parent), ui(new Ui::FrequencyCalDialog), dev(dev) @@ -22,9 +22,9 @@ FrequencyCalDialog::FrequencyCalDialog(Device *dev, QWidget *parent) : p.frequencyCorrection.ppm = ui->ppm->value(); dev->SendPacket(p); // force restart of current mode for setting to take effect - auto activeMode = Mode::getActiveMode(); - activeMode->deactivate(); - activeMode->activate(); + auto activeMode = handler->getActiveMode(); + handler->deactivate(activeMode); + handler->activate(activeMode); accept(); delete this; }); diff --git a/Software/PC_Application/Calibration/frequencycaldialog.h b/Software/PC_Application/Calibration/frequencycaldialog.h index 7358407..9ddf4e9 100644 --- a/Software/PC_Application/Calibration/frequencycaldialog.h +++ b/Software/PC_Application/Calibration/frequencycaldialog.h @@ -2,6 +2,7 @@ #define FREQUENCYCALDIALOG_H #include "Device/device.h" +#include "modehandler.h" #include "mode.h" #include @@ -15,7 +16,7 @@ class FrequencyCalDialog : public QDialog Q_OBJECT public: - explicit FrequencyCalDialog(Device *dev, QWidget *parent = nullptr); + explicit FrequencyCalDialog(Device *dev, ModeHandler *handler, QWidget *parent = nullptr); ~FrequencyCalDialog(); private: diff --git a/Software/PC_Application/Calibration/receivercaldialog.cpp b/Software/PC_Application/Calibration/receivercaldialog.cpp index 1b74176..bd64cfe 100644 --- a/Software/PC_Application/Calibration/receivercaldialog.cpp +++ b/Software/PC_Application/Calibration/receivercaldialog.cpp @@ -1,7 +1,7 @@ #include "receivercaldialog.h" -ReceiverCalDialog::ReceiverCalDialog(Device *dev) - : AmplitudeCalDialog(dev) +ReceiverCalDialog::ReceiverCalDialog(Device *dev, ModeHandler *handler) + : AmplitudeCalDialog(dev, handler) { setWindowTitle("Receiver Calibration Dialog"); LoadFromDevice(); diff --git a/Software/PC_Application/Calibration/receivercaldialog.h b/Software/PC_Application/Calibration/receivercaldialog.h index 1032c73..28fecf4 100644 --- a/Software/PC_Application/Calibration/receivercaldialog.h +++ b/Software/PC_Application/Calibration/receivercaldialog.h @@ -2,12 +2,13 @@ #define RECEIVERCALDIALOG_H #include "amplitudecaldialog.h" +#include "modehandler.h" class ReceiverCalDialog : public AmplitudeCalDialog { Q_OBJECT public: - ReceiverCalDialog(Device *dev); + ReceiverCalDialog(Device *dev, ModeHandler *handler); protected: Protocol::PacketType requestCommand() override { return Protocol::PacketType::RequestReceiverCal; } Protocol::PacketType pointType() override { return Protocol::PacketType::ReceiverCalPoint; } diff --git a/Software/PC_Application/Calibration/sourcecaldialog.cpp b/Software/PC_Application/Calibration/sourcecaldialog.cpp index 9d047b1..c511920 100644 --- a/Software/PC_Application/Calibration/sourcecaldialog.cpp +++ b/Software/PC_Application/Calibration/sourcecaldialog.cpp @@ -2,8 +2,8 @@ #include -SourceCalDialog::SourceCalDialog(Device *dev) - : AmplitudeCalDialog(dev) +SourceCalDialog::SourceCalDialog(Device *dev, ModeHandler *handler) + : AmplitudeCalDialog(dev, handler) { setWindowTitle("Source Calibration Dialog"); LoadFromDevice(); diff --git a/Software/PC_Application/Calibration/sourcecaldialog.h b/Software/PC_Application/Calibration/sourcecaldialog.h index 7bd691c..f343e3b 100644 --- a/Software/PC_Application/Calibration/sourcecaldialog.h +++ b/Software/PC_Application/Calibration/sourcecaldialog.h @@ -2,6 +2,7 @@ #define SOURCECALDIALOG_H #include "amplitudecaldialog.h" +#include "modehandler.h" #include @@ -9,7 +10,7 @@ class SourceCalDialog : public AmplitudeCalDialog { Q_OBJECT public: - SourceCalDialog(Device *dev); + SourceCalDialog(Device *dev, ModeHandler *handler); protected: Protocol::PacketType requestCommand() override { return Protocol::PacketType::RequestSourceCal; } Protocol::PacketType pointType() override { return Protocol::PacketType::SourceCalPoint; } diff --git a/Software/PC_Application/Generator/generator.cpp b/Software/PC_Application/Generator/generator.cpp index 94d4d0f..efecde8 100644 --- a/Software/PC_Application/Generator/generator.cpp +++ b/Software/PC_Application/Generator/generator.cpp @@ -1,4 +1,5 @@ #include "generator.h" +#include "modehandler.h" #include @@ -55,7 +56,7 @@ void Generator::fromJSON(nlohmann::json j) void Generator::updateDevice() { - if(!window->getDevice() || Mode::getActiveMode() != this) { + if(!window->getDevice() || window->getModeHandler()->getActiveMode() != this) { // can't update if not connected return; } diff --git a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp index de035c7..cc2cf6d 100644 --- a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp +++ b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp @@ -17,6 +17,7 @@ #include "Device/firmwareupdatedialog.h" #include "preferences.h" #include "Generator/signalgenwidget.h" +#include "modehandler.h" #include #include @@ -433,7 +434,7 @@ using namespace std; void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d) { - if(Mode::getActiveMode() != this) { + if(window->getModeHandler()->getActiveMode() != this) { return; } @@ -570,7 +571,7 @@ void SpectrumAnalyzer::SettingsChanged() } } - if(window->getDevice() && Mode::getActiveMode() == this) { + if(window->getDevice() && window->getModeHandler()->getActiveMode() == this) { window->getDevice()->Configure(settings, [=](Device::TransmissionResult res){ // device received command changingSettings = false; diff --git a/Software/PC_Application/VNA/vna.cpp b/Software/PC_Application/VNA/vna.cpp index fc0cd22..b176d78 100644 --- a/Software/PC_Application/VNA/vna.cpp +++ b/Software/PC_Application/VNA/vna.cpp @@ -22,6 +22,7 @@ #include "Calibration/manualcalibrationdialog.h" #include "Util/util.h" #include "Tools/parameters.h" +#include "modehandler.h" #include #include @@ -801,7 +802,7 @@ using namespace std; void VNA::NewDatapoint(Protocol::Datapoint d) { - if(Mode::getActiveMode() != this) { + if(window->getModeHandler()->getActiveMode() != this) { // ignore return; } @@ -972,7 +973,7 @@ void VNA::SettingsChanged(bool resetTraces, std::functiongetDevice() && Mode::getActiveMode() == this) { + if(window->getDevice() && window->getModeHandler()->getActiveMode() == this) { if(s.excitePort1 == 0 && s.excitePort2 == 0) { // no signal at either port, just set the device to idle window->getDevice()->SetIdle(); @@ -1486,7 +1487,7 @@ void VNA::SetupSCPI() return ret; })); scpi_cal->add(new SCPICommand("MEASure", [=](QStringList params) -> QString { - if(params.size() != 1 || CalibrationMeasurementActive() || !window->getDevice() || Mode::getActiveMode() != this) { + if(params.size() != 1 || CalibrationMeasurementActive() || !window->getDevice() || window->getModeHandler()->getActiveMode() != this) { // no measurement specified, still busy or invalid mode return SCPI::getResultName(SCPI::Result::Error); } else { diff --git a/Software/PC_Application/appwindow.cpp b/Software/PC_Application/appwindow.cpp index 12c788b..11c87b1 100644 --- a/Software/PC_Application/appwindow.cpp +++ b/Software/PC_Application/appwindow.cpp @@ -264,7 +264,7 @@ AppWindow::AppWindow(QWidget *parent) LoadSetup(filename); }); connect(ui->actionSave_image, &QAction::triggered, [=](){ - Mode::getActiveMode()->saveSreenshot(); + modeHandler->getActiveMode()->saveSreenshot(); }); connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl); @@ -284,17 +284,38 @@ AppWindow::AppWindow(QWidget *parent) StartTCPServer(p.SCPIServer.port); } } - - if(p.Acquisition.useMedianAveraging) { - modeHandler->setAveragingMode(Averaging::Mode::Median); - } else { - modeHandler->setAveragingMode(Averaging::Mode::Mean); + // averaging mode may have changed, update for all relevant modes + for (auto m : modeHandler->getModes()) + { + switch (m->getType()) + { + case Mode::Type::VNA: + if(p.Acquisition.useMedianAveraging) { + static_cast(m)->setAveragingMode(Averaging::Mode::Median); + } + else { + static_cast(m)->setAveragingMode(Averaging::Mode::Mean); + } + break; + case Mode::Type::SA: + if(p.Acquisition.useMedianAveraging) { + static_cast(m)->setAveragingMode(Averaging::Mode::Median); + } + else { + static_cast(m)->setAveragingMode(Averaging::Mode::Mean); + } + break; + case Mode::Type::SG: + case Mode::Type::Last: + default: + break; + } } // acquisition frequencies may have changed, update UpdateAcquisitionFrequencies(); - auto active = Mode::getActiveMode(); + auto active = modeHandler->getActiveMode(); if (active) { active->updateGraphColors(); @@ -369,8 +390,8 @@ void AppWindow::closeEvent(QCloseEvent *event) QSettings settings; settings.setValue("geometry", saveGeometry()); // deactivate currently used mode (stores mode state in settings) - if(Mode::getActiveMode()) { - Mode::getActiveMode()->deactivate(); + if(modeHandler->getActiveMode()) { + modeHandler->deactivate(modeHandler->getActiveMode()); } delete device; delete modeHandler; @@ -406,8 +427,8 @@ bool AppWindow::ConnectToDevice(QString serial) ui->actionFrequency_Calibration->setEnabled(true); UpdateAcquisitionFrequencies(); - if (Mode::getActiveMode()) { - Mode::getActiveMode()->initializeDevice(); + if (modeHandler->getActiveMode()) { + modeHandler->getActiveMode()->initializeDevice(); } UpdateReference(); @@ -445,8 +466,8 @@ void AppWindow::DisconnectDevice() deviceActionGroup->checkedAction()->setChecked(false); } UpdateStatusBar(DeviceStatusBar::Disconnected); - if(Mode::getActiveMode()) { - Mode::getActiveMode()->deviceDisconnected(); + if(modeHandler->getActiveMode()) { + modeHandler->getActiveMode()->deviceDisconnected(); } qDebug() << "Disconnected device"; } @@ -585,7 +606,6 @@ void AppWindow::SetupSCPI() return "INVALID MDOE"; } if(mode) { - mode->activate(); int index = modeHandler->findIndex(mode); modeHandler->setCurrentIndex(index); return SCPI::getResultName(SCPI::Result::Empty); @@ -593,7 +613,7 @@ void AppWindow::SetupSCPI() return SCPI::getResultName(SCPI::Result::Error); } }, [=](QStringList) -> QString { - auto active = Mode::getActiveMode(); + auto active = modeHandler->getActiveMode(); if(active) { switch(active->getType()) { case Mode::Type::VNA: return "VNA"; @@ -955,7 +975,7 @@ void AppWindow::StartManualControl() connect(manual, &QDialog::finished, [=](){ manual = nullptr; if(device) { - Mode::getActiveMode()->initializeDevice(); + modeHandler->getActiveMode()->initializeDevice(); } }); if(AppWindow::showGUI()) { @@ -1035,7 +1055,7 @@ void AppWindow::DeviceStatusUpdated() void AppWindow::SourceCalibrationDialog() { - auto d = new SourceCalDialog(device); + auto d = new SourceCalDialog(device, modeHandler); if(AppWindow::showGUI()) { d->exec(); } @@ -1043,7 +1063,7 @@ void AppWindow::SourceCalibrationDialog() void AppWindow::ReceiverCalibrationDialog() { - auto d = new ReceiverCalDialog(device); + auto d = new ReceiverCalDialog(device, modeHandler); if(AppWindow::showGUI()) { d->exec(); } @@ -1051,7 +1071,7 @@ void AppWindow::ReceiverCalibrationDialog() void AppWindow::FrequencyCalibrationDialog() { - auto d = new FrequencyCalDialog(device); + auto d = new FrequencyCalDialog(device, modeHandler); if(AppWindow::showGUI()) { d->exec(); } @@ -1082,8 +1102,8 @@ nlohmann::json AppWindow::SaveSetup() jm.push_back(jmode); } j["Modes"] = jm; - if(Mode::getActiveMode()) { - j["activeMode"] = Mode::getActiveMode()->getName().toStdString(); + if(modeHandler->getActiveMode()) { + j["activeMode"] = modeHandler->getActiveMode()->getName().toStdString(); } nlohmann::json ref; @@ -1171,8 +1191,8 @@ void AppWindow::LoadSetup(nlohmann::json j) } } // if no mode is activated, there might have been a problem with the setup file. Activate the first mode anyway, to prevent invalid GUI state - if(!Mode::getActiveMode() && modeHandler->getModes().size() > 0) { - modeHandler->getModes()[0]->activate(); + if(!modeHandler->getActiveMode() && modeHandler->getModes().size() > 0) { + modeHandler->activate(modeHandler->getModes()[0]); } } @@ -1186,6 +1206,12 @@ QStackedWidget *AppWindow::getCentral() const return central; } +ModeHandler* AppWindow::getModeHandler() const +{ + return modeHandler; +} + + Ui::MainWindow *AppWindow::getUi() const { return ui; diff --git a/Software/PC_Application/appwindow.h b/Software/PC_Application/appwindow.h index 8b1269e..3fcc8b9 100644 --- a/Software/PC_Application/appwindow.h +++ b/Software/PC_Application/appwindow.h @@ -42,6 +42,7 @@ public: Ui::MainWindow *getUi() const; QStackedWidget *getCentral() const; + ModeHandler* getModeHandler() const; Device*&getDevice(); const QString& getAppVersion() const; diff --git a/Software/PC_Application/mode.cpp b/Software/PC_Application/mode.cpp index 998b0db..b5eb493 100644 --- a/Software/PC_Application/mode.cpp +++ b/Software/PC_Application/mode.cpp @@ -13,7 +13,6 @@ #include #include -Mode* Mode::activeMode = nullptr; //QButtonGroup* Mode::modeButtonGroup = nullptr; Mode::Mode(AppWindow *window, QString name, QString SCPIname) @@ -29,9 +28,6 @@ Mode::Mode(AppWindow *window, QString name, QString SCPIname) Mode::~Mode() { window->getSCPI()->remove(this); - if(activeMode == this) { - deactivate(); - } window->getCentral()->removeWidget(central); delete central; for(auto d : docks) { @@ -44,13 +40,6 @@ Mode::~Mode() void Mode::activate() { - if(activeMode == this) { - // already active; - return; - } else if(activeMode) { - activeMode->deactivate(); - } - qDebug() << "Activating mode" << name; // show all mode specific GUI elements for(auto t : toolbars) { @@ -88,8 +77,6 @@ void Mode::activate() } } - activeMode = this; - if(window->getDevice()) { initializeDevice(); } @@ -126,12 +113,6 @@ void Mode::deactivate() if(window->getDevice()) { window->getDevice()->SetIdle(); } - activeMode = nullptr; -} - -Mode *Mode::getActiveMode() -{ - return activeMode; } QString Mode::TypeToName(Mode::Type t) @@ -168,16 +149,6 @@ void Mode::saveSreenshot() central->grab().save(filename); } -Mode *Mode::createNew(AppWindow *window, QString name, Mode::Type t) -{ - switch(t) { - case Type::VNA: return new VNA(window, name); - case Type::SG: return new Generator(window, name); - case Type::SA: return new SpectrumAnalyzer(window, name); - default: return nullptr; - } -} - void Mode::finalize(QWidget *centralWidget) { central = centralWidget; @@ -204,9 +175,7 @@ void Mode::finalize(QWidget *centralWidget) void Mode::setStatusbarMessage(QString msg) { statusbarMsg = msg; - if(this == activeMode) { - emit statusbarMessage(msg); - } + emit statusbarMessage(msg); } QString Mode::getName() const diff --git a/Software/PC_Application/mode.h b/Software/PC_Application/mode.h index ce1627c..e554776 100644 --- a/Software/PC_Application/mode.h +++ b/Software/PC_Application/mode.h @@ -16,6 +16,7 @@ class Mode : public QObject, public Savable, public SCPINode { Q_OBJECT + friend class ModeHandler; public: enum class Type { VNA, @@ -27,13 +28,10 @@ public: Mode(AppWindow *window, QString name, QString SCPIname); ~Mode(); - virtual void activate(); // derived classes must call Mode::activate before doing anything - virtual void deactivate(); // derived classes must call Mode::deactivate before returning virtual void shutdown(){}; // called when the application is about to exit QString getName() const; void setName(const QString &value); void updateGraphColors(); - static Mode *getActiveMode(); static QString TypeToName(Type t); static Type TypeFromName(QString s); virtual Type getType() = 0; @@ -43,11 +41,13 @@ public: virtual void saveSreenshot(); - static Mode *createNew(AppWindow *window, QString name, Type t); - signals: void statusbarMessage(QString msg); protected: + + virtual void activate(); // derived classes must call Mode::activate before doing anything + virtual void deactivate(); // derived classes must call Mode::deactivate before returning + void setStatusbarMessage(QString msg); // call once the derived class is fully initialized void finalize(QWidget *centralWidget); @@ -57,8 +57,6 @@ protected: std::set docks; private: - static std::vector modes; - static Mode *activeMode; // static QButtonGroup *modeButtonGroup; QString name; QString statusbarMsg; diff --git a/Software/PC_Application/modehandler.cpp b/Software/PC_Application/modehandler.cpp index d456e5c..b42a79e 100644 --- a/Software/PC_Application/modehandler.cpp +++ b/Software/PC_Application/modehandler.cpp @@ -20,7 +20,7 @@ void ModeHandler::shutdown() int ModeHandler::createMode(QString name, Mode::Type t) { - auto mode = Mode::createNew(aw, name, t); + auto mode = createNew(aw, name, t); return createMode(mode); } @@ -30,18 +30,52 @@ int ModeHandler::createMode(Mode *mode) currentModeIndex = int(modes.size()) - 1; connect(mode, &Mode::statusbarMessage, this, &ModeHandler::setStatusBarMessageChanged); - auto * m = getMode(currentModeIndex); - m->activate(); + auto m = getMode(currentModeIndex); + activate(m); emit ModeCreated(currentModeIndex); return (currentModeIndex); } +Mode *ModeHandler::createNew(AppWindow *aw, QString name, Mode::Type t) +{ + switch(t) { + case Mode::Type::VNA: return new VNA(aw, name); + case Mode::Type::SG: return new Generator(aw, name); + case Mode::Type::SA: return new SpectrumAnalyzer(aw, name); + default: return nullptr; + } +} + +Mode* ModeHandler::getActiveMode() +{ + return activeMode; +} + Mode* ModeHandler::getMode(int index) { return modes.at(index); } +void ModeHandler::activate(Mode * mode) +{ + if (getActiveMode() == mode) { + // Already active + return; + } + else if (getActiveMode()) { + deactivate(getActiveMode()); + } + activeMode = mode; + mode->activate(); +} + +void ModeHandler::deactivate(Mode* mode) +{ + mode->deactivate(); + activeMode = nullptr; +} + std::vector ModeHandler::getModes() { return modes; @@ -51,8 +85,8 @@ void ModeHandler::setCurrentIndex(int index) { if (index >= 0) { currentModeIndex = index; - auto * m = getMode(getCurrentIndex()); - m->activate(); + auto m = getMode(getCurrentIndex()); + activate(m); emit CurrentModeChanged(getCurrentIndex()); } } @@ -111,6 +145,10 @@ void ModeHandler::closeMode(int index) } } + if (getActiveMode() == modes.at(index)) { + deactivate(getActiveMode()); + } + delete modes.at(index); modes.erase(modes.begin() + index); @@ -130,7 +168,10 @@ void ModeHandler::closeModes() void ModeHandler::setStatusBarMessageChanged(const QString &msg) { - emit StatusBarMessageChanged(msg); + QObject* mode = sender(); + if ( getActiveMode() == mode) { + emit StatusBarMessageChanged(msg); + } } bool ModeHandler::nameAllowed(const QString &name) @@ -161,36 +202,3 @@ Mode* ModeHandler::findFirstOfType(Mode::Type t) } return nullptr; } - -void ModeHandler::setAveragingMode(Averaging::Mode value) -{ - - - // averaging mode may have changed, update for all relevant modes - for (auto m : getModes()) - { - switch (m->getType()) - { - case Mode::Type::VNA: - static_cast(m)->setAveragingMode(value); - break; - case Mode::Type::SA: - static_cast(m)->setAveragingMode(value); - break; - case Mode::Type::SG: - case Mode::Type::Last: - default: - break; - } - } - - for(auto m : modes) { - if (m->getType() == Mode::Type::SA) { - static_cast(m)->setAveragingMode(value); - } - else if (m->getType() == Mode::Type::VNA) { - static_cast(m)->setAveragingMode(value); - } - } -} - diff --git a/Software/PC_Application/modehandler.h b/Software/PC_Application/modehandler.h index de4e1d0..e34e662 100644 --- a/Software/PC_Application/modehandler.h +++ b/Software/PC_Application/modehandler.h @@ -21,6 +21,11 @@ public: void closeModes(); int getCurrentIndex(); + Mode* getActiveMode(); + + void activate(Mode * mode); + void deactivate(Mode* mode); + Mode* getMode(int index); std::vector getModes(); @@ -28,8 +33,6 @@ public: int findIndex(Mode *targetMode); Mode* findFirstOfType(Mode::Type t); - void setAveragingMode(Averaging::Mode m); - signals: void StatusBarMessageChanged(const QString &msg); @@ -44,7 +47,9 @@ private: std::vector modes; int currentModeIndex; int createMode(Mode *mode); + Mode *createNew(AppWindow *window, QString name, Mode::Type t); AppWindow *aw; + Mode *activeMode = nullptr; private slots: void setStatusBarMessageChanged(const QString &msg); From 6bd80c594420a984e19e7a73639ac050853d6341 Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Thu, 14 Jul 2022 08:25:33 -0500 Subject: [PATCH 8/9] mode: remove mode handler dependency in child modes --- Software/PC_Application/Generator/generator.cpp | 3 +-- .../PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp | 5 ++--- Software/PC_Application/VNA/vna.cpp | 7 +++---- Software/PC_Application/mode.cpp | 4 ++++ Software/PC_Application/mode.h | 1 + 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Software/PC_Application/Generator/generator.cpp b/Software/PC_Application/Generator/generator.cpp index efecde8..6a52878 100644 --- a/Software/PC_Application/Generator/generator.cpp +++ b/Software/PC_Application/Generator/generator.cpp @@ -1,5 +1,4 @@ #include "generator.h" -#include "modehandler.h" #include @@ -56,7 +55,7 @@ void Generator::fromJSON(nlohmann::json j) void Generator::updateDevice() { - if(!window->getDevice() || window->getModeHandler()->getActiveMode() != this) { + if(!window->getDevice() || isActive != true) { // can't update if not connected return; } diff --git a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp index cc2cf6d..12d8d94 100644 --- a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp +++ b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.cpp @@ -17,7 +17,6 @@ #include "Device/firmwareupdatedialog.h" #include "preferences.h" #include "Generator/signalgenwidget.h" -#include "modehandler.h" #include #include @@ -434,7 +433,7 @@ using namespace std; void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d) { - if(window->getModeHandler()->getActiveMode() != this) { + if(isActive != true) { return; } @@ -571,7 +570,7 @@ void SpectrumAnalyzer::SettingsChanged() } } - if(window->getDevice() && window->getModeHandler()->getActiveMode() == this) { + if(window->getDevice() && isActive) { window->getDevice()->Configure(settings, [=](Device::TransmissionResult res){ // device received command changingSettings = false; diff --git a/Software/PC_Application/VNA/vna.cpp b/Software/PC_Application/VNA/vna.cpp index b176d78..aa65a67 100644 --- a/Software/PC_Application/VNA/vna.cpp +++ b/Software/PC_Application/VNA/vna.cpp @@ -22,7 +22,6 @@ #include "Calibration/manualcalibrationdialog.h" #include "Util/util.h" #include "Tools/parameters.h" -#include "modehandler.h" #include #include @@ -802,7 +801,7 @@ using namespace std; void VNA::NewDatapoint(Protocol::Datapoint d) { - if(window->getModeHandler()->getActiveMode() != this) { + if(isActive != true) { // ignore return; } @@ -973,7 +972,7 @@ void VNA::SettingsChanged(bool resetTraces, std::functiongetDevice() && window->getModeHandler()->getActiveMode() == this) { + if(window->getDevice() && isActive) { if(s.excitePort1 == 0 && s.excitePort2 == 0) { // no signal at either port, just set the device to idle window->getDevice()->SetIdle(); @@ -1487,7 +1486,7 @@ void VNA::SetupSCPI() return ret; })); scpi_cal->add(new SCPICommand("MEASure", [=](QStringList params) -> QString { - if(params.size() != 1 || CalibrationMeasurementActive() || !window->getDevice() || window->getModeHandler()->getActiveMode() != this) { + if(params.size() != 1 || CalibrationMeasurementActive() || !window->getDevice() || isActive != true) { // no measurement specified, still busy or invalid mode return SCPI::getResultName(SCPI::Result::Error); } else { diff --git a/Software/PC_Application/mode.cpp b/Software/PC_Application/mode.cpp index b5eb493..ec31fb1 100644 --- a/Software/PC_Application/mode.cpp +++ b/Software/PC_Application/mode.cpp @@ -19,6 +19,7 @@ Mode::Mode(AppWindow *window, QString name, QString SCPIname) : QObject(window), SCPINode(SCPIname), window(window), + isActive(false), name(name), central(nullptr) { @@ -40,6 +41,7 @@ Mode::~Mode() void Mode::activate() { + isActive = true; qDebug() << "Activating mode" << name; // show all mode specific GUI elements for(auto t : toolbars) { @@ -86,6 +88,7 @@ void Mode::activate() void Mode::deactivate() { + isActive = false; QSettings settings; // save dock/toolbar visibility for(auto d : docks) { @@ -110,6 +113,7 @@ void Mode::deactivate() } qDebug() << "Deactivated mode" << name; + if(window->getDevice()) { window->getDevice()->SetIdle(); } diff --git a/Software/PC_Application/mode.h b/Software/PC_Application/mode.h index e554776..9742e87 100644 --- a/Software/PC_Application/mode.h +++ b/Software/PC_Application/mode.h @@ -47,6 +47,7 @@ protected: virtual void activate(); // derived classes must call Mode::activate before doing anything virtual void deactivate(); // derived classes must call Mode::deactivate before returning + bool isActive; void setStatusbarMessage(QString msg); // call once the derived class is fully initialized From fd5d21db0f4f6a04157de23cdae069976aca1560 Mon Sep 17 00:00:00 2001 From: Kiara Navarro Date: Thu, 14 Jul 2022 08:51:45 -0500 Subject: [PATCH 9/9] mode: convert averaging mode as a method used in all modes --- Software/PC_Application/Generator/generator.h | 2 ++ .../SpectrumAnalyzer/spectrumanalyzer.h | 2 +- Software/PC_Application/VNA/vna.h | 2 +- Software/PC_Application/appwindow.cpp | 11 ++--------- Software/PC_Application/mode.h | 2 ++ 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Software/PC_Application/Generator/generator.h b/Software/PC_Application/Generator/generator.h index 41f4bb5..5d97585 100644 --- a/Software/PC_Application/Generator/generator.h +++ b/Software/PC_Application/Generator/generator.h @@ -18,6 +18,8 @@ public: virtual nlohmann::json toJSON() override; virtual void fromJSON(nlohmann::json j) override; + void setAveragingMode(Averaging::Mode mode) override {Q_UNUSED(mode)}; + private slots: void updateDevice(); diff --git a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.h b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.h index d247d25..fcec0da 100644 --- a/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.h +++ b/Software/PC_Application/SpectrumAnalyzer/spectrumanalyzer.h @@ -28,7 +28,7 @@ public: virtual void fromJSON(nlohmann::json j) override; void updateGraphColors(); - void setAveragingMode(Averaging::Mode mode); + void setAveragingMode(Averaging::Mode mode) override; private: diff --git a/Software/PC_Application/VNA/vna.h b/Software/PC_Application/VNA/vna.h index 77068b2..2702af1 100644 --- a/Software/PC_Application/VNA/vna.h +++ b/Software/PC_Application/VNA/vna.h @@ -31,7 +31,7 @@ public: virtual void fromJSON(nlohmann::json j) override; void updateGraphColors(); - void setAveragingMode(Averaging::Mode mode); + void setAveragingMode(Averaging::Mode mode) override; enum class SweepType { Frequency = 0, diff --git a/Software/PC_Application/appwindow.cpp b/Software/PC_Application/appwindow.cpp index 11c87b1..a16dd5e 100644 --- a/Software/PC_Application/appwindow.cpp +++ b/Software/PC_Application/appwindow.cpp @@ -290,19 +290,12 @@ AppWindow::AppWindow(QWidget *parent) switch (m->getType()) { case Mode::Type::VNA: - if(p.Acquisition.useMedianAveraging) { - static_cast(m)->setAveragingMode(Averaging::Mode::Median); - } - else { - static_cast(m)->setAveragingMode(Averaging::Mode::Mean); - } - break; case Mode::Type::SA: if(p.Acquisition.useMedianAveraging) { - static_cast(m)->setAveragingMode(Averaging::Mode::Median); + m->setAveragingMode(Averaging::Mode::Median); } else { - static_cast(m)->setAveragingMode(Averaging::Mode::Mean); + m->setAveragingMode(Averaging::Mode::Mean); } break; case Mode::Type::SG: diff --git a/Software/PC_Application/mode.h b/Software/PC_Application/mode.h index 9742e87..1784a5e 100644 --- a/Software/PC_Application/mode.h +++ b/Software/PC_Application/mode.h @@ -41,6 +41,8 @@ public: virtual void saveSreenshot(); + virtual void setAveragingMode(Averaging::Mode mode) = 0; + signals: void statusbarMessage(QString msg); protected: