diff --git a/Software/PC_Application/Traces/XYPlotConstantLineEditDialog.ui b/Software/PC_Application/Traces/XYPlotConstantLineEditDialog.ui index d238bab..f1d3867 100644 --- a/Software/PC_Application/Traces/XYPlotConstantLineEditDialog.ui +++ b/Software/PC_Application/Traces/XYPlotConstantLineEditDialog.ui @@ -11,7 +11,7 @@ - Dialog + Edit line true diff --git a/Software/PC_Application/Traces/xyplotaxisdialog.cpp b/Software/PC_Application/Traces/xyplotaxisdialog.cpp index 147d9b5..a642253 100644 --- a/Software/PC_Application/Traces/xyplotaxisdialog.cpp +++ b/Software/PC_Application/Traces/xyplotaxisdialog.cpp @@ -3,7 +3,12 @@ #include "ui_xyplotaxisdialog.h" #include "traceaxis.h" +#include #include +#include +#include + +#include using namespace std; @@ -183,16 +188,68 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) : ui->removeLine->setEnabled(true); editLine(line); connect(line, &XYPlotConstantLine::editingFinished, [=](){ - item->setText(line->getDescription()); + if(line->getPoints().size() < 2) { // must have 2 points to be a line + int index = ui->lineList->currentRow(); + removeLine(index); + } else { + item->setText(line->getDescription()); + } }); }); connect(ui->removeLine, &QPushButton::clicked, [=](){ - auto index = ui->lineList->currentRow(); - delete ui->lineList->takeItem(index); - delete plot->constantLines[index]; - plot->constantLines.erase(plot->constantLines.begin() + index); - if(plot->constantLines.size() == 0) { - ui->removeLine->setEnabled(false); + int index = ui->lineList->currentRow(); + removeLine(index); + }); + connect(ui->exportLines, &QPushButton::clicked, [=](){ + QString filename = QFileDialog::getSaveFileName(nullptr, "Save limit lines", "", "Limit files (*.limits)", nullptr, QFileDialog::DontUseNativeDialog); + if(filename.isEmpty()) { + // aborted selection + return; + } + if(!filename.endsWith(".limits")) { + filename.append(".limits"); + } + + nlohmann::json jlines; + for(auto l : plot->constantLines ) { + jlines.push_back(l->toJSON()); + } + nlohmann::json j; + j["limitLines"] = jlines; + + ofstream file; + file.open(filename.toStdString()); + file << setw(4) << j << endl; + file.close(); + + }); + connect(ui->importLines, &QPushButton::clicked, [=](){ + QString filename = QFileDialog::getOpenFileName(nullptr, "Load limit lines", "", "Limit files (*.limits)", nullptr, QFileDialog::DontUseNativeDialog); + ifstream file; + file.open(filename.toStdString()); + if(!file.is_open()) { + qWarning() << "Unable to open file:" << filename; + return; + } + nlohmann::json j; + try { + file >> j; + } catch (exception &e) { + InformationBox::ShowError("Error", "Failed to parse file (" + QString(e.what()) + ")"); + qWarning() << "Parsing of limits file failed: " << e.what(); + file.close(); + return; + } + file.close(); + if(j.contains("limitLines")) { + for(auto jline : j["limitLines"]) { + auto line = new XYPlotConstantLine; + line->fromJSON(jline); + plot->constantLines.push_back(line); + auto item = new QListWidgetItem(line->getDescription()); + ui->lineList->addItem(item); + + } } }); @@ -276,3 +333,15 @@ bool XYplotAxisDialog::isSupported(XAxis::Type type) { return XAxis::isSupported(type, plot->getModel().getSource()); } + +void XYplotAxisDialog::removeLine(int index) { + if (index < 0) { + return; + } + delete ui->lineList->takeItem(index); + delete plot->constantLines[index]; + plot->constantLines.erase(plot->constantLines.begin() + index); + if(plot->constantLines.size() == 0) { + ui->removeLine->setEnabled(false); + } +} diff --git a/Software/PC_Application/Traces/xyplotaxisdialog.h b/Software/PC_Application/Traces/xyplotaxisdialog.h index e14b434..5ab211d 100644 --- a/Software/PC_Application/Traces/xyplotaxisdialog.h +++ b/Software/PC_Application/Traces/xyplotaxisdialog.h @@ -26,6 +26,7 @@ private: bool isSupported(XAxis::Type type); Ui::XYplotAxisDialog *ui; TraceXYPlot *plot; + void removeLine(int index); }; #endif // XYPLOTAXISDIALOG_H diff --git a/Software/PC_Application/Traces/xyplotaxisdialog.ui b/Software/PC_Application/Traces/xyplotaxisdialog.ui index 76147d5..6db0d45 100644 --- a/Software/PC_Application/Traces/xyplotaxisdialog.ui +++ b/Software/PC_Application/Traces/xyplotaxisdialog.ui @@ -489,6 +489,34 @@ + + + + Export + + + + + + + :/icons/export.png:/icons/export.png + + + + + + + Import + + + + + + + :/icons/import.png:/icons/import.png + + + @@ -564,8 +592,8 @@ - + diff --git a/Software/PC_Application/appwindow.cpp b/Software/PC_Application/appwindow.cpp index 8bfa449..ced60da 100644 --- a/Software/PC_Application/appwindow.cpp +++ b/Software/PC_Application/appwindow.cpp @@ -248,6 +248,58 @@ AppWindow::AppWindow(QWidget *parent) connect(modeHandler, &ModeHandler::StatusBarMessageChanged, setModeStatusbar); + SetupMenu(); + + setWindowTitle(qlibrevnaApp->applicationName() + " v" + getAppVersion()); + + setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); + setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); + setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); + setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); + + { + QSettings settings; + restoreGeometry(settings.value("geometry").toByteArray()); + } + + SetupSCPI(); + + auto pref = Preferences::getInstance(); + if(pref.Startup.UseSetupFile) { + LoadSetup(pref.Startup.SetupFile); + } + // List available devices + UpdateDeviceList(); + if(pref.Startup.ConnectToFirstDevice) { + // at least one device available + ConnectToDevice(); + } + + if(parser.isSet("setup")) { + LoadSetup(parser.value("setup")); + } + if(parser.isSet("cal")) { + VNA* mode = static_cast(modeHandler->findFirstOfType(Mode::Type::VNA)); + mode->LoadCalibration(parser.value("cal")); + } + if(!parser.isSet("no-gui")) { + InformationBox::setGUI(true); + resize(1280, 800); + show(); + } else { + InformationBox::setGUI(false); + noGUIset = true; + } +} + +AppWindow::~AppWindow() +{ + StopTCPServer(); + delete ui; +} + +void AppWindow::SetupMenu() +{ // UI connections connect(ui->actionUpdate_Device_List, &QAction::triggered, this, &AppWindow::UpdateDeviceList); connect(ui->actionDisconnect, &QAction::triggered, this, &AppWindow::DisconnectDevice); @@ -329,53 +381,6 @@ AppWindow::AppWindow(QWidget *parent) auto &a = About::getInstance(); a.about(); }); - - setWindowTitle(qlibrevnaApp->applicationName() + " v" + getAppVersion()); - - setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); - setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); - setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); - setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); - - { - QSettings settings; - restoreGeometry(settings.value("geometry").toByteArray()); - } - - SetupSCPI(); - - auto pref = Preferences::getInstance(); - if(pref.Startup.UseSetupFile) { - LoadSetup(pref.Startup.SetupFile); - } - // List available devices - UpdateDeviceList(); - if(pref.Startup.ConnectToFirstDevice) { - // at least one device available - ConnectToDevice(); - } - - if(parser.isSet("setup")) { - LoadSetup(parser.value("setup")); - } - if(parser.isSet("cal")) { - VNA* mode = static_cast(modeHandler->findFirstOfType(Mode::Type::VNA)); - mode->LoadCalibration(parser.value("cal")); - } - if(!parser.isSet("no-gui")) { - InformationBox::setGUI(true); - resize(1280, 800); - show(); - } else { - InformationBox::setGUI(false); - noGUIset = true; - } -} - -AppWindow::~AppWindow() -{ - StopTCPServer(); - delete ui; } void AppWindow::closeEvent(QCloseEvent *event) @@ -937,6 +942,7 @@ int AppWindow::UpdateDeviceList() devices.insert(device->serial()); } int available = 0; + bool found = false; if(devices.size()) { for(auto d : devices) { if(!parser.value("device").isEmpty() && parser.value("device") != d) { @@ -952,13 +958,11 @@ int AppWindow::UpdateDeviceList() connect(connectAction, &QAction::triggered, [this, d]() { ConnectToDevice(d); }); - ui->menuConnect_to->setEnabled(true); + found = true; available++; } - } else { - // no devices available, disable connection option - ui->menuConnect_to->setEnabled(false); } + ui->menuConnect_to->setEnabled(found); qDebug() << "Updated device list, found" << available; return available; } diff --git a/Software/PC_Application/appwindow.h b/Software/PC_Application/appwindow.h index 3fcc8b9..289e2dd 100644 --- a/Software/PC_Application/appwindow.h +++ b/Software/PC_Application/appwindow.h @@ -84,6 +84,7 @@ private: void DeviceConnectionLost(); + void SetupMenu(); void SetupStatusBar(); void UpdateStatusBar(DeviceStatusBar status); void CreateToolbars(); diff --git a/Software/PC_Application/modewindow.cpp b/Software/PC_Application/modewindow.cpp index 447c739..178b939 100644 --- a/Software/PC_Application/modewindow.cpp +++ b/Software/PC_Application/modewindow.cpp @@ -9,11 +9,10 @@ #include ModeWindow::ModeWindow(ModeHandler* handler, AppWindow* aw): - QWidget(aw), + QWidget(nullptr), handler(handler), aw(aw) { - SetupUi(); connect(handler, &ModeHandler::ModeCreated, this, &ModeWindow::ModeCreated); @@ -63,7 +62,7 @@ void ModeWindow::SetupUi() mAdd->addAction(action); connect(action, &QAction::triggered, [=](){ bool ok; - QString text = QInputDialog::getText(this, + QString text = QInputDialog::getText(aw, "Create new "+Mode::TypeToName(type)+" tab", "Name:", QLineEdit::Normal, Mode::TypeToName(type), &ok);