#include "dbcmaineditor.h" #include "ui_dbcmaineditor.h" #include #include #include DBCMainEditor::DBCMainEditor(DBCHandler *handler, const QVector *frames, QWidget *parent) : QDialog(parent), ui(new Ui::DBCMainEditor) { ui->setupUi(this); readSettings(); dbcHandler = handler; 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" << "Comment"; ui->MessagesTable->setColumnCount(5); ui->MessagesTable->setColumnWidth(0, 80); ui->MessagesTable->setColumnWidth(1, 240); ui->MessagesTable->setColumnWidth(2, 80); ui->MessagesTable->setColumnWidth(3, 80); ui->MessagesTable->setColumnWidth(4, 340); 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); sigEditor = new DBCSignalEditor(handler); } void DBCMainEditor::showEvent(QShowEvent* event) { QDialog::showEvent(event); inhibitCellChanged = true; refreshNodesTable(); if (dbcHandler->getFileByIdx(0)->dbc_nodes.count() > 0) refreshMessagesTable(&dbcHandler->getFileByIdx(0)->dbc_nodes.at(0)); currRow = 0; inhibitCellChanged = false; } DBCMainEditor::~DBCMainEditor() { delete ui; delete sigEditor; } void DBCMainEditor::closeEvent(QCloseEvent *event) { Q_UNUSED(event); writeSettings(); } void DBCMainEditor::readSettings() { QSettings settings; if (settings.value("Main/SaveRestorePositions", false).toBool()) { resize(settings.value("DBCMainEditor/WindowSize", QSize(1103, 571)).toSize()); move(settings.value("DBCMainEditor/WindowPos", QPoint(50, 50)).toPoint()); } } void DBCMainEditor::writeSettings() { QSettings settings; if (settings.value("Main/SaveRestorePositions", false).toBool()) { settings.setValue("DBCMainEditor/WindowSize", size()); settings.setValue("DBCMainEditor/WindowPos", pos()); } } 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) { 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)); } void DBCMainEditor::deleteCurrentNode() { int thisRow = ui->NodesTable->currentRow(); QString nodeName = ui->NodesTable->item(thisRow, 0)->text(); if (nodeName.length() > 0 && nodeName.compare("Vector__XXX", Qt::CaseInsensitive) != 0) { ui->NodesTable->removeRow(thisRow); dbcHandler->getFileByIdx(0)->dbc_nodes.removeAt(thisRow); inhibitCellChanged = true; refreshMessagesTable(&dbcHandler->getFileByIdx(0)->dbc_nodes[0]); ui->NodesTable->selectRow(0); inhibitCellChanged = false; } } void DBCMainEditor::deleteCurrentMessage() { int thisRow = ui->MessagesTable->currentRow(); if (ui->MessagesTable->item(thisRow, 0)->text().length() > 0) { ui->MessagesTable->removeRow(thisRow); dbcHandler->getFileByIdx(0)->messageHandler->removeMessageByIndex(thisRow); } } void DBCMainEditor::onCellChangedNode(int row,int col) { 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 (dbcHandler->getFileByIdx(0)->findNodeByName(newName) != NULL) //duplicates an existing node! { QMessageBox msg; msg.setParent(0); msg.setText("An existing node with that name already exists! Aborting!"); msg.exec(); return; } newNode.name = newName; dbcHandler->getFileByIdx(0)->dbc_nodes.append(newNode); qDebug() << "# of nodes now " << dbcHandler->getFileByIdx(0)->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 = dbcHandler->getFileByIdx(0)->findNodeByIdx(row); QString nodeName = ui->NodesTable->item(row, col)->text().simplified().replace(' ', '_'); if (oldNode == NULL) 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 = dbcHandler->getFileByIdx(0)->findNodeByName(nodeName); if (thisNode == NULL) return; thisNode->comment = ui->NodesTable->item(row, col)->text().simplified(); qDebug() << "New comment: " << thisNode->comment; } } ui->NodesTable->setCurrentCell(row, col); } void DBCMainEditor::onCellChangedMessage(int row,int col) { if (inhibitCellChanged) return; qDebug() << "Editing row: " << row << " col: " << col; QTableWidgetItem *replacement = NULL; int msgID; QString msgName; int msgLen; QString msgComment; DBC_MESSAGE newMsg; DBC_NODE *node = dbcHandler->getFileByIdx(0)->findNodeByIdx(ui->NodesTable->currentRow()); DBC_MESSAGE *msg; if (node == NULL) { qDebug() << "No node set?!? This is bad!"; return; //dbcHandler->findNodeByIdx(0); } msgID = Utility::ParseStringToNum(ui->MessagesTable->item(row, 0)->text()); qDebug() << "Msg ID of edited: " << msgID; msg = dbcHandler->getFileByIdx(0)->messageHandler->findMsgByID(msgID); switch(col) { case 0: //msg id if (row == ui->MessagesTable->rowCount() - 1) //new record { if (dbcHandler->getFileByIdx(0)->messageHandler->findMsgByID(msgID) != NULL) { QMessageBox msg; msg.setParent(0); msg.setText("An existing msg with that ID already exists! Aborting!"); msg.exec(); return; } newMsg.ID = msgID; newMsg.name = ""; newMsg.sender = node; newMsg.len = 0; for (int i = 0; i < referenceFrames->length(); i++) { if (referenceFrames->at(i).ID == msgID) { newMsg.len = referenceFrames->at(i).len; break; } } dbcHandler->getFileByIdx(0)->messageHandler->addMessage(newMsg); } else //editing an existing record { if (msg != NULL) msg->ID = msgID; } inhibitCellChanged = true; replacement = new QTableWidgetItem(Utility::formatNumber(msgID)); ui->MessagesTable->setItem(row, col, replacement); replacement = new QTableWidgetItem(QString::number(newMsg.len)); ui->MessagesTable->setItem(row, 2, replacement); inhibitCellChanged = false; break; case 1: //msg name msgName = ui->MessagesTable->item(row, col)->text().simplified().replace(' ', '_'); if (msgName.length() == 0) return; if (row == ui->MessagesTable->rowCount() - 1) //new record { if (dbcHandler->getFileByIdx(0)->messageHandler->findMsgByName(msgName) != NULL) { QMessageBox msg; msg.setParent(0); msg.setText("An existing msg with that name already exists! Aborting!"); msg.exec(); return; } newMsg.ID = -1; newMsg.name = msgName; newMsg.sender = node; dbcHandler->getFileByIdx(0)->messageHandler->addMessage(newMsg); } else { if (msg != NULL) msg->name = msgName; } inhibitCellChanged = true; replacement = new QTableWidgetItem(msgName); ui->MessagesTable->setItem(row, col, replacement); inhibitCellChanged = false; break; case 2: //data length msgLen = ui->MessagesTable->item(row, col)->text().toInt(); if (msgLen < 0) msgLen = 0; if (msgLen > 8) msgLen = 8; if (row == ui->MessagesTable->rowCount() - 1) //new record { DBC_MESSAGE newMsg; newMsg.ID = -1; newMsg.name = ""; newMsg.len = msgLen; newMsg.sender = node; dbcHandler->getFileByIdx(0)->messageHandler->addMessage(newMsg); } else //editing an existing record { if (msg != NULL) msg->len = msgLen; } inhibitCellChanged = true; replacement = new QTableWidgetItem(QString::number(msgLen, 16)); ui->MessagesTable->setItem(row, col, replacement); inhibitCellChanged = false; break; case 3: //signals (number) - we don't handle anything here. User cannot directly change this value break; case 4: //comment msgComment = ui->MessagesTable->item(row, col)->text().simplified(); if (row == ui->MessagesTable->rowCount() - 1) //new record { DBC_MESSAGE newMsg; newMsg.ID = -1; newMsg.name = ""; newMsg.len = 0; newMsg.comment = msgComment; newMsg.sender = node; dbcHandler->getFileByIdx(0)->messageHandler->addMessage(newMsg); } else //editing an existing record { if (msg != NULL) msg->comment = msgComment; } inhibitCellChanged = true; replacement = new QTableWidgetItem(msgComment); ui->MessagesTable->setItem(row, col, replacement); inhibitCellChanged = false; break; } if (row == ui->MessagesTable->rowCount() - 1) { ui->MessagesTable->insertRow(ui->MessagesTable->rowCount()); } 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 == NULL) return; nodeName = item->text(); qDebug() << "Trying to find node with name " << nodeName; DBC_NODE *node = dbcHandler->getFileByIdx(0)->findNodeByName(nodeName); //qDebug() << "Address of node: " << (int)node; inhibitCellChanged = true; refreshMessagesTable(node); inhibitCellChanged = false; } } void DBCMainEditor::onCellClickedMessage(int row, int col) { if (col == 3) //3 is the signals field. If clicked we go to the signals dialog { QString idString = ui->MessagesTable->item(row, 0)->text(); DBC_MESSAGE *message = dbcHandler->getFileByIdx(0)->messageHandler->findMsgByID(Utility::ParseStringToNum(idString)); sigEditor->setMessageRef(message); sigEditor->exec(); //blocks this window from being active until we're done //now update the displayed # of signals inhibitCellChanged = true; QTableWidgetItem *replacement = new QTableWidgetItem(QString::number(message->sigHandler->getCount())); ui->MessagesTable->setItem(row, col, replacement); inhibitCellChanged = false; } } void DBCMainEditor::refreshNodesTable() { ui->NodesTable->clearContents(); //first step, clear out any previous crap ui->NodesTable->setRowCount(0); int rowIdx; if (dbcHandler->getFileByIdx(0)->findNodeByName("Vector__XXX") == NULL) { DBC_NODE newNode; newNode.name = "Vector__XXX"; newNode.comment = "Default node if no other node is specified"; dbcHandler->getFileByIdx(0)->dbc_nodes.append(newNode); } for (int x = 0; x < dbcHandler->getFileByIdx(0)->dbc_nodes.count(); x++) { DBC_NODE node = dbcHandler->getFileByIdx(0)->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()); } void DBCMainEditor::refreshMessagesTable(const DBC_NODE *node) { ui->MessagesTable->clearContents(); ui->MessagesTable->setRowCount(0); qDebug() << "In refreshMessagesTable"; int rowIdx; if (node != NULL) { for (int x = 0; x < dbcHandler->getFileByIdx(0)->messageHandler->getCount(); x++) { DBC_MESSAGE *msg = dbcHandler->getFileByIdx(0)->messageHandler->findMsgByIdx(x); if (msg->sender == node) { //many of these are simplistic first versions just to test functionality. QTableWidgetItem *msgID = new QTableWidgetItem(Utility::formatNumber(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 *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, 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. } } } //insert blank record that can be used to add new messages ui->MessagesTable->insertRow(ui->MessagesTable->rowCount()); }