Merge branch 'master' of github.com:qurrent-llc/SavvyCAN

This commit is contained in:
Andy Huska
2023-05-11 16:51:42 -05:00
83 changed files with 2307 additions and 1281 deletions
+1
View File
@@ -110,6 +110,7 @@ public: //TODO: this is sloppy. It shouldn't all be public!
QList<DBC_VAL_ENUM_ENTRY> valList;
QList<DBC_SIGNAL *> multiplexedChildren;
DBC_SIGNAL *multiplexParent;
DBC_SIGNAL *self;
DBC_SIGNAL();
bool processAsText(const CANFrame &frame, QString &outString, bool outputName = true);
+24 -10
View File
@@ -441,12 +441,21 @@ void DBCFile::findAttributesByType(DBC_ATTRIBUTE_TYPE typ, QList<DBC_ATTRIBUTE>
}
}
//there's no external way to clear the flag. It is only cleared when the file is saved by this object.
void DBCFile::setDirtyFlag()
{
isDirty = true;
}
//BE CAREFUL HERE. Do not clear the dirty flag unless you're absolutely sure nothing has changed.
//Currently the signal editor clears this flag if the entire undo buffer is emptied but still
//it's possible that signals or messages were deleted or added so this is potentially not that safe
//It would be better if every node, message, and signal had a dirty flag. Then the DBCFile getDirtyFlag
//function could traverse the tree and see if anything is dirty.
void DBCFile::clearDirtyFlag()
{
isDirty = false;
}
bool DBCFile::getDirtyFlag()
{
return isDirty;
@@ -1294,7 +1303,7 @@ bool DBCFile::saveFile(QString fileName)
int msgNumber = 1;
int sigNumber = 1;
QFile *outFile = new QFile(fileName);
QString nodesOutput, msgOutput, commentsOutput, valuesOutput;
QString nodesOutput, msgOutput, commentsOutput, valuesOutput, extMultiplexOutput;
QString defaultsOutput, attrValOutput;
bool hasExtendedMultiplexing = false;
@@ -1512,6 +1521,9 @@ bool DBCFile::saveFile(QString fileName)
msgOutput.clear(); //got to reset it after writing
}
outFile->write(commentsOutput.toUtf8());
commentsOutput.clear();
//Now dump out all of the stored attributes
for (int x = 0; x < dbc_attributes.count(); x++)
{
@@ -1573,6 +1585,8 @@ bool DBCFile::saveFile(QString fileName)
defaultsOutput.append("\"" + dbc_attributes[x].enumVals[dbc_attributes[x].defaultValue.toInt()] + "\";\n");
break;
case ATTR_INT:
defaultsOutput.append(QString::number(dbc_attributes[x].defaultValue.toLongLong()) + ";\n");
break;
case ATTR_FLOAT:
defaultsOutput.append(dbc_attributes[x].defaultValue.toString() + ";\n");
break;
@@ -1592,7 +1606,7 @@ bool DBCFile::saveFile(QString fileName)
uint32_t ID = msg->ID;
if (msg->ID > 0x7FF || msg->extendedID)
{
msg->ID += 0x80000000ul; //set bit 31 if this ID is extended.
ID += 0x80000000ul; //set bit 31 if this ID is extended.
}
for (int s = 0; s < msg->sigHandler->getCount(); s++)
@@ -1605,7 +1619,7 @@ bool DBCFile::saveFile(QString fileName)
msgOutput.append(sig->name + " " + sig->multiplexParent->name + " ");
msgOutput.append(QString::number(sig->multiplexLowValue) + "-" + QString::number(sig->multiplexHighValue) + ";");
msgOutput.append("\n");
outFile->write(msgOutput.toUtf8());
extMultiplexOutput.append(msgOutput);
msgOutput.clear(); //got to reset it after writing
}
}
@@ -1613,15 +1627,15 @@ bool DBCFile::saveFile(QString fileName)
}
//now write out all of the accumulated comments and value tables from above
outFile->write(attrValOutput.toUtf8());
outFile->write(defaultsOutput.toUtf8());
outFile->write(commentsOutput.toUtf8());
outFile->write(attrValOutput.toUtf8());
outFile->write(valuesOutput.toUtf8());
outFile->write(extMultiplexOutput.toUtf8());
attrValOutput.clear();
defaultsOutput.clear();
commentsOutput.clear();
valuesOutput.clear();
extMultiplexOutput.clear();
outFile->close();
delete outFile;
@@ -2235,14 +2249,14 @@ DBCHandler::DBCHandler()
qDebug() << "Previously loaded DBC file count: " << filecount;
for (int i=0; i<filecount; i++)
{
QString filename = settings.value("DBC/Filename_" + QString(i),"").toString();
QString filename = settings.value("DBC/Filename_" + QString::number(i),"").toString();
DBCFile * file = loadDBCFile(filename);
if (file)
{
int bus = settings.value("DBC/AssocBus_" + QString(i),0).toInt();
int bus = settings.value("DBC/AssocBus_" + QString::number(i),0).toInt();
file->setAssocBus(bus);
MatchingCriteria_t matchingCriteria = (MatchingCriteria_t)settings.value("DBC/MatchingCriteria_" + QString(i),0).toInt();
MatchingCriteria_t matchingCriteria = (MatchingCriteria_t)settings.value("DBC/MatchingCriteria_" + QString::number(i),0).toInt();
DBC_ATTRIBUTE attr;
+1
View File
@@ -87,6 +87,7 @@ public:
void setAssocBus(int bus);
void setDirtyFlag();
bool getDirtyFlag();
void clearDirtyFlag();
void sort();
DBCMessageHandler *messageHandler;
+6 -6
View File
@@ -108,10 +108,10 @@ void DBCLoadSaveWindow::updateSettings()
qDebug() << "Save DBC settings #" << i << " File: " << file->getFullFilename()
<< "Bus: " << file->getAssocBus() << "MC: " << file->messageHandler->getMatchingCriteria()
<< "Filter Labeling: " << (file->messageHandler->filterLabeling() ? "enabled" : "disabled");
settings.setValue("DBC/Filename_" + QString(i), file->getFullFilename());
settings.setValue("DBC/AssocBus_" + QString(i), file->getAssocBus());
settings.setValue("DBC/MatchingCriteria_" + QString(i), file->messageHandler->getMatchingCriteria());
settings.setValue("DBC/FilterLabeling_" + QString(i), file->messageHandler->filterLabeling());
settings.setValue("DBC/Filename_" + QString::number(i), file->getFullFilename());
settings.setValue("DBC/AssocBus_" + QString::number(i), file->getAssocBus());
settings.setValue("DBC/MatchingCriteria_" + QString::number(i), file->messageHandler->getMatchingCriteria());
settings.setValue("DBC/FilterLabeling_" + QString::number(i), file->messageHandler->filterLabeling());
}
}
emit updatedDBCSettings();
@@ -200,7 +200,7 @@ void DBCLoadSaveWindow::loadFile()
DBC_ATTRIBUTE *attr = file->findAttributeByName("matchingcriteria");
QComboBox * mc_item = addMatchingCriteriaCombobox(idx);
if (attr && attr->defaultValue > 0)
if (attr && attr->defaultValue.toInt() > 0)
{
mc_item->setCurrentIndex(attr->defaultValue.toInt());
}
@@ -208,7 +208,7 @@ void DBCLoadSaveWindow::loadFile()
attr = file->findAttributeByName("filterlabeling");
QTableWidgetItem *item = new QTableWidgetItem("");
ui->tableFiles->setItem(idx, 3, item);
if (attr && attr->defaultValue > 0)
if (attr && attr->defaultValue.toInt() > 0)
{
item->setCheckState(Qt::Checked);
}
+4
View File
@@ -675,6 +675,9 @@ void DBCMainEditor::newMessage()
msgItem = nodeItem->parent();
nodeItem = msgItem->parent();
}
if (typ == DBCItemTypes::NODE){
msgItem = nodeItem;
}
//if there was a comment this will find the location of the comment and snip it out.
QString nodeName = nodeItem->data(0, Qt::DisplayRole).toString().split(" - ")[0];
@@ -702,6 +705,7 @@ void DBCMainEditor::newMessage()
msg.name = nodeName + "Msg" + QString::number(randGen.bounded(500));
msg.ID = 0;
msg.len = 8;
msg.bgColor = QApplication::palette().color(QPalette::Base);
}
}
else
+316 -131
View File
@@ -37,7 +37,9 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
ui->bitfield->setMode(GridMode::SIGNAL_VIEW);
connect(ui->bitfield, SIGNAL(gridClicked(int)), this, SLOT(bitfieldClicked(int)));
connect(ui->bitfield, SIGNAL(gridClicked(int)), this, SLOT(bitfieldLeftClicked(int)));
connect(ui->bitfield, SIGNAL(gridRightClicked(int)), this, SLOT(bitfieldRightClicked(int)));
connect(ui->valuesTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomMenuValues(QPoint)));
ui->valuesTable->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->valuesTable, SIGNAL(cellChanged(int,int)), this, SLOT(onValuesCellChanged(int,int)));
@@ -47,18 +49,29 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
[=]()
{
if (currentSignal == nullptr) return;
if (currentSignal->intelByteOrder != ui->cbIntelFormat->isChecked()) dbcFile->setDirtyFlag();
currentSignal->intelByteOrder = ui->cbIntelFormat->isChecked();
fillSignalForm(currentSignal);
if (currentSignal->intelByteOrder != ui->cbIntelFormat->isChecked())
{
dbcFile->setDirtyFlag();
pushToUndoBuffer();
currentSignal->intelByteOrder = ui->cbIntelFormat->isChecked();
//fillSignalForm(currentSignal);
refreshBitGrid();
}
});
connect(ui->comboReceiver, &QComboBox::currentTextChanged,
[=]()
{
if (currentSignal == nullptr) return;
if (inhibitMsgProc) return;
DBC_NODE *node = dbcFile->findNodeByName(ui->comboReceiver->currentText());
if (currentSignal->receiver != node) dbcFile->setDirtyFlag();
currentSignal->receiver = node;
if (currentSignal->receiver != node)
{
dbcFile->setDirtyFlag();
pushToUndoBuffer();
currentSignal->receiver = node;
}
});
connect(ui->comboType, &QComboBox::currentTextChanged,
[=]()
@@ -67,38 +80,66 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
switch (ui->comboType->currentIndex())
{
case 0:
currentSignal->valType = UNSIGNED_INT;
if (currentSignal->valType != UNSIGNED_INT)
{
pushToUndoBuffer();
currentSignal->valType = UNSIGNED_INT;
dbcFile->setDirtyFlag();
fillSignalForm(currentSignal);
}
break;
case 1:
currentSignal->valType = SIGNED_INT;
if (currentSignal->valType != SIGNED_INT)
{
pushToUndoBuffer();
currentSignal->valType = SIGNED_INT;
dbcFile->setDirtyFlag();
fillSignalForm(currentSignal);
}
break;
case 2:
currentSignal->valType = SP_FLOAT;
if (dbcMessage) //if we have a good msg reference we can use it to get the # of bytes expected.
if (currentSignal->valType != SP_FLOAT)
{
int maxBit = ((dbcMessage->len * 8) - 32 + 7);
if (maxBit < 0) maxBit = 0;
if (currentSignal->startBit > maxBit) currentSignal->startBit = maxBit;
pushToUndoBuffer();
currentSignal->valType = SP_FLOAT;
dbcFile->setDirtyFlag();
if (dbcMessage) //if we have a good msg reference we can use it to get the # of bytes expected.
{
int maxBit = ((dbcMessage->len * 8) - 32 + 7);
if (maxBit < 0) maxBit = 0;
if (currentSignal->startBit > maxBit) currentSignal->startBit = maxBit;
}
else if (currentSignal->startBit > 39) currentSignal->startBit = 39;
currentSignal->signalSize = 32;
fillSignalForm(currentSignal);
}
else if (currentSignal->startBit > 39) currentSignal->startBit = 39;
currentSignal->signalSize = 32;
break;
case 3:
currentSignal->valType = DP_FLOAT;
if (dbcMessage)
if (currentSignal->valType != DP_FLOAT)
{
int maxBit = ((dbcMessage->len * 8) - 64 + 7);
if (currentSignal->startBit > maxBit) currentSignal->startBit = maxBit;
pushToUndoBuffer();
currentSignal->valType = DP_FLOAT;
dbcFile->setDirtyFlag();
if (dbcMessage)
{
int maxBit = ((dbcMessage->len * 8) - 64 + 7);
if (currentSignal->startBit > maxBit) currentSignal->startBit = maxBit;
}
else currentSignal->startBit = 7; //has to be!
currentSignal->signalSize = 64;
fillSignalForm(currentSignal);
}
else currentSignal->startBit = 7; //has to be!
currentSignal->signalSize = 64;
break;
case 4:
currentSignal->valType = STRING;
if (currentSignal->valType != STRING)
{
pushToUndoBuffer();
currentSignal->valType = STRING;
dbcFile->setDirtyFlag();
fillSignalForm(currentSignal);
}
break;
}
dbcFile->setDirtyFlag();
fillSignalForm(currentSignal);
});
connect(ui->txtBias, &QLineEdit::editingFinished,
[=]()
@@ -109,8 +150,12 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
temp = ui->txtBias->text().toDouble(&result);
if (result)
{
if (currentSignal->bias != temp) dbcFile->setDirtyFlag();
currentSignal->bias = temp;
if (currentSignal->bias != temp)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->bias = temp;
}
}
});
@@ -123,8 +168,12 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
temp = ui->txtMaxVal->text().toDouble(&result);
if (result)
{
if (currentSignal->max != temp) dbcFile->setDirtyFlag();
currentSignal->max = temp;
if (currentSignal->max != temp)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->max = temp;
}
}
});
@@ -137,10 +186,15 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
temp = ui->txtMinVal->text().toDouble(&result);
if (result)
{
if (currentSignal->min != temp) dbcFile->setDirtyFlag();
currentSignal->min = temp;
if (currentSignal->min != temp)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->min = temp;
}
}
});
connect(ui->txtScale, &QLineEdit::editingFinished,
[=]()
{
@@ -150,26 +204,40 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
temp = ui->txtScale->text().toDouble(&result);
if (result)
{
if (currentSignal->factor != temp) dbcFile->setDirtyFlag();
currentSignal->factor = temp;
if (currentSignal->factor != temp)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->factor = temp;
}
}
});
connect(ui->txtComment, &QLineEdit::editingFinished,
[=]()
{
if (currentSignal == nullptr) return;
if (currentSignal->comment != ui->txtComment->text().simplified().replace(' ','_')) dbcFile->setDirtyFlag();
currentSignal->comment = ui->txtComment->text().simplified().replace(' ', '_');
emit updatedTreeInfo(currentSignal);
if (currentSignal->comment != ui->txtComment->text().simplified().replace(' ','_'))
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->comment = ui->txtComment->text().simplified().replace(' ', '_');
emit updatedTreeInfo(currentSignal);
}
});
connect(ui->txtUnitName, &QLineEdit::editingFinished,
[=]()
{
if (currentSignal == nullptr) return;
if (currentSignal->unitName != ui->txtUnitName->text().simplified().replace(' ','_')) dbcFile->setDirtyFlag();
currentSignal->unitName = ui->txtUnitName->text().simplified().replace(' ', '_');
if (currentSignal->unitName != ui->txtUnitName->text().simplified().replace(' ','_'))
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->unitName = ui->txtUnitName->text().simplified().replace(' ', '_');
}
});
connect(ui->txtBitLength, &QLineEdit::textChanged,
[=]()
{
@@ -182,20 +250,35 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
if (temp > (int)(dbcMessage->len * 8)) return;
}
else if (temp > 64) return;
if (currentSignal->signalSize != temp) dbcFile->setDirtyFlag();
if (currentSignal->valType != SP_FLOAT && currentSignal->valType != DP_FLOAT)
if (currentSignal->valType == SP_FLOAT) temp = 32;
if (currentSignal->valType == DP_FLOAT) temp = 64;
if (currentSignal->signalSize != temp)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->signalSize = temp;
fillSignalForm(currentSignal);
//fillSignalForm(currentSignal);
refreshBitGrid();
}
});
connect(ui->txtName, &QLineEdit::editingFinished,
[=]()
{
if (currentSignal == nullptr) return;
QString tempNameStr = ui->txtName->text().simplified().replace(' ', '_');
if (currentSignal->name != tempNameStr) dbcFile->setDirtyFlag();
if (tempNameStr.length() > 0) currentSignal->name = tempNameStr;
//need to update the tree too.
emit updatedTreeInfo(currentSignal);
if (tempNameStr.length() == 0) return; //can't do that!
if (currentSignal->name != tempNameStr)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->name = tempNameStr;
refreshBitGrid();
//need to update the tree too.
emit updatedTreeInfo(currentSignal);
}
});
connect(ui->txtMultiplexLow, &QLineEdit::editingFinished,
@@ -204,9 +287,13 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
if (currentSignal == nullptr) return;
int temp;
temp = Utility::ParseStringToNum(ui->txtMultiplexLow->text());
if (currentSignal->multiplexLowValue != temp) dbcFile->setDirtyFlag();
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
currentSignal->multiplexLowValue = temp;
if (currentSignal->multiplexLowValue != temp)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
currentSignal->multiplexLowValue = temp;
}
});
connect(ui->txtMultiplexHigh, &QLineEdit::editingFinished,
@@ -215,78 +302,98 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
if (!currentSignal) return;
int temp;
temp = Utility::ParseStringToNum(ui->txtMultiplexHigh->text());
if (currentSignal->multiplexHighValue != temp) dbcFile->setDirtyFlag();
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
currentSignal->multiplexHighValue = temp;
if (currentSignal->multiplexHighValue != temp)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
currentSignal->multiplexHighValue = temp;
}
});
connect(ui->rbExtended, &QRadioButton::toggled,
[=](bool state)
{
if (!currentSignal) return;
if (state && currentSignal) //signal is now set as an extended multiplex/multiplexor
if (!state) return; //we only need to handle the case where it is true
//only do anything if this is different from the current state. It should be because we're in a toggle event but let's be sure
if (!currentSignal->isMultiplexed || !currentSignal->isMultiplexor)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->isMultiplexed = true;
currentSignal->isMultiplexor = true;
//an extended multi signal cannot be the root multiplexor for a message so make sure to remove it if it was.
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
fillSignalForm(currentSignal);
}
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
dbcFile->setDirtyFlag();
});
connect(ui->rbMultiplexed, &QRadioButton::toggled,
[=](bool state)
{
if (!currentSignal) return;
if (state && currentSignal) //signal is now set as a multiplexed signal
if (!state) return; //we only need to handle the case where it is true
//only do anything if this is different from the current state. It should be because we're in a toggle event but let's be sure
if (!currentSignal->isMultiplexed || currentSignal->isMultiplexor)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->isMultiplexed = true;
currentSignal->isMultiplexor = false;
//if the set multiplexor for the message was this signal then clear it
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
fillSignalForm(currentSignal);
}
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
dbcFile->setDirtyFlag();
});
connect(ui->rbMultiplexor, &QRadioButton::toggled,
[=](bool state)
{
if (!currentSignal) return;
if (state && currentSignal) //signal is now set as a multiplexed signal
if (!state) return; //we only need to handle the case where it is true
if (currentSignal->isMultiplexed || !currentSignal->isMultiplexor)
{
//don't allow this signal to be a multiplexor if there is already one for this message.
//if (dbcMessage->multiplexorSignal != currentSignal && dbcMessage->multiplexorSignal != nullptr) return; //I spoke too soon above...
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->isMultiplexed = false;
currentSignal->isMultiplexor = true;
//we just set that this is the multiplexor so update the message to show that as well.
dbcMessage->multiplexorSignal = currentSignal;
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
fillSignalForm(currentSignal);
}
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
dbcFile->setDirtyFlag();
});
connect(ui->rbNotMulti, &QRadioButton::toggled,
[=](bool state)
{
if (!currentSignal) return;
if (state && currentSignal) //signal is now set as a multiplexed signal
if (!state) return; //we only need to handle the case where it is true
if (currentSignal->isMultiplexed || currentSignal->isMultiplexor)
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
currentSignal->isMultiplexed = false;
currentSignal->isMultiplexor = false;
if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
fillSignalForm(currentSignal);
}
ui->txtMultiplexLow->setEnabled(currentSignal->isMultiplexed);
ui->txtMultiplexHigh->setEnabled(currentSignal->isMultiplexed);
ui->cbMultiplexParent->setEnabled(currentSignal->isMultiplexed);
dbcFile->setDirtyFlag();
});
connect(ui->cbMultiplexParent, &QComboBox::textActivated,
@@ -294,17 +401,20 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
{
if (currentSignal == nullptr) return;
if (inhibitMsgProc) return;
//qDebug() << "Curr text: :" << ui->cbMultiplexParent->currentText();
//try to look up the signal that we're set to now, remove this signal from existing children list
//add it to this one, update this signal's parent multiplexor
DBC_SIGNAL *newSig = dbcMessage->sigHandler->findSignalByName(ui->cbMultiplexParent->currentText());
DBC_SIGNAL *oldParent = currentSignal->multiplexParent;
if (newSig && oldParent)
if (newSig && oldParent && (newSig != oldParent))
{
pushToUndoBuffer();
dbcFile->setDirtyFlag();
oldParent->multiplexedChildren.removeOne(currentSignal);
currentSignal->multiplexParent = newSig;
newSig->multiplexedChildren.append(currentSignal);
dbcFile->setDirtyFlag();
refreshBitGrid();
emit updatedTreeInfo(currentSignal);
}
});
@@ -333,6 +443,12 @@ bool DBCSignalEditor::eventFilter(QObject *obj, QEvent *event)
case Qt::Key_F1:
HelpWindow::getRef()->showHelp("signaleditor.md");
break;
case Qt::Key_Z:
if (keyEvent->modifiers() == Qt::ControlModifier)
{
popFromUndoBuffer();
}
break;
}
return true;
} else {
@@ -392,18 +508,6 @@ void DBCSignalEditor::showEvent(QShowEvent* event)
fillSignalForm(currentSignal);
fillValueTable(currentSignal);
ui->bitfield->clearSignalNames();
for (int x = 0; x < dbcMessage->sigHandler->getCount(); x++)
{
DBC_SIGNAL *sig = dbcMessage->sigHandler->findSignalByIdx(x);
//only set a signal name for signals which match multiplexparent with our currentsignal
if (!sig->multiplexParent || ((sig->multiplexParent == currentSignal->multiplexParent) && (sig->multiplexHighValue == currentSignal->multiplexHighValue)) )
{
ui->bitfield->setSignalNames(x, sig->name);
qDebug() << sig->name << sig->multiplexParent;
}
}
}
void DBCSignalEditor::refreshView()
@@ -467,12 +571,14 @@ void DBCSignalEditor::deleteCurrentValue()
/* WARNING: fillSignalForm can be called recursively since it is in the listener of cbIntelFormat */
void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
{
unsigned char bitpattern[64];
//sanity checks
if (!dbcMessage) return;
if (!dbcMessage->sigHandler) return;
inhibitMsgProc = true;
if (sig == nullptr) {
ui->groupBox->setEnabled(false);
//ui->groupBox->setEnabled(false);
ui->txtName->setText("");
ui->txtBias->setText("");
ui->txtBitLength->setText("");
@@ -486,9 +592,6 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
ui->rbMultiplexed->setChecked(false);
ui->rbMultiplexor->setChecked(false);
ui->rbNotMulti->setChecked(true);
memset(bitpattern, 0, 64); //clear it out
ui->bitfield->setReference(bitpattern, false);
ui->bitfield->updateData(bitpattern, true);
ui->comboReceiver->setCurrentIndex(0);
ui->comboType->setCurrentIndex(0);
inhibitMsgProc = false;
@@ -496,9 +599,8 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
}
/* we have a signal */
ui->groupBox->setEnabled(true);
//ui->groupBox->setEnabled(true);
generateUsedBits();
ui->txtName->setText(sig->name);
ui->txtBias->setText(QString::number(sig->bias));
ui->txtBitLength->setText(QString::number(sig->signalSize));
@@ -532,7 +634,9 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
DBC_SIGNAL *sig_iter = dbcMessage->sigHandler->findSignalByIdx(i);
if (sig_iter && sig_iter->isMultiplexor && (sig_iter != sig))
{
ui->cbMultiplexParent->addItem(sig_iter->name);
//only add this entry if there are no other entries with that name yet
if (ui->cbMultiplexParent->findText(sig_iter->name) == -1)
ui->cbMultiplexParent->addItem(sig_iter->name);
if (sig->multiplexParent == sig_iter) ui->cbMultiplexParent->setCurrentIndex(ui->cbMultiplexParent->count() - 1);
}
}
@@ -541,42 +645,6 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
ui->txtMultiplexHigh->setEnabled(sig->isMultiplexed);
ui->cbMultiplexParent->setEnabled(sig->isMultiplexed);
memset(bitpattern, 0, 64); //clear it out first.
int startBit, endBit;
startBit = sig->startBit;
bitpattern[startBit / 8] |= 1 << (startBit % 8); //make the start bit a different color to set it apart
ui->bitfield->setReference(bitpattern, false);
if (sig->intelByteOrder)
{
endBit = startBit + sig->signalSize - 1;
if (startBit < 0) startBit = 0;
if (endBit > 511) endBit = 511;
for (int y = startBit; y <= endBit; y++)
{
int byt = y / 8;
bitpattern[byt] |= 1 << (y % 8);
}
}
else //big endian / motorola format
{
//much more irritating than the intel version...
int size = sig->signalSize;
while (size > 0)
{
int byt = startBit / 8;
bitpattern[byt] |= 1 << (startBit % 8);
size--;
if ((startBit % 8) == 0) startBit += 15;
else startBit--;
if (startBit > 511) startBit = 511;
}
}
ui->bitfield->updateData(bitpattern, true);
ui->cbIntelFormat->setChecked(sig->intelByteOrder);
switch (sig->valType)
@@ -607,9 +675,71 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
}
}
refreshBitGrid();
inhibitMsgProc = false;
}
void DBCSignalEditor::refreshBitGrid()
{
unsigned char bitpattern[64];
memset(bitpattern, 0, 64); //clear it out
ui->bitfield->setReference(bitpattern, false);
ui->bitfield->updateData(bitpattern, true);
ui->bitfield->clearSignalNames();
for (int x = 0; x < dbcMessage->sigHandler->getCount(); x++)
{
DBC_SIGNAL *sig = dbcMessage->sigHandler->findSignalByIdx(x);
//only set a signal name for signals which match multiplexparent with our currentsignal
if (!sig->multiplexParent || ((sig->multiplexParent == currentSignal->multiplexParent) && (sig->multiplexHighValue == currentSignal->multiplexHighValue)) )
{
ui->bitfield->setSignalNames(x, sig->name);
//qDebug() << sig->name << sig->multiplexParent;
}
}
generateUsedBits();
memset(bitpattern, 0, 64); //clear it out first.
int startBit, endBit;
startBit = currentSignal->startBit;
bitpattern[startBit / 8] |= 1 << (startBit % 8); //make the start bit a different color to set it apart
ui->bitfield->setReference(bitpattern, false);
if (currentSignal->intelByteOrder)
{
endBit = startBit + currentSignal->signalSize - 1;
if (startBit < 0) startBit = 0;
if (endBit > 511) endBit = 511;
for (int y = startBit; y <= endBit; y++)
{
int byt = y / 8;
bitpattern[byt] |= 1 << (y % 8);
}
}
else //big endian / motorola format
{
//much more irritating than the intel version...
int size = currentSignal->signalSize;
while (size > 0)
{
int byt = startBit / 8;
bitpattern[byt] |= 1 << (startBit % 8);
size--;
if ((startBit % 8) == 0) startBit += 15;
else startBit--;
if (startBit > 511) startBit = 511;
}
}
ui->bitfield->updateData(bitpattern, true);
}
/* fillValueTable also handles "enabled" state */
void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig)
{
@@ -644,9 +774,12 @@ void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig)
inhibitCellChanged = false;
}
void DBCSignalEditor::bitfieldClicked(int bit)
//Left clicking the grid sets the "starting bit" for the current signal
void DBCSignalEditor::bitfieldLeftClicked(int bit)
{
if (currentSignal == nullptr) return;
pushToUndoBuffer();
currentSignal->startBit = bit;
if (currentSignal->valType == SP_FLOAT)
{
@@ -672,6 +805,28 @@ void DBCSignalEditor::bitfieldClicked(int bit)
fillSignalForm(currentSignal);
}
//Right clicking the grid starts editing on whichever signal currently "owns" that bit.
//If there is no other signal then nothing happens (right now).
//Would be possible to create a new signal in that case
void DBCSignalEditor::bitfieldRightClicked(int bit)
{
//will return -1 if there is no signal there. Otherwise, returns signal number
//which is quite luckily also the index into the signal handler table
int sigNum = ui->bitfield->getUsedSignalNum(bit);
if (sigNum < 0) return;
pushToUndoBuffer(); // undo to resume editing the previous signal
currentSignal = dbcMessage->sigHandler->findSignalByIdx(sigNum);
if (currentSignal)
{
fillSignalForm(currentSignal);
fillValueTable(currentSignal);
}
}
void DBCSignalEditor::generateUsedBits()
{
uint8_t usedBits[64];
@@ -728,3 +883,33 @@ void DBCSignalEditor::generateUsedBits()
ui->bitfield->setUsed(usedBits, false);
ui->bitfield->setBytesToDraw(dbcMessage->len);
}
//Copy the current signal in its entirety to the undo buffer. Just for safe keeping
//Called before an edit is done to save the state so we can revert if necessary
void DBCSignalEditor::pushToUndoBuffer()
{
if (!currentSignal) return;
//store a copy of the pointer so that if we need to pop we can pop to the proper place
currentSignal->self = currentSignal;
undoBuffer.append(*currentSignal); //save the whole thing
qDebug() << "Pushing to undo buffer";
}
//Pop the last copy of a signal from the stack and begin editing it
void DBCSignalEditor::popFromUndoBuffer()
{
if (undoBuffer.empty())
{
dbcFile->clearDirtyFlag(); //TODO: Don't do this. Implement per-item dirty flags.
qDebug() << "Undo buffer empty";
return; //can't pop if there are no stored entries!
}
qDebug() << "Popping undo buffer";
DBC_SIGNAL sig = undoBuffer.back();
undoBuffer.pop_back();
currentSignal = sig.self; //restore the pointer
*currentSignal = sig; //write the contents into the memory pointed to
fillSignalForm(currentSignal);
fillValueTable(currentSignal);
}
+6 -1
View File
@@ -26,7 +26,8 @@ signals:
void updatedTreeInfo(DBC_SIGNAL *sig);
private slots:
void bitfieldClicked(int bit);
void bitfieldLeftClicked(int bit);
void bitfieldRightClicked(int bit);
void onValuesCellChanged(int row,int col);
void onCustomMenuValues(QPoint);
void deleteCurrentValue();
@@ -36,6 +37,7 @@ private:
DBCHandler *dbcHandler;
DBC_MESSAGE *dbcMessage;
DBC_SIGNAL *currentSignal;
QList<DBC_SIGNAL> undoBuffer;
DBCFile *dbcFile;
bool inhibitCellChanged;
bool inhibitMsgProc;
@@ -43,11 +45,14 @@ private:
void fillSignalForm(DBC_SIGNAL *sig);
void fillValueTable(DBC_SIGNAL *sig);
void generateUsedBits();
void refreshBitGrid();
void closeEvent(QCloseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
void readSettings();
void writeSettings();
void pushToUndoBuffer();
void popFromUndoBuffer();
};
#endif // DBCSIGNALEDITOR_H