Vast reworking of DBC editing system.

Currently not functional but the overall graphical layout is more or less complete.
This commit is contained in:
Collin Kidder
2020-07-19 20:29:14 -04:00
parent 067292108d
commit fc6dc4ea55
32 changed files with 462 additions and 524 deletions
+15
View File
@@ -97,3 +97,18 @@ when you installed Qt.
### What to do if `qmake` fails with error `Project ERROR: Unknown module(s) in QT: qml serialbus help` on Ubuntu? :
`sudo apt install libqt5serialbus5-dev qtdeclarative5-dev qttools5-dev`
### Used Items Requiring Attribution
nodes by Adrien Coquet from the Noun Project
message by Vectorstall from the Noun Project
signal by shashank singh from the Noun Project
signal by juli from the Noun Project
signal by yudi from the Noun Project
Death by Adrien Coquet from the Noun Project
+5 -2
View File
@@ -15,7 +15,7 @@ DEFINES += QCUSTOMPLOT_USE_OPENGL
TARGET = SavvyCAN
TEMPLATE = app
SOURCES += main.cpp\
SOURCES += main.cpp\
mainwindow.cpp \
canframemodel.cpp \
utility.cpp \
@@ -39,6 +39,7 @@ SOURCES += main.cpp\
re/sniffer/snifferitem.cpp \
re/sniffer/sniffermodel.cpp \
re/sniffer/snifferwindow.cpp \
dbc/dbcmessageeditor.cpp \
dbc/dbc_classes.cpp \
dbc/dbchandler.cpp \
dbc/dbcloadsavewindow.cpp \
@@ -73,7 +74,7 @@ SOURCES += main.cpp\
HEADERS += mainwindow.h \
can_structs.h \
canframemodel.h \
canframemodel.h \
utility.h \
qcustomplot.h \
frameplaybackwindow.h \
@@ -103,6 +104,7 @@ HEADERS += mainwindow.h \
dbc/dbcloadsavewindow.h \
dbc/dbcmaineditor.h \
dbc/dbcsignaleditor.h \
dbc/dbcmessageeditor.h \
re/discretestatewindow.h \
re/filecomparatorwindow.h \
re/flowviewwindow.h \
@@ -132,6 +134,7 @@ HEADERS += mainwindow.h \
filterutility.h
FORMS += ui/candatagrid.ui \
ui/dbcmessageeditor.ui \
ui/connectionwindow.ui \
ui/dbcloadsavewindow.ui \
ui/dbcmaineditor.ui \
+104 -346
View File
@@ -20,41 +20,30 @@ DBCMainEditor::DBCMainEditor( const QVector<CANFrame> *frames, QWidget *parent)
dbcHandler = DBCHandler::getReference();
referenceFrames = frames;
QStringList headers;
headers << "Node Name" << "Comment";
ui->NodesTable->setColumnCount(2);
ui->NodesTable->setColumnWidth(0, 240);
ui->NodesTable->setColumnWidth(1, 700);
ui->NodesTable->setHorizontalHeaderLabels(headers);
ui->NodesTable->horizontalHeader()->setStretchLastSection(true);
QStringList headers2;
headers2 << "Msg ID" << "Msg Name" << "Data Len" << "Signals" << "Fg" << "Bg" << "Comment";
ui->MessagesTable->setColumnCount(headers2.count());
ui->MessagesTable->setColumnWidth(0, 80);
ui->MessagesTable->setColumnWidth(1, 200);
ui->MessagesTable->setColumnWidth(2, 80);
ui->MessagesTable->setColumnWidth(3, 80);
ui->MessagesTable->setColumnWidth(4, 40);
ui->MessagesTable->setColumnWidth(5, 40);
ui->MessagesTable->setColumnWidth(6, 300);
ui->MessagesTable->setHorizontalHeaderLabels(headers2);
ui->MessagesTable->horizontalHeader()->setStretchLastSection(true);
connect(ui->NodesTable, SIGNAL(cellChanged(int,int)), this, SLOT(onCellChangedNode(int,int)));
connect(ui->NodesTable, SIGNAL(cellClicked(int,int)), this, SLOT(onCellClickedNode(int,int)));
connect(ui->NodesTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomMenuNode(QPoint)));
ui->NodesTable->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->MessagesTable, SIGNAL(cellChanged(int,int)), this, SLOT(onCellChangedMessage(int,int)));
connect(ui->MessagesTable, SIGNAL(cellClicked(int,int)), this, SLOT(onCellClickedMessage(int,int)));
connect(ui->MessagesTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomMenuMessage(QPoint)));
ui->MessagesTable->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->btnSearch, &QAbstractButton::clicked, this, &DBCMainEditor::handleSearch);
connect(ui->lineSearch, &QLineEdit::returnPressed, this, &DBCMainEditor::handleSearch);
connect(ui->treeDBC, &QTreeWidget::doubleClicked, this, &DBCMainEditor::onTreeDoubleClicked);
sigEditor = new DBCSignalEditor(this);
msgEditor = new DBCMessageEditor(this);
nodeIcon = QIcon(":/icons/images/node.png");
messageIcon = QIcon(":/icons/images/message.png");
signalIcon = QIcon(":/icons/images/signal.png");
multiplexedSignalIcon = QIcon(":/icons/images/multiplexed-signal.png");
multiplexorSignalIcon = QIcon(":/icons/images/multiplexor-signal.png");
//ui->btnDelete->setFixedSize(32,32);
ui->btnDelete->setIconSize(QSize(32, 32));
//ui->btnNewNode->setFixedSize(32,32);
ui->btnNewNode->setIconSize(QSize(32, 32));
//ui->btnNewMessage->setFixedSize(32,32);
ui->btnNewMessage->setIconSize(QSize(32, 32));
//ui->btnNewSignal->setFixedSize(32,32);
ui->btnNewSignal->setIconSize(QSize(32, 32));
installEventFilter(this);
}
@@ -63,13 +52,7 @@ void DBCMainEditor::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
inhibitCellChanged = true;
refreshNodesTable();
if (dbcFile->dbc_nodes.count() > 0)
refreshMessagesTable(&dbcFile->dbc_nodes.at(0));
currRow = 0;
inhibitCellChanged = false;
refreshTree();
}
DBCMainEditor::~DBCMainEditor()
@@ -132,30 +115,20 @@ void DBCMainEditor::writeSettings()
}
}
void DBCMainEditor::onCustomMenuNode(QPoint point)
{
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->addAction(tr("Delete currently selected node"), this, SLOT(deleteCurrentNode()));
menu->popup(ui->NodesTable->mapToGlobal(point));
}
void DBCMainEditor::onCustomMenuMessage(QPoint point)
void DBCMainEditor::onCustomMenuTree(QPoint point)
{
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->addAction(tr("Delete currently selected message"), this, SLOT(deleteCurrentMessage()));
menu->popup(ui->MessagesTable->mapToGlobal(point));
//menu->popup(ui->MessagesTable->mapToGlobal(point));
}
void DBCMainEditor::deleteCurrentNode()
void DBCMainEditor::deleteCurrentTreeItem()
{
/*
int thisRow = ui->NodesTable->currentRow();
QTableWidgetItem* thisItem = ui->NodesTable->item(thisRow, 0);
if (!thisItem) return;
@@ -168,11 +141,12 @@ void DBCMainEditor::deleteCurrentNode()
refreshMessagesTable(&dbcFile->dbc_nodes[0]);
ui->NodesTable->selectRow(0);
inhibitCellChanged = false;
}
} */
}
void DBCMainEditor::deleteCurrentMessage()
{
//void DBCMainEditor::deleteCurrentMessage()
//{
/*
int thisRow = ui->MessagesTable->currentRow();
QTableWidgetItem* thisItem = ui->MessagesTable->item(thisRow, 0);
if (!thisItem) return;
@@ -181,10 +155,12 @@ void DBCMainEditor::deleteCurrentMessage()
ui->MessagesTable->removeRow(thisRow);
dbcFile->messageHandler->removeMessageByIndex(thisRow);
}
}
*/
//}
void DBCMainEditor::handleSearch()
{
/*
uint32_t msgId = Utility::ParseStringToNum(ui->lineSearch->text());
if (ui->radioID->isChecked())
{
@@ -255,228 +231,50 @@ void DBCMainEditor::handleSearch()
}
}
}
}
} */
}
void DBCMainEditor::onCellChangedNode(int row,int col)
//Double clicking is interpreted as a desire to edit the given item.
void DBCMainEditor::onTreeDoubleClicked(const QModelIndex &index)
{
if (inhibitCellChanged) return;
if (row == ui->NodesTable->rowCount() - 1)
{
//if this was the last row then it's new and we need to both
//create another potentially new record underneath and also
//add a node entry in the nodes list and store the record
//That is, so long as the node name was filled out
if (col == 0)
{
DBC_NODE newNode;
QString newName = ui->NodesTable->item(row, col)->text().simplified().replace(' ', '_');
qDebug() << "new name: " << newName;
if (newName.length() == 0) return;
if (dbcFile->findNodeByName(newName) != nullptr) //duplicates an existing node!
{
QMessageBox msg;
msg.setParent(nullptr);
msg.setText("An existing node with that name already exists! Aborting!");
msg.exec();
return;
}
newNode.name = newName;
dbcFile->dbc_nodes.append(newNode);
qDebug() << "# of nodes now " << dbcFile->dbc_nodes.count();
QTableWidgetItem *widgetName = new QTableWidgetItem(newName);
inhibitCellChanged = true;
ui->NodesTable->setItem(row, col, widgetName);
ui->NodesTable->insertRow(ui->NodesTable->rowCount());
inhibitCellChanged = false;
}
}
else
{
if (col == 0)
{
DBC_NODE *oldNode = dbcFile->findNodeByIdx(row);
QString nodeName = ui->NodesTable->item(row, col)->text().simplified().replace(' ', '_');
if (oldNode == nullptr) return;
if (row != 0) oldNode->name = nodeName;
else nodeName = oldNode->name;
inhibitCellChanged = true;
QTableWidgetItem *widgetName = new QTableWidgetItem(nodeName);
ui->NodesTable->setItem(row, col, widgetName);
inhibitCellChanged = false;
}
if (col == 1) //must have been col 1 then
{
QString nodeName = ui->NodesTable->item(row, 0)->text().simplified().replace(' ', '_');
qDebug() << "searching for node " << nodeName;
DBC_NODE *thisNode = dbcFile->findNodeByName(nodeName);
if (thisNode == nullptr) return;
thisNode->comment = ui->NodesTable->item(row, col)->text().simplified();
qDebug() << "New comment: " << thisNode->comment;
}
}
ui->NodesTable->setCurrentCell(row, col);
}
Q_UNUSED(index)
void DBCMainEditor::onCellChangedMessage(int row,int col)
{
QTableWidgetItem* item = nullptr;
bool ret = false;
DBC_MESSAGE *msg = nullptr;
uint msgID;
if (inhibitCellChanged) return;
DBC_NODE *node = dbcFile->findNodeByIdx(ui->NodesTable->currentRow());
if (node == nullptr)
{
qDebug() << "No node set?!? This is bad!";
return;
}
item = ui->MessagesTable->item(row, 0);
if(!item) return;
msgID = Utility::ParseStringToNum2(item->text(), &ret);
msg = dbcFile->messageHandler->findMsgByID(msgID);
switch(col)
{
case 0: //msg id
{
/* sanity checks */
if(!ret)
{
/* bad message id */
ui->MessagesTable->item(row, 0)->setText("");
return;
}
if (msg != nullptr)
{
QMessageBox msg;
msg.setParent(nullptr);
msg.setText("An existing msg with that ID already exists! Aborting!");
msg.exec();
ui->MessagesTable->item(row, 0)->setText("");
return;
}
/* insert row */
DBC_MESSAGE newMsg;
newMsg.ID = msgID;
newMsg.name = "";
newMsg.sender = node;
newMsg.len = 0;
newMsg.fgColor = QColor(dbcFile->findAttributeByName("GenMsgForegroundColor")->defaultValue.toString());
newMsg.bgColor = QColor(dbcFile->findAttributeByName("GenMsgBackgroundColor")->defaultValue.toString());
for (int i = 0; i < referenceFrames->length(); i++)
{
if ((uint) referenceFrames->at(i).frameId() == msgID)
{
newMsg.len = static_cast<unsigned int>(referenceFrames->at(i).payload().length());
break;
}
}
dbcFile->messageHandler->addMessage(newMsg);
/* insert message in table */
inhibitCellChanged = true;
item = ui->MessagesTable->item(row, 0);
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
item->setText(Utility::formatCANID(msgID));
for(int i=1 ; i < ui->MessagesTable->columnCount(); i++)
{
item = ui->MessagesTable->item(row, i);
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
/* set length */
item = ui->MessagesTable->item(row, 2);
item->setText(QString::number(newMsg.len));
inhibitCellChanged = false;
/* insert a new row */
insertBlankRow();
break;
}
case 1: //msg name
{
QString msgName = ui->MessagesTable->item(row, 1)->text().simplified().replace(' ', '_');
if (msgName.length() == 0) return;
if( ret && (msg!=nullptr) )
msg->name = msgName;
break;
}
case 2: //data length
{
bool parseOk = false;
uint msgLen = ui->MessagesTable->item(row, col)->text().toUInt(&parseOk);
/* sanity checks */
if(!parseOk)
{
ui->MessagesTable->item(row, col)->setText("");
return;
}
if (msgLen > 8)
{
msgLen = 8;
ui->MessagesTable->item(row, col)->setText(QString::number(msgLen));
}
if( ret && (msg!=nullptr) )
msg->len = msgLen;
break;
}
case 3: //signals (number) - we don't handle anything here. User cannot directly change this value
break;
case 6: //comment
{
QString msgComment = ui->MessagesTable->item(row, col)->text().simplified();
if( ret && (msgComment!=nullptr) )
msg->comment = msgComment;
break;
}
}
ui->MessagesTable->setCurrentCell(row, col);
}
void DBCMainEditor::onCellClickedNode(int row, int col)
{
//reload messages list if the currently selected row has changed.
qDebug() << "Clicked at row " << row << " col " << col;
if (row != currRow)
{
currRow = row;
QTableWidgetItem *item = ui->NodesTable->item(currRow, 0);
QString nodeName;
if (item == nullptr) return;
nodeName = item->text();
qDebug() << "Trying to find node with name " << nodeName;
DBC_NODE *node = dbcFile->findNodeByName(nodeName);
//qDebug() << "Address of node: " << (int)node;
inhibitCellChanged = true;
refreshMessagesTable(node);
inhibitCellChanged = false;
}
}
void DBCMainEditor::onCellClickedMessage(int row, int col)
{
QTableWidgetItem* thisItem = ui->MessagesTable->item(row, col);
QTableWidgetItem* firstCol = ui->MessagesTable->item(row, 0);
QTreeWidgetItem* firstCol = ui->treeDBC->currentItem();
bool ret = false;
DBC_MESSAGE *msg;
DBC_SIGNAL *sig;
uint32_t msgID;
QString idString;
if (col == 3) //3 is the signals field. If clicked we go to the signals dialog
qDebug() << firstCol->data(0, Qt::UserRole) << " - " << firstCol->text(0);
switch (firstCol->data(0, Qt::UserRole).toInt())
{
case 1: //a node
break;
case 2: //a message
idString = firstCol->text(0).split(" ")[0];
msgID = static_cast<uint32_t>(Utility::ParseStringToNum(idString));
msg = dbcFile->messageHandler->findMsgByID(msgID);
msgEditor->setMessageRef(msg);
msgEditor->setFileIdx(fileIdx);
msgEditor->setWindowModality(Qt::WindowModal);
msgEditor->exec(); //blocks this window from being active until we're done
break;
case 3: //a signal
idString = firstCol->parent()->text(0).split(" ")[0];
msgID = static_cast<uint32_t>(Utility::ParseStringToNum(idString));
msg = dbcFile->messageHandler->findMsgByID(msgID);
sig = msg->sigHandler->findSignalByName(firstCol->text(0).split(" ")[0]);
sigEditor->setSignalRef(sig);
sigEditor->setMessageRef(msg);
sigEditor->setFileIdx(fileIdx);
sigEditor->setWindowModality(Qt::WindowModal);
sigEditor->exec(); //blocks this window from being active until we're done
break;
}
/* if (col == 3) //3 is the signals field. If clicked we go to the signals dialog
{
QTableWidgetItem* msg = ui->MessagesTable->item(row, 0);
if(msg) {
@@ -546,15 +344,17 @@ void DBCMainEditor::onCellClickedMessage(int row, int col)
msg->attributes.append(newVal);
}
}
}
} */
}
void DBCMainEditor::refreshNodesTable()
{
ui->NodesTable->clearContents(); //first step, clear out any previous crap
ui->NodesTable->setRowCount(0);
int rowIdx;
/*
* Recreate the whole tree with pretty icons and custom user roles that give the rest of code an easy way to figure out whether a given tree node
* is a node, message, or signal.
*/
void DBCMainEditor::refreshTree()
{
ui->treeDBC->clear();
if (dbcFile->findNodeByName("Vector__XXX") == nullptr)
{
@@ -564,82 +364,40 @@ void DBCMainEditor::refreshNodesTable()
dbcFile->dbc_nodes.append(newNode);
}
for (int x = 0; x < dbcFile->dbc_nodes.count(); x++)
{
DBC_NODE node = dbcFile->dbc_nodes.at(x);
QTableWidgetItem *nodeName = new QTableWidgetItem(node.name);
QTableWidgetItem *nodeComment = new QTableWidgetItem(node.comment);
rowIdx = ui->NodesTable->rowCount();
ui->NodesTable->insertRow(rowIdx);
ui->NodesTable->setItem(rowIdx, 0, nodeName);
ui->NodesTable->setItem(rowIdx, 1, nodeComment);
}
//insert a fresh entry at the bottom that contains nothing
ui->NodesTable->insertRow(ui->NodesTable->rowCount());
ui->NodesTable->selectRow(0);
}
void DBCMainEditor::refreshMessagesTable(const DBC_NODE *node)
{
ui->MessagesTable->clearContents();
ui->MessagesTable->setRowCount(0);
qDebug() << "In refreshMessagesTable";
int rowIdx;
if (node != nullptr)
foreach (DBC_NODE node, dbcFile->dbc_nodes)
{
QTreeWidgetItem *nodeItem = new QTreeWidgetItem();
QString nodeInfo = node.name;
if (node.comment.count() > 0) nodeInfo.append(" - ").append(node.comment);
nodeItem->setText(0, nodeInfo);
nodeItem->setIcon(0, nodeIcon);
nodeItem->setData(0, Qt::UserRole, 1);
for (int x = 0; x < dbcFile->messageHandler->getCount(); x++)
{
DBC_MESSAGE *msg = dbcFile->messageHandler->findMsgByIdx(x);
if (msg->sender == node)
if (msg->sender->name == node.name)
{
//many of these are simplistic first versions just to test functionality.
QTableWidgetItem *msgID = new QTableWidgetItem(Utility::formatCANID(msg->ID));
QTableWidgetItem *msgName = new QTableWidgetItem(msg->name);
QTableWidgetItem *msgLen = new QTableWidgetItem(QString::number(msg->len));
QTableWidgetItem *msgSignals = new QTableWidgetItem(QString::number(msg->sigHandler->getCount()));
QTableWidgetItem *fgColor = new QTableWidgetItem("");
if (msg->fgColor.isValid()) fgColor->setBackground(msg->fgColor);
else fgColor->setBackground(QColor(dbcFile->findAttributeByName("GenMsgForegroundColor")->defaultValue.toString()));
QTableWidgetItem *bgColor = new QTableWidgetItem("");
if (msg->bgColor.isValid()) bgColor->setBackground(msg->bgColor);
else bgColor->setBackground(QColor(dbcFile->findAttributeByName("GenMsgBackgroundColor")->defaultValue.toString()));
QTableWidgetItem *msgComment = new QTableWidgetItem(msg->comment);
rowIdx = ui->MessagesTable->rowCount();
ui->MessagesTable->insertRow(rowIdx);
ui->MessagesTable->setItem(rowIdx, 0, msgID);
ui->MessagesTable->setItem(rowIdx, 1, msgName);
ui->MessagesTable->setItem(rowIdx, 2, msgLen);
ui->MessagesTable->setItem(rowIdx, 3, msgSignals);
ui->MessagesTable->setItem(rowIdx, 4, fgColor);
ui->MessagesTable->setItem(rowIdx, 5, bgColor);
ui->MessagesTable->setItem(rowIdx, 6, msgComment);
//note that there is a sending node field in the structure but we're
//not displaying it. It has to be the node we selected from the node list
//so no need to show that here.
QTreeWidgetItem *msgItem = new QTreeWidgetItem(nodeItem);
QString msgInfo = Utility::formatCANID(msg->ID) + " " + msg->name;
if (msg->comment.count() > 0) msgInfo.append(" - ").append(msg->comment);
msgItem->setText(0, msgInfo);
msgItem->setIcon(0, messageIcon);
msgItem->setData(0, Qt::UserRole, 2);
for (int i = 0; i < msg->sigHandler->getCount(); i++)
{
DBC_SIGNAL *sig = msg->sigHandler->findSignalByIdx(i);
QTreeWidgetItem *sigItem = new QTreeWidgetItem(msgItem);
QString sigInfo = sig->name;
if (sig->comment.count() > 0) sigInfo.append(" - ").append(sig->comment);
sigItem->setText(0, sigInfo);
if (sig->isMultiplexed) sigItem->setIcon(0, multiplexedSignalIcon);
else if (sig->isMultiplexor) sigItem->setIcon(0, multiplexorSignalIcon);
else sigItem->setIcon(0, signalIcon);
sigItem->setData(0, Qt::UserRole, 3);
}
}
}
ui->treeDBC->addTopLevelItem(nodeItem);
}
//insert blank record that can be used to add new messages
insertBlankRow();
}
void DBCMainEditor::insertBlankRow()
{
int rowIdx = ui->MessagesTable->rowCount();
ui->MessagesTable->insertRow(rowIdx);
for(int i=1 ; i < ui->MessagesTable->columnCount(); i++)
{
QTableWidgetItem *item = new QTableWidgetItem("");
if (i == 4) item->setBackground(QApplication::palette().color(QPalette::WindowText)); //foreground color
if (i == 5) item->setBackground(QApplication::palette().color(QPalette::Base));
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
ui->MessagesTable->setItem(rowIdx, i, item);
}
ui->treeDBC->sortItems(0, Qt::SortOrder::AscendingOrder); //sort the display list for ease in viewing by mere mortals, helps me a lot.
}
+12 -13
View File
@@ -3,8 +3,10 @@
#include <QDialog>
#include <QDebug>
#include <QIcon>
#include "dbchandler.h"
#include "dbcsignaleditor.h"
#include "dbcmessageeditor.h"
#include "utility.h"
namespace Ui {
@@ -21,14 +23,9 @@ public:
void setFileIdx(int idx);
private slots:
void onCellChangedNode(int,int);
void onCellClickedNode(int, int);
void onCellClickedMessage(int, int);
void onCellChangedMessage(int,int);
void onCustomMenuNode(QPoint);
void onCustomMenuMessage(QPoint);
void deleteCurrentNode();
void deleteCurrentMessage();
void onTreeDoubleClicked(const QModelIndex &index);
void onCustomMenuTree(QPoint);
void deleteCurrentTreeItem();
void handleSearch();
private:
@@ -36,19 +33,21 @@ private:
DBCHandler *dbcHandler;
const QVector<CANFrame> *referenceFrames;
DBCSignalEditor *sigEditor;
int currRow;
DBCMessageEditor *msgEditor;
DBCFile *dbcFile;
int fileIdx;
bool inhibitCellChanged;
QIcon nodeIcon;
QIcon messageIcon;
QIcon signalIcon;
QIcon multiplexorSignalIcon;
QIcon multiplexedSignalIcon;
void refreshNodesTable();
void refreshMessagesTable(const DBC_NODE *node);
void refreshTree();
void showEvent(QShowEvent* event);
void closeEvent(QCloseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
void readSettings();
void writeSettings();
void insertBlankRow();
};
+185
View File
@@ -0,0 +1,185 @@
#include "dbcmessageeditor.h"
#include "ui_dbcmessageeditor.h"
#include <QSettings>
#include <QKeyEvent>
#include <QColorDialog>
#include "helpwindow.h"
#include "utility.h"
DBCMessageEditor::DBCMessageEditor(QWidget *parent) :
QDialog(parent),
ui(new Ui::DBCMessageEditor)
{
ui->setupUi(this);
readSettings();
dbcHandler = DBCHandler::getReference();
dbcMessage = nullptr;
connect(ui->btnTextColor, &QAbstractButton::clicked,
[=]()
{
QColor newColor = QColorDialog::getColor(dbcMessage->fgColor);
dbcMessage->fgColor = newColor;
DBC_ATTRIBUTE_VALUE *val = dbcMessage->findAttrValByName("GenMsgForegroundColor");
if (val)
{
val->value = newColor.name();
}
else
{
DBC_ATTRIBUTE_VALUE newVal;
newVal.attrName = "GenMsgForegroundColor";
newVal.value = newColor.name();
dbcMessage->attributes.append(newVal);
}
generateSampleText();
});
connect(ui->btnBackgroundColor, &QAbstractButton::clicked,
[=]()
{
QColor newColor = QColorDialog::getColor(dbcMessage->bgColor);
dbcMessage->bgColor = newColor;
DBC_ATTRIBUTE_VALUE *val = dbcMessage->findAttrValByName("GenMsgBackgroundColor");
if (val)
{
val->value = newColor.name();
}
else
{
DBC_ATTRIBUTE_VALUE newVal;
newVal.attrName = "GenMsgBackgroundColor";
newVal.value = newColor.name();
dbcMessage->attributes.append(newVal);
}
generateSampleText();
});
installEventFilter(this);
}
DBCMessageEditor::~DBCMessageEditor()
{
removeEventFilter(this);
delete ui;
}
void DBCMessageEditor::closeEvent(QCloseEvent *event)
{
Q_UNUSED(event);
writeSettings();
}
bool DBCMessageEditor::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyRelease) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
switch (keyEvent->key())
{
case Qt::Key_F1:
HelpWindow::getRef()->showHelp("messageeditor.html");
break;
}
return true;
} else {
// standard event processing
return QObject::eventFilter(obj, event);
}
return false;
}
void DBCMessageEditor::setFileIdx(int idx)
{
if (idx < 0 || idx > dbcHandler->getFileCount() - 1) return;
dbcFile = dbcHandler->getFileByIdx(idx);
for (int x = 0; x < dbcFile->dbc_nodes.count(); x++)
{
ui->comboSender->addItem(dbcFile->dbc_nodes[x].name);
}
}
void DBCMessageEditor::readSettings()
{
QSettings settings;
if (settings.value("Main/SaveRestorePositions", false).toBool())
{
resize(settings.value("DBCMessageEditor/WindowSize", QSize(340, 400)).toSize());
move(settings.value("DBCMessageEditor/WindowPos", QPoint(100, 100)).toPoint());
}
}
void DBCMessageEditor::writeSettings()
{
QSettings settings;
if (settings.value("Main/SaveRestorePositions", false).toBool())
{
settings.setValue("DBCMessageEditor/WindowSize", size());
settings.setValue("DBCMessageEditor/WindowPos", pos());
}
}
void DBCMessageEditor::setMessageRef(DBC_MESSAGE *msg)
{
dbcMessage = msg;
}
void DBCMessageEditor::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
refreshView();
}
void DBCMessageEditor::refreshView()
{
ui->lineComment->setText(dbcMessage->comment);
ui->lineFrameID->setText(Utility::formatCANID(dbcMessage->ID));
ui->lineMsgName->setText(dbcMessage->name);
ui->lineFrameLen->setText(QString::number(dbcMessage->len));
for (int i = 0; i < ui->comboSender->count(); i++)
{
if (ui->comboSender->itemText(i) == dbcMessage->sender->name)
{
ui->comboSender->setCurrentIndex(i);
break;
}
}
generateSampleText();
}
void DBCMessageEditor::generateSampleText()
{
QBrush fg, bg;
if (dbcMessage->fgColor.isValid()) fg = QBrush(dbcMessage->fgColor);
else fg = QBrush(QColor(dbcFile->findAttributeByName("GenMsgForegroundColor")->defaultValue.toString()));
if (dbcMessage->bgColor.isValid()) bg = QBrush(dbcMessage->bgColor);
else bg = QBrush(QColor(dbcFile->findAttributeByName("GenMsgBackgroundColor")->defaultValue.toString()));
ui->listSample->clear();
QListWidgetItem *item = new QListWidgetItem("Test String");
item->setForeground(fg);
item->setBackground(bg);
ui->listSample->addItem(item);
item = new QListWidgetItem("0x20F TestMsg");
item->setForeground(fg);
item->setBackground(bg);
ui->listSample->addItem(item);
item = new QListWidgetItem("20 FF 10 A1 BB CC 4D");
item->setForeground(fg);
item->setBackground(bg);
ui->listSample->addItem(item);
item = new QListWidgetItem("1024.3434");
item->setForeground(fg);
item->setBackground(bg);
ui->listSample->addItem(item);
}
+38
View File
@@ -0,0 +1,38 @@
#ifndef DBCMESSAGEEDITOR_H
#define DBCMESSAGEEDITOR_H
#include <QDialog>
#include "dbc_classes.h"
#include "dbchandler.h"
namespace Ui {
class DBCMessageEditor;
}
class DBCMessageEditor : public QDialog
{
Q_OBJECT
public:
explicit DBCMessageEditor(QWidget *parent = nullptr);
~DBCMessageEditor();
void showEvent(QShowEvent*);
void setMessageRef(DBC_MESSAGE *msg);
void setFileIdx(int idx);
private:
Ui::DBCMessageEditor *ui;
DBCHandler *dbcHandler;
DBC_MESSAGE *dbcMessage;
DBCFile *dbcFile;
void closeEvent(QCloseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
void readSettings();
void writeSettings();
void refreshView();
void generateSampleText();
};
#endif // DBCMESSAGEEDITOR_H
+9 -133
View File
@@ -34,10 +34,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
ui->comboType->addItem("DOUBLE PRECISION");
ui->comboType->addItem("STRING");
connect(ui->signalsList, SIGNAL(currentRowChanged(int)), this, SLOT(clickSignalList(int)));
connect(ui->bitfield, SIGNAL(gridClicked(int,int)), this, SLOT(bitfieldClicked(int,int)));
connect(ui->signalsList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomMenuSignals(QPoint)));
ui->signalsList->setContextMenuPolicy(Qt::CustomContextMenu);
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)));
@@ -155,7 +152,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
QString tempNameStr = ui->txtName->text().simplified().replace(' ', '_');
if (tempNameStr.length() > 0) currentSignal->name = tempNameStr;
//need to update the list too.
ui->signalsList->currentItem()->setText(currentSignal->name);
//ui->signalsList->currentItem()->setText(currentSignal->name);
});
connect(ui->txtMultiplexValue, &QLineEdit::editingFinished,
@@ -228,9 +225,6 @@ bool DBCSignalEditor::eventFilter(QObject *obj, QEvent *event)
case Qt::Key_F1:
HelpWindow::getRef()->showHelp("signaleditor.html");
break;
case Qt::Key_F2:
cloneSignal();
break;
}
return true;
} else {
@@ -278,12 +272,18 @@ void DBCSignalEditor::setMessageRef(DBC_MESSAGE *msg)
dbcMessage = msg;
}
void DBCSignalEditor::setSignalRef(DBC_SIGNAL *sig)
{
currentSignal = sig;
}
void DBCSignalEditor::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
currentSignal = nullptr;
refreshSignalsList();
fillSignalForm(currentSignal);
fillValueTable(currentSignal);
}
void DBCSignalEditor::onValuesCellChanged(int row,int col)
@@ -317,21 +317,6 @@ void DBCSignalEditor::onValuesCellChanged(int row,int col)
}
}
void DBCSignalEditor::onCustomMenuSignals(QPoint point)
{
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->addAction(tr("Add a new signal"), this, SLOT(addNewSignal()));
if (ui->signalsList->currentRow() != -1)
{
menu->addAction(tr("Clone currently selected signal"), this, SLOT(cloneSignal()));
menu->addAction(tr("Delete currently selected signal"), this, SLOT(deleteCurrentSignal()));
}
menu->popup(ui->signalsList->mapToGlobal(point));
}
void DBCSignalEditor::onCustomMenuValues(QPoint point)
{
QMenu *menu = new QMenu(this);
@@ -342,86 +327,6 @@ void DBCSignalEditor::onCustomMenuValues(QPoint point)
menu->popup(ui->valuesTable->mapToGlobal(point));
}
void DBCSignalEditor::addNewSignal()
{
int num = QRandomGenerator::global()->bounded(70000);
QString newName = "SIGNAL" + QString::number(num);
DBC_SIGNAL newSig;
newSig.name = newName;
newSig.bias = 0.0;
newSig.factor = 1.0;
newSig.intelByteOrder = true;
newSig.max = 0.0;
newSig.min = 0.0;
newSig.receiver = dbcFile->findNodeByIdx(0);
newSig.signalSize = 1;
newSig.startBit = 0;
newSig.valType = UNSIGNED_INT;
newSig.isMultiplexed = false;
newSig.isMultiplexor = false;
newSig.multiplexValue = 0;
newSig.parentMessage = dbcMessage;
dbcMessage->sigHandler->addSignal(newSig);
/* add item at the end of the list and select it */
/* this will call clickSignalList */
ui->signalsList->addItem(newName);
ui->signalsList->setCurrentRow(ui->signalsList->count()-1);
}
void DBCSignalEditor::cloneSignal()
{
int num = QRandomGenerator::global()->bounded(100);
int idx = ui->signalsList->currentRow();
if (idx < 0) return;
DBC_SIGNAL *oldSig = dbcMessage->sigHandler->findSignalByIdx(idx);
if (!oldSig) return;
QString newName = oldSig->name + QString::number(num);
DBC_SIGNAL newSig;
newSig.name = newName;
newSig.bias = oldSig->bias;
newSig.factor = oldSig->factor;
newSig.intelByteOrder = oldSig->intelByteOrder;
newSig.max = oldSig->max;
newSig.min = oldSig->min;
newSig.receiver = oldSig->receiver;
newSig.signalSize = oldSig->signalSize;
newSig.startBit = oldSig->startBit;
newSig.valType = oldSig->valType;
newSig.valList.append(oldSig->valList);
newSig.isMultiplexed = oldSig->isMultiplexed;
newSig.isMultiplexor = oldSig->isMultiplexor; //maybe should force this false since you can't have two or more!
newSig.multiplexValue = oldSig->multiplexValue;
newSig.parentMessage = dbcMessage;
dbcMessage->sigHandler->addSignal(newSig);
/* add item at the end of the list */
ui->signalsList->addItem(newName);
//unlike adding a signal we don't want to select the new signal here.
//ui->signalsList->setCurrentRow(ui->signalsList->count()-1);
}
void DBCSignalEditor::deleteCurrentSignal()
{
int currIdx = ui->signalsList->currentRow();
//if(currIdx==ui->signalsList->count()-1)
//return;
if (currIdx > -1)
{
delete(ui->signalsList->item(currIdx));
dbcMessage->sigHandler->removeSignal(currIdx);
currentSignal = nullptr;
}
}
void DBCSignalEditor::deleteCurrentValue()
{
int currIdx = ui->valuesTable->currentRow();
@@ -432,25 +337,6 @@ void DBCSignalEditor::deleteCurrentValue()
}
}
void DBCSignalEditor::refreshSignalsList()
{
ui->signalsList->clear();
for (int x = 0; x < dbcMessage->sigHandler->getCount(); x++)
{
DBC_SIGNAL *sig = dbcMessage->sigHandler->findSignalByIdx(x);
ui->signalsList->addItem(sig->name);
}
if( ui->signalsList->count()>0 ) {
/* click first element */
ui->signalsList->setCurrentRow(0);
}
else
clickSignalList(-1);
}
/* fillSignalForm also handles group "enabled" state */
/* WARNING: fillSignalForm can be called recursively since it is in the listener of cbIntelFormat */
void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
@@ -598,16 +484,6 @@ void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig)
inhibitCellChanged = false;
}
void DBCSignalEditor::clickSignalList(int row)
{
//qDebug() << ui->signalsList->item(row)->text();
DBC_SIGNAL *thisSig = (row<0) ? nullptr : dbcMessage->sigHandler->findSignalByName(ui->signalsList->item(row)->text());
currentSignal = thisSig;
fillSignalForm(thisSig);
fillValueTable(thisSig);
}
void DBCSignalEditor::bitfieldClicked(int x, int y)
{
int bit = (7 - x) + (y * 8);
+2 -7
View File
@@ -16,19 +16,15 @@ class DBCSignalEditor : public QDialog
public:
explicit DBCSignalEditor(QWidget *parent = 0);
void setMessageRef(DBC_MESSAGE *msg);
void showEvent(QShowEvent*);
void setFileIdx(int idx);
void setSignalRef(DBC_SIGNAL *sig);
void showEvent(QShowEvent*);
~DBCSignalEditor();
private slots:
void clickSignalList(int);
void bitfieldClicked(int x, int y);
void onValuesCellChanged(int row,int col);
void onCustomMenuSignals(QPoint);
void onCustomMenuValues(QPoint);
void addNewSignal();
void cloneSignal();
void deleteCurrentSignal();
void deleteCurrentValue();
private:
@@ -39,7 +35,6 @@ private:
DBCFile *dbcFile;
bool inhibitCellChanged;
void refreshSignalsList();
void fillSignalForm(DBC_SIGNAL *sig);
void fillValueTable(DBC_SIGNAL *sig);
void generateUsedBits();
+9
View File
@@ -6,5 +6,14 @@
<file>images/PlayHS.png</file>
<file>images/ReverseHS.png</file>
<file>images/StopHS.png</file>
<file>images/signal.png</file>
<file>images/node.png</file>
<file>images/message.png</file>
<file>images/multiplexed-signal.png</file>
<file>images/multiplexor-signal.png</file>
<file>images/skull.png</file>
<file>images/signal_new.png</file>
<file>images/node_new.png</file>
<file>images/message_new.png</file>
</qresource>
</RCC>
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.
+80 -16
View File
@@ -13,33 +13,95 @@
<property name="windowTitle">
<string>DBC Editing Window</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="1,3">
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,5,1">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<widget class="QToolButton" name="btnNewNode">
<property name="text">
<string>Nodes</string>
<string>New Node</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/images/node_new.png</normaloff>:/icons/images/node_new.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="NodesTable"/>
<widget class="QToolButton" name="btnNewMessage">
<property name="text">
<string>New Message</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/images/message_new.png</normaloff>:/icons/images/message_new.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnNewSignal">
<property name="text">
<string>New Signal</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/images/signal_new.png</normaloff>:/icons/images/signal_new.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnDelete">
<property name="text">
<string>Delete</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/images/skull.png</normaloff>:/icons/images/skull.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextUnderIcon</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTreeWidget" name="treeDBC">
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Messages</string>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="MessagesTable"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
@@ -82,6 +144,8 @@
</item>
</layout>
</widget>
<resources/>
<resources>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>
+3 -7
View File
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1239</width>
<width>967</width>
<height>644</height>
</rect>
</property>
@@ -15,10 +15,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="10,1,4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,2,1">
<item>
<widget class="QListWidget" name="signalsList"/>
</item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="2,1">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
@@ -210,7 +207,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Value Table For Selected Signal:</string>
<string>Value Table:</string>
</property>
</widget>
</item>
@@ -228,7 +225,6 @@
</customwidget>
</customwidgets>
<tabstops>
<tabstop>signalsList</tabstop>
<tabstop>txtName</tabstop>
<tabstop>rbNotMulti</tabstop>
<tabstop>rbMultiplexed</tabstop>