mode/app: decouple mode creation from gui components
Signed-off-by: Kiara Navarro <sophiekovalevsky@fedoraproject.org>
This commit is contained in:
parent
2e055bb55d
commit
7a0e6da706
@ -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 +=
|
||||
|
@ -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 <QDockWidget>
|
||||
#include <QDesktopWidget>
|
||||
#include <QApplication>
|
||||
#include <QActionGroup>
|
||||
#include <mode.h>
|
||||
#include <QDebug>
|
||||
#include <QGridLayout>
|
||||
#include <QVBoxLayout>
|
||||
@ -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<VNA*>(m)->setAveragingMode(Averaging::Mode::Median);
|
||||
}
|
||||
else {
|
||||
static_cast<VNA*>(m)->setAveragingMode(Averaging::Mode::Mean);
|
||||
}
|
||||
break;
|
||||
case Mode::Type::SA:
|
||||
if(p.Acquisition.useMedianAveraging) {
|
||||
static_cast<SpectrumAnalyzer*>(m)->setAveragingMode(Averaging::Mode::Median);
|
||||
}
|
||||
else {
|
||||
static_cast<SpectrumAnalyzer*>(m)->setAveragingMode(Averaging::Mode::Mean);
|
||||
}
|
||||
break;
|
||||
case Mode::Type::SG:
|
||||
case Mode::Type::Last:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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<VNA*>(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<VNA*>(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<Generator*>(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<SpectrumAnalyzer*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -13,10 +13,7 @@
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
|
||||
std::vector<Mode*> 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 *> 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;
|
||||
}
|
||||
|
@ -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<Mode *> getModes();
|
||||
static Mode* findFirstOfType(Type t);
|
||||
|
||||
virtual QWidget *getCentral() const;
|
||||
|
||||
signals:
|
||||
void statusbarMessage(QString msg);
|
||||
@ -60,14 +59,12 @@ protected:
|
||||
std::set<QDockWidget*> docks;
|
||||
|
||||
private:
|
||||
int findTabIndex();
|
||||
static std::vector<Mode*> modes;
|
||||
static Mode *activeMode;
|
||||
static QTabBar *tabbar;
|
||||
static QWidget *cornerWidget;
|
||||
// static QButtonGroup *modeButtonGroup;
|
||||
QString name;
|
||||
QString statusbarMsg;
|
||||
|
||||
QWidget *central;
|
||||
};
|
||||
|
||||
|
138
Software/PC_Application/modehandler.cpp
Normal file
138
Software/PC_Application/modehandler.cpp
Normal file
@ -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<Mode*> 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<VNA*>(m)->setAveragingMode(value);
|
||||
break;
|
||||
case Mode::Type::SA:
|
||||
static_cast<SpectrumAnalyzer*>(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<SpectrumAnalyzer*>(m)->setAveragingMode(value);
|
||||
}
|
||||
else if (m->getType() == Mode::Type::VNA) {
|
||||
static_cast<VNA*>(m)->setAveragingMode(value);
|
||||
}
|
||||
}
|
||||
}
|
50
Software/PC_Application/modehandler.h
Normal file
50
Software/PC_Application/modehandler.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef MODEHANDLER_H
|
||||
#define MODEHANDLER_H
|
||||
|
||||
#include "mode.h"
|
||||
#include "appwindow.h"
|
||||
|
||||
#include <vector>
|
||||
#include <QObject>
|
||||
|
||||
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<Mode*> 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<Mode*> modes;
|
||||
int currentModeIndex;
|
||||
void createMode(Mode *mode);
|
||||
AppWindow *aw;
|
||||
|
||||
private slots:
|
||||
void setStatusBarMessageChanged(const QString &msg);
|
||||
};
|
||||
|
||||
#endif // MODEHANDLER_H
|
14
Software/PC_Application/modetabwidget.cpp
Normal file
14
Software/PC_Application/modetabwidget.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "modetabwidget.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
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);
|
||||
}
|
18
Software/PC_Application/modetabwidget.h
Normal file
18
Software/PC_Application/modetabwidget.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef MODETABWIDGET_H
|
||||
#define MODETABWIDGET_H
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QTabBar>
|
||||
|
||||
class ModeTabWidget: public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ModeTabWidget(QWidget* parent = nullptr);
|
||||
~ModeTabWidget() = default;
|
||||
|
||||
private:
|
||||
QTabBar * tabBar = nullptr;
|
||||
};
|
||||
|
||||
#endif // MODETABWIDGET_H
|
99
Software/PC_Application/modewindow.cpp
Normal file
99
Software/PC_Application/modewindow.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#include "modewindow.h"
|
||||
|
||||
#include "mode.h"
|
||||
#include "ui_modewindow.h"
|
||||
#include "appwindow.h"
|
||||
#include "CustomWidgets/informationbox.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
#include <QPushButton>
|
||||
#include <QMenuBar>
|
||||
|
||||
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;
|
||||
}
|
28
Software/PC_Application/modewindow.h
Normal file
28
Software/PC_Application/modewindow.h
Normal file
@ -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
|
45
Software/PC_Application/modewindow.ui
Normal file
45
Software/PC_Application/modewindow.ui
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ModeWindow</class>
|
||||
<widget class="QWidget" name="ModeWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>22</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="ModeTabWidget" name="tabwidgetModes">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="usesScrollButtons">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tabsClosable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ModeTabWidget</class>
|
||||
<extends>QTabWidget</extends>
|
||||
<header>modetabwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Reference in New Issue
Block a user