From 33588611149acb3a4d91a17482a610d2029115ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Tue, 3 Nov 2020 00:37:06 +0100 Subject: [PATCH] Treeview for markers, added peak table function --- .../PC_Application/Traces/markerwidget.cpp | 33 ++-- .../PC_Application/Traces/markerwidget.ui | 24 +-- Software/PC_Application/Traces/trace.cpp | 5 +- .../PC_Application/Traces/tracemarker.cpp | 157 ++++++++++++++---- Software/PC_Application/Traces/tracemarker.h | 20 ++- .../Traces/tracemarkermodel.cpp | 154 ++++++++++++----- .../PC_Application/Traces/tracemarkermodel.h | 12 +- .../PC_Application/Traces/tracesmithchart.cpp | 3 + .../PC_Application/Traces/tracexyplot.cpp | 5 +- 9 files changed, 307 insertions(+), 106 deletions(-) diff --git a/Software/PC_Application/Traces/markerwidget.cpp b/Software/PC_Application/Traces/markerwidget.cpp index 2731b95..ce7cc7b 100644 --- a/Software/PC_Application/Traces/markerwidget.cpp +++ b/Software/PC_Application/Traces/markerwidget.cpp @@ -7,14 +7,14 @@ MarkerWidget::MarkerWidget(TraceMarkerModel &model, QWidget *parent) : model(model) { ui->setupUi(this); - ui->tableView->setModel(&model); - ui->tableView->setItemDelegateForColumn(TraceMarkerModel::ColIndexTrace, new MarkerTraceDelegate); - ui->tableView->setItemDelegateForColumn(TraceMarkerModel::ColIndexType, new MarkerTypeDelegate); - ui->tableView->setItemDelegateForColumn(TraceMarkerModel::ColIndexSettings, new MarkerSettingsDelegate); + 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->tableView->setColumnWidth(TraceMarkerModel::ColIndexNumber, 21); - ui->tableView->setColumnWidth(TraceMarkerModel::ColIndexTrace, 80); - ui->tableView->setColumnWidth(TraceMarkerModel::ColIndexType, 150); + ui->treeView->setColumnWidth(TraceMarkerModel::ColIndexNumber, 80); + ui->treeView->setColumnWidth(TraceMarkerModel::ColIndexTrace, 80); + ui->treeView->setColumnWidth(TraceMarkerModel::ColIndexType, 150); connect(&model.getModel(), &TraceModel::traceAdded, this, &MarkerWidget::updatePersistentEditors); connect(&model.getModel(), &TraceModel::traceRemoved, this, &MarkerWidget::updatePersistentEditors); @@ -23,15 +23,22 @@ MarkerWidget::MarkerWidget(TraceMarkerModel &model, QWidget *parent) : MarkerWidget::~MarkerWidget() { - delete ui->tableView->itemDelegateForColumn(TraceMarkerModel::ColIndexTrace); - delete ui->tableView->itemDelegateForColumn(TraceMarkerModel::ColIndexType); - delete ui->tableView->itemDelegateForColumn(TraceMarkerModel::ColIndexSettings); + 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() { - model.removeMarker(ui->tableView->currentIndex().row()); + auto marker = model.markerFromIndex(ui->treeView->currentIndex()); + if(!marker || marker->getParent()) { + // can't delete child markers directly + return; + } + model.removeMarker(marker); + marker->blockSignals(true); + delete marker; } void MarkerWidget::on_bAdd_clicked() @@ -48,8 +55,8 @@ void MarkerWidget::updatePersistentEditors() auto columns = {TraceMarkerModel::ColIndexTrace, TraceMarkerModel::ColIndexType}; for(auto c : columns) { auto index = model.index(i, c); - ui->tableView->closePersistentEditor(index); - ui->tableView->openPersistentEditor(index); + ui->treeView->closePersistentEditor(index); + ui->treeView->openPersistentEditor(index); } } } diff --git a/Software/PC_Application/Traces/markerwidget.ui b/Software/PC_Application/Traces/markerwidget.ui index 2850bfe..9874f09 100644 --- a/Software/PC_Application/Traces/markerwidget.ui +++ b/Software/PC_Application/Traces/markerwidget.ui @@ -15,22 +15,16 @@ - - - QAbstractItemView::SelectRows - - - 21 - - + + true - - - false - - - 21 - + + + true + + + true + diff --git a/Software/PC_Application/Traces/trace.cpp b/Software/PC_Application/Traces/trace.cpp index 9e3d4fc..1f8bd44 100644 --- a/Software/PC_Application/Traces/trace.cpp +++ b/Software/PC_Application/Traces/trace.cpp @@ -323,7 +323,7 @@ std::vector Trace::findPeakFrequencies(unsigned int maxPeaks, double min if(dbm <= min_dbm) { min_dbm = dbm; } - if((dbm <= max_dbm - minValley) && (max_dbm >= minLevel)) { + if((dbm <= max_dbm - minValley) && (max_dbm >= minLevel) && frequency) { // peak was high enough and dropped below minValley afterwards peakInfo peak; peak.frequency = frequency; @@ -331,7 +331,8 @@ std::vector Trace::findPeakFrequencies(unsigned int maxPeaks, double min peaks.push_back(peak); // reset frequency = 0.0; - max_dbm = min_dbm = dbm; + max_dbm = -200.0; + min_dbm = dbm; } } if(peaks.size() > maxPeaks) { diff --git a/Software/PC_Application/Traces/tracemarker.cpp b/Software/PC_Application/Traces/tracemarker.cpp index 1ef8656..1a35704 100644 --- a/Software/PC_Application/Traces/tracemarker.cpp +++ b/Software/PC_Application/Traces/tracemarker.cpp @@ -10,7 +10,7 @@ using namespace std; -TraceMarker::TraceMarker(TraceMarkerModel *model, int number) +TraceMarker::TraceMarker(TraceMarkerModel *model, int number, TraceMarker *parent, QString descr) : editingFrequeny(false), model(model), parentTrace(nullptr), @@ -18,7 +18,9 @@ TraceMarker::TraceMarker(TraceMarkerModel *model, int number) number(number), data(0), type(Type::Manual), + description(descr), delta(nullptr), + parent(parent), cutoffAmplitude(-3.0) { @@ -58,6 +60,7 @@ void TraceMarker::assignTrace(Trace *t) m->assignTrace(t); } update(); + emit traceChanged(this); } Trace *TraceMarker::trace() @@ -84,6 +87,9 @@ QString TraceMarker::readableData() auto phase = arg(valueDiff); return Unit::ToString(freqDiff, "Hz", " kMG") + " / " + QString::number(toDecibel(), 'g', 4) + "db@" + QString::number(phase*180/M_PI, 'g', 4); } + break; + case Type::PeakTable: + return "Found " + QString::number(helperMarkers.size()) + " peaks"; case Type::Lowpass: case Type::Highpass: if(parentTrace->isReflection()) { @@ -123,8 +129,8 @@ QString TraceMarker::readableData() } break; case Type::TOI: { - auto avgFundamental = (toDecibel() + helperMarkers[0]->toDecibel()) / 2; - auto avgDistortion = (helperMarkers[1]->toDecibel() + helperMarkers[2]->toDecibel()) / 2; + auto avgFundamental = (helperMarkers[0]->toDecibel() + helperMarkers[1]->toDecibel()) / 2; + auto avgDistortion = (helperMarkers[2]->toDecibel() + helperMarkers[3]->toDecibel()) / 2; auto TOI = (3 * avgFundamental - avgDistortion) / 2; return "Fundamental: " + Unit::ToString(avgFundamental, "dbm", " ", 3) + ", distortion: " + Unit::ToString(avgDistortion, "dbm", " ", 3) + ", TOI: "+Unit::ToString(TOI, "dbm", " ", 3); } @@ -145,6 +151,7 @@ QString TraceMarker::readableSettings() case Type::Lowpass: case Type::Highpass: case Type::Bandpass: + case Type::PeakTable: return Unit::ToString(cutoffAmplitude, "db", " ", 3); case Type::TOI: return "none"; @@ -153,6 +160,15 @@ QString TraceMarker::readableSettings() } } +QString TraceMarker::readableType() +{ + if(parent) { + return description; + } else { + return typeToString(type); + } +} + void TraceMarker::setFrequency(double freq) { frequency = freq; @@ -179,19 +195,23 @@ void TraceMarker::traceDataChanged() void TraceMarker::updateSymbol() { - constexpr int width = 15, height = 15; - symbol = QPixmap(width, height); - symbol.fill(Qt::transparent); - QPainter p(&symbol); - p.setRenderHint(QPainter::Antialiasing); - QPointF points[] = {QPointF(0,0),QPointF(width,0),QPointF(width/2,height)}; - auto traceColor = parentTrace->color(); - p.setPen(traceColor); - p.setBrush(traceColor); - p.drawConvexPolygon(points, 3); - auto brightness = traceColor.redF() * 0.299 + traceColor.greenF() * 0.587 + traceColor.blueF() * 0.114; - p.setPen((brightness > 0.6) ? Qt::black : Qt::white); - p.drawText(QRectF(0,0,width, height*2.0/3.0), Qt::AlignCenter, QString::number(number) + suffix); + if(isVisible()) { + constexpr int width = 15, height = 15; + symbol = QPixmap(width, height); + symbol.fill(Qt::transparent); + QPainter p(&symbol); + p.setRenderHint(QPainter::Antialiasing); + QPointF points[] = {QPointF(0,0),QPointF(width,0),QPointF(width/2,height)}; + auto traceColor = parentTrace->color(); + p.setPen(traceColor); + p.setBrush(traceColor); + p.drawConvexPolygon(points, 3); + auto brightness = traceColor.redF() * 0.299 + traceColor.greenF() * 0.587 + traceColor.blueF() * 0.114; + p.setPen((brightness > 0.6) ? Qt::black : Qt::white); + p.drawText(QRectF(0,0,width, height*2.0/3.0), Qt::AlignCenter, QString::number(number) + suffix); + } else { + symbol = QPixmap(1,1); + } emit symbolChanged(this); } @@ -204,6 +224,7 @@ std::set TraceMarker::getSupportedTypes() supported.insert(Type::Maximum); supported.insert(Type::Minimum); supported.insert(Type::Delta); + supported.insert(Type::PeakTable); if(parentTrace->isLive()) { switch(parentTrace->liveParameter()) { case Trace::LiveParameter::S11: @@ -256,10 +277,12 @@ void TraceMarker::assignDeltaMarker(TraceMarker *m) void TraceMarker::deleteHelperMarkers() { + emit beginRemoveHelperMarkers(this); for(auto m : helperMarkers) { delete m; } helperMarkers.clear(); + emit endRemoveHelperMarkers(this); } void TraceMarker::setType(TraceMarker::Type t) @@ -267,7 +290,11 @@ void TraceMarker::setType(TraceMarker::Type t) // remove any potential helper markers deleteHelperMarkers(); type = t; - vector helperSuffixes; + using helper_descr = struct { + QString suffix; + QString description; + }; + vector required_helpers; switch(type) { case Type::Delta: if(!delta) { @@ -293,24 +320,24 @@ void TraceMarker::setType(TraceMarker::Type t) break; case Type::Lowpass: case Type::Highpass: - helperSuffixes = {"c"}; + required_helpers = {{"c", "cutoff"}}; break; case Type::Bandpass: - helperSuffixes = {"l", "h" ,"c"}; + required_helpers = {{"l", "lower cutoff"}, {"h", "higher cutoff"} ,{"c", "center"}}; break; case Type::TOI: - helperSuffixes = {"p", "l", "r"}; + required_helpers = {{"p", "first peak"}, {"p", "second peak"}, {"l", "left intermodulation"}, {"r", "right intermodulation"}}; default: break; } // create helper markers - for(auto suffix : helperSuffixes) { - auto helper = new TraceMarker(model); - helper->suffix = suffix; - helper->number = number; + for(auto h : required_helpers) { + auto helper = new TraceMarker(model, number, this, h.description); + helper->suffix = h.suffix; helper->assignTrace(parentTrace); helperMarkers.push_back(helper); } + updateSymbol(); emit typeChanged(this); update(); } @@ -320,10 +347,50 @@ double TraceMarker::toDecibel() return 20*log10(abs(data)); } +bool TraceMarker::isVisible() +{ + switch(type) { + case Type::Manual: + case Type::Delta: + case Type::Maximum: + case Type::Minimum: + return true; + default: + return false; + } +} + +QString TraceMarker::getSuffix() const +{ + return suffix; +} + +const std::vector &TraceMarker::getHelperMarkers() const +{ + return helperMarkers; +} + +TraceMarker *TraceMarker::helperMarker(unsigned int i) +{ + if(i < helperMarkers.size()) { + return helperMarkers[i]; + } else { + return nullptr; + } +} + +TraceMarker *TraceMarker::getParent() const +{ + return parent; +} + void TraceMarker::setNumber(int value) { number = value; updateSymbol(); + for(auto h : helperMarkers) { + h->setNumber(number); + } } QWidget *TraceMarker::getTypeEditor(QAbstractItemDelegate *delegate) @@ -398,6 +465,7 @@ void TraceMarker::updateTypeFromEditor(QWidget *w) } } } + update(); } SIUnitEdit *TraceMarker::getSettingsEditor() @@ -411,6 +479,7 @@ SIUnitEdit *TraceMarker::getSettingsEditor() return new SIUnitEdit("Hz", " kMG"); case Type::Lowpass: case Type::Highpass: + case Type::PeakTable: return new SIUnitEdit("db", " "); case Type::TOI: return nullptr; @@ -433,8 +502,11 @@ void TraceMarker::adjustSettings(double value) if(value > 0.0) { value = -value; } + /* no break */ + case Type::PeakTable: cutoffAmplitude = value; } + update(); } void TraceMarker::update() @@ -454,6 +526,20 @@ void TraceMarker::update() case Type::Minimum: setFrequency(parentTrace->findExtremumFreq(false)); break; + case Type::PeakTable: { + deleteHelperMarkers(); + auto peaks = parentTrace->findPeakFrequencies(100, cutoffAmplitude); + char suffix = 'a'; + for(auto p : peaks) { + auto helper = new TraceMarker(model, number, this); + helper->suffix = suffix; + helper->assignTrace(parentTrace); + helper->setFrequency(p); + suffix++; + helperMarkers.push_back(helper); + } + } + break; case Type::Lowpass: case Type::Highpass: if(parentTrace->isReflection()) { @@ -539,11 +625,11 @@ void TraceMarker::update() // assign marker frequenies: // this marker is the left peak, first helper the right peak. // 2nd and 3rd helpers are left and right TOI peaks - setFrequency(peaks[0]); - helperMarkers[0]->setFrequency(peaks[1]); + helperMarkers[0]->setFrequency(peaks[0]); + helperMarkers[1]->setFrequency(peaks[1]); auto freqDiff = peaks[1] - peaks[0]; - helperMarkers[1]->setFrequency(peaks[0] - freqDiff); - helperMarkers[2]->setFrequency(peaks[1] + freqDiff); + helperMarkers[2]->setFrequency(peaks[0] - freqDiff); + helperMarkers[3]->setFrequency(peaks[1] + freqDiff); } break; } @@ -565,6 +651,21 @@ std::complex TraceMarker::getData() const return data; } +bool TraceMarker::isMovable() +{ + if(parent) { + // helper traces are never movable by the user + return false; + } + switch(type) { + case Type::Manual: + case Type::Delta: + return true; + default: + return false; + } +} + QPixmap &TraceMarker::getSymbol() { return symbol; diff --git a/Software/PC_Application/Traces/tracemarker.h b/Software/PC_Application/Traces/tracemarker.h index 3b4a37d..9a7ce3f 100644 --- a/Software/PC_Application/Traces/tracemarker.h +++ b/Software/PC_Application/Traces/tracemarker.h @@ -13,32 +13,38 @@ class TraceMarker : public QObject { Q_OBJECT; public: - TraceMarker(TraceMarkerModel *model, int number = 1); + TraceMarker(TraceMarkerModel *model, int number = 1, TraceMarker *parent = nullptr, QString descr = QString()); ~TraceMarker(); void assignTrace(Trace *t); Trace* trace(); QString readableData(); QString readableSettings(); + QString readableType(); double getFrequency() const; std::complex getData() const; + bool isMovable(); QPixmap& getSymbol(); int getNumber() const; + void setNumber(int value); + bool editingFrequeny; Trace *getTrace() const; - void setNumber(int value); QWidget *getTypeEditor(QAbstractItemDelegate *delegate = nullptr); void updateTypeFromEditor(QWidget *c); - SIUnitEdit* getSettingsEditor(); void adjustSettings(double value); // Updates marker position and data on automatic markers. Should be called whenever the tracedata is complete void update(); + TraceMarker *getParent() const; + const std::vector& getHelperMarkers() const; + TraceMarker *helperMarker(unsigned int i); + QString getSuffix() const; public slots: void setFrequency(double freq); @@ -47,6 +53,9 @@ signals: void dataChanged(TraceMarker *m); void symbolChanged(TraceMarker *m); void typeChanged(TraceMarker *m); + void traceChanged(TraceMarker *m); + void beginRemoveHelperMarkers(TraceMarker *m); + void endRemoveHelperMarkers(TraceMarker *m); private slots: void parentTraceDeleted(Trace *t); @@ -61,6 +70,7 @@ private: Maximum, Minimum, Delta, + PeakTable, Lowpass, Highpass, Bandpass, @@ -73,6 +83,7 @@ private: case Type::Maximum: return "Maximum"; case Type::Minimum: return "Minimum"; case Type::Delta: return "Delta"; + case Type::PeakTable: return "Peak Table"; case Type::Lowpass: return "Lowpass"; case Type::Highpass: return "Highpass"; case Type::Bandpass: return "Bandpass"; @@ -85,6 +96,7 @@ private: void deleteHelperMarkers(); void setType(Type t); double toDecibel(); + bool isVisible(); TraceMarkerModel *model; Trace *parentTrace; @@ -94,9 +106,11 @@ private: QPixmap symbol; Type type; QString suffix; + QString description; TraceMarker *delta; std::vector helperMarkers; + TraceMarker *parent; double cutoffAmplitude; }; diff --git a/Software/PC_Application/Traces/tracemarkermodel.cpp b/Software/PC_Application/Traces/tracemarkermodel.cpp index 8141b63..491052f 100644 --- a/Software/PC_Application/Traces/tracemarkermodel.cpp +++ b/Software/PC_Application/Traces/tracemarkermodel.cpp @@ -5,11 +5,48 @@ #include "CustomWidgets/siunitedit.h" #include +static constexpr int rowHeight = 21; + TraceMarkerModel::TraceMarkerModel(TraceModel &model, QObject *parent) - : QAbstractTableModel(parent), + : QAbstractItemModel(parent), model(model) { markers.clear(); + root = new TraceMarker(this); +} + +QModelIndex TraceMarkerModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) { + return QModelIndex(); + } + if(parent.isValid()) { + auto parentItem = markerFromIndex(parent); + auto child = parentItem->helperMarker(row); + if(child) { + return createIndex(row, column, parentItem); + } + } + return createIndex(row, column, root); +} + +QModelIndex TraceMarkerModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) { + return QModelIndex(); + } + + auto childItem = markerFromIndex(index); + auto *parentItem = childItem->getParent(); + if(parentItem) { + // find out the number of the child + auto it = find(markers.begin(), markers.end(), parentItem); + auto row = it - markers.begin(); + return createIndex(row, 0, root); + } else { + // no parent + return QModelIndex(); + } } TraceMarker *TraceMarkerModel::createDefaultMarker() @@ -39,19 +76,25 @@ void TraceMarkerModel::addMarker(TraceMarker *t) 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) { + 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) { + markerDataChanged(m); + endRemoveRows(); + }); connect(t, &TraceMarker::deleted, this, qOverload(&TraceMarkerModel::removeMarker)); emit markerAdded(t); } -void TraceMarkerModel::removeMarker(unsigned int index, bool delete_marker) +void TraceMarkerModel::removeMarker(unsigned int index) { if (index < markers.size()) { beginRemoveRows(QModelIndex(), index, index); - if(delete_marker) { - // disconnect from deleted signal prior to deleting the marker. Otherwise a second (possibly non-existent) will be erased from the list - disconnect(markers[index], &TraceMarker::deleted, this, qOverload(&TraceMarkerModel::removeMarker)); - delete markers[index]; - } markers.erase(markers.begin() + index); endRemoveRows(); } @@ -61,7 +104,7 @@ void TraceMarkerModel::removeMarker(TraceMarker *m) { auto it = std::find(markers.begin(), markers.end(), m); if(it != markers.end()) { - removeMarker(it - markers.begin(), false); + removeMarker(it - markers.begin()); } } @@ -72,7 +115,12 @@ void TraceMarkerModel::markerDataChanged(TraceMarker *m) // only update the other columns, do not override editor data emit dataChanged(index(row, ColIndexData), index(row, ColIndexData)); } else { - emit dataChanged(index(row, ColIndexSettings), index(row, ColIndexData)); + emit dataChanged(index(row, ColIndexNumber), index(row, ColIndexData)); + // also update any potential helper markers + for(unsigned int i=0;igetHelperMarkers().size();i++) { + auto modelIndex = createIndex(i, 0, m); + emit dataChanged(index(i, ColIndexNumber, modelIndex), index(i, ColIndexData, modelIndex)); + } } } @@ -81,9 +129,13 @@ TraceMarker *TraceMarkerModel::marker(int index) return markers.at(index); } -int TraceMarkerModel::rowCount(const QModelIndex &) const +int TraceMarkerModel::rowCount(const QModelIndex &index) const { - return markers.size(); + if(!index.isValid()) { + return markers.size(); + } + auto marker = markerFromIndex(index); + return marker->getHelperMarkers().size(); } int TraceMarkerModel::columnCount(const QModelIndex &) const @@ -93,29 +145,23 @@ int TraceMarkerModel::columnCount(const QModelIndex &) const QVariant TraceMarkerModel::data(const QModelIndex &index, int role) const { - auto marker = markers[index.row()]; - switch(index.column()) { - case ColIndexNumber: - switch(role) { - case Qt::DisplayRole: return QVariant((unsigned int)marker->getNumber()); break; - } - case ColIndexTrace: - switch(role) { - case Qt::DisplayRole: + auto marker = markerFromIndex(index); + if(role == Qt::DisplayRole) { + switch(index.column()) { + case ColIndexNumber: + return QString::number(marker->getNumber()) + marker->getSuffix(); + case ColIndexTrace: if(marker->getTrace()) { return marker->getTrace()->name(); } break; + case ColIndexType: + return marker->readableType(); + case ColIndexSettings: + return marker->readableSettings(); + case ColIndexData: + return marker->readableData(); } - case ColIndexSettings: - switch(role) { - case Qt::DisplayRole: return marker->readableSettings(); break; - } - case ColIndexData: - switch(role) { - case Qt::DisplayRole: return marker->readableData(); break; - } - break; } return QVariant(); } @@ -141,7 +187,7 @@ bool TraceMarkerModel::setData(const QModelIndex &index, const QVariant &value, if((unsigned int) index.row() >= markers.size()) { return false; } - auto m = markers[index.row()]; + auto m = markerFromIndex(index); switch(index.column()) { case ColIndexNumber: { m->setNumber(value.toInt()); @@ -171,6 +217,11 @@ Qt::ItemFlags TraceMarkerModel::flags(const QModelIndex &index) const case ColIndexSettings: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break; case ColIndexData: flags |= Qt::ItemIsEnabled; break; } + auto marker = markerFromIndex(index); + if(marker->getParent()) { + // this is a helper marker -> nothing is editable + flags &= ~Qt::ItemIsEditable; + } return (Qt::ItemFlags) flags; } @@ -202,10 +253,26 @@ void TraceMarkerModel::updateMarkers() } } +TraceMarker *TraceMarkerModel::markerFromIndex(const QModelIndex &index) const +{ + auto m = static_cast(index.internalPointer()); + if(m == root) { + return markers[index.row()]; + } else { + return m->helperMarker(index.row()); + } +} + +QSize MarkerTraceDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return QSize(0, rowHeight); +} + QWidget *MarkerTraceDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const { auto model = (TraceMarkerModel*) index.model(); auto c = new QComboBox(parent); + c->setMaximumHeight(rowHeight); connect(c, qOverload(&QComboBox::currentIndexChanged), [c](int) { c->clearFocus(); }); @@ -218,8 +285,7 @@ QWidget *MarkerTraceDelegate::createEditor(QWidget *parent, const QStyleOptionVi void MarkerTraceDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { - auto model = (TraceMarkerModel*) index.model(); - auto marker = model->getMarkers()[index.row()]; + auto marker = static_cast(index.model())->markerFromIndex(index); auto c = (QComboBox*) editor; for(int i=0;icount();i++) { if(qvariant_cast(c->itemData(i)) == marker->trace()) { @@ -236,13 +302,18 @@ void MarkerTraceDelegate::setModelData(QWidget *editor, QAbstractItemModel *mode markerModel->setData(index, c->itemData(c->currentIndex())); } +QSize MarkerSettingsDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return QSize(0, rowHeight); +} + QWidget *MarkerSettingsDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { - auto model = (TraceMarkerModel*) index.model(); - auto marker = model->getMarkers()[index.row()]; + auto marker = static_cast(index.model())->markerFromIndex(index); marker->editingFrequeny = true; auto e = marker->getSettingsEditor(); if(e) { + e->setMaximumHeight(rowHeight); e->setParent(parent); connect(e, &SIUnitEdit::valueUpdated, this, &MarkerSettingsDelegate::commitData); } @@ -252,25 +323,28 @@ QWidget *MarkerSettingsDelegate::createEditor(QWidget *parent, const QStyleOptio void MarkerSettingsDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { auto markerModel = (TraceMarkerModel*) model; - auto marker = markerModel->getMarkers()[index.row()]; + auto marker = markerModel->markerFromIndex(index); marker->editingFrequeny = false; auto si = (SIUnitEdit*) editor; markerModel->setData(index, si->value()); } +QSize MarkerTypeDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return QSize(0, rowHeight); +} + QWidget *MarkerTypeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { - auto model = (TraceMarkerModel*) index.model(); - auto marker = model->getMarkers()[index.row()]; + auto marker = static_cast(index.model())->markerFromIndex(index); auto editor = marker->getTypeEditor(const_cast(this)); + editor->setMaximumHeight(rowHeight); editor->setParent(parent); -// connect(editor, &QWidget::focusC) return editor; } void MarkerTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { - auto markerModel = (TraceMarkerModel*) model; - auto marker = markerModel->getMarkers()[index.row()]; + auto marker = static_cast(index.model())->markerFromIndex(index); marker->updateTypeFromEditor(editor); } diff --git a/Software/PC_Application/Traces/tracemarkermodel.h b/Software/PC_Application/Traces/tracemarkermodel.h index 7f91d2d..7283f98 100644 --- a/Software/PC_Application/Traces/tracemarkermodel.h +++ b/Software/PC_Application/Traces/tracemarkermodel.h @@ -10,6 +10,7 @@ class MarkerTraceDelegate : public QStyledItemDelegate { Q_OBJECT; + QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override; QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override; void setEditorData(QWidget * editor, const QModelIndex & index) const override; void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override; @@ -18,6 +19,7 @@ class MarkerTraceDelegate : public QStyledItemDelegate class MarkerTypeDelegate : public QStyledItemDelegate { Q_OBJECT; + QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override; QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override; void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override; }; @@ -25,11 +27,12 @@ class MarkerTypeDelegate : public QStyledItemDelegate class MarkerSettingsDelegate : public QStyledItemDelegate { Q_OBJECT; + QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const override; QWidget *createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override; void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override; }; -class TraceMarkerModel : public QAbstractTableModel +class TraceMarkerModel : public QAbstractItemModel { Q_OBJECT public: @@ -44,6 +47,8 @@ public: ColIndexLast, }; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role) const override; @@ -57,10 +62,11 @@ public: std::vector getMarkers(Trace *t); TraceModel& getModel(); void updateMarkers(); + TraceMarker *markerFromIndex(const QModelIndex &index) const; public slots: void addMarker(TraceMarker *t); - void removeMarker(unsigned int index, bool delete_marker = true); + void removeMarker(unsigned int index); void removeMarker(TraceMarker *m); @@ -72,7 +78,7 @@ private slots: private: std::vector markers; TraceModel &model; - + TraceMarker *root; }; #endif // TRACEMARKERMODEL_H diff --git a/Software/PC_Application/Traces/tracesmithchart.cpp b/Software/PC_Application/Traces/tracesmithchart.cpp index 08e89a4..d05d680 100644 --- a/Software/PC_Application/Traces/tracesmithchart.cpp +++ b/Software/PC_Application/Traces/tracesmithchart.cpp @@ -40,6 +40,9 @@ void TraceSmithChart::mousePressEvent(QMouseEvent *event) for(auto t : traces) { auto markers = t.first->getMarkers(); for(auto m : markers) { + if(!m->isMovable()) { + continue; + } auto S = m->getData(); auto markerPoint = plotToPixel(S); auto yDiff = abs(markerPoint.y() - clickPoint.y()); diff --git a/Software/PC_Application/Traces/tracexyplot.cpp b/Software/PC_Application/Traces/tracexyplot.cpp index 4571bbe..fb8582e 100644 --- a/Software/PC_Application/Traces/tracexyplot.cpp +++ b/Software/PC_Application/Traces/tracexyplot.cpp @@ -580,9 +580,7 @@ void TraceXYPlot::markerDataChanged(TraceMarker *m) void TraceXYPlot::markerSymbolChanged(TraceMarker *m) { auto qwtMarker = markers[m]; - auto old_sym = qwtMarker->symbol(); qwtMarker->setSymbol(nullptr); - delete old_sym; QwtSymbol *sym=new QwtSymbol; sym->setPixmap(m->getSymbol()); @@ -597,6 +595,9 @@ void TraceXYPlot::clicked(const QPointF pos) unsigned int closestDistance = numeric_limits::max(); TraceMarker *closestMarker = nullptr; for(auto m : markers) { + if(!m.first->isMovable()) { + continue; + } auto markerPoint = drawPicker->plotToPixel(m.second->value()); auto yDiff = abs(markerPoint.y() - clickPoint.y()); auto xDiff = abs(markerPoint.x() - clickPoint.x());