Further preparation

This commit is contained in:
Jan Käberich 2020-11-25 21:20:31 +01:00
parent 66f8b86159
commit 6e13473337
5 changed files with 207 additions and 25 deletions

View File

@ -8,6 +8,34 @@ TraceMathEditDialog::TraceMathEditDialog(Trace &t, QWidget *parent) :
auto model = new MathModel(t); auto model = new MathModel(t);
ui->setupUi(this); ui->setupUi(this);
ui->view->setModel(model); ui->view->setModel(model);
connect(ui->view->selectionModel(), &QItemSelectionModel::currentRowChanged, [=](const QModelIndex &current, 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() TraceMathEditDialog::~TraceMathEditDialog()
@ -24,7 +52,7 @@ MathModel::MathModel(Trace &t, QObject *parent)
int MathModel::rowCount(const QModelIndex &parent) const int MathModel::rowCount(const QModelIndex &parent) const
{ {
return t.getMath().size(); return t.getMathOperations().size();
} }
int MathModel::columnCount(const QModelIndex &parent) const int MathModel::columnCount(const QModelIndex &parent) const
@ -37,16 +65,18 @@ QVariant MathModel::data(const QModelIndex &index, int role) const
if(!index.isValid()) { if(!index.isValid()) {
return QVariant(); return QVariant();
} }
auto math = t.getMath().at(index.row()); auto math = t.getMathOperations().at(index.row());
switch(index.column()) { switch(index.column()) {
case ColIndexEnabled: // case ColIndexEnabled:
if(role == Qt::CheckStateRole) { // if(role == Qt::CheckStateRole) {
return math.enabled ? Qt::Checked : Qt::Unchecked; // return math.enabled ? Qt::Checked : Qt::Unchecked;
} // }
break; // break;
case ColIndexDescription: case ColIndexDescription:
if(role == Qt::DisplayRole) { if(role == Qt::DisplayRole) {
return math.math->description(); return math.math->description();
} else if(role == Qt::CheckStateRole){
return math.enabled ? Qt::Checked : Qt::Unchecked;
} }
break; break;
} }
@ -57,7 +87,7 @@ QVariant MathModel::headerData(int section, Qt::Orientation orientation, int rol
{ {
if(orientation == Qt::Horizontal && role == Qt::DisplayRole) { if(orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch(section) { switch(section) {
case ColIndexEnabled: return "Enabled"; break; // case ColIndexEnabled: return "Enabled"; break;
case ColIndexDescription: return "Description"; break; case ColIndexDescription: return "Description"; break;
default: 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 Qt::ItemFlags MathModel::flags(const QModelIndex &index) const
{ {
int flags = Qt::NoItemFlags; int flags = Qt::NoItemFlags;
if(index.row() > 1) { if(index.row() >= 1) {
// the first entry is always the trace itself and not enabled // the first entry is always the trace itself and not enabled
flags |= Qt::ItemIsEnabled; flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable;
} }
switch(index.column()) { switch(index.column()) {
case ColIndexEnabled: flags |= Qt::ItemIsUserCheckable; break; case ColIndexDescription: flags |= Qt::ItemIsUserCheckable; break;
default: default:
break; break;
} }
return (Qt::ItemFlags) flags; 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));
}

View File

@ -16,8 +16,8 @@ public:
MathModel(Trace &t, QObject *parent = 0); MathModel(Trace &t, QObject *parent = 0);
enum { enum {
ColIndexEnabled = 0, // ColIndexEnabled = 0,
ColIndexDescription = 1, ColIndexDescription = 0,
ColIndexLast, ColIndexLast,
}; };
@ -27,6 +27,9 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::ItemFlags flags(const QModelIndex &index) const override;
void deleteRow(unsigned int row);
void rowsSwapped(unsigned int top);
private: private:
Trace &t; Trace &t;
}; };

View File

@ -21,9 +21,24 @@
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QTableView" name="view"> <widget class="QTableView" name="view">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior"> <property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum> <enum>QAbstractItemView::SelectRows</enum>
</property> </property>
<property name="showGrid">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderMinimumSectionSize"> <attribute name="horizontalHeaderMinimumSectionSize">
<number>20</number> <number>20</number>
</attribute> </attribute>
@ -62,6 +77,9 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="bDelete"> <widget class="QPushButton" name="bDelete">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -80,6 +98,38 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="bMoveUp">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Move up</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="go-up"/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="bMoveDown">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Move down</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="go-down"/>
</property>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">

View File

@ -18,8 +18,13 @@ Trace::Trace(QString name, QColor color, LiveParameter live)
lastMath(nullptr) lastMath(nullptr)
{ {
MathInfo self = {.math = this, .enabled = true}; MathInfo self = {.math = this, .enabled = true};
math.push_back(self); mathOps.push_back(self);
updateLastMath(math.rbegin()); updateLastMath(mathOps.rbegin());
self.enabled = false;
mathOps.push_back(self);
mathOps.push_back(self);
mathOps.push_back(self);
} }
Trace::~Trace() Trace::~Trace()
@ -231,15 +236,15 @@ void Trace::updateTimeDomainData()
// cout << "TDR: " << this << " (took " << duration << "ms)" <<endl; // cout << "TDR: " << this << " (took " << duration << "ms)" <<endl;
} }
const std::vector<Trace::MathInfo>& Trace::getMath() const const std::vector<Trace::MathInfo>& Trace::getMathOperations() const
{ {
return math; return mathOps;
} }
void Trace::updateLastMath(vector<MathInfo>::reverse_iterator start) void Trace::updateLastMath(vector<MathInfo>::reverse_iterator start)
{ {
TraceMath *newLast = nullptr; TraceMath *newLast = nullptr;
for(auto it = start;it != math.rend();it++) { for(auto it = start;it != mathOps.rend();it++) {
if(it->enabled) { if(it->enabled) {
newLast = it->math; newLast = it->math;
break; break;
@ -404,15 +409,90 @@ bool Trace::mathEnabled()
bool Trace::hasMathOperations() bool Trace::hasMathOperations()
{ {
return math.size() > 1; return mathOps.size() > 1;
} }
void Trace::enableMath(bool enable) 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); 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_index<mathOps.size();next_index++) {
if(mathOps[next_index].enabled) {
break;
}
}
unsigned int prev_index = index - 1;
for(;prev_index>0;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() unsigned int Trace::size()
{ {
return lastMath->numSamples(); return lastMath->numSamples();

View File

@ -64,9 +64,6 @@ public:
bool isCalibration(); bool isCalibration();
bool isLive(); bool isLive();
bool isReflection(); 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; } LiveParameter liveParameter() { return _liveParam; }
LivedataType liveType() { return _liveType; } LivedataType liveType() { return _liveType; }
unsigned int size(); unsigned int size();
@ -106,12 +103,22 @@ public:
DataType outputType(DataType inputType) override { Q_UNUSED(inputType) return DataType::Frequency;}; DataType outputType(DataType inputType) override { Q_UNUSED(inputType) return DataType::Frequency;};
QString description() override; 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 { class MathInfo {
public: public:
TraceMath *math; TraceMath *math;
bool enabled; bool enabled;
}; };
const std::vector<MathInfo>& getMath() const; const std::vector<MathInfo>& getMathOperations() const;
public slots: public slots:
void setTouchstoneParameter(int value); void setTouchstoneParameter(int value);
@ -160,7 +167,7 @@ private:
bool valid; bool valid;
} settings; } settings;
std::vector<MathInfo> math; std::vector<MathInfo> mathOps;
TraceMath *lastMath; TraceMath *lastMath;
void updateLastMath(std::vector<MathInfo>::reverse_iterator start); void updateLastMath(std::vector<MathInfo>::reverse_iterator start);
}; };