mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-05 14:35:23 +00:00
PC Application: partial firmware update dialog
This commit is contained in:
parent
8c8749accd
commit
07ba714f1f
134 changed files with 13954 additions and 7 deletions
79
Software/PC_Application/CustomWidgets/siunitedit.cpp
Normal file
79
Software/PC_Application/CustomWidgets/siunitedit.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#include "siunitedit.h"
|
||||
|
||||
#include <QDoubleValidator>
|
||||
#include <unit.h>
|
||||
#include <QEvent>
|
||||
#include <QKeyEvent>
|
||||
|
||||
SIUnitEdit::SIUnitEdit(QString unit, QString prefixes, int precision, QWidget *parent)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
this->unit = unit;
|
||||
this->prefixes = prefixes;
|
||||
this->precision = precision;
|
||||
setAlignment(Qt::AlignCenter);
|
||||
installEventFilter(this);
|
||||
setValidator(new QDoubleValidator);
|
||||
connect(this, &QLineEdit::editingFinished, [this]() {
|
||||
parseNewValue(1.0);
|
||||
});
|
||||
}
|
||||
|
||||
SIUnitEdit::SIUnitEdit(QWidget *parent)
|
||||
: SIUnitEdit("", " ", 4, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SIUnitEdit::setValue(double value)
|
||||
{
|
||||
setValueQuiet(value);
|
||||
emit valueChanged(value);
|
||||
}
|
||||
|
||||
bool SIUnitEdit::eventFilter(QObject *, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
int key = static_cast<QKeyEvent *>(event)->key();
|
||||
if(key == Qt::Key_Escape) {
|
||||
// abort editing process and set old value
|
||||
setValueQuiet(_value);
|
||||
return true;
|
||||
}
|
||||
if(key == Qt::Key_Return) {
|
||||
// use new value without prefix
|
||||
parseNewValue(1.0);
|
||||
return true;
|
||||
}
|
||||
auto mod = static_cast<QKeyEvent *>(event)->modifiers();
|
||||
if (!(mod & Qt::ShiftModifier)) {
|
||||
key = tolower(key);
|
||||
}
|
||||
if(key <= 255 && prefixes.indexOf(key) >= 0) {
|
||||
// a valid prefix key was pressed
|
||||
parseNewValue(Unit::SIPrefixToFactor(key));
|
||||
return true;
|
||||
}
|
||||
} else if(event->type() == QEvent::FocusOut) {
|
||||
if(!text().isEmpty()) {
|
||||
parseNewValue(1.0);
|
||||
} else {
|
||||
setValueQuiet(_value);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SIUnitEdit::setValueQuiet(double value)
|
||||
{
|
||||
_value = value;
|
||||
clear();
|
||||
setPlaceholderText(Unit::ToString(value, unit, prefixes, precision));
|
||||
clearFocus();
|
||||
}
|
||||
|
||||
void SIUnitEdit::parseNewValue(double factor)
|
||||
{
|
||||
double v = text().toDouble() * factor;
|
||||
setValue(v);
|
||||
}
|
||||
31
Software/PC_Application/CustomWidgets/siunitedit.h
Normal file
31
Software/PC_Application/CustomWidgets/siunitedit.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef SIUNITEDIT_H
|
||||
#define SIUNITEDIT_H
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
class SIUnitEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SIUnitEdit(QString unit = QString(), QString prefixes = " ", int precision = 0, QWidget *parent = nullptr);
|
||||
SIUnitEdit(QWidget *parent);
|
||||
|
||||
void setUnit(QString unit) { this->unit = unit; setValueQuiet(_value); }
|
||||
void setPrefixes(QString prefixes) { this->prefixes = prefixes; setValueQuiet(_value); }
|
||||
void setPrecision(int precision) { this->precision = precision; setValueQuiet(_value); }
|
||||
double value() { return _value; }
|
||||
public slots:
|
||||
void setValue(double value);
|
||||
void setValueQuiet(double value);
|
||||
signals:
|
||||
void valueChanged(double newvalue);
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
private:
|
||||
void parseNewValue(double factor);
|
||||
QString unit, prefixes;
|
||||
int precision;
|
||||
double _value;
|
||||
};
|
||||
|
||||
#endif // SIUNITEDIT_H
|
||||
141
Software/PC_Application/CustomWidgets/tilewidget.cpp
Normal file
141
Software/PC_Application/CustomWidgets/tilewidget.cpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include "tilewidget.h"
|
||||
#include "ui_tilewidget.h"
|
||||
#include <QDebug>
|
||||
#include "Traces/tracebodeplot.h"
|
||||
#include "Traces/tracesmithchart.h"
|
||||
|
||||
TileWidget::TileWidget(TraceModel &model, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::TileWidget),
|
||||
splitter(0),
|
||||
isSplit(false),
|
||||
parent(0),
|
||||
child1(0),
|
||||
child2(0),
|
||||
hasContent(false),
|
||||
content(0),
|
||||
model(model)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
auto layout = new QGridLayout;
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
ui->ContentPage->setLayout(layout);
|
||||
ui->bClose->setVisible(false);
|
||||
}
|
||||
|
||||
TileWidget::~TileWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TileWidget::splitVertically()
|
||||
{
|
||||
if(isSplit) {
|
||||
return;
|
||||
}
|
||||
isSplit = true;
|
||||
splitter = new QSplitter(Qt::Vertical);
|
||||
split();
|
||||
}
|
||||
|
||||
void TileWidget::splitHorizontally()
|
||||
{
|
||||
if(isSplit) {
|
||||
return;
|
||||
}
|
||||
isSplit = true;
|
||||
splitter = new QSplitter(Qt::Horizontal);
|
||||
split();
|
||||
}
|
||||
|
||||
void TileWidget::closeTile()
|
||||
{
|
||||
if(!parent) {
|
||||
// Unable to close toplevel tile
|
||||
return;
|
||||
}
|
||||
auto pTile = parent;
|
||||
TileWidget *absorbedTile;
|
||||
if(this == parent->child1) {
|
||||
absorbedTile = parent->child2;
|
||||
} else {
|
||||
absorbedTile = parent->child1;
|
||||
}
|
||||
delete this;
|
||||
|
||||
if(absorbedTile->isSplit) {
|
||||
pTile->isSplit = true;
|
||||
pTile->child1 = absorbedTile->child1;
|
||||
pTile->child2 = absorbedTile->child2;
|
||||
pTile->child1->parent = pTile;
|
||||
pTile->child2->parent = pTile;
|
||||
pTile->ui->ContentPage->layout()->addWidget(absorbedTile->splitter);
|
||||
auto oldsplitter = pTile->splitter;
|
||||
pTile->splitter = absorbedTile->splitter;
|
||||
delete absorbedTile;
|
||||
delete oldsplitter;
|
||||
} else if(absorbedTile->hasContent) {
|
||||
pTile->setContent(absorbedTile->content);
|
||||
delete absorbedTile;
|
||||
pTile->isSplit = false;
|
||||
delete pTile->splitter;
|
||||
pTile->splitter = nullptr;
|
||||
} else {
|
||||
delete absorbedTile;
|
||||
pTile->isSplit = false;
|
||||
pTile->hasContent = false;
|
||||
delete pTile->splitter;
|
||||
pTile->ui->stack->setCurrentWidget(pTile->ui->TilePage);
|
||||
}
|
||||
}
|
||||
|
||||
void TileWidget::setPlot(TracePlot *plot)
|
||||
{
|
||||
if(!isSplit && !hasContent) {
|
||||
setContent(plot);
|
||||
}
|
||||
}
|
||||
|
||||
TileWidget::TileWidget(TraceModel &model, TileWidget &parent)
|
||||
: TileWidget(model)
|
||||
{
|
||||
this->parent = &parent;
|
||||
ui->bClose->setVisible(true);
|
||||
}
|
||||
|
||||
void TileWidget::split()
|
||||
{
|
||||
splitter->setHandleWidth(0);
|
||||
child1 = new TileWidget(model, *this);
|
||||
child2 = new TileWidget(model, *this);
|
||||
splitter->addWidget(child1);
|
||||
splitter->addWidget(child2);
|
||||
ui->ContentPage->layout()->addWidget(splitter);
|
||||
ui->stack->setCurrentWidget(ui->ContentPage);
|
||||
}
|
||||
|
||||
void TileWidget::setContent(TracePlot *plot)
|
||||
{
|
||||
content = plot;
|
||||
hasContent = true;
|
||||
ui->ContentPage->layout()->addWidget(plot);
|
||||
ui->stack->setCurrentWidget(ui->ContentPage);
|
||||
connect(content, &TracePlot::deleted, this, &TileWidget::traceDeleted);
|
||||
}
|
||||
|
||||
void TileWidget::on_bSmithchart_clicked()
|
||||
{
|
||||
setContent(new TraceSmithChart(model));
|
||||
}
|
||||
|
||||
void TileWidget::on_bBodeplot_clicked()
|
||||
{
|
||||
setContent(new TraceBodePlot(model));
|
||||
}
|
||||
|
||||
void TileWidget::traceDeleted(TracePlot *)
|
||||
{
|
||||
ui->stack->setCurrentWidget(ui->TilePage);
|
||||
hasContent = false;
|
||||
content = nullptr;
|
||||
}
|
||||
49
Software/PC_Application/CustomWidgets/tilewidget.h
Normal file
49
Software/PC_Application/CustomWidgets/tilewidget.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef TILEWIDGET_H
|
||||
#define TILEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "Traces/traceplot.h"
|
||||
#include <QSplitter>
|
||||
#include "Traces/tracemodel.h"
|
||||
|
||||
namespace Ui {
|
||||
class TileWidget;
|
||||
}
|
||||
|
||||
class TileWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TileWidget(TraceModel &model, QWidget *parent = nullptr);
|
||||
~TileWidget();
|
||||
|
||||
TileWidget *Child1() { return child1; };
|
||||
TileWidget *Child2() { return child2; };
|
||||
public slots:
|
||||
void splitVertically();
|
||||
void splitHorizontally();
|
||||
void closeTile();
|
||||
void setPlot(TracePlot *plot);
|
||||
|
||||
private slots:
|
||||
void on_bSmithchart_clicked();
|
||||
void on_bBodeplot_clicked();
|
||||
void traceDeleted(TracePlot *t);
|
||||
|
||||
private:
|
||||
TileWidget(TraceModel &model, TileWidget &parent);
|
||||
void split();
|
||||
void setContent(TracePlot *plot);
|
||||
void setChild();
|
||||
Ui::TileWidget *ui;
|
||||
QSplitter *splitter;
|
||||
bool isSplit;
|
||||
TileWidget *parent;
|
||||
TileWidget *child1, *child2;
|
||||
bool hasContent;
|
||||
TracePlot *content;
|
||||
TraceModel &model;
|
||||
};
|
||||
|
||||
#endif // TILEWIDGET_H
|
||||
266
Software/PC_Application/CustomWidgets/tilewidget.ui
Normal file
266
Software/PC_Application/CustomWidgets/tilewidget.ui
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TileWidget</class>
|
||||
<widget class="QWidget" name="TileWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>465</width>
|
||||
<height>350</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stack">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="TilePage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Plots</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="bSmithchart">
|
||||
<property name="text">
|
||||
<string>Smithchart</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="bBodeplot">
|
||||
<property name="text">
|
||||
<string>Bodeplot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Split Tile</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="bSplitV">
|
||||
<property name="text">
|
||||
<string>Vertical</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/vertical.svg</normaloff>:/icons/vertical.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="bSplitH">
|
||||
<property name="text">
|
||||
<string>Horizontal</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/horizontal.svg</normaloff>:/icons/horizontal.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="bClose">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close Tile</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/close.svg</normaloff>:/icons/close.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="ContentPage"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../icons.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>bClose</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>TileWidget</receiver>
|
||||
<slot>closeTile()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>199</x>
|
||||
<y>74</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>149</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>bSplitH</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>TileWidget</receiver>
|
||||
<slot>splitHorizontally()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>199</x>
|
||||
<y>224</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>149</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>bSplitV</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>TileWidget</receiver>
|
||||
<slot>splitVertically()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>199</x>
|
||||
<y>149</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>149</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>splitVertically()</slot>
|
||||
<slot>splitHorizontally()</slot>
|
||||
<slot>closeTile()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
66
Software/PC_Application/CustomWidgets/toggleswitch.cpp
Normal file
66
Software/PC_Application/CustomWidgets/toggleswitch.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include "toggleswitch.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
|
||||
ToggleSwitch::ToggleSwitch(QWidget *parent, bool state) : QAbstractButton(parent),
|
||||
_height(24),
|
||||
_width(128),
|
||||
state(state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QSize ToggleSwitch::sizeHint() const
|
||||
{
|
||||
return QSize(_width, _height);
|
||||
}
|
||||
|
||||
void ToggleSwitch::toggle()
|
||||
{
|
||||
state = !state;
|
||||
emit toggled(state);
|
||||
}
|
||||
|
||||
void ToggleSwitch::setState(bool state)
|
||||
{
|
||||
if(this->state != state) {
|
||||
this->state = state;
|
||||
emit toggled(state);
|
||||
}
|
||||
}
|
||||
|
||||
void ToggleSwitch::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(Qt::black);
|
||||
p.setOpacity(isEnabled() ? 0.38 : 0.12);
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
p.drawRoundedRect(QRect(0, 0, width(), height()), 8.0, 8.0);
|
||||
p.setOpacity(1.0);
|
||||
QRect rect;
|
||||
QString statename;
|
||||
if(state) {
|
||||
p.setBrush(isEnabled() ? Qt::darkGreen : Qt::gray);
|
||||
rect = QRect(width()/2, 0, width()/2, height());
|
||||
statename = "ON";
|
||||
} else {
|
||||
p.setBrush(isEnabled() ? QColor("#AA090E") : Qt::lightGray);
|
||||
rect = QRect(0, 0, width()/2, height());
|
||||
statename = "OFF";
|
||||
}
|
||||
p.drawRoundedRect(rect, 8.0, 8.0);
|
||||
QFont font = p.font();
|
||||
p.setPen(Qt::SolidLine);
|
||||
p.setPen(isEnabled() ? Qt::black : Qt::gray);
|
||||
p.drawText(rect, Qt::AlignCenter, statename);
|
||||
}
|
||||
|
||||
void ToggleSwitch::mouseReleaseEvent(QMouseEvent *e)
|
||||
{
|
||||
if(e->button() & Qt::LeftButton) {
|
||||
toggle();
|
||||
}
|
||||
QAbstractButton::mouseReleaseEvent(e);
|
||||
}
|
||||
28
Software/PC_Application/CustomWidgets/toggleswitch.h
Normal file
28
Software/PC_Application/CustomWidgets/toggleswitch.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef TOGGLESWITCH_H
|
||||
#define TOGGLESWITCH_H
|
||||
|
||||
#include <QAbstractButton>
|
||||
|
||||
class ToggleSwitch : public QAbstractButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ToggleSwitch(QWidget* parent = nullptr, bool state = false);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
signals:
|
||||
void toggled(bool newstate);
|
||||
public slots:
|
||||
void toggle();
|
||||
void setState(bool state);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
void mouseReleaseEvent(QMouseEvent*) override;
|
||||
|
||||
private:
|
||||
int _height, _width;
|
||||
bool state;
|
||||
};
|
||||
|
||||
#endif // TOGGLESWITCH_H
|
||||
185
Software/PC_Application/CustomWidgets/touchstoneimport.cpp
Normal file
185
Software/PC_Application/CustomWidgets/touchstoneimport.cpp
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
#include "touchstoneimport.h"
|
||||
#include "ui_touchstoneimport.h"
|
||||
#include <QFileDialog>
|
||||
#include <QDebug>
|
||||
#include <QtGlobal>
|
||||
|
||||
using namespace std;
|
||||
|
||||
TouchstoneImport::TouchstoneImport(QWidget *parent, int ports) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::TouchstoneImport),
|
||||
touchstone(ports),
|
||||
status(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
connect(ui->browse, &QPushButton::clicked, this, &TouchstoneImport::evaluateFile);
|
||||
ui->port1Group->setId(ui->port1_1, 0);
|
||||
ui->port1Group->setId(ui->port1_2, 1);
|
||||
ui->port1Group->setId(ui->port1_3, 2);
|
||||
ui->port1Group->setId(ui->port1_4, 3);
|
||||
ui->port2Group->setId(ui->port2_1, 0);
|
||||
ui->port2Group->setId(ui->port2_2, 1);
|
||||
ui->port2Group->setId(ui->port2_3, 2);
|
||||
ui->port2Group->setId(ui->port2_4, 3);
|
||||
// prevent selection of same port for port1 and 2
|
||||
connect(ui->port1Group, qOverload<int>(&QButtonGroup::buttonClicked), [=](int id) {
|
||||
preventCollisionWithGroup(ui->port2Group, id);
|
||||
});
|
||||
connect(ui->port2Group, qOverload<int>(&QButtonGroup::buttonClicked), [=](int id) {
|
||||
preventCollisionWithGroup(ui->port1Group, id);
|
||||
});
|
||||
setPorts(ports);
|
||||
}
|
||||
|
||||
TouchstoneImport::~TouchstoneImport()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool TouchstoneImport::getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
Touchstone TouchstoneImport::getTouchstone()
|
||||
{
|
||||
if(required_ports == 1) {
|
||||
auto t1 = touchstone;
|
||||
t1.reduceTo1Port(ui->port1Group->checkedId());
|
||||
return t1;
|
||||
} else if(required_ports == 2) {
|
||||
auto t2 = touchstone;
|
||||
t2.reduceTo2Port(ui->port1Group->checkedId(), ui->port2Group->checkedId());
|
||||
return t2;
|
||||
}
|
||||
|
||||
return touchstone;
|
||||
}
|
||||
|
||||
void TouchstoneImport::setPorts(int ports)
|
||||
{
|
||||
required_ports = ports;
|
||||
ui->port1Widget->setVisible(ports >= 1);
|
||||
ui->port2Widget->setVisible(ports >= 2);
|
||||
}
|
||||
|
||||
QString TouchstoneImport::getFilename()
|
||||
{
|
||||
return ui->file->text();
|
||||
}
|
||||
|
||||
void TouchstoneImport::selectPort(int destination, int source)
|
||||
{
|
||||
switch(destination) {
|
||||
case 0:
|
||||
ui->port1Group->button(source)->setChecked(true);
|
||||
preventCollisionWithGroup(ui->port2Group, source);
|
||||
break;
|
||||
case 1:
|
||||
ui->port2Group->button(source)->setChecked(true);
|
||||
preventCollisionWithGroup(ui->port1Group, source);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> TouchstoneImport::getPorts()
|
||||
{
|
||||
vector<int> ret;
|
||||
if(required_ports >= 1) {
|
||||
ret.push_back(ui->port1Group->checkedId());
|
||||
}
|
||||
if(required_ports >= 2) {
|
||||
ret.push_back(ui->port2Group->checkedId());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TouchstoneImport::setFile(QString filename)
|
||||
{
|
||||
ui->file->setText(filename);
|
||||
evaluateFile();
|
||||
}
|
||||
|
||||
void TouchstoneImport::on_browse_clicked()
|
||||
{
|
||||
auto filename = QFileDialog::getOpenFileName(nullptr, "Open measurement file", "", "Touchstone files (*.s1p *.s2p *.s3p *.s4p)", nullptr, QFileDialog::DontUseNativeDialog);
|
||||
if (filename.length() > 0) {
|
||||
ui->file->setText(filename);
|
||||
evaluateFile();
|
||||
}
|
||||
}
|
||||
|
||||
void TouchstoneImport::evaluateFile()
|
||||
{
|
||||
bool new_status = false;
|
||||
ui->port1_1->setEnabled(false);
|
||||
ui->port1_2->setEnabled(false);
|
||||
ui->port1_3->setEnabled(false);
|
||||
ui->port1_4->setEnabled(false);
|
||||
if (required_ports != 1) {
|
||||
ui->port2_1->setEnabled(false);
|
||||
ui->port2_2->setEnabled(false);
|
||||
ui->port2_3->setEnabled(false);
|
||||
ui->port2_4->setEnabled(false);
|
||||
}
|
||||
ui->points->setText("");
|
||||
ui->lowerFreq->setText("");
|
||||
ui->upperFreq->setText("");
|
||||
ui->status->clear();
|
||||
try {
|
||||
touchstone = Touchstone::fromFile(ui->file->text().toStdString());
|
||||
if (required_ports > 0 && touchstone.ports() < (unsigned int) required_ports) {
|
||||
throw runtime_error("Not enough ports in file");
|
||||
}
|
||||
ui->port1_1->setEnabled(touchstone.ports() >= 1);
|
||||
ui->port1_2->setEnabled(touchstone.ports() >= 2);
|
||||
ui->port1_3->setEnabled(touchstone.ports() >= 3);
|
||||
ui->port1_4->setEnabled(touchstone.ports() >= 4);
|
||||
if (required_ports != 1) {
|
||||
ui->port2_1->setEnabled(touchstone.ports() >= 1);
|
||||
ui->port2_2->setEnabled(touchstone.ports() >= 2);
|
||||
ui->port2_3->setEnabled(touchstone.ports() >= 3);
|
||||
ui->port2_4->setEnabled(touchstone.ports() >= 4);
|
||||
}
|
||||
ui->points->setText(QString::number(touchstone.points()));
|
||||
ui->lowerFreq->setText(QString::number(touchstone.minFreq()));
|
||||
ui->upperFreq->setText(QString::number(touchstone.maxFreq()));
|
||||
if(ui->port1Group->checkedId() == -1 || !ui->port1Group->checkedButton()->isEnabled()) {
|
||||
// no or invalid S parameter selected
|
||||
ui->port1_1->setChecked(true);
|
||||
}
|
||||
if (required_ports != 1) {
|
||||
preventCollisionWithGroup(ui->port2Group, 0);
|
||||
}
|
||||
new_status = true;
|
||||
} catch (const exception &e) {
|
||||
ui->status->setText(e.what());
|
||||
}
|
||||
if (new_status != status) {
|
||||
status = new_status;
|
||||
emit statusChanged(status);
|
||||
}
|
||||
emit filenameChanged(ui->file->text());
|
||||
}
|
||||
|
||||
void TouchstoneImport::preventCollisionWithGroup(QButtonGroup *group, int id)
|
||||
{
|
||||
for(unsigned int i=0;i<touchstone.ports();i++) {
|
||||
group->button(i)->setEnabled(true);
|
||||
}
|
||||
// change selection in second group and mark invalid
|
||||
group->button(id)->setEnabled(false);
|
||||
group->button(id)->setChecked(false);
|
||||
if (group->checkedId() == -1 || group->checkedId() == id) {
|
||||
for(int i=0;i<4;i++) {
|
||||
if(i == id) {
|
||||
continue;
|
||||
}
|
||||
if(group->button(i)->isEnabled()) {
|
||||
group->button(i)->setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
Software/PC_Application/CustomWidgets/touchstoneimport.h
Normal file
46
Software/PC_Application/CustomWidgets/touchstoneimport.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef TOUCHSTONEIMPORT_H
|
||||
#define TOUCHSTONEIMPORT_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "touchstone.h"
|
||||
#include <QButtonGroup>
|
||||
|
||||
namespace Ui {
|
||||
class TouchstoneImport;
|
||||
}
|
||||
|
||||
class TouchstoneImport : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TouchstoneImport(QWidget *parent = nullptr, int ports = 0);
|
||||
~TouchstoneImport();
|
||||
|
||||
bool getStatus();
|
||||
Touchstone getTouchstone();
|
||||
void setPorts(int ports);
|
||||
QString getFilename();
|
||||
void selectPort(int destination, int source);
|
||||
std::vector<int> getPorts();
|
||||
|
||||
signals:
|
||||
void statusChanged(bool status);
|
||||
void filenameChanged(QString name);
|
||||
|
||||
public slots:
|
||||
void setFile(QString filename);
|
||||
|
||||
private slots:
|
||||
void on_browse_clicked();
|
||||
|
||||
private:
|
||||
void evaluateFile();
|
||||
void preventCollisionWithGroup(QButtonGroup *group, int id);
|
||||
Ui::TouchstoneImport *ui;
|
||||
int required_ports;
|
||||
Touchstone touchstone;
|
||||
bool status;
|
||||
};
|
||||
|
||||
#endif // TOUCHSTONEIMPORT_H
|
||||
312
Software/PC_Application/CustomWidgets/touchstoneimport.ui
Normal file
312
Software/PC_Application/CustomWidgets/touchstoneimport.ui
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TouchstoneImport</class>
|
||||
<widget class="QWidget" name="TouchstoneImport">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>228</width>
|
||||
<height>227</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="file">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="browse">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="status">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>239</red>
|
||||
<green>41</green>
|
||||
<blue>41</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>239</red>
|
||||
<green>41</green>
|
||||
<blue>41</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="WindowText">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>190</red>
|
||||
<green>190</green>
|
||||
<blue>190</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="port1Widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Port 1:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="port1_1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">port1Group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="port1_2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">port1Group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="port1_3">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">port1Group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="port1_4">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">port1Group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="port2Widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="port2Selector">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Port 2:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="port2_1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">port2Group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="port2_2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">port2Group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="port2_3">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">port2Group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="port2_4">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">port2Group</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>Points:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="points">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>Lower Frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lowerFreq">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>Upper Frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="upperFreq">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="port2Group"/>
|
||||
<buttongroup name="port1Group"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
Loading…
Add table
Add a link
Reference in a new issue