400 lines
14 KiB
C++
400 lines
14 KiB
C++
#include "dbccomparatorwindow.h"
|
|
#include "ui_dbccomparatorwindow.h"
|
|
#include "helpwindow.h"
|
|
#include <QProgressDialog>
|
|
#include <QSettings>
|
|
#include <qevent.h>
|
|
|
|
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<QKeyEvent *>(event);
|
|
switch (keyEvent->key())
|
|
{
|
|
case Qt::Key_F1:
|
|
HelpWindow::getRef()->showHelp("filecomparison.html");
|
|
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(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);
|
|
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);
|
|
sigDiffTwo->addChild(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);
|
|
sigModifiedRoot->addChild(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);
|
|
sigDiffOne->addChild(msgItem);
|
|
}
|
|
msgItem->addChild(missingSigItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < secondDBC->messageHandler->getCount(); i++)
|
|
{
|
|
QString msgName = secondDBC->messageHandler->findMsgByIdx(i)->name;
|
|
DBC_MESSAGE *msg = firstDBC->messageHandler->findMsgByName(msgName);
|
|
if (!msg)
|
|
{
|
|
QTreeWidgetItem *missingMsgItem = new QTreeWidgetItem();
|
|
missingMsgItem->setText(0, msgName);
|
|
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();
|
|
|
|
}
|
|
}
|
|
|