Add ability to load Tesla ODIN JSON files. Where will you get such a
file? State secret.
This commit is contained in:
@@ -8,6 +8,9 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "connections/canconmanager.h"
|
#include "connections/canconmanager.h"
|
||||||
|
|
||||||
@@ -1376,6 +1379,7 @@ int DBCHandler::createBlankFile()
|
|||||||
//add our custom attributes to the new file so that we know they're already there.
|
//add our custom attributes to the new file so that we know they're already there.
|
||||||
attr.attrType = MESSAGE;
|
attr.attrType = MESSAGE;
|
||||||
attr.defaultValue = QApplication::palette().color(QPalette::Base).name();
|
attr.defaultValue = QApplication::palette().color(QPalette::Base).name();
|
||||||
|
qDebug() << attr.defaultValue;
|
||||||
attr.enumVals.clear();
|
attr.enumVals.clear();
|
||||||
attr.lower = 0;
|
attr.lower = 0;
|
||||||
attr.upper = 0;
|
attr.upper = 0;
|
||||||
@@ -1385,6 +1389,7 @@ int DBCHandler::createBlankFile()
|
|||||||
|
|
||||||
attr.attrType = MESSAGE;
|
attr.attrType = MESSAGE;
|
||||||
attr.defaultValue = QApplication::palette().color(QPalette::WindowText).name();
|
attr.defaultValue = QApplication::palette().color(QPalette::WindowText).name();
|
||||||
|
qDebug() << attr.defaultValue;
|
||||||
attr.enumVals.clear();
|
attr.enumVals.clear();
|
||||||
attr.lower = 0;
|
attr.lower = 0;
|
||||||
attr.upper = 0;
|
attr.upper = 0;
|
||||||
@@ -1401,6 +1406,11 @@ int DBCHandler::createBlankFile()
|
|||||||
attr.valType = QINT;
|
attr.valType = QINT;
|
||||||
newFile.dbc_attributes.append(attr);
|
newFile.dbc_attributes.append(attr);
|
||||||
|
|
||||||
|
DBC_NODE falseNode;
|
||||||
|
falseNode.name = "Vector__XXX";
|
||||||
|
falseNode.comment = "Default node if none specified";
|
||||||
|
newFile.dbc_nodes.append(falseNode);
|
||||||
|
|
||||||
loadedFiles.append(newFile);
|
loadedFiles.append(newFile);
|
||||||
return loadedFiles.count();
|
return loadedFiles.count();
|
||||||
}
|
}
|
||||||
@@ -1440,6 +1450,178 @@ DBCFile* DBCHandler::loadDBCFile(int idx)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBCFile* DBCHandler::loadJSONFile(int idx)
|
||||||
|
{
|
||||||
|
if (idx > -1 && idx < loadedFiles.count()) removeDBCFile(idx);
|
||||||
|
|
||||||
|
QString filename;
|
||||||
|
QFileDialog dialog;
|
||||||
|
QSettings settings;
|
||||||
|
DBCFile *thisFile;
|
||||||
|
DBC_MESSAGE *pMsg;
|
||||||
|
|
||||||
|
QStringList filters;
|
||||||
|
filters.append(QString(tr("JSON File (*.json *.JSON)")));
|
||||||
|
|
||||||
|
dialog.setDirectory(settings.value("DBC/LoadSaveDirectory", dialog.directory().path()).toString());
|
||||||
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||||
|
dialog.setNameFilters(filters);
|
||||||
|
dialog.setViewMode(QFileDialog::Detail);
|
||||||
|
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
filename = dialog.selectedFiles()[0];
|
||||||
|
//right now there is only one file type that can be loaded here so just do it.
|
||||||
|
createBlankFile();
|
||||||
|
thisFile = &loadedFiles.last();
|
||||||
|
QFile *inFile = new QFile(filename);
|
||||||
|
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
|
qDebug() << "Could not open JSON file for reading.";
|
||||||
|
delete inFile;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
QByteArray wholeFileData = inFile->readAll();
|
||||||
|
inFile->close();
|
||||||
|
delete inFile;
|
||||||
|
//qDebug() << "Data Length: " << wholeFileData.length();
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(wholeFileData);
|
||||||
|
if (jsonDoc.isNull())
|
||||||
|
{
|
||||||
|
qDebug() << "Couldn't load the json file, shit the bed, don't know why I did it.";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
qDebug() << "Loaded JSON";
|
||||||
|
|
||||||
|
QJsonObject jsonObj = jsonDoc.object();
|
||||||
|
QJsonObject jsonMessages = jsonObj["messages"].toObject();
|
||||||
|
|
||||||
|
QJsonObject::iterator iter;
|
||||||
|
for (iter = jsonMessages.begin(); iter != jsonMessages.end(); iter++)
|
||||||
|
{
|
||||||
|
qDebug() << iter.key();
|
||||||
|
DBC_MESSAGE msg;
|
||||||
|
msg.ID = static_cast<uint32_t>(iter->toObject().find("origin_id").value().toInt());
|
||||||
|
msg.name = QString(iter.key().toUtf8());
|
||||||
|
msg.len = static_cast<unsigned int>(iter->toObject().find("length_bytes").value().toInt());
|
||||||
|
msg.sender = thisFile->findNodeByIdx(0);
|
||||||
|
QString nodeName = iter->toObject().find("originNode").value().toString();
|
||||||
|
msg.sender = thisFile->findNodeByName(nodeName);
|
||||||
|
msg.bgColor = QColor();
|
||||||
|
msg.fgColor = QColor();
|
||||||
|
if (!msg.sender && nodeName.length() > 1)
|
||||||
|
{
|
||||||
|
DBC_NODE node;
|
||||||
|
node.name = nodeName;
|
||||||
|
thisFile->dbc_nodes.append(node);
|
||||||
|
msg.sender = thisFile->findNodeByName(nodeName);
|
||||||
|
}
|
||||||
|
if (nodeName.length() < 2) msg.sender = thisFile->findNodeByIdx(0);
|
||||||
|
thisFile->messageHandler->addMessage(msg);
|
||||||
|
pMsg = thisFile->messageHandler->findMsgByID(msg.ID);
|
||||||
|
if (!pMsg)
|
||||||
|
{
|
||||||
|
qDebug() << "pMsg was null... I have no idea how that is possible. DEBUG ME";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject jsonSigs = iter->toObject().find("signals").value().toObject();
|
||||||
|
QJsonObject::iterator sigIter;
|
||||||
|
for (sigIter = jsonSigs.begin(); sigIter != jsonSigs.end(); sigIter++)
|
||||||
|
{
|
||||||
|
qDebug() << sigIter.key();
|
||||||
|
DBC_SIGNAL sig;
|
||||||
|
QJsonObject sigObj = sigIter->toObject();
|
||||||
|
if (sigObj.isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "EMPTY!?";
|
||||||
|
}
|
||||||
|
sig.name = QString(sigIter.key().toUtf8());
|
||||||
|
sig.factor = sigObj.find("scale").value().toDouble();
|
||||||
|
sig.bias = sigObj.find("offset").value().toDouble();
|
||||||
|
sig.max = sigObj.find("max").value().toInt();
|
||||||
|
sig.min = sigObj.find("min").value().toInt();
|
||||||
|
sig.startBit = sigObj.find("start_position").value().toInt();
|
||||||
|
sig.unitName = sigObj.find("units").value().toString();
|
||||||
|
sig.signalSize = sigObj.find("width").value().toInt();
|
||||||
|
sig.isMultiplexed = false;
|
||||||
|
sig.isMultiplexor = false;
|
||||||
|
sig.parentMessage = pMsg;
|
||||||
|
if (!sigObj.find("mux_id")->isUndefined())
|
||||||
|
{
|
||||||
|
QJsonValue muxVal = sigObj.find("mux_id").value();
|
||||||
|
sig.multiplexValue = muxVal.toInt();
|
||||||
|
sig.isMultiplexed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sig.multiplexValue = 0;
|
||||||
|
}
|
||||||
|
QJsonValue muxerVal = sigObj.find("is_muxer").value();
|
||||||
|
if (!muxerVal.isNull())
|
||||||
|
{
|
||||||
|
if (muxerVal.toBool())
|
||||||
|
{
|
||||||
|
sig.isMultiplexor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject valuesObj = sigObj.find("value_description")->toObject();
|
||||||
|
if (!valuesObj.isEmpty())
|
||||||
|
{
|
||||||
|
QJsonObject::iterator valIter;
|
||||||
|
for (valIter = valuesObj.begin(); valIter != valuesObj.end(); valIter++)
|
||||||
|
{
|
||||||
|
DBC_VAL_ENUM_ENTRY valEnum;
|
||||||
|
valEnum.value = valIter.value().toInt();
|
||||||
|
valEnum.descript = valIter.key().toUtf8();
|
||||||
|
sig.valList.append(valEnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonArray rxArray = sigObj.find("receivers")->toArray();
|
||||||
|
if (rxArray.size() < 1) sig.receiver = thisFile->findNodeByIdx(0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << rxArray[0].toString();
|
||||||
|
sig.receiver = thisFile->findNodeByName(rxArray[0].toString());
|
||||||
|
if (!sig.receiver && rxArray[0].toString().length() > 1)
|
||||||
|
{
|
||||||
|
DBC_NODE node;
|
||||||
|
node.name = rxArray[0].toString();
|
||||||
|
thisFile->dbc_nodes.append(node);
|
||||||
|
sig.receiver = thisFile->findNodeByName(rxArray[0].toString());
|
||||||
|
}
|
||||||
|
if (!sig.receiver) sig.receiver = thisFile->findNodeByIdx(0);
|
||||||
|
}
|
||||||
|
if (!sigObj.find("endianness").value().toString().compare("BIG"))
|
||||||
|
{
|
||||||
|
sig.intelByteOrder = false;
|
||||||
|
}
|
||||||
|
else sig.intelByteOrder = true;
|
||||||
|
|
||||||
|
if (!sigObj.find("signedness").value().toString().compare("UNSIGNED"))
|
||||||
|
{
|
||||||
|
sig.valType = DBC_SIG_VAL_TYPE::UNSIGNED_INT;
|
||||||
|
}
|
||||||
|
else sig.valType = DBC_SIG_VAL_TYPE::SIGNED_INT;
|
||||||
|
|
||||||
|
pMsg->sigHandler->addSignal(sig);
|
||||||
|
if (sig.isMultiplexor) //if this signal was the multiplexor then store that info
|
||||||
|
{
|
||||||
|
DBC_SIGNAL *pSig = pMsg->sigHandler->findSignalByName(sig.name);
|
||||||
|
if (pSig) pMsg->multiplexorSignal = pSig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.setValue("DBC/LoadSaveDirectory", dialog.directory().path());
|
||||||
|
return thisFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void DBCHandler::removeDBCFile(int idx)
|
void DBCHandler::removeDBCFile(int idx)
|
||||||
{
|
{
|
||||||
if (loadedFiles.count() == 0) return;
|
if (loadedFiles.count() == 0) return;
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ public:
|
|||||||
DBCFile* getFileByIdx(int idx);
|
DBCFile* getFileByIdx(int idx);
|
||||||
DBCFile* getFileByName(QString name);
|
DBCFile* getFileByName(QString name);
|
||||||
int createBlankFile();
|
int createBlankFile();
|
||||||
|
DBCFile* loadJSONFile(int);
|
||||||
static DBCHandler *getReference();
|
static DBCHandler *getReference();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ DBCLoadSaveWindow::DBCLoadSaveWindow(const QVector<CANFrame> *frames, QWidget *p
|
|||||||
connect(ui->btnNewDBC, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::newFile);
|
connect(ui->btnNewDBC, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::newFile);
|
||||||
connect(ui->tableFiles, &QTableWidget::cellChanged, this, &DBCLoadSaveWindow::cellChanged);
|
connect(ui->tableFiles, &QTableWidget::cellChanged, this, &DBCLoadSaveWindow::cellChanged);
|
||||||
connect(ui->tableFiles, &QTableWidget::cellDoubleClicked, this, &DBCLoadSaveWindow::cellDoubleClicked);
|
connect(ui->tableFiles, &QTableWidget::cellDoubleClicked, this, &DBCLoadSaveWindow::cellDoubleClicked);
|
||||||
|
connect(ui->btnLoadJSON, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::loadJSON);
|
||||||
|
|
||||||
editorWindow = new DBCMainEditor(frames, this);
|
editorWindow = new DBCMainEditor(frames, this);
|
||||||
currentlyEditingFile = nullptr;
|
currentlyEditingFile = nullptr;
|
||||||
@@ -101,6 +102,28 @@ void DBCLoadSaveWindow::loadFile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DBCLoadSaveWindow::loadJSON()
|
||||||
|
{
|
||||||
|
DBCFile *file = dbcHandler->loadJSONFile(-1);
|
||||||
|
if(file) {
|
||||||
|
int idx = ui->tableFiles->rowCount();
|
||||||
|
ui->tableFiles->insertRow(ui->tableFiles->rowCount());
|
||||||
|
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
|
||||||
|
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
|
||||||
|
DBC_ATTRIBUTE *attr = file->findAttributeByName("isj1939dbc");
|
||||||
|
QTableWidgetItem *item = new QTableWidgetItem("");
|
||||||
|
ui->tableFiles->setItem(idx, 2, item);
|
||||||
|
if (attr && attr->defaultValue > 0)
|
||||||
|
{
|
||||||
|
item->setCheckState(Qt::Checked);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->setCheckState(Qt::Unchecked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DBCLoadSaveWindow::saveFile()
|
void DBCLoadSaveWindow::saveFile()
|
||||||
{
|
{
|
||||||
int idx = ui->tableFiles->currentRow();
|
int idx = ui->tableFiles->currentRow();
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void loadFile();
|
void loadFile();
|
||||||
|
void loadJSON();
|
||||||
void saveFile();
|
void saveFile();
|
||||||
void removeFile();
|
void removeFile();
|
||||||
void moveUp();
|
void moveUp();
|
||||||
|
|||||||
@@ -522,9 +522,12 @@ void DBCMainEditor::refreshMessagesTable(const DBC_NODE *node)
|
|||||||
QTableWidgetItem *msgLen = new QTableWidgetItem(QString::number(msg->len));
|
QTableWidgetItem *msgLen = new QTableWidgetItem(QString::number(msg->len));
|
||||||
QTableWidgetItem *msgSignals = new QTableWidgetItem(QString::number(msg->sigHandler->getCount()));
|
QTableWidgetItem *msgSignals = new QTableWidgetItem(QString::number(msg->sigHandler->getCount()));
|
||||||
QTableWidgetItem *fgColor = new QTableWidgetItem("");
|
QTableWidgetItem *fgColor = new QTableWidgetItem("");
|
||||||
fgColor->setBackgroundColor(msg->fgColor);
|
if (msg->fgColor.isValid()) fgColor->setBackgroundColor(msg->fgColor);
|
||||||
|
else fgColor->setBackgroundColor(QColor(dbcFile->findAttributeByName("GenMsgForegroundColor")->defaultValue.toString()));
|
||||||
QTableWidgetItem *bgColor = new QTableWidgetItem("");
|
QTableWidgetItem *bgColor = new QTableWidgetItem("");
|
||||||
bgColor->setBackgroundColor(msg->bgColor);
|
if (msg->bgColor.isValid()) bgColor->setBackgroundColor(msg->bgColor);
|
||||||
|
else bgColor->setBackgroundColor(QColor(dbcFile->findAttributeByName("GenMsgBackgroundColor")->defaultValue.toString()));
|
||||||
|
|
||||||
QTableWidgetItem *msgComment = new QTableWidgetItem(msg->comment);
|
QTableWidgetItem *msgComment = new QTableWidgetItem(msg->comment);
|
||||||
|
|
||||||
rowIdx = ui->MessagesTable->rowCount();
|
rowIdx = ui->MessagesTable->rowCount();
|
||||||
|
|||||||
@@ -24,6 +24,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnLoadJSON">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load Tesla JSON (shhhh....)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
Reference in New Issue
Block a user