#include "dbccomparatorwindow.h" #include "ui_dbccomparatorwindow.h" #include "helpwindow.h" #include #include #include DBCComparatorWindow::DBCComparatorWindow(QWidget *parent) : QDialog(parent), ui(new Ui::DBCComparatorWindow) { ui->setupUi(this); setWindowFlags(Qt::Window); connect(ui->btnDBCFile1, SIGNAL(clicked(bool)), this, SLOT(loadFirstFile())); connect(ui->btnDBCFile2, SIGNAL(clicked(bool)), this, SLOT(loadSecondFile())); connect(ui->btnSaveDetails, SIGNAL(clicked(bool)), this, SLOT(saveDetails())); ui->lblFirstFile->setText(""); ui->lblSecondFile->setText(""); firstDBC = nullptr; secondDBC = nullptr; installEventFilter(this); } DBCComparatorWindow::~DBCComparatorWindow() { removeEventFilter(this); delete ui; } void DBCComparatorWindow::showEvent(QShowEvent *) { readSettings(); } void DBCComparatorWindow::closeEvent(QCloseEvent *event) { Q_UNUSED(event) writeSettings(); } bool DBCComparatorWindow::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::KeyRelease) { QKeyEvent *keyEvent = static_cast(event); switch (keyEvent->key()) { case Qt::Key_F1: HelpWindow::getRef()->showHelp("filecomparison.md"); break; } return true; } else { // standard event processing return QObject::eventFilter(obj, event); } return false; } void DBCComparatorWindow::readSettings() { QSettings settings; if (settings.value("Main/SaveRestorePositions", false).toBool()) { resize(settings.value("DBCComparator/WindowSize", QSize(720, 631)).toSize()); move(Utility::constrainedWindowPos(settings.value("DBCComparator/WindowPos", QPoint(50, 50)).toPoint())); } } void DBCComparatorWindow::writeSettings() { QSettings settings; if (settings.value("Main/SaveRestorePositions", false).toBool()) { settings.setValue("DBCComparator/WindowSize", size()); settings.setValue("DBCComparator/WindowPos", pos()); } } QString DBCComparatorWindow::loadDBC(DBCFile **file) { QString filename; QFileDialog dialog; QSettings settings; QStringList filters; filters.append(QString(tr("DBC Files (*.dbc *.DBC)"))); dialog.setDirectory(settings.value("FileIO/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]; QProgressDialog progress(qApp->activeWindow()); progress.setWindowModality(Qt::WindowModal); progress.setLabelText("Loading file..."); progress.setCancelButton(nullptr); progress.setRange(0,0); progress.setMinimumDuration(0); progress.show(); qApp->processEvents(); if (dialog.selectedNameFilter() == filters[0]) { if (file[0]) delete file[0]; file[0] = new DBCFile; file[0]->loadFile(filename); qDebug() << "Loaded the DBC file into first slot"; } progress.cancel(); return filename; } return QString(); } void DBCComparatorWindow::loadFirstFile() { QString filename; filename = loadDBC(&firstDBC); ui->lblFirstFile->setText(filename); if (firstDBC && secondDBC) calculateDetails(); } void DBCComparatorWindow::loadSecondFile() { QString filename; filename = loadDBC(&secondDBC); ui->lblSecondFile->setText(filename); if (firstDBC && secondDBC) calculateDetails(); } void DBCComparatorWindow::calculateDetails() { QProgressDialog progress(this); progress.setWindowModality(Qt::WindowModal); progress.setLabelText("Calculating differences"); progress.setCancelButton(nullptr); progress.setRange(0,0); progress.setMinimumDuration(0); progress.show(); qApp->processEvents(); firstDBC->sort(); secondDBC->sort(); ui->treeDetails->clear(); //Find nodes missing in one of the DBC files QTreeWidgetItem *nodeDiffRoot = new QTreeWidgetItem(); nodeDiffRoot->setText(0, "Node Differences"); QTreeWidgetItem *nodesMissingDBCFirst = new QTreeWidgetItem(); nodesMissingDBCFirst->setText(0, "Nodes not found in first DBC"); QTreeWidgetItem *nodesMissingDBCSecond = new QTreeWidgetItem(); nodesMissingDBCSecond->setText(0, "Nodes not found in second DBC"); nodeDiffRoot->addChild(nodesMissingDBCFirst); nodeDiffRoot->addChild(nodesMissingDBCSecond); ui->treeDetails->addTopLevelItem(nodeDiffRoot); for (int i = 0; i < firstDBC->dbc_nodes.count(); i++) { QString nodeName = firstDBC->dbc_nodes[i].name; DBC_NODE *node = secondDBC->findNodeByName(nodeName); if (!node) { QTreeWidgetItem *missingNodeItem = new QTreeWidgetItem(); missingNodeItem->setText(0, nodeName); nodesMissingDBCSecond->addChild(missingNodeItem); } } for (int i = 0; i < secondDBC->dbc_nodes.count(); i++) { QString nodeName = secondDBC->dbc_nodes[i].name; DBC_NODE *node = firstDBC->findNodeByName(nodeName); if (!node) { QTreeWidgetItem *missingNodeItem = new QTreeWidgetItem(); missingNodeItem->setText(0, nodeName); nodesMissingDBCFirst->addChild(missingNodeItem); } } //Find messages that are missing in one of the DBC files //If a message exists in both then check for missing signals QTreeWidgetItem *msgDiffRoot = new QTreeWidgetItem(); msgDiffRoot->setText(0, "Message Differences"); QTreeWidgetItem *msgMissingDBCFirst = new QTreeWidgetItem(); msgMissingDBCFirst->setText(0, "Messages not found in first DBC"); QTreeWidgetItem *msgMissingDBCSecond = new QTreeWidgetItem(); msgMissingDBCSecond->setText(0, "Messages not found in second DBC"); QTreeWidgetItem *msgSignalsDiff = new QTreeWidgetItem(); msgSignalsDiff->setText(0, "Messages with missing signals"); QTreeWidgetItem *sigDiffOne = new QTreeWidgetItem(); sigDiffOne->setText(0, "Missing from first DBC"); QTreeWidgetItem *sigDiffTwo = new QTreeWidgetItem(); sigDiffTwo->setText(0, "Missing from second DBC"); QTreeWidgetItem *sigModifiedRoot = new QTreeWidgetItem(); sigModifiedRoot->setText(0, "Modified Signals"); msgSignalsDiff->addChild(sigDiffOne); msgSignalsDiff->addChild(sigDiffTwo); msgDiffRoot->addChild(msgMissingDBCFirst); msgDiffRoot->addChild(msgMissingDBCSecond); msgDiffRoot->addChild(msgSignalsDiff); msgDiffRoot->addChild(sigModifiedRoot); ui->treeDetails->addTopLevelItem(msgDiffRoot); QTreeWidgetItem *msgItem {}; QTreeWidgetItem *sigTemp {}; for (int i = 0; i < firstDBC->messageHandler->getCount(); i++) { DBC_MESSAGE *thisMsg = firstDBC->messageHandler->findMsgByIdx(i); QString msgName = thisMsg->name; DBC_MESSAGE *otherMsg = secondDBC->messageHandler->findMsgByName(msgName); if (!otherMsg) { QTreeWidgetItem *missingMsgItem = new QTreeWidgetItem(); missingMsgItem->setText(0, msgName+ " (" + Utility::formatCANID(thisMsg->ID) + ")"); msgMissingDBCSecond->addChild(missingMsgItem); } else //both have Msg. Check sigs for missing { bool thisMsgHasMissing = false; bool thisMsgHasMods = false; for (int i = 0; i < thisMsg->sigHandler->getCount(); i++) { DBC_SIGNAL *thisSig = thisMsg->sigHandler->findSignalByIdx(i); QString sigName = thisSig->name; DBC_SIGNAL *otherSig = otherMsg->sigHandler->findSignalByName(sigName); if (!otherSig) { QTreeWidgetItem *missingSigItem = new QTreeWidgetItem(); missingSigItem->setText(0, sigName); if (!thisMsgHasMissing) { thisMsgHasMissing = true; msgItem = new QTreeWidgetItem(); msgItem->setText(0, msgName + " (" + Utility::formatCANID(thisMsg->ID) + ")"); sigDiffTwo->addChild(msgItem); } if (msgItem) msgItem->addChild(missingSigItem); } else //signal exists on both sides. See if it as changed position or length { bool didChange = false; QTreeWidgetItem *sigItem = new QTreeWidgetItem(); sigItem->setText(0, sigName); if (thisSig->startBit != otherSig->startBit) { didChange = true; QTreeWidgetItem *sigStartBit = new QTreeWidgetItem(); sigStartBit->setText(0, "Start Bit First DBC: " + QString::number(thisSig->startBit) + " Second: " + QString::number(otherSig->startBit)); sigItem->addChild(sigStartBit); } if (thisSig->signalSize != otherSig->signalSize) { didChange = true; QTreeWidgetItem *sigSize = new QTreeWidgetItem(); sigSize->setText(0, "Size First DBC: " + QString::number(thisSig->signalSize) + " Second: " + QString::number(otherSig->signalSize)); sigItem->addChild(sigSize); } if (thisSig->bias != otherSig->bias) { didChange = true; QTreeWidgetItem *sigBias = new QTreeWidgetItem(); sigBias->setText(0, "Bias First DBC: " + QString::number(thisSig->bias) + " Second: " + QString::number(otherSig->bias)); sigItem->addChild(sigBias); } if (thisSig->factor != otherSig->factor) { didChange = true; QTreeWidgetItem *sigFactor = new QTreeWidgetItem(); sigFactor->setText(0, "Factor First DBC: " + QString::number(thisSig->factor) + " Second: " + QString::number(otherSig->factor)); sigItem->addChild(sigFactor); } if (didChange) { if (!thisMsgHasMods) { thisMsgHasMods = true; sigTemp = new QTreeWidgetItem(); sigTemp->setText(0, msgName + " (" + Utility::formatCANID(thisMsg->ID) + ")"); sigModifiedRoot->addChild(sigTemp); } if (sigTemp) sigTemp->addChild(sigItem); } } } thisMsgHasMissing = false; for (int i = 0; i < otherMsg->sigHandler->getCount(); i++) { DBC_SIGNAL *thisSig = otherMsg->sigHandler->findSignalByIdx(i); QString sigName = thisSig->name; DBC_SIGNAL *otherSig = thisMsg->sigHandler->findSignalByName(sigName); if (!otherSig) { QTreeWidgetItem *missingSigItem = new QTreeWidgetItem(); missingSigItem->setText(0, sigName); if (!thisMsgHasMissing) { thisMsgHasMissing = true; msgItem = new QTreeWidgetItem(); msgItem->setText(0, msgName + " (" + Utility::formatCANID(thisMsg->ID) + ")"); sigDiffOne->addChild(msgItem); } msgItem->addChild(missingSigItem); } } } } for (int i = 0; i < secondDBC->messageHandler->getCount(); i++) { DBC_MESSAGE *origMsg = secondDBC->messageHandler->findMsgByIdx(i); QString msgName = origMsg->name; DBC_MESSAGE *msg = firstDBC->messageHandler->findMsgByName(msgName); if (!msg) { QTreeWidgetItem *missingMsgItem = new QTreeWidgetItem(); missingMsgItem->setText(0, msgName + " (" + Utility::formatCANID(origMsg->ID) + ")"); msgMissingDBCFirst->addChild(missingMsgItem); } } QSettings settings; if (settings.value("InfoCompare/AutoExpand", false).toBool()) { ui->treeDetails->expandAll(); } progress.cancel(); qApp->processEvents(); } void DBCComparatorWindow::saveDetails() { QString filename; QFileDialog dialog(this); QSettings settings; QStringList filters; filters.append(QString(tr("Text File (*.txt)"))); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilters(filters); dialog.setViewMode(QFileDialog::Detail); dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setDirectory(settings.value("FileComparator/LoadSaveDirectory", dialog.directory().path()).toString()); if (dialog.exec() == QDialog::Accepted) { filename = dialog.selectedFiles()[0]; settings.setValue("FileComparator/LoadSaveDirectory", dialog.directory().path()); if (!filename.contains('.')) filename += ".txt"; QFile *outFile = new QFile(filename); if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text)) return; QTreeWidget *tree = ui->treeDetails; QTreeWidgetItemIterator it(tree); while (*it) { QTreeWidgetItem *item = *it; QString itemText = item->text(0); while (item->parent()) { outFile->write(" "); item = item->parent(); } outFile->write(itemText.toUtf8() + "\n"); ++it; } outFile->close(); } }