#include "tracemarkermodel.h" #include "unit.h" #include #include #include "CustomWidgets/siunitedit.h" #include TraceMarkerModel::TraceMarkerModel(TraceModel &model, QObject *parent) : QAbstractTableModel(parent), model(model) { markers.clear(); } TraceMarker *TraceMarkerModel::createDefaultMarker() { // find lowest free number int number = 0; bool used; do { number++; used = false; for(auto m : markers) { if(m->getNumber() == number) { used = true; break; } } } while (used); auto marker = new TraceMarker(this, number); marker->setFrequency(2150000000); marker->assignTrace(model.trace(0)); return marker; } void TraceMarkerModel::addMarker(TraceMarker *t) { beginInsertRows(QModelIndex(), markers.size(), markers.size()); markers.push_back(t); endInsertRows(); connect(t, &TraceMarker::dataChanged, this, &TraceMarkerModel::markerDataChanged); connect(t, &TraceMarker::deleted, this, qOverload(&TraceMarkerModel::removeMarker)); emit markerAdded(t); } void TraceMarkerModel::removeMarker(unsigned int index, bool delete_marker) { 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(); } } void TraceMarkerModel::removeMarker(TraceMarker *m) { auto it = std::find(markers.begin(), markers.end(), m); if(it != markers.end()) { removeMarker(it - markers.begin(), false); } } void TraceMarkerModel::markerDataChanged(TraceMarker *m) { auto row = find(markers.begin(), markers.end(), m) - markers.begin(); if(m->editingFrequeny) { // 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)); } } TraceMarker *TraceMarkerModel::marker(int index) { return markers.at(index); } int TraceMarkerModel::rowCount(const QModelIndex &) const { return markers.size(); } int TraceMarkerModel::columnCount(const QModelIndex &) const { return ColIndexLast; } 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: if(marker->getTrace()) { return marker->getTrace()->name(); } break; } 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(); } QVariant TraceMarkerModel::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; } } else { return QVariant(); } } bool TraceMarkerModel::setData(const QModelIndex &index, const QVariant &value, int) { if((unsigned int) index.row() >= markers.size()) { return false; } auto m = markers[index.row()]; switch(index.column()) { case ColIndexNumber: { m->setNumber(value.toInt()); } break; case ColIndexTrace: { auto trace = qvariant_cast(value); m->assignTrace(trace); } break; case ColIndexSettings: { m->adjustSettings(value.toDouble()); } break; } return false; } Qt::ItemFlags TraceMarkerModel::flags(const QModelIndex &index) const { int flags = Qt::NoItemFlags; switch(index.column()) { case ColIndexNumber: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; 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; case ColIndexData: flags |= Qt::ItemIsEnabled; break; } return (Qt::ItemFlags) flags; } std::vector TraceMarkerModel::getMarkers() { return markers; } std::vector TraceMarkerModel::getMarkers(Trace *t) { std::vector attachedMarkers; for(auto m : markers) { if(m->getTrace() == t) { attachedMarkers.push_back(m); } } return attachedMarkers; } TraceModel &TraceMarkerModel::getModel() { return model; } void TraceMarkerModel::updateMarkers() { for(auto m : markers) { m->update(); } } QWidget *MarkerTraceDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const { auto model = (TraceMarkerModel*) index.model(); auto c = new QComboBox(parent); connect(c, qOverload(&QComboBox::currentIndexChanged), [c](int) { c->clearFocus(); }); auto traces = model->getModel().getTraces(); for(auto t : traces) { c->addItem(t->name(), QVariant::fromValue(t)); } return c; } void MarkerTraceDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { auto model = (TraceMarkerModel*) index.model(); auto marker = model->getMarkers()[index.row()]; auto c = (QComboBox*) editor; for(int i=0;icount();i++) { if(qvariant_cast(c->itemData(i)) == marker->trace()) { c->setCurrentIndex(i); return; } } } void MarkerTraceDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { auto markerModel = (TraceMarkerModel*) model; auto c = (QComboBox*) editor; markerModel->setData(index, c->itemData(c->currentIndex())); } QWidget *MarkerSettingsDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { auto model = (TraceMarkerModel*) index.model(); auto marker = model->getMarkers()[index.row()]; marker->editingFrequeny = true; auto e = marker->getSettingsEditor(); if(e) { e->setParent(parent); connect(e, &SIUnitEdit::valueUpdated, this, &MarkerSettingsDelegate::commitData); } return e; } void MarkerSettingsDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { auto markerModel = (TraceMarkerModel*) model; auto marker = markerModel->getMarkers()[index.row()]; marker->editingFrequeny = false; auto si = (SIUnitEdit*) editor; markerModel->setData(index, si->value()); } QWidget *MarkerTypeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { auto model = (TraceMarkerModel*) index.model(); auto marker = model->getMarkers()[index.row()]; auto editor = marker->getTypeEditor(const_cast(this)); 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()]; marker->updateTypeFromEditor(editor); }