diff --git a/Software/PC_Application/Traces/Math/tracematheditdialog.cpp b/Software/PC_Application/Traces/Math/tracematheditdialog.cpp index d946b59..db9531c 100644 --- a/Software/PC_Application/Traces/Math/tracematheditdialog.cpp +++ b/Software/PC_Application/Traces/Math/tracematheditdialog.cpp @@ -8,6 +8,34 @@ TraceMathEditDialog::TraceMathEditDialog(Trace &t, QWidget *parent) : auto model = new MathModel(t); ui->setupUi(this); ui->view->setModel(model); + + connect(ui->view->selectionModel(), &QItemSelectionModel::currentRowChanged, [=](const QModelIndex ¤t, const QModelIndex &previous){ + if(!current.isValid()) { + ui->bDelete->setEnabled(false); + ui->bMoveUp->setEnabled(false); + ui->bMoveDown->setEnabled(false); + } else { + ui->bDelete->setEnabled(true); + ui->bMoveUp->setEnabled(current.row() > 1); + ui->bMoveDown->setEnabled(current.row() + 1 < model->rowCount()); + } + }); + + connect(ui->bDelete, &QPushButton::clicked, [=](){ + model->deleteRow(ui->view->currentIndex().row()); + }); + connect(ui->bMoveUp, &QPushButton::clicked, [&](){ + auto index = ui->view->currentIndex(); + t.swapMathOrder(index.row() - 1); + model->rowsSwapped(index.row() - 1); + ui->view->setCurrentIndex(index.sibling(index.row() - 1, 0)); + }); + connect(ui->bMoveDown, &QPushButton::clicked, [&](){ + auto index = ui->view->currentIndex(); + t.swapMathOrder(index.row()); + model->rowsSwapped(index.row()); + ui->view->setCurrentIndex(index.sibling(index.row() + 1, 0)); + }); } TraceMathEditDialog::~TraceMathEditDialog() @@ -24,7 +52,7 @@ MathModel::MathModel(Trace &t, QObject *parent) int MathModel::rowCount(const QModelIndex &parent) const { - return t.getMath().size(); + return t.getMathOperations().size(); } int MathModel::columnCount(const QModelIndex &parent) const @@ -37,16 +65,18 @@ QVariant MathModel::data(const QModelIndex &index, int role) const if(!index.isValid()) { return QVariant(); } - auto math = t.getMath().at(index.row()); + auto math = t.getMathOperations().at(index.row()); switch(index.column()) { - case ColIndexEnabled: - if(role == Qt::CheckStateRole) { - return math.enabled ? Qt::Checked : Qt::Unchecked; - } - break; +// case ColIndexEnabled: +// if(role == Qt::CheckStateRole) { +// return math.enabled ? Qt::Checked : Qt::Unchecked; +// } +// break; case ColIndexDescription: if(role == Qt::DisplayRole) { return math.math->description(); + } else if(role == Qt::CheckStateRole){ + return math.enabled ? Qt::Checked : Qt::Unchecked; } break; } @@ -57,7 +87,7 @@ QVariant MathModel::headerData(int section, Qt::Orientation orientation, int rol { if(orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch(section) { - case ColIndexEnabled: return "Enabled"; break; +// case ColIndexEnabled: return "Enabled"; break; case ColIndexDescription: return "Description"; break; default: break; } @@ -68,14 +98,26 @@ QVariant MathModel::headerData(int section, Qt::Orientation orientation, int rol Qt::ItemFlags MathModel::flags(const QModelIndex &index) const { int flags = Qt::NoItemFlags; - if(index.row() > 1) { + if(index.row() >= 1) { // the first entry is always the trace itself and not enabled - flags |= Qt::ItemIsEnabled; + flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable; } switch(index.column()) { - case ColIndexEnabled: flags |= Qt::ItemIsUserCheckable; break; + case ColIndexDescription: flags |= Qt::ItemIsUserCheckable; break; default: break; } return (Qt::ItemFlags) flags; } + +void MathModel::deleteRow(unsigned int row) +{ + beginRemoveRows(QModelIndex(), row, row); + t.removeMathOperation(row); + endRemoveRows(); +} + +void MathModel::rowsSwapped(unsigned int top) +{ +// emit dataChanged(createIndex(top, 0), createIndex(top+1, ColIndexLast - 1)); +} diff --git a/Software/PC_Application/Traces/Math/tracematheditdialog.h b/Software/PC_Application/Traces/Math/tracematheditdialog.h index 6edcde5..167ae57 100644 --- a/Software/PC_Application/Traces/Math/tracematheditdialog.h +++ b/Software/PC_Application/Traces/Math/tracematheditdialog.h @@ -16,8 +16,8 @@ public: MathModel(Trace &t, QObject *parent = 0); enum { - ColIndexEnabled = 0, - ColIndexDescription = 1, +// ColIndexEnabled = 0, + ColIndexDescription = 0, ColIndexLast, }; @@ -27,6 +27,9 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; + void deleteRow(unsigned int row); + void rowsSwapped(unsigned int top); + private: Trace &t; }; diff --git a/Software/PC_Application/Traces/Math/tracematheditdialog.ui b/Software/PC_Application/Traces/Math/tracematheditdialog.ui index 87822c8..f0805cb 100644 --- a/Software/PC_Application/Traces/Math/tracematheditdialog.ui +++ b/Software/PC_Application/Traces/Math/tracematheditdialog.ui @@ -21,9 +21,24 @@ + + Qt::ScrollBarAsNeeded + + + true + + + QAbstractItemView::InternalMove + + + QAbstractItemView::SingleSelection + QAbstractItemView::SelectRows + + false + 20 @@ -62,6 +77,9 @@ + + false + 0 @@ -80,6 +98,38 @@ + + + + false + + + Move up + + + + + + + + + + + + + false + + + Move down + + + + + + + + + diff --git a/Software/PC_Application/Traces/trace.cpp b/Software/PC_Application/Traces/trace.cpp index 07e4db5..0550caf 100644 --- a/Software/PC_Application/Traces/trace.cpp +++ b/Software/PC_Application/Traces/trace.cpp @@ -18,8 +18,13 @@ Trace::Trace(QString name, QColor color, LiveParameter live) lastMath(nullptr) { MathInfo self = {.math = this, .enabled = true}; - math.push_back(self); - updateLastMath(math.rbegin()); + mathOps.push_back(self); + updateLastMath(mathOps.rbegin()); + + self.enabled = false; + mathOps.push_back(self); + mathOps.push_back(self); + mathOps.push_back(self); } Trace::~Trace() @@ -231,15 +236,15 @@ void Trace::updateTimeDomainData() // cout << "TDR: " << this << " (took " << duration << "ms)" <& Trace::getMath() const +const std::vector& Trace::getMathOperations() const { - return math; + return mathOps; } void Trace::updateLastMath(vector::reverse_iterator start) { TraceMath *newLast = nullptr; - for(auto it = start;it != math.rend();it++) { + for(auto it = start;it != mathOps.rend();it++) { if(it->enabled) { newLast = it->math; break; @@ -404,15 +409,90 @@ bool Trace::mathEnabled() bool Trace::hasMathOperations() { - return math.size() > 1; + return mathOps.size() > 1; } void Trace::enableMath(bool enable) { - auto start = enable ? math.rbegin() : make_reverse_iterator(math.begin()); + auto start = enable ? mathOps.rbegin() : make_reverse_iterator(mathOps.begin()); updateLastMath(start); } +void Trace::addMathOperation(TraceMath *math) +{ + MathInfo info = {.math = math, .enabled = true}; + math->assignInput(lastMath); + mathOps.push_back(info); + updateLastMath(mathOps.rbegin()); +} + +void Trace::removeMathOperation(unsigned int index) +{ + if(index < 1 || index >= mathOps.size()) { + return; + } + if(mathOps[index].enabled) { + enableMathOperation(index, false); + } + delete mathOps[index].math; + mathOps.erase(mathOps.begin() + index); +} + +void Trace::swapMathOrder(unsigned int index) +{ + if(index < 1 || index + 1 >= mathOps.size()) { + return; + } + // store enable state and disable prior to swap (can reuse enable/disable function to handle input assignment) + bool index_enabled = mathOps[index].enabled; + bool next_enabled = mathOps[index].enabled; + enableMathOperation(index, false); + enableMathOperation(index + 1, false); + // actually swap the information + swap(mathOps[index], mathOps[index+1]); + // restore enable state + enableMathOperation(index, next_enabled); + enableMathOperation(index + 1, index_enabled); +} + +void Trace::enableMathOperation(unsigned int index, bool enable) +{ + if(index < 1 || index >= mathOps.size()) { + return; + } + if(mathOps[index].enabled != enable) { + // find the next and previous operations that are enabled + unsigned int next_index = index + 1; + for(;next_index0;prev_index--) { + if(mathOps[prev_index].enabled) { + break; + } + } + if(enable) { + // assign the previous enabled operation as the input for this operation + mathOps[index].math->assignInput(mathOps[prev_index].math); + // if another operation was active after index, reassign its input to index + if(next_index < mathOps.size()) { + mathOps[next_index].math->assignInput(mathOps[index].math); + } + } else { + // this operation gets disabled, reassign possible operation after it + if(next_index < mathOps.size()) { + mathOps[next_index].math->assignInput(mathOps[prev_index].math); + } + mathOps[index].math->removeInput(); + } + mathOps[index].enabled = enable; + updateLastMath(mathOps.rbegin()); + } +} + unsigned int Trace::size() { return lastMath->numSamples(); diff --git a/Software/PC_Application/Traces/trace.h b/Software/PC_Application/Traces/trace.h index 6f5b805..3b3b608 100644 --- a/Software/PC_Application/Traces/trace.h +++ b/Software/PC_Application/Traces/trace.h @@ -64,9 +64,6 @@ public: bool isCalibration(); bool isLive(); bool isReflection(); - bool mathEnabled(); // check if math operations are enabled - bool hasMathOperations(); // check if math operations are set up (not necessarily enabled) - void enableMath(bool enable); LiveParameter liveParameter() { return _liveParam; } LivedataType liveType() { return _liveType; } unsigned int size(); @@ -106,12 +103,22 @@ public: DataType outputType(DataType inputType) override { Q_UNUSED(inputType) return DataType::Frequency;}; QString description() override; + bool mathEnabled(); // check if math operations are enabled + bool hasMathOperations(); // check if math operations are set up (not necessarily enabled) + void enableMath(bool enable); + // Adds a new math operation at the end of the list and enables it + void addMathOperation(TraceMath *mathOps); + // removes the math operation at the given index. Index 0 is invalid as this would be the trace itself + void removeMathOperation(unsigned int index); + // swaps the order of math operations at index and index+1. Does nothing if either index is invalid + void swapMathOrder(unsigned int index); + void enableMathOperation(unsigned int index, bool enable); class MathInfo { public: TraceMath *math; bool enabled; }; - const std::vector& getMath() const; + const std::vector& getMathOperations() const; public slots: void setTouchstoneParameter(int value); @@ -160,7 +167,7 @@ private: bool valid; } settings; - std::vector math; + std::vector mathOps; TraceMath *lastMath; void updateLastMath(std::vector::reverse_iterator start); };