PC Application: partial firmware update dialog

This commit is contained in:
Jan Käberich 2020-08-30 22:03:41 +02:00
parent 8c8749accd
commit 07ba714f1f
134 changed files with 13954 additions and 7 deletions

View 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);
}

View 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

View 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;
}

View 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

View 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>

View 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);
}

View 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

View 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;
}
}
}
}

View 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

View 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>