Marker improvements: linked marker groups

This commit is contained in:
Jan Käberich 2021-06-19 15:33:43 +02:00
parent cf401fcb01
commit a232be3443
31 changed files with 755 additions and 318 deletions

View file

@ -28,6 +28,10 @@ HEADERS += \
Tools/eseries.h \
Tools/impedancematchdialog.h \
Tools/parameters.h \
Traces/Marker/marker.h \
Traces/Marker/markergroup.h \
Traces/Marker/markermodel.h \
Traces/Marker/markerwidget.h \
Traces/Math/dft.h \
Traces/Math/expression.h \
Traces/Math/medianfilter.h \
@ -84,14 +88,11 @@ HEADERS += \
Traces/Math/tracemath.h \
Traces/Math/windowfunction.h \
Traces/fftcomplex.h \
Traces/markerwidget.h \
Traces/sparamtraceselector.h \
Traces/trace.h \
Traces/tracecsvexport.h \
Traces/traceeditdialog.h \
Traces/traceimportdialog.h \
Traces/tracemarker.h \
Traces/tracemarkermodel.h \
Traces/tracemodel.h \
Traces/traceplot.h \
Traces/tracesmithchart.h \
@ -152,6 +153,10 @@ SOURCES += \
Tools/eseries.cpp \
Tools/impedancematchdialog.cpp \
Tools/parameters.cpp \
Traces/Marker/marker.cpp \
Traces/Marker/markergroup.cpp \
Traces/Marker/markermodel.cpp \
Traces/Marker/markerwidget.cpp \
Traces/Math/dft.cpp \
Traces/Math/expression.cpp \
Traces/Math/medianfilter.cpp \
@ -197,14 +202,11 @@ SOURCES += \
Traces/Math/tracemath.cpp \
Traces/Math/windowfunction.cpp \
Traces/fftcomplex.cpp \
Traces/markerwidget.cpp \
Traces/sparamtraceselector.cpp \
Traces/trace.cpp \
Traces/tracecsvexport.cpp \
Traces/traceeditdialog.cpp \
Traces/traceimportdialog.cpp \
Traces/tracemarker.cpp \
Traces/tracemarkermodel.cpp \
Traces/tracemodel.cpp \
Traces/traceplot.cpp \
Traces/tracesmithchart.cpp \
@ -256,6 +258,7 @@ FORMS += \
Device/manualcontroldialog.ui \
Generator/signalgenwidget.ui \
Tools/impedancematchdialog.ui \
Traces/Marker/markerwidget.ui \
Traces/Math/dftdialog.ui \
Traces/Math/dftexplanationwidget.ui \
Traces/Math/expressiondialog.ui \
@ -268,7 +271,6 @@ FORMS += \
Traces/Math/timedomaingatingexplanationwidget.ui \
Traces/Math/timegatedialog.ui \
Traces/Math/timegateexplanationwidget.ui \
Traces/markerwidget.ui \
Traces/smithchartdialog.ui \
Traces/tracecsvexport.ui \
Traces/traceeditdialog.ui \

View file

@ -30,7 +30,7 @@
#include "CustomWidgets/tilewidget.h"
#include "CustomWidgets/siunitedit.h"
#include <QDockWidget>
#include "Traces/markerwidget.h"
#include "Traces/Marker/markerwidget.h"
#include "Tools/impedancematchdialog.h"
#include "Calibration/calibrationtracedialog.h"
#include "ui_main.h"
@ -232,7 +232,7 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window)
window->addToolBar(tb_trackgen);
toolbars.insert(tb_trackgen);
markerModel = new TraceMarkerModel(traceModel, this);
markerModel = new MarkerModel(traceModel, this);
auto tracesDock = new QDockWidget("Traces");
traceWidget = new TraceWidgetSA(traceModel, window);

View file

@ -78,7 +78,7 @@ private:
unsigned int averages;
TraceModel traceModel;
TraceWidget *traceWidget;
TraceMarkerModel *markerModel;
MarkerModel *markerModel;
Averaging average;
TileWidget *central;

View file

@ -7,7 +7,7 @@ using namespace std;
constexpr double ImpedanceMatchDialog::Z0;
ImpedanceMatchDialog::ImpedanceMatchDialog(TraceMarkerModel &model, TraceMarker *marker, QWidget *parent) :
ImpedanceMatchDialog::ImpedanceMatchDialog(MarkerModel &model, Marker *marker, QWidget *parent) :
QDialog(parent),
ui(new Ui::ImpedanceMatchDialog)
{
@ -44,7 +44,7 @@ ImpedanceMatchDialog::ImpedanceMatchDialog(TraceMarkerModel &model, TraceMarker
// matching only possible for reflections
continue;
}
ui->cSource->addItem("From Marker "+QString::number(m->getNumber()), QVariant::fromValue<TraceMarker*>(m));
ui->cSource->addItem("From Marker "+QString::number(m->getNumber()), QVariant::fromValue<Marker*>(m));
if(m == marker) {
// select the last index, e.i. the just created marker
ui->cSource->setCurrentIndex(ui->cSource->count()-1);
@ -65,7 +65,7 @@ void ImpedanceMatchDialog::on_cSource_currentIndexChanged(int index)
ui->zImag->setEnabled(index == 0);
ui->zFreq->setEnabled(index == 0);
if(index > 0) {
auto m = qvariant_cast<TraceMarker*>(ui->cSource->itemData(index));
auto m = qvariant_cast<Marker*>(ui->cSource->itemData(index));
ui->rbSeries->setChecked(true);
auto data = m->getData();
auto reflection = Z0 * (1.0 + data) / (1.0 - data);

View file

@ -2,7 +2,7 @@
#define IMPEDANCEMATCHDIALOG_H
#include <QDialog>
#include "Traces/tracemarkermodel.h"
#include "Traces/Marker/markermodel.h"
namespace Ui {
class ImpedanceMatchDialog;
@ -13,7 +13,7 @@ class ImpedanceMatchDialog : public QDialog
Q_OBJECT
public:
explicit ImpedanceMatchDialog(TraceMarkerModel &model, TraceMarker *marker = nullptr, QWidget *parent = nullptr);
explicit ImpedanceMatchDialog(MarkerModel &model, Marker *marker = nullptr, QWidget *parent = nullptr);
~ImpedanceMatchDialog();
private slots:

View file

@ -1,20 +1,21 @@
#include "tracemarker.h"
#include "marker.h"
#include <QPainter>
#include "CustomWidgets/siunitedit.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QSpinBox>
#include <QDebug>
#include "tracemarkermodel.h"
#include "markermodel.h"
#include "unit.h"
#include <QMenu>
#include <QActionGroup>
#include <QApplication>
#include "preferences.h"
#include "markergroup.h"
using namespace std;
TraceMarker::TraceMarker(TraceMarkerModel *model, int number, TraceMarker *parent, QString descr)
Marker::Marker(MarkerModel *model, int number, Marker *parent, QString descr)
: editingFrequency(false),
model(model),
parentTrace(nullptr),
@ -29,14 +30,15 @@ TraceMarker::TraceMarker(TraceMarkerModel *model, int number, TraceMarker *paren
cutoffAmplitude(-3.0),
peakThreshold(-40.0),
offset(10000),
formatTable(Format::dBAngle)
formatTable(Format::dBAngle),
group(nullptr)
{
connect(this, &TraceMarker::traceChanged, this, &TraceMarker::updateContextmenu);
connect(this, &TraceMarker::typeChanged, this, &TraceMarker::updateContextmenu);
connect(this, &Marker::traceChanged, this, &Marker::updateContextmenu);
connect(this, &Marker::typeChanged, this, &Marker::updateContextmenu);
updateContextmenu();
}
TraceMarker::~TraceMarker()
Marker::~Marker()
{
if(parentTrace) {
parentTrace->removeMarker(this);
@ -45,7 +47,7 @@ TraceMarker::~TraceMarker()
emit deleted(this);
}
void TraceMarker::assignTrace(Trace *t)
void Marker::assignTrace(Trace *t)
{
bool firstAssignment = false;
if(parentTrace) {
@ -64,11 +66,11 @@ void TraceMarker::assignTrace(Trace *t)
setType(type);
}
connect(parentTrace, &Trace::deleted, this, &TraceMarker::parentTraceDeleted);
connect(parentTrace, &Trace::dataChanged, this, &TraceMarker::traceDataChanged);
connect(parentTrace, &Trace::colorChanged, this, &TraceMarker::updateSymbol);
connect(parentTrace, &Trace::typeChanged, this, &TraceMarker::domainChanged);
connect(parentTrace, &Trace::typeChanged, this, &TraceMarker::checkDeltaMarker);
connect(parentTrace, &Trace::deleted, this, &Marker::parentTraceDeleted);
connect(parentTrace, &Trace::dataChanged, this, &Marker::traceDataChanged);
connect(parentTrace, &Trace::colorChanged, this, &Marker::updateSymbol);
connect(parentTrace, &Trace::typeChanged, this, &Marker::traceTypeChanged);
connect(parentTrace, &Trace::typeChanged, this, &Marker::checkDeltaMarker);
constrainPosition();
updateSymbol();
parentTrace->addMarker(this);
@ -95,18 +97,19 @@ void TraceMarker::assignTrace(Trace *t)
emit traceChanged(this);
}
Trace *TraceMarker::trace()
Trace *Marker::trace()
{
return parentTrace;
}
QString TraceMarker::formatToString(TraceMarker::Format f)
QString Marker::formatToString(Marker::Format f)
{
switch(f) {
case Format::dB: return "dB";
case Format::dBAngle: return "dB + angle";
case Format::RealImag: return "real + imag";
case Format::Impedance: return "Impedance";
case Format::VSWR: return "VSWR";
case Format::TOI: return "Third order intercept";
case Format::AvgTone: return "Average Tone Level";
case Format::AvgModulationProduct: return "Average Modulation Product Level";
@ -120,7 +123,7 @@ QString TraceMarker::formatToString(TraceMarker::Format f)
return "";
}
TraceMarker::Format TraceMarker::formatFromString(QString s)
Marker::Format Marker::formatFromString(QString s)
{
for(int i=0;i<(int) Format::Last;i++) {
if(s.compare(formatToString((Format) i)) == 0) {
@ -130,7 +133,7 @@ TraceMarker::Format TraceMarker::formatFromString(QString s)
return Format::Last;
}
std::vector<TraceMarker::Format> TraceMarker::formats()
std::vector<Marker::Format> Marker::formats()
{
std::vector<Format> ret;
for(int i=0;i<(int) Format::Last;i++) {
@ -139,7 +142,7 @@ std::vector<TraceMarker::Format> TraceMarker::formats()
return ret;
}
std::vector<TraceMarker::Format> TraceMarker::applicableFormats()
std::vector<Marker::Format> Marker::applicableFormats()
{
std::vector<Format> ret;
if(isTimeDomain()) {
@ -171,12 +174,12 @@ std::vector<TraceMarker::Format> TraceMarker::applicableFormats()
if(parentTrace) {
if(parentTrace->isReflection()) {
ret.push_back(Format::Impedance);
ret.push_back(Format::VSWR);
}
if(!isnan(parentTrace->getNoise(parentTrace->minX()))) {
ret.push_back(Format::Noise);
}
}
break;
case Type::Bandpass:
ret.push_back(Format::CenterBandwidth);
@ -203,7 +206,7 @@ std::vector<TraceMarker::Format> TraceMarker::applicableFormats()
return ret;
}
QString TraceMarker::readableData(Format f)
QString Marker::readableData(Format f)
{
if(!parentTrace) {
return "";
@ -293,6 +296,13 @@ QString TraceMarker::readableData(Format f)
case Format::dB: return Unit::ToString(Unit::dB(data), "dB", " ", 4);
case Format::dBAngle: return Unit::ToString(Unit::dB(data), "dB", " ", 4) + "/"+Unit::ToString(arg(data)*180/M_PI, "°", " ", 4);
case Format::RealImag: return Unit::ToString(data.real(), "", " ", 5) + "+"+Unit::ToString(data.imag(), "", " ", 5)+"j";
case Format::VSWR:
if(abs(data) < 1.0) {
return "VSWR: "+Unit::ToString(((1+abs(data)) / (1-abs(data))), ":1", " ", 5);
} else {
return "VSWR: NaN";
}
break;
case Format::Noise: return Unit::ToString(parentTrace->getNoise(position), "dbm/Hz", " ", 3);
case Format::TOI: {
auto avgFundamental = (helperMarkers[0]->toDecibel() + helperMarkers[1]->toDecibel()) / 2;
@ -362,7 +372,7 @@ QString TraceMarker::readableData(Format f)
return "Invalid";
}
QString TraceMarker::readablePosition()
QString Marker::readablePosition()
{
auto pos = position;
QString ret;
@ -378,7 +388,7 @@ QString TraceMarker::readablePosition()
return ret;
}
QString TraceMarker::readableSettings()
QString Marker::readableSettings()
{
if(isTimeDomain()) {
switch(type) {
@ -411,7 +421,7 @@ QString TraceMarker::readableSettings()
}
}
QString TraceMarker::tooltipSettings()
QString Marker::tooltipSettings()
{
if(isTimeDomain()) {
switch(type) {
@ -442,7 +452,7 @@ QString TraceMarker::tooltipSettings()
}
}
QString TraceMarker::readableType()
QString Marker::readableType()
{
if(parent) {
return description;
@ -451,20 +461,21 @@ QString TraceMarker::readableType()
}
}
void TraceMarker::setPosition(double pos)
void Marker::setPosition(double pos)
{
position = pos;
constrainPosition();
emit positionChanged(position);
}
void TraceMarker::parentTraceDeleted(Trace *t)
void Marker::parentTraceDeleted(Trace *t)
{
if(t == parentTrace) {
delete this;
}
}
void TraceMarker::traceDataChanged()
void Marker::traceDataChanged()
{
complex<double> newdata;
if(!parentTrace || parentTrace->numSamples() == 0) {
@ -488,7 +499,7 @@ void TraceMarker::traceDataChanged()
}
}
void TraceMarker::updateSymbol()
void Marker::updateSymbol()
{
if(isVisible()) {
constexpr int width = 15, height = 15;
@ -510,7 +521,7 @@ void TraceMarker::updateSymbol()
emit symbolChanged(this);
}
void TraceMarker::checkDeltaMarker()
void Marker::checkDeltaMarker()
{
if(type != Type::Delta) {
// not a delta marker, nothing to do
@ -523,7 +534,7 @@ void TraceMarker::checkDeltaMarker()
}
}
void TraceMarker::deltaDeleted()
void Marker::deltaDeleted()
{
// the delta marker of this marker has been deleted, find new match
delta = nullptr;
@ -532,7 +543,7 @@ void TraceMarker::deltaDeleted()
update();
}
void TraceMarker::updateContextmenu()
void Marker::updateContextmenu()
{
if(parent) {
// do nothing, using contextmenu from parent anyway
@ -600,14 +611,66 @@ void TraceMarker::updateContextmenu()
graph->addAction(setFormatAction);
}
std::vector<MarkerGroup*> applicableGroups;
for(auto g : model->getGroups()) {
if(g->applicable(this)) {
applicableGroups.push_back(g);
}
}
contextmenu.addSeparator();
bool needsSeparator = false;
if((applicableGroups.size() > 0 && group == nullptr) || applicableGroups.size() > 1) {
// there are other groups available than the one the marker might already be assigned to
auto addGroupMenu = new QMenu("Add to linked group");
auto groupGroup = new QActionGroup(addGroupMenu);
for(auto g : model->getGroups()) {
auto addGroupAction = new QAction(QString::number(g->getNumber()));
groupGroup->addAction(addGroupAction);
addGroupAction->setCheckable(true);
if(g == group) {
// already assigned to this group
addGroupAction->setChecked(true);
}
connect(addGroupAction, &QAction::triggered, [=](bool checked){
if(checked) {
g->add(this);
}
});
addGroupMenu->addAction(addGroupAction);
}
contextmenu.addMenu(addGroupMenu);
needsSeparator = true;
}
if(group != nullptr) {
// "remove from group" available
auto removeGroup = new QAction("Remove from linked group");
connect(removeGroup, &QAction::triggered, [=](){
group->remove(this);
});
contextmenu.addAction(removeGroup);
needsSeparator = true;
}
if(needsSeparator) {
contextmenu.addSeparator();
}
auto deleteAction = new QAction("Delete");
connect(deleteAction, &QAction::triggered, this, &TraceMarker::deleteLater);
connect(deleteAction, &QAction::triggered, this, &Marker::deleteLater);
contextmenu.addAction(deleteAction);
}
std::set<TraceMarker::Type> TraceMarker::getSupportedTypes()
void Marker::traceTypeChanged()
{
set<TraceMarker::Type> supported;
// domain may have changed
emit domainChanged(this);
}
std::set<Marker::Type> Marker::getSupportedTypes()
{
set<Marker::Type> supported;
if(parentTrace) {
if(isTimeDomain()) {
// only basic markers in time domain
@ -647,7 +710,7 @@ std::set<TraceMarker::Type> TraceMarker::getSupportedTypes()
return supported;
}
void TraceMarker::constrainPosition()
void Marker::constrainPosition()
{
if(parentTrace) {
if(parentTrace->size() > 0) {
@ -661,7 +724,7 @@ void TraceMarker::constrainPosition()
}
}
void TraceMarker::constrainFormat()
void Marker::constrainFormat()
{
auto vec = applicableFormats();
// check format
@ -679,9 +742,9 @@ void TraceMarker::constrainFormat()
}
}
TraceMarker *TraceMarker::bestDeltaCandidate()
Marker *Marker::bestDeltaCandidate()
{
TraceMarker *match = nullptr;
Marker *match = nullptr;
// invalid delta marker assigned, attempt to find a matching marker
for(int pass = 0;pass < 3;pass++) {
for(auto m : model->getMarkers()) {
@ -707,26 +770,26 @@ TraceMarker *TraceMarker::bestDeltaCandidate()
return match;
}
void TraceMarker::assignDeltaMarker(TraceMarker *m)
void Marker::assignDeltaMarker(Marker *m)
{
if(type != Type::Delta) {
// ignore
return;
}
if(delta) {
disconnect(delta, &TraceMarker::dataChanged, this, &TraceMarker::update);
disconnect(delta, &Marker::dataChanged, this, &Marker::update);
}
delta = m;
if(delta && delta != this) {
// this marker has to be updated when the delta marker changes
connect(delta, &TraceMarker::rawDataChanged, this, &TraceMarker::update);
connect(delta, &TraceMarker::domainChanged, this, &TraceMarker::checkDeltaMarker);
connect(delta, &TraceMarker::deleted, this, &TraceMarker::deltaDeleted);
connect(delta, &Marker::rawDataChanged, this, &Marker::update);
connect(delta, &Marker::domainChanged, this, &Marker::checkDeltaMarker);
connect(delta, &Marker::deleted, this, &Marker::deltaDeleted);
}
emit assignedDeltaChanged(this);
}
void TraceMarker::deleteHelperMarkers()
void Marker::deleteHelperMarkers()
{
if(helperMarkers.size() > 0) {
emit beginRemoveHelperMarkers(this);
@ -738,7 +801,7 @@ void TraceMarker::deleteHelperMarkers()
}
}
void TraceMarker::setType(TraceMarker::Type t)
void Marker::setType(Marker::Type t)
{
// remove any potential helper markers
deleteHelperMarkers();
@ -775,7 +838,7 @@ void TraceMarker::setType(TraceMarker::Type t)
}
// create helper markers
for(auto h : required_helpers) {
auto helper = new TraceMarker(model, number, this, h.description);
auto helper = new Marker(model, number, this, h.description);
helper->suffix = h.suffix;
helper->assignTrace(parentTrace);
helper->setType(h.type);
@ -788,12 +851,12 @@ void TraceMarker::setType(TraceMarker::Type t)
update();
}
double TraceMarker::toDecibel()
double Marker::toDecibel()
{
return Unit::dB(data);
}
bool TraceMarker::isVisible()
bool Marker::isVisible()
{
switch(type) {
case Type::Manual:
@ -807,7 +870,7 @@ bool TraceMarker::isVisible()
}
}
void TraceMarker::setTableFormat(TraceMarker::Format f)
void Marker::setTableFormat(Marker::Format f)
{
if(formatTable == f) {
// already correct format, nothing to do
@ -825,28 +888,42 @@ void TraceMarker::setTableFormat(TraceMarker::Format f)
emit dataFormatChanged(this);
}
std::set<TraceMarker::Format> TraceMarker::getGraphDisplayFormats() const
MarkerGroup *Marker::getGroup() const
{
return group;
}
void Marker::setGroup(MarkerGroup *value)
{
group = value;
updateContextmenu();
}
std::set<Marker::Format> Marker::getGraphDisplayFormats() const
{
return formatGraph;
}
TraceMarker::Type TraceMarker::getType() const
Marker::Type Marker::getType() const
{
return type;
}
QString TraceMarker::getSuffix() const
QString Marker::getSuffix() const
{
return suffix;
}
nlohmann::json TraceMarker::toJSON()
nlohmann::json Marker::toJSON()
{
nlohmann::json j;
j["trace"] = parentTrace->toHash();
j["type"] = typeToString(type).toStdString();
j["number"] = number;
j["position"] = position;
if(group) {
j["group"] = group->getNumber();
}
switch(type) {
case Type::Delta:
j["delta_marker"] = delta->toHash();
@ -875,7 +952,7 @@ nlohmann::json TraceMarker::toJSON()
return j;
}
void TraceMarker::fromJSON(nlohmann::json j)
void Marker::fromJSON(nlohmann::json j)
{
if(!j.contains("trace")) {
throw runtime_error("Marker has no trace assigned");
@ -937,9 +1014,14 @@ void TraceMarker::fromJSON(nlohmann::json j)
}
updateContextmenu();
update();
if(j.contains("group")) {
unsigned int number = j.value("group", 1);
model->addToGroupCreateIfNotExisting(this, number);
}
}
unsigned int TraceMarker::toHash()
unsigned int Marker::toHash()
{
// taking the easy way: create the json string and hash it (already contains all necessary information)
// This is slower than it could be, but this function is only used when loading setups, so this isn't a big problem
@ -947,12 +1029,12 @@ unsigned int TraceMarker::toHash()
return hash<std::string>{}(json_string);
}
const std::vector<TraceMarker *> &TraceMarker::getHelperMarkers() const
const std::vector<Marker *> &Marker::getHelperMarkers() const
{
return helperMarkers;
}
TraceMarker *TraceMarker::helperMarker(unsigned int i)
Marker *Marker::helperMarker(unsigned int i)
{
if(i < helperMarkers.size()) {
return helperMarkers[i];
@ -961,12 +1043,12 @@ TraceMarker *TraceMarker::helperMarker(unsigned int i)
}
}
TraceMarker *TraceMarker::getParent() const
Marker *Marker::getParent() const
{
return parent;
}
void TraceMarker::setNumber(int value)
void Marker::setNumber(int value)
{
number = value;
updateSymbol();
@ -975,7 +1057,7 @@ void TraceMarker::setNumber(int value)
}
}
QWidget *TraceMarker::getTypeEditor(QAbstractItemDelegate *delegate)
QWidget *Marker::getTypeEditor(QAbstractItemDelegate *delegate)
{
auto c = new QComboBox;
for(auto t : getSupportedTypes()) {
@ -1032,7 +1114,7 @@ QWidget *TraceMarker::getTypeEditor(QAbstractItemDelegate *delegate)
}
}
void TraceMarker::updateTypeFromEditor(QWidget *w)
void Marker::updateTypeFromEditor(QWidget *w)
{
QComboBox *c;
if(type == Type::Delta) {
@ -1050,13 +1132,16 @@ void TraceMarker::updateTypeFromEditor(QWidget *w)
update();
}
SIUnitEdit *TraceMarker::getSettingsEditor()
SIUnitEdit *Marker::getSettingsEditor()
{
SIUnitEdit *ret = nullptr;
if(isTimeDomain()) {
switch(type) {
case Type::Manual:
case Type::Delta:
return new SIUnitEdit("", "fpnum k", 6);
ret = new SIUnitEdit("", "fpnum k", 6);
ret->setValue(position);
break;
default:
return nullptr;
}
@ -1066,21 +1151,32 @@ SIUnitEdit *TraceMarker::getSettingsEditor()
case Type::Maximum:
case Type::Minimum:
case Type::Delta:
ret = new SIUnitEdit("Hz", " kMG", 6);
ret->setValue(position);
break;
case Type::PhaseNoise:
default:
return new SIUnitEdit("Hz", " kMG", 6);
ret = new SIUnitEdit("Hz", " kMG", 6);
ret->setValue(offset);
break;
case Type::Lowpass:
case Type::Highpass:
case Type::PeakTable:
case Type::Bandpass: // initialize with "dB"
return new SIUnitEdit("db", " ", 3);
ret = new SIUnitEdit("db", " ", 3);
ret->setValue(cutoffAmplitude);
break;
case Type::PeakTable:
ret = new SIUnitEdit("db", " ", 3);
ret->setValue(peakThreshold);
break;
case Type::TOI:
case Type::Last:
return nullptr;
}
}
return ret;
}
void TraceMarker::adjustSettings(double value)
void Marker::adjustSettings(double value)
{
if(isTimeDomain()) {
switch(type) {
@ -1127,7 +1223,7 @@ void TraceMarker::adjustSettings(double value)
update();
}
QMenu *TraceMarker::getContextMenu() {
QMenu *Marker::getContextMenu() {
if(parent) {
return parent->getContextMenu();
} else {
@ -1135,7 +1231,7 @@ QMenu *TraceMarker::getContextMenu() {
}
}
void TraceMarker::update()
void Marker::update()
{
if(!parentTrace->size()) {
// empty trace, nothing to do
@ -1157,7 +1253,7 @@ void TraceMarker::update()
auto peaks = parentTrace->findPeakFrequencies(100, peakThreshold);
char suffix = 'a';
for(auto p : peaks) {
auto helper = new TraceMarker(model, number, this);
auto helper = new Marker(model, number, this);
helper->suffix = suffix;
helper->assignTrace(parentTrace);
helper->setPosition(p);
@ -1271,22 +1367,22 @@ void TraceMarker::update()
emit dataChanged(this);
}
Trace *TraceMarker::getTrace() const
Trace *Marker::getTrace() const
{
return parentTrace;
}
int TraceMarker::getNumber() const
int Marker::getNumber() const
{
return number;
}
std::complex<double> TraceMarker::getData() const
std::complex<double> Marker::getData() const
{
return data;
}
bool TraceMarker::isMovable()
bool Marker::isMovable()
{
if(parent) {
// helper traces are never movable by the user
@ -1301,17 +1397,17 @@ bool TraceMarker::isMovable()
}
}
QPixmap &TraceMarker::getSymbol()
QPixmap &Marker::getSymbol()
{
return symbol;
}
double TraceMarker::getPosition() const
double Marker::getPosition() const
{
return position;
}
bool TraceMarker::isTimeDomain()
bool Marker::isTimeDomain()
{
if(parentTrace) {
if(parentTrace->outputType() == Trace::DataType::Time) {

View file

@ -3,20 +3,21 @@
#include <QPixmap>
#include <QObject>
#include "trace.h"
#include "../trace.h"
#include <QMenu>
#include <QComboBox>
#include "CustomWidgets/siunitedit.h"
#include "savable.h"
class TraceMarkerModel;
class MarkerModel;
class MarkerGroup;
class TraceMarker : public QObject, public Savable
class Marker : public QObject, public Savable
{
Q_OBJECT;
public:
TraceMarker(TraceMarkerModel *model, int number = 1, TraceMarker *parent = nullptr, QString descr = QString());
~TraceMarker();
Marker(MarkerModel *model, int number = 1, Marker *parent = nullptr, QString descr = QString());
~Marker();
void assignTrace(Trace *t);
Trace* trace();
@ -25,6 +26,7 @@ public:
dBAngle,
RealImag,
Impedance,
VSWR,
// Noise marker parameters
Noise,
PhaseNoise,
@ -88,10 +90,10 @@ public:
// Updates marker position and data on automatic markers. Should be called whenever the tracedata is complete
void update();
TraceMarker *getParent() const;
const std::vector<TraceMarker *>& getHelperMarkers() const;
TraceMarker *helperMarker(unsigned int i);
void assignDeltaMarker(TraceMarker *m);
Marker *getParent() const;
const std::vector<Marker *>& getHelperMarkers() const;
Marker *helperMarker(unsigned int i);
void assignDeltaMarker(Marker *m);
QString getSuffix() const;
virtual nlohmann::json toJSON() override;
@ -106,18 +108,23 @@ public:
std::set<Format> getGraphDisplayFormats() const;
MarkerGroup *getGroup() const;
void setGroup(MarkerGroup *value);
public slots:
void setPosition(double freq);
void updateContextmenu();
signals:
void deleted(TraceMarker *m);
void dataChanged(TraceMarker *m);
void symbolChanged(TraceMarker *m);
void typeChanged(TraceMarker *m);
void assignedDeltaChanged(TraceMarker *m);
void traceChanged(TraceMarker *m);
void beginRemoveHelperMarkers(TraceMarker *m);
void endRemoveHelperMarkers(TraceMarker *m);
void dataFormatChanged(TraceMarker *m);
void positionChanged(double pos);
void deleted(Marker *m);
void dataChanged(Marker *m);
void symbolChanged(Marker *m);
void typeChanged(Marker *m);
void assignedDeltaChanged(Marker *m);
void traceChanged(Marker *m);
void beginRemoveHelperMarkers(Marker *m);
void endRemoveHelperMarkers(Marker *m);
void dataFormatChanged(Marker *m);
private slots:
void parentTraceDeleted(Trace *t);
@ -125,10 +132,10 @@ private slots:
void updateSymbol();
void checkDeltaMarker();
void deltaDeleted();
void updateContextmenu();
void traceTypeChanged();
signals:
void rawDataChanged();
void domainChanged();
void domainChanged(Marker *m);
private:
std::set<Type> getSupportedTypes();
static QString typeToString(Type t) {
@ -148,7 +155,7 @@ private:
}
void constrainPosition();
void constrainFormat();
TraceMarker *bestDeltaCandidate();
Marker *bestDeltaCandidate();
void deleteHelperMarkers();
void setType(Type t);
double toDecibel();
@ -156,7 +163,7 @@ private:
void setTableFormat(Format f);
TraceMarkerModel *model;
MarkerModel *model;
Trace *parentTrace;
double position;
int number;
@ -170,9 +177,9 @@ private:
QMenu contextmenu;
TraceMarker *delta;
std::vector<TraceMarker*> helperMarkers;
TraceMarker *parent;
Marker *delta;
std::vector<Marker*> helperMarkers;
Marker *parent;
// settings for the different marker types
double cutoffAmplitude;
double peakThreshold;
@ -180,6 +187,8 @@ private:
Format formatTable;
std::set<Format> formatGraph;
MarkerGroup *group;
};
#endif // TRACEMARKER_H

View file

@ -0,0 +1,106 @@
#include "markergroup.h"
MarkerGroup::~MarkerGroup()
{
while(markers.size()) {
remove(*markers.begin());
}
}
bool MarkerGroup::add(Marker *m)
{
if(!applicable(m)) {
// can't add to group
return false;
}
if(m->getGroup()) {
// marker already in other group remove from it
m->getGroup()->remove(m);
}
connect(m, &Marker::positionChanged, this, &MarkerGroup::markerMoved);
connect(m, &Marker::typeChanged, this, &MarkerGroup::checkMarker);
connect(m, &Marker::domainChanged, this, &MarkerGroup::checkMarker);
connect(m, &Marker::deleted, [=](){
remove(m);
});
if(markers.size() > 0) {
m->setPosition((*markers.begin())->getPosition());
}
m->setGroup(this);
markers.insert(m);
return true;
}
bool MarkerGroup::remove(Marker *m)
{
if(markers.count(m)) {
// todo break connections, notify marker
disconnect(m, &Marker::positionChanged, this, &MarkerGroup::markerMoved);
disconnect(m, &Marker::typeChanged, this, &MarkerGroup::checkMarker);
disconnect(m, &Marker::domainChanged, this, &MarkerGroup::checkMarker);
m->setGroup(nullptr);
markers.erase(m);
if(markers.size() == 0) {
// all markers removed
emit emptied(this);
}
return true;
} else {
// not in group
return false;
}
}
bool MarkerGroup::applicable(Marker *m)
{
if(!m->isMovable()) {
// can't add automatic markers to group
return false;
}
if(markers.size() == 0) {
// first marker in group
isTimeDomain = m->isTimeDomain();
} else {
// check domain
if(isTimeDomain != m->isTimeDomain()) {
// only markers of the same domain are allowed in a group
return false;
}
}
return true;
}
void MarkerGroup::markerMoved(double newpos)
{
// moving the other markers will trigger additional calls to this slot.
// Set and check guard variable
if(adjustingMarkers) {
return;
}
adjustingMarkers = true;
for(auto m : markers) {
m->setPosition(newpos);
}
adjustingMarkers = false;
}
void MarkerGroup::checkMarker(Marker *m)
{
if(!applicable(m)) {
remove(m);
}
}
unsigned int MarkerGroup::getNumber() const
{
return number;
}

View file

@ -0,0 +1,39 @@
#ifndef MARKERGROUP_H
#define MARKERGROUP_H
#include <QObject>
#include "marker.h"
class MarkerGroup : public QObject
{
Q_OBJECT
public:
MarkerGroup(unsigned int number)
: adjustingMarkers(false),
isTimeDomain(false),
markers(),
number(number){};
~MarkerGroup();
bool add(Marker *m);
bool remove(Marker *m);
unsigned int getNumber() const;
bool applicable(Marker *m);
signals:
void emptied(MarkerGroup*);
private:
void markerMoved(double newpos);
// Check if marker still applicable for group, remove if necessary
void checkMarker(Marker *m);
bool adjustingMarkers;
bool isTimeDomain;
std::set<Marker*> markers;
unsigned int number;
};
#endif // MARKERGROUP_H

View file

@ -1,29 +1,30 @@
#include "tracemarkermodel.h"
#include "markermodel.h"
#include "unit.h"
#include <QComboBox>
#include <QApplication>
#include "CustomWidgets/siunitedit.h"
#include <QDebug>
#include "markergroup.h"
using namespace std;
static constexpr int rowHeight = 21;
TraceMarkerModel::TraceMarkerModel(TraceModel &model, QObject *parent)
MarkerModel::MarkerModel(TraceModel &model, QObject *parent)
: QAbstractItemModel(parent),
model(model)
{
model.setMarkerModel(this);
markers.clear();
root = new TraceMarker(this);
root = new Marker(this);
}
TraceMarkerModel::~TraceMarkerModel()
MarkerModel::~MarkerModel()
{
delete root;
}
QModelIndex TraceMarkerModel::index(int row, int column, const QModelIndex &parent) const
QModelIndex MarkerModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent)) {
return QModelIndex();
@ -38,7 +39,7 @@ QModelIndex TraceMarkerModel::index(int row, int column, const QModelIndex &pare
return createIndex(row, column, root);
}
QModelIndex TraceMarkerModel::parent(const QModelIndex &index) const
QModelIndex MarkerModel::parent(const QModelIndex &index) const
{
if (!index.isValid()) {
return QModelIndex();
@ -57,7 +58,7 @@ QModelIndex TraceMarkerModel::parent(const QModelIndex &index) const
}
}
TraceMarker *TraceMarkerModel::createDefaultMarker()
Marker *MarkerModel::createDefaultMarker()
{
// find lowest free number
int number = 0;
@ -72,34 +73,34 @@ TraceMarker *TraceMarkerModel::createDefaultMarker()
}
}
} while (used);
auto marker = new TraceMarker(this, number);
auto marker = new Marker(this, number);
marker->setPosition(2150000000);
marker->assignTrace(model.trace(0));
return marker;
}
void TraceMarkerModel::addMarker(TraceMarker *t)
void MarkerModel::addMarker(Marker *t)
{
beginInsertRows(QModelIndex(), markers.size(), markers.size());
markers.push_back(t);
endInsertRows();
connect(t, &TraceMarker::dataChanged, this, &TraceMarkerModel::markerDataChanged);
connect(t, &TraceMarker::typeChanged, this, &TraceMarkerModel::markerDataChanged);
connect(t, &TraceMarker::traceChanged, this, &TraceMarkerModel::markerDataChanged);
connect(t, &TraceMarker::beginRemoveHelperMarkers, [=](TraceMarker *m) {
connect(t, &Marker::dataChanged, this, &MarkerModel::markerDataChanged);
connect(t, &Marker::typeChanged, this, &MarkerModel::markerDataChanged);
connect(t, &Marker::traceChanged, this, &MarkerModel::markerDataChanged);
connect(t, &Marker::beginRemoveHelperMarkers, [=](Marker *m) {
auto row = find(markers.begin(), markers.end(), m) - markers.begin();
auto modelIndex = createIndex(row, 0, root);
beginRemoveRows(modelIndex, 0, m->getHelperMarkers().size() - 1);
});
connect(t, &TraceMarker::endRemoveHelperMarkers, [=](TraceMarker *m) {
connect(t, &Marker::endRemoveHelperMarkers, [=](Marker *m) {
endRemoveRows();
markerDataChanged(m);
});
connect(t, &TraceMarker::deleted, this, qOverload<TraceMarker*>(&TraceMarkerModel::removeMarker));
connect(t, &Marker::deleted, this, qOverload<Marker*>(&MarkerModel::removeMarker));
emit markerAdded(t);
}
void TraceMarkerModel::removeMarker(unsigned int index)
void MarkerModel::removeMarker(unsigned int index)
{
if (index < markers.size()) {
beginRemoveRows(QModelIndex(), index, index);
@ -108,7 +109,7 @@ void TraceMarkerModel::removeMarker(unsigned int index)
}
}
void TraceMarkerModel::removeMarker(TraceMarker *m)
void MarkerModel::removeMarker(Marker *m)
{
auto it = std::find(markers.begin(), markers.end(), m);
if(it != markers.end()) {
@ -116,7 +117,7 @@ void TraceMarkerModel::removeMarker(TraceMarker *m)
}
}
void TraceMarkerModel::markerDataChanged(TraceMarker *m)
void MarkerModel::markerDataChanged(Marker *m)
{
auto row = find(markers.begin(), markers.end(), m) - markers.begin();
if(m->editingFrequency) {
@ -132,12 +133,76 @@ void TraceMarkerModel::markerDataChanged(TraceMarker *m)
}
}
TraceMarker *TraceMarkerModel::marker(int index)
void MarkerModel::groupEmptied(MarkerGroup *g)
{
groups.erase(g);
delete g;
// notify markers of deleted group
for(auto m : markers) {
m->updateContextmenu();
}
}
std::set<MarkerGroup *> MarkerModel::getGroups() const
{
return groups;
}
MarkerGroup *MarkerModel::createMarkerGroup()
{
// find lowest available number
unsigned int number = 0;
bool used;
do {
number++;
used = false;
for(auto g : groups) {
if(g->getNumber() == number) {
used = true;
break;
}
}
} while (used);
auto group = createMarkerGroup(number);
return group;
}
MarkerGroup *MarkerModel::createMarkerGroup(unsigned int number)
{
auto group = new MarkerGroup(number);
groups.insert(group);
connect(group, &MarkerGroup::emptied, this, &MarkerModel::groupEmptied);
// notify markers of additional group
for(auto m : markers) {
m->updateContextmenu();
}
return group;
}
void MarkerModel::addToGroupCreateIfNotExisting(Marker *m, unsigned int number)
{
MarkerGroup *group = nullptr;
// find group
for(auto g : groups) {
if(g->getNumber() == number) {
group = g;
break;
}
}
if(!group) {
// group does not exist yet
group = createMarkerGroup(number);
}
group->add(m);
}
Marker *MarkerModel::marker(int index)
{
return markers.at(index);
}
int TraceMarkerModel::rowCount(const QModelIndex &index) const
int MarkerModel::rowCount(const QModelIndex &index) const
{
if(!index.isValid()) {
return markers.size();
@ -146,18 +211,23 @@ int TraceMarkerModel::rowCount(const QModelIndex &index) const
return marker->getHelperMarkers().size();
}
int TraceMarkerModel::columnCount(const QModelIndex &) const
int MarkerModel::columnCount(const QModelIndex &) const
{
return ColIndexLast;
}
QVariant TraceMarkerModel::data(const QModelIndex &index, int role) const
QVariant MarkerModel::data(const QModelIndex &index, int role) const
{
auto marker = markerFromIndex(index);
if(role == Qt::DisplayRole) {
switch(index.column()) {
case ColIndexNumber:
return QString::number(marker->getNumber()) + marker->getSuffix();
case ColIndexGroup:
if(marker->getGroup()) {
return QString::number(marker->getGroup()->getNumber());
}
break;
case ColIndexTrace:
if(marker->getTrace()) {
return marker->getTrace()->name();
@ -174,23 +244,41 @@ QVariant TraceMarkerModel::data(const QModelIndex &index, int role) const
return QVariant();
}
QVariant TraceMarkerModel::headerData(int section, Qt::Orientation orientation, int role) const
QVariant MarkerModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch(section) {
case ColIndexNumber: return "#"; break;
case ColIndexTrace: return "Trace"; break;
case ColIndexType: return "Type"; break;
case ColIndexSettings: return "Settings"; break;
case ColIndexData: return "Data"; break;
default: return QVariant(); break;
if(orientation == Qt::Horizontal) {
switch(role) {
case Qt::DecorationRole:
switch(section) {
case ColIndexGroup: return QIcon(":/icons/chainlink.png");
}
break;
case Qt::DisplayRole:
switch(section) {
case ColIndexNumber: return "#";
case ColIndexTrace: return "Trace";
case ColIndexType: return "Type";
case ColIndexSettings: return "Settings";
case ColIndexData: return "Data";
}
break;
case Qt::ToolTipRole:
case Qt::WhatsThisRole:
switch(section) {
case ColIndexNumber: return "Marker number, used to identify markers on the graphs";
case ColIndexGroup: return "Number of group this marker is linked to. Linked markers move together.";
case ColIndexTrace: return "The trace from which the marker gets its data";
case ColIndexType: return "Markertype, depending on the type, the marker can be positioned by the user or will be set automatically";
case ColIndexSettings: return "Configurable marker parameter, depends on the marker type";
case ColIndexData: return "Tracedata at the marker position";
}
break;
}
} else {
return QVariant();
}
return QVariant();
}
bool TraceMarkerModel::setData(const QModelIndex &index, const QVariant &value, int)
bool MarkerModel::setData(const QModelIndex &index, const QVariant &value, int)
{
if((unsigned int) index.row() >= markers.size()) {
return false;
@ -215,11 +303,12 @@ bool TraceMarkerModel::setData(const QModelIndex &index, const QVariant &value,
return false;
}
Qt::ItemFlags TraceMarkerModel::flags(const QModelIndex &index) const
Qt::ItemFlags MarkerModel::flags(const QModelIndex &index) const
{
int flags = Qt::ItemIsSelectable;
switch(index.column()) {
case ColIndexNumber: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
case ColIndexGroup: flags |= Qt::ItemIsEnabled; break;
case ColIndexTrace: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
case ColIndexType: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
case ColIndexSettings: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
@ -233,14 +322,14 @@ Qt::ItemFlags TraceMarkerModel::flags(const QModelIndex &index) const
return (Qt::ItemFlags) flags;
}
std::vector<TraceMarker *> TraceMarkerModel::getMarkers()
std::vector<Marker *> MarkerModel::getMarkers()
{
return markers;
}
std::vector<TraceMarker *> TraceMarkerModel::getMarkers(Trace *t)
std::vector<Marker *> MarkerModel::getMarkers(Trace *t)
{
std::vector<TraceMarker*> attachedMarkers;
std::vector<Marker*> attachedMarkers;
for(auto m : markers) {
if(m->getTrace() == t) {
attachedMarkers.push_back(m);
@ -249,21 +338,21 @@ std::vector<TraceMarker *> TraceMarkerModel::getMarkers(Trace *t)
return attachedMarkers;
}
TraceModel &TraceMarkerModel::getModel()
TraceModel &MarkerModel::getModel()
{
return model;
}
void TraceMarkerModel::updateMarkers()
void MarkerModel::updateMarkers()
{
for(auto m : markers) {
m->update();
}
}
TraceMarker *TraceMarkerModel::markerFromIndex(const QModelIndex &index) const
Marker *MarkerModel::markerFromIndex(const QModelIndex &index) const
{
auto m = static_cast<TraceMarker*>(index.internalPointer());
auto m = static_cast<Marker*>(index.internalPointer());
if(m == root) {
return markers[index.row()];
} else {
@ -271,7 +360,7 @@ TraceMarker *TraceMarkerModel::markerFromIndex(const QModelIndex &index) const
}
}
nlohmann::json TraceMarkerModel::toJSON()
nlohmann::json MarkerModel::toJSON()
{
nlohmann::json j;
for(auto m : markers) {
@ -280,14 +369,14 @@ nlohmann::json TraceMarkerModel::toJSON()
return j;
}
void TraceMarkerModel::fromJSON(nlohmann::json j)
void MarkerModel::fromJSON(nlohmann::json j)
{
// remove old markers
while(markers.size() > 0) {
removeMarker((unsigned int) 0);
}
for(auto jm : j) {
auto m = new TraceMarker(this);
auto m = new Marker(this);
try {
m->fromJSON(jm);
addMarker(m);
@ -298,7 +387,7 @@ void TraceMarkerModel::fromJSON(nlohmann::json j)
}
// second pass to assign delta markers
for(unsigned int i=0;i<markers.size();i++) {
if(markers[i]->getType() == TraceMarker::Type::Delta) {
if(markers[i]->getType() == Marker::Type::Delta) {
if(!j[i].contains("delta_marker")) {
qWarning() << "JSON data does not contain assigned delta marker";
continue;
@ -329,7 +418,7 @@ QSize MarkerTraceDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIn
QWidget *MarkerTraceDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
{
auto model = (TraceMarkerModel*) index.model();
auto model = (MarkerModel*) index.model();
auto c = new QComboBox(parent);
c->setMaximumHeight(rowHeight);
connect(c, qOverload<int>(&QComboBox::currentIndexChanged), [c](int) {
@ -346,7 +435,7 @@ QWidget *MarkerTraceDelegate::createEditor(QWidget *parent, const QStyleOptionVi
void MarkerTraceDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
auto marker = static_cast<const TraceMarkerModel*>(index.model())->markerFromIndex(index);
auto marker = static_cast<const MarkerModel*>(index.model())->markerFromIndex(index);
auto c = (QComboBox*) editor;
MarkerWidgetTraceInfo markerInfo;
markerInfo.trace = marker->trace();
@ -361,7 +450,7 @@ void MarkerTraceDelegate::setEditorData(QWidget *editor, const QModelIndex &inde
void MarkerTraceDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
auto markerModel = (TraceMarkerModel*) model;
auto markerModel = (MarkerModel*) model;
auto c = (QComboBox*) editor;
markerModel->setData(index, c->itemData(c->currentIndex()));
}
@ -373,7 +462,7 @@ QSize MarkerSettingsDelegate::sizeHint(const QStyleOptionViewItem &, const QMode
QWidget *MarkerSettingsDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
{
auto marker = static_cast<const TraceMarkerModel*>(index.model())->markerFromIndex(index);
auto marker = static_cast<const MarkerModel*>(index.model())->markerFromIndex(index);
marker->editingFrequency = true;
auto e = marker->getSettingsEditor();
if(e) {
@ -389,7 +478,7 @@ QWidget *MarkerSettingsDelegate::createEditor(QWidget *parent, const QStyleOptio
void MarkerSettingsDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
auto markerModel = (TraceMarkerModel*) model;
auto markerModel = (MarkerModel*) model;
auto si = (SIUnitEdit*) editor;
markerModel->setData(index, si->value());
}
@ -401,7 +490,7 @@ QSize MarkerTypeDelegate::sizeHint(const QStyleOptionViewItem &, const QModelInd
QWidget *MarkerTypeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
{
auto marker = static_cast<const TraceMarkerModel*>(index.model())->markerFromIndex(index);
auto marker = static_cast<const MarkerModel*>(index.model())->markerFromIndex(index);
auto editor = marker->getTypeEditor(const_cast<MarkerTypeDelegate*>(this));
editor->setMaximumHeight(rowHeight);
editor->setParent(parent);
@ -410,6 +499,6 @@ QWidget *MarkerTypeDelegate::createEditor(QWidget *parent, const QStyleOptionVie
void MarkerTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *, const QModelIndex &index) const
{
auto marker = static_cast<const TraceMarkerModel*>(index.model())->markerFromIndex(index);
auto marker = static_cast<const MarkerModel*>(index.model())->markerFromIndex(index);
marker->updateTypeFromEditor(editor);
}

View file

@ -2,9 +2,9 @@
#define TRACEMARKERMODEL_H
#include <QAbstractTableModel>
#include "tracemarker.h"
#include "marker.h"
#include <vector>
#include "tracemodel.h"
#include "../tracemodel.h"
#include <QStyledItemDelegate>
#include "savable.h"
@ -44,19 +44,20 @@ class MarkerSettingsDelegate : public QStyledItemDelegate
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override;
};
class TraceMarkerModel : public QAbstractItemModel, public Savable
class MarkerModel : public QAbstractItemModel, public Savable
{
Q_OBJECT
public:
TraceMarkerModel(TraceModel &model, QObject *parent = 0);
~TraceMarkerModel();
MarkerModel(TraceModel &model, QObject *parent = 0);
~MarkerModel();
enum {
ColIndexNumber = 0,
ColIndexTrace = 1,
ColIndexType = 2,
ColIndexSettings = 3,
ColIndexData = 4,
ColIndexNumber,
ColIndexGroup,
ColIndexTrace,
ColIndexType,
ColIndexSettings,
ColIndexData,
ColIndexLast,
};
@ -69,33 +70,41 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
TraceMarker* createDefaultMarker();
TraceMarker *marker(int index);
std::vector<TraceMarker*> getMarkers();
std::vector<TraceMarker*> getMarkers(Trace *t);
Marker* createDefaultMarker();
Marker *marker(int index);
std::vector<Marker*> getMarkers();
std::vector<Marker*> getMarkers(Trace *t);
TraceModel& getModel();
void updateMarkers();
TraceMarker *markerFromIndex(const QModelIndex &index) const;
Marker *markerFromIndex(const QModelIndex &index) const;
MarkerGroup *createMarkerGroup();
void addToGroupCreateIfNotExisting(Marker *m, unsigned int number);
virtual nlohmann::json toJSON() override;
virtual void fromJSON(nlohmann::json j) override;
std::set<MarkerGroup *> getGroups() const;
public slots:
void addMarker(TraceMarker *t);
void addMarker(Marker *t);
void removeMarker(unsigned int index);
void removeMarker(TraceMarker *m);
void removeMarker(Marker *m);
signals:
void markerAdded(TraceMarker *t);
void markerAdded(Marker *t);
void setupLoadComplete();
private slots:
void markerDataChanged(TraceMarker *m);
void markerDataChanged(Marker *m);
void groupEmptied(MarkerGroup *g);
private:
std::vector<TraceMarker*> markers;
MarkerGroup* createMarkerGroup(unsigned int number);
std::vector<Marker*> markers;
std::set<MarkerGroup*> groups;
TraceModel &model;
TraceMarker *root;
Marker *root;
};
#endif // TRACEMARKERMODEL_H

View file

@ -0,0 +1,153 @@
#include "markerwidget.h"
#include "ui_markerwidget.h"
#include <QKeyEvent>
#include <QMenu>
#include "markergroup.h"
MarkerWidget::MarkerWidget(MarkerModel &model, QWidget *parent) :
QWidget(parent),
ui(new Ui::MarkerWidget),
model(model)
{
ui->setupUi(this);
ui->treeView->setModel(&model);
ui->treeView->setItemDelegateForColumn(MarkerModel::ColIndexTrace, new MarkerTraceDelegate);
ui->treeView->setItemDelegateForColumn(MarkerModel::ColIndexType, new MarkerTypeDelegate);
ui->treeView->setItemDelegateForColumn(MarkerModel::ColIndexSettings, new MarkerSettingsDelegate);
ui->treeView->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection);
ui->treeView->installEventFilter(this);
ui->treeView->setColumnWidth(MarkerModel::ColIndexNumber, 60);
ui->treeView->setColumnWidth(MarkerModel::ColIndexGroup, 20);
ui->treeView->setColumnWidth(MarkerModel::ColIndexTrace, 60);
ui->treeView->setColumnWidth(MarkerModel::ColIndexType, 120);
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->treeView, &QTreeView::customContextMenuRequested, [&](const QPoint &p){
if(ui->treeView->selectionModel()->selectedRows().size() <= 1) {
// only one marker selected, execute its context menu
auto index = ui->treeView->indexAt(p);
if(index.isValid()) {
auto marker = model.markerFromIndex(index);
auto menu = marker->getContextMenu();
menu->exec(mapToGlobal(p));
}
} else {
std::vector<Marker*> selected;
bool anyInGroup = false;
for(auto index : ui->treeView->selectionModel()->selectedRows()) {
auto marker = model.markerFromIndex(index);
selected.push_back(marker);
if(marker->getGroup()) {
anyInGroup = true;
}
}
// multiple markers selected, execute group context menu
QMenu menu;
auto createGroup = new QAction("Link selected");
connect(createGroup, &QAction::triggered, [&](){
auto g = model.createMarkerGroup();
// assign markers to group
for(auto m : selected) {
g->add(m);
}
});
menu.addAction(createGroup);
if(anyInGroup) {
auto removeGroup = new QAction("Break Links");
connect(removeGroup, &QAction::triggered, [&](){
// remove selected markers from groups if they are already assigned to one
for(auto m : selected) {
if(m->getGroup()) {
m->getGroup()->remove(m);
}
}
});
menu.addAction(removeGroup);
}
menu.exec(mapToGlobal(p));
}
});
connect(&model.getModel(), &TraceModel::traceAdded, this, &MarkerWidget::updatePersistentEditors);
connect(&model.getModel(), &TraceModel::traceRemoved, this, &MarkerWidget::updatePersistentEditors);
connect(&model.getModel(), &TraceModel::traceNameChanged, this, &MarkerWidget::updatePersistentEditors);
connect(&model, &MarkerModel::markerAdded, [=](Marker *m) {
connect(m, &Marker::typeChanged, this, &MarkerWidget::updatePersistentEditors);
connect(m, &Marker::traceChanged, this, &MarkerWidget::updatePersistentEditors);
connect(m, &Marker::assignedDeltaChanged, this, &MarkerWidget::updatePersistentEditors);
updatePersistentEditors();
});
connect(&model, &MarkerModel::setupLoadComplete, this, &MarkerWidget::updatePersistentEditors);
}
MarkerWidget::~MarkerWidget()
{
delete ui->treeView->itemDelegateForColumn(MarkerModel::ColIndexTrace);
delete ui->treeView->itemDelegateForColumn(MarkerModel::ColIndexType);
delete ui->treeView->itemDelegateForColumn(MarkerModel::ColIndexSettings);
delete ui;
}
void MarkerWidget::on_bDelete_clicked()
{
if (model.rowCount() <= 0) {
return; // there is nothing to delete (empty model)
}
std::vector<Marker*> toDelete;
for(auto ind : ui->treeView->selectionModel()->selectedRows()) {
if ( ! ind.isValid() ) {
continue; // if no marker clicked/selected in treeView, the index is not valid
}
auto marker = model.markerFromIndex(ind);
if(!marker || marker->getParent()) {
// can't delete child markers directly
continue;
}
toDelete.push_back(marker);
}
for(auto m : toDelete) {
delete m;
}
}
void MarkerWidget::on_bAdd_clicked()
{
auto marker = model.createDefaultMarker();
model.addMarker(marker);
}
bool MarkerWidget::eventFilter(QObject *, QEvent *event)
{
if (event->type() == QEvent::KeyPress) {
int key = static_cast<QKeyEvent *>(event)->key();
if(key == Qt::Key_Escape) {
// deselect all
ui->treeView->selectionModel()->clearSelection();
return true;
}
if(key == Qt::Key_Delete) {
// delete selected
on_bDelete_clicked();
return true;
}
}
return false;
}
void MarkerWidget::updatePersistentEditors()
{
for(int i=0;i<model.rowCount();i++) {
auto columns = {MarkerModel::ColIndexTrace, MarkerModel::ColIndexType};
for(auto c : columns) {
auto index = model.index(i, c);
ui->treeView->closePersistentEditor(index);
ui->treeView->openPersistentEditor(index);
}
}
}

View file

@ -2,7 +2,7 @@
#define MARKERWIDGET_H
#include <QWidget>
#include "tracemarkermodel.h"
#include "markermodel.h"
namespace Ui {
class MarkerWidget;
@ -13,7 +13,7 @@ class MarkerWidget : public QWidget
Q_OBJECT
public:
explicit MarkerWidget(TraceMarkerModel &model, QWidget *parent = nullptr);
explicit MarkerWidget(MarkerModel &model, QWidget *parent = nullptr);
~MarkerWidget();
private slots:
@ -22,8 +22,9 @@ private slots:
void updatePersistentEditors();
private:
bool eventFilter(QObject *obj, QEvent *event) override;
Ui::MarkerWidget *ui;
TraceMarkerModel &model;
MarkerModel &model;
};
#endif // MARKERWIDGET_H

View file

@ -16,6 +16,9 @@
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTreeView" name="treeView">
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
<property name="itemsExpandable">
<bool>true</bool>
</property>
@ -25,6 +28,9 @@
<property name="expandsOnDoubleClick">
<bool>true</bool>
</property>
<attribute name="headerMinimumSectionSize">
<number>0</number>
</attribute>
</widget>
</item>
<item>
@ -44,7 +50,7 @@
<string/>
</property>
<property name="icon">
<iconset theme="list-add" resource="../icons.qrc">
<iconset theme="list-add" resource="../../icons.qrc">
<normaloff>:/icons/add.png</normaloff>:/icons/add.png</iconset>
</property>
</widget>
@ -64,7 +70,7 @@
<string/>
</property>
<property name="icon">
<iconset theme="list-remove" resource="../icons.qrc">
<iconset theme="list-remove" resource="../../icons.qrc">
<normaloff>:/icons/remove.png</normaloff>:/icons/remove.png</iconset>
</property>
</widget>
@ -87,7 +93,7 @@
</layout>
</widget>
<resources>
<include location="../icons.qrc"/>
<include location="../../icons.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -1,74 +0,0 @@
#include "markerwidget.h"
#include "ui_markerwidget.h"
MarkerWidget::MarkerWidget(TraceMarkerModel &model, QWidget *parent) :
QWidget(parent),
ui(new Ui::MarkerWidget),
model(model)
{
ui->setupUi(this);
ui->treeView->setModel(&model);
ui->treeView->setItemDelegateForColumn(TraceMarkerModel::ColIndexTrace, new MarkerTraceDelegate);
ui->treeView->setItemDelegateForColumn(TraceMarkerModel::ColIndexType, new MarkerTypeDelegate);
ui->treeView->setItemDelegateForColumn(TraceMarkerModel::ColIndexSettings, new MarkerSettingsDelegate);
ui->treeView->setColumnWidth(TraceMarkerModel::ColIndexNumber, 60); // reduced width to fit widget when App is not maximized
ui->treeView->setColumnWidth(TraceMarkerModel::ColIndexTrace, 60); // reduced width to fit widget when App is not maximized
ui->treeView->setColumnWidth(TraceMarkerModel::ColIndexType, 120); // reduced width to fit widget when App is not maximized
connect(&model.getModel(), &TraceModel::traceAdded, this, &MarkerWidget::updatePersistentEditors);
connect(&model.getModel(), &TraceModel::traceRemoved, this, &MarkerWidget::updatePersistentEditors);
connect(&model.getModel(), &TraceModel::traceNameChanged, this, &MarkerWidget::updatePersistentEditors);
connect(&model, &TraceMarkerModel::markerAdded, [=](TraceMarker *m) {
connect(m, &TraceMarker::typeChanged, this, &MarkerWidget::updatePersistentEditors);
connect(m, &TraceMarker::traceChanged, this, &MarkerWidget::updatePersistentEditors);
connect(m, &TraceMarker::assignedDeltaChanged, this, &MarkerWidget::updatePersistentEditors);
updatePersistentEditors();
});
connect(&model, &TraceMarkerModel::setupLoadComplete, this, &MarkerWidget::updatePersistentEditors);
}
MarkerWidget::~MarkerWidget()
{
delete ui->treeView->itemDelegateForColumn(TraceMarkerModel::ColIndexTrace);
delete ui->treeView->itemDelegateForColumn(TraceMarkerModel::ColIndexType);
delete ui->treeView->itemDelegateForColumn(TraceMarkerModel::ColIndexSettings);
delete ui;
}
void MarkerWidget::on_bDelete_clicked()
{
if (model.rowCount() <= 0) {
return; // there is nothing to delete (empty model)
}
QModelIndex ind = ui->treeView->currentIndex();
if ( ! ind.isValid() ) {
return; // if no marker clicked/selected in treeView, the index is not valid
}
auto marker = model.markerFromIndex(ind);
if(!marker || marker->getParent()) {
// can't delete child markers directly
return;
}
delete marker;
}
void MarkerWidget::on_bAdd_clicked()
{
auto marker = model.createDefaultMarker();
model.addMarker(marker);
}
void MarkerWidget::updatePersistentEditors()
{
for(int i=0;i<model.rowCount();i++) {
auto columns = {TraceMarkerModel::ColIndexTrace, TraceMarkerModel::ColIndexType};
for(auto c : columns) {
auto index = model.index(i, c);
ui->treeView->closePersistentEditor(index);
ui->treeView->openPersistentEditor(index);
}
}
}

View file

@ -6,7 +6,7 @@
#include <QSettings>
#include <functional>
#include "unit.h"
#include "tracemarker.h"
#include "Marker/marker.h"
using namespace std;
@ -261,16 +261,16 @@ void Trace::setColor(QColor color) {
}
}
void Trace::addMarker(TraceMarker *m)
void Trace::addMarker(Marker *m)
{
markers.insert(m);
connect(m, &TraceMarker::dataFormatChanged, this, &Trace::markerFormatChanged);
connect(m, &Marker::dataFormatChanged, this, &Trace::markerFormatChanged);
emit markerAdded(m);
}
void Trace::removeMarker(TraceMarker *m)
void Trace::removeMarker(Marker *m)
{
disconnect(m, &TraceMarker::dataFormatChanged, this, &Trace::markerFormatChanged);
disconnect(m, &Marker::dataFormatChanged, this, &Trace::markerFormatChanged);
markers.erase(m);
emit markerRemoved(m);
}
@ -652,7 +652,7 @@ void Trace::setCalibration(bool value)
calibration = value;
}
std::set<TraceMarker *> Trace::getMarkers() const
std::set<Marker *> Trace::getMarkers() const
{
return markers;
}

View file

@ -11,7 +11,7 @@
#include "Device/device.h"
#include "Math/tracemath.h"
class TraceMarker;
class Marker;
class Trace : public TraceMath
{
@ -88,7 +88,7 @@ public:
/* Returns the noise in dbm/Hz for spectrum analyzer measurements. May return NaN if calculation not possible */
double getNoise(double frequency);
int index(double x);
std::set<TraceMarker *> getMarkers() const;
std::set<Marker *> getMarkers() const;
void setCalibration(bool value);
void setReflection(bool value);
@ -146,8 +146,8 @@ public:
public slots:
void setVisible(bool visible);
void setColor(QColor color);
void addMarker(TraceMarker *m);
void removeMarker(TraceMarker *m);
void addMarker(Marker *m);
void removeMarker(Marker *m);
signals:
void cleared(Trace *t);
@ -158,9 +158,9 @@ signals:
void nameChanged();
void pauseChanged();
void colorChanged(Trace *t);
void markerAdded(TraceMarker *m);
void markerRemoved(TraceMarker *m);
void markerFormatChanged(TraceMarker *m);
void markerAdded(Marker *m);
void markerRemoved(Marker *m);
void markerFormatChanged(Marker *m);
private:
QString _name;
@ -176,7 +176,7 @@ private:
bool timeDomain;
QString filename;
unsigned int fileParemeter;
std::set<TraceMarker*> markers;
std::set<Marker*> markers;
struct {
union {
Protocol::SweepSettings VNA;

View file

@ -243,12 +243,12 @@ void TraceModel::addSAData(const Protocol::SpectrumAnalyzerResult& d, const Prot
}
}
TraceMarkerModel *TraceModel::getMarkerModel() const
MarkerModel *TraceModel::getMarkerModel() const
{
return markerModel;
}
void TraceModel::setMarkerModel(TraceMarkerModel *value)
void TraceModel::setMarkerModel(MarkerModel *value)
{
markerModel = value;
}

View file

@ -7,7 +7,7 @@
#include "Device/device.h"
#include "savable.h"
class TraceMarkerModel;
class MarkerModel;
class TraceModel : public QAbstractTableModel, public Savable
{
@ -42,8 +42,8 @@ public:
virtual nlohmann::json toJSON() override;
virtual void fromJSON(nlohmann::json j) override;
TraceMarkerModel *getMarkerModel() const;
void setMarkerModel(TraceMarkerModel *value);
MarkerModel *getMarkerModel() const;
void setMarkerModel(MarkerModel *value);
signals:
void SpanChanged(double fmin, double fmax);
@ -59,7 +59,7 @@ public slots:
private:
std::vector<Trace*> traces;
TraceMarkerModel *markerModel;
MarkerModel *markerModel;
};
#endif // TRACEMODEL_H

View file

@ -1,11 +1,11 @@
#include "traceplot.h"
#include "tracemarker.h"
#include "Marker/marker.h"
#include "preferences.h"
#include <QPainter>
#include <QMimeData>
#include <QDebug>
#include "unit.h"
#include "tracemarkermodel.h"
#include "Marker/markermodel.h"
std::set<TracePlot*> TracePlot::plots;
@ -229,12 +229,12 @@ void TracePlot::leaveEvent(QEvent *event)
selectedMarker = nullptr;
}
TraceMarker *TracePlot::markerAtPosition(QPoint p, bool onlyMovable)
Marker *TracePlot::markerAtPosition(QPoint p, bool onlyMovable)
{
auto clickPoint = p - QPoint(marginLeft, marginTop);
// check if click was near a marker
unsigned int closestDistance = numeric_limits<unsigned int>::max();
TraceMarker *closestMarker = nullptr;
Marker *closestMarker = nullptr;
for(auto t : traces) {
if(!t.second) {
// this trace is disabled, skip
@ -378,16 +378,16 @@ void TracePlot::checkIfStillSupported(Trace *t)
}
}
void TracePlot::markerAdded(TraceMarker *m)
void TracePlot::markerAdded(Marker *m)
{
connect(m, &TraceMarker::dataChanged, this, &TracePlot::triggerReplot);
connect(m, &TraceMarker::symbolChanged, this, &TracePlot::triggerReplot);
connect(m, &Marker::dataChanged, this, &TracePlot::triggerReplot);
connect(m, &Marker::symbolChanged, this, &TracePlot::triggerReplot);
triggerReplot();
}
void TracePlot::markerRemoved(TraceMarker *m)
void TracePlot::markerRemoved(Marker *m)
{
disconnect(m, &TraceMarker::dataChanged, this, &TracePlot::triggerReplot);
disconnect(m, &TraceMarker::symbolChanged, this, &TracePlot::triggerReplot);
disconnect(m, &Marker::dataChanged, this, &TracePlot::triggerReplot);
disconnect(m, &Marker::symbolChanged, this, &TracePlot::triggerReplot);
triggerReplot();
}

View file

@ -50,14 +50,14 @@ protected:
bool markedForDeletion;
static std::set<TracePlot*> plots;
virtual QPoint markerToPixel(TraceMarker *m) = 0;
virtual QPoint markerToPixel(Marker *m) = 0;
virtual double nearestTracePoint(Trace *t, QPoint pixel, double *distance = nullptr) = 0;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void leaveEvent(QEvent *event) override;
TraceMarker *markerAtPosition(QPoint p, bool onlyMovable = false);
Marker *markerAtPosition(QPoint p, bool onlyMovable = false);
void createMarkerAtPosition(QPoint p);
@ -74,8 +74,8 @@ protected slots:
void traceDeleted(Trace *t);
void triggerReplot();
void checkIfStillSupported(Trace *t);
virtual void markerAdded(TraceMarker *m);
virtual void markerRemoved(TraceMarker *m);
virtual void markerAdded(Marker *m);
virtual void markerRemoved(Marker *m);
virtual bool xCoordinateVisible(double x) = 0;
protected:
static constexpr unsigned int marginTop = 20;
@ -87,7 +87,7 @@ protected:
double sweep_fmin, sweep_fmax;
TraceModel &model;
TraceMarker *selectedMarker;
Marker *selectedMarker;
bool dropPending;
QPoint dropPosition;

View file

@ -2,7 +2,7 @@
#include <QPainter>
#include <array>
#include <math.h>
#include "tracemarker.h"
#include "Marker/marker.h"
#include <QDebug>
#include "preferences.h"
#include "ui_smithchartdialog.h"
@ -82,7 +82,7 @@ std::complex<double> TraceSmithChart::pixelToData(QPoint p)
return complex<double>(data.x() / smithCoordMax, -data.y() / smithCoordMax);
}
QPoint TraceSmithChart::markerToPixel(TraceMarker *m)
QPoint TraceSmithChart::markerToPixel(Marker *m)
{
QPoint ret = QPoint();
// if(!m->isTimeDomain()) {

View file

@ -25,7 +25,7 @@ protected:
QPoint dataToPixel(Trace::Data d);
std::complex<double> pixelToData(QPoint p);
QPoint markerToPixel(TraceMarker *m) override;
QPoint markerToPixel(Marker *m) override;
double nearestTracePoint(Trace *t, QPoint pixel, double *distance = nullptr) override;
virtual bool xCoordinateVisible(double x);

View file

@ -3,7 +3,7 @@
#include "trace.h"
#include <cmath>
#include <QFrame>
#include "tracemarker.h"
#include "Marker/marker.h"
#include "xyplotaxisdialog.h"
#include <preferences.h>
#include <QPainter>
@ -913,7 +913,7 @@ QPointF TraceXYPlot::pixelToPlotValue(QPoint pixel, int Yaxis)
return p;
}
QPoint TraceXYPlot::markerToPixel(TraceMarker *m)
QPoint TraceXYPlot::markerToPixel(Marker *m)
{
auto t = m->getTrace();
QPointF plotPoint = traceToCoordinate(t, t->index(m->getPosition()), YAxis[0].type);

View file

@ -75,7 +75,7 @@ private:
QPointF traceToCoordinate(Trace *t, unsigned int sample, YAxisType type);
QPoint plotValueToPixel(QPointF plotValue, int Yaxis);
QPointF pixelToPlotValue(QPoint pixel, int YAxis);
QPoint markerToPixel(TraceMarker *m) override;
QPoint markerToPixel(Marker *m) override;
double nearestTracePoint(Trace *t, QPoint pixel, double *distance = nullptr) override;
virtual bool xCoordinateVisible(double x);
void traceDropped(Trace *t, QPoint position) override;

View file

@ -31,7 +31,7 @@
#include "CustomWidgets/tilewidget.h"
#include "CustomWidgets/siunitedit.h"
#include <QDockWidget>
#include "Traces/markerwidget.h"
#include "Traces/Marker/markerwidget.h"
#include "Tools/impedancematchdialog.h"
#include "Calibration/calibrationtracedialog.h"
#include "ui_main.h"
@ -416,7 +416,7 @@ VNA::VNA(AppWindow *window)
// toolbars.insert(tb_portExtension);
markerModel = new TraceMarkerModel(traceModel, this);
markerModel = new MarkerModel(traceModel, this);
auto tracesDock = new QDockWidget("Traces");
traceWidget = new TraceWidgetVNA(traceModel, cal, deembedding);

View file

@ -69,7 +69,7 @@ private:
unsigned int averages;
TraceModel traceModel;
TraceWidget *traceWidget;
TraceMarkerModel *markerModel;
MarkerModel *markerModel;
Averaging average;
// Calibration

View file

@ -30,7 +30,7 @@
#include "CustomWidgets/tilewidget.h"
#include "CustomWidgets/siunitedit.h"
#include <QDockWidget>
#include "Traces/markerwidget.h"
#include "Traces/Marker/markerwidget.h"
#include "Tools/impedancematchdialog.h"
#include "Calibration/calibrationtracedialog.h"
#include "ui_main.h"

View file

@ -11,7 +11,7 @@
#include "Calibration/calibration.h"
#include <QProgressDialog>
#include "Traces/tracemodel.h"
#include "Traces/tracemarkermodel.h"
#include "Traces/Marker/markermodel.h"
#include "averaging.h"
#include "Device/devicelog.h"
#include "preferences.h"

View file

@ -49,5 +49,6 @@
<file>icons/port2.svg</file>
<file>icons/down.png</file>
<file>icons/up.png</file>
<file>icons/chainlink.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB