Addition of a file comparison window that can be used to find what sort of things changed between two files.
This commit is contained in:
+6
-3
@@ -28,7 +28,8 @@ SOURCES += main.cpp\
|
|||||||
dbchandler.cpp \
|
dbchandler.cpp \
|
||||||
dbcmaineditor.cpp \
|
dbcmaineditor.cpp \
|
||||||
dbcsignaleditor.cpp \
|
dbcsignaleditor.cpp \
|
||||||
framefileio.cpp
|
framefileio.cpp \
|
||||||
|
filecomparatorwindow.cpp
|
||||||
|
|
||||||
HEADERS += mainwindow.h \
|
HEADERS += mainwindow.h \
|
||||||
can_structs.h \
|
can_structs.h \
|
||||||
@@ -49,7 +50,8 @@ HEADERS += mainwindow.h \
|
|||||||
dbcmaineditor.h \
|
dbcmaineditor.h \
|
||||||
dbcsignaleditor.h \
|
dbcsignaleditor.h \
|
||||||
framefileio.h \
|
framefileio.h \
|
||||||
config.h
|
config.h \
|
||||||
|
filecomparatorwindow.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui \
|
FORMS += mainwindow.ui \
|
||||||
graphingwindow.ui \
|
graphingwindow.ui \
|
||||||
@@ -60,7 +62,8 @@ FORMS += mainwindow.ui \
|
|||||||
flowviewwindow.ui \
|
flowviewwindow.ui \
|
||||||
framesenderwindow.ui \
|
framesenderwindow.ui \
|
||||||
dbcmaineditor.ui \
|
dbcmaineditor.ui \
|
||||||
dbcsignaleditor.ui
|
dbcsignaleditor.ui \
|
||||||
|
filecomparatorwindow.ui
|
||||||
|
|
||||||
DISTFILES +=
|
DISTFILES +=
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,259 @@
|
|||||||
|
#include "filecomparatorwindow.h"
|
||||||
|
#include "ui_filecomparatorwindow.h"
|
||||||
|
|
||||||
|
FileComparatorWindow::FileComparatorWindow(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::FileComparatorWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->btnFirstFile, SIGNAL(clicked(bool)), this, SLOT(loadFirstFile()));
|
||||||
|
connect(ui->btnSecondFile, SIGNAL(clicked(bool)), this, SLOT(loadSecondFile()));
|
||||||
|
connect(ui->btnSaveDetails, SIGNAL(clicked(bool)), this, SLOT(saveDetails()));
|
||||||
|
|
||||||
|
ui->lblFirstFile->setText("");
|
||||||
|
ui->lblSecondFile->setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
FileComparatorWindow::~FileComparatorWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileComparatorWindow::loadFirstFile()
|
||||||
|
{
|
||||||
|
firstFileFrames.clear();
|
||||||
|
QString result = FrameFileIO::loadFrameFile(&firstFileFrames);
|
||||||
|
if (result.length() > 0)
|
||||||
|
{
|
||||||
|
ui->lblFirstFile->setText(result);
|
||||||
|
firstFilename = result;
|
||||||
|
if (firstFileFrames.count() > 0 && secondFileFrames.count() > 0) calculateDetails();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileComparatorWindow::loadSecondFile()
|
||||||
|
{
|
||||||
|
secondFileFrames.clear();
|
||||||
|
QString result = FrameFileIO::loadFrameFile(&secondFileFrames);
|
||||||
|
if (result.length() > 0)
|
||||||
|
{
|
||||||
|
ui->lblSecondFile->setText(result);
|
||||||
|
secondFilename = result;
|
||||||
|
if (firstFileFrames.count() > 0 && secondFileFrames.count() > 0) calculateDetails();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileComparatorWindow::calculateDetails()
|
||||||
|
{
|
||||||
|
QHash<int, FrameData> firstFileIDs;
|
||||||
|
QHash<int, FrameData> secondFileIDs;
|
||||||
|
uint64_t shiftBase = 1; //stupid hack to ensure that 64 bit shifting is used.
|
||||||
|
QTreeWidgetItem *firstOnlyBase, *secondOnlyBase, *sharedBase, *bitmapBaseFirst, *bitmapBaseSecond;
|
||||||
|
QTreeWidgetItem *valuesBase, *detail, *sharedItem, *valuesFirst, *valuesSecond;
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
ui->treeDetails->clear();
|
||||||
|
|
||||||
|
firstOnlyBase = new QTreeWidgetItem();
|
||||||
|
firstOnlyBase->setText(0,"IDs found only in " + firstFilename);
|
||||||
|
secondOnlyBase = new QTreeWidgetItem();
|
||||||
|
secondOnlyBase->setText(0, "IDs found only in " + secondFilename);
|
||||||
|
sharedBase = new QTreeWidgetItem();
|
||||||
|
sharedBase->setText(0,"IDs found in both files");
|
||||||
|
|
||||||
|
//first we have to fill out the data structures to get ready to do the report
|
||||||
|
for (int x = 0; x < firstFileFrames.count(); x++)
|
||||||
|
{
|
||||||
|
CANFrame frame = firstFileFrames.at(x);
|
||||||
|
if (firstFileIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there
|
||||||
|
{
|
||||||
|
for (int y = 0; y < frame.len; y++)
|
||||||
|
{
|
||||||
|
firstFileIDs[frame.ID].values[y][frame.data[y]]++;
|
||||||
|
firstFileIDs[frame.ID].bitmap |= frame.data[y] << (8 * y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //never seen this ID before so add one
|
||||||
|
{
|
||||||
|
FrameData *newData = new FrameData();
|
||||||
|
newData->ID = frame.ID;
|
||||||
|
newData->dataLen = frame.len;
|
||||||
|
//it would be possible to implement a constructor for FrameData
|
||||||
|
//that sets the bitmap and values to zero. That would be cleaner and better.
|
||||||
|
newData->bitmap = 0;
|
||||||
|
//C++ arrays take the form of a single memory block so zap the whole block at once
|
||||||
|
memset(newData->values, 0, 256 * 8);
|
||||||
|
for (int y = 0; y < frame.len; y++)
|
||||||
|
{
|
||||||
|
newData->values[y][frame.data[y]] = 1;
|
||||||
|
newData->bitmap |= frame.data[y] << (8 * y);
|
||||||
|
}
|
||||||
|
firstFileIDs.insert(frame.ID, *newData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < secondFileFrames.count(); x++)
|
||||||
|
{
|
||||||
|
CANFrame frame = secondFileFrames.at(x);
|
||||||
|
if (secondFileIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there
|
||||||
|
{
|
||||||
|
for (int y = 0; y < frame.len; y++)
|
||||||
|
{
|
||||||
|
secondFileIDs[frame.ID].values[y][frame.data[y]]++;
|
||||||
|
secondFileIDs[frame.ID].bitmap |= frame.data[y] << (8 * y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //never seen this ID before so add one
|
||||||
|
{
|
||||||
|
FrameData *newData = new FrameData();
|
||||||
|
newData->ID = frame.ID;
|
||||||
|
newData->dataLen = frame.len;
|
||||||
|
newData->bitmap = 0;
|
||||||
|
memset(newData->values, 0, 256 * 8);
|
||||||
|
for (int y = 0; y < frame.len; y++)
|
||||||
|
{
|
||||||
|
newData->values[y][frame.data[y]] = 1;
|
||||||
|
newData->bitmap |= frame.data[y] << (8 * y);
|
||||||
|
}
|
||||||
|
secondFileIDs.insert(frame.ID, *newData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//now we iterate through the IDs within both files and see which are unique to one file and which
|
||||||
|
//are shared
|
||||||
|
QHash<int, FrameData>::iterator i;
|
||||||
|
for (i = firstFileIDs.begin(); i != firstFileIDs.end(); ++i)
|
||||||
|
{
|
||||||
|
int keyone = i.key();
|
||||||
|
if (!secondFileIDs.contains(keyone))
|
||||||
|
{
|
||||||
|
valuesBase = new QTreeWidgetItem();
|
||||||
|
valuesBase->setText(0, QString::number(keyone, 16));
|
||||||
|
firstOnlyBase->addChild(valuesBase);
|
||||||
|
}
|
||||||
|
else //ID was in both files
|
||||||
|
{
|
||||||
|
sharedItem = new QTreeWidgetItem();
|
||||||
|
sharedItem->setText(0, Utility::formatHexNum(keyone));
|
||||||
|
sharedBase->addChild(sharedItem);
|
||||||
|
//if the ID was in both files then we can use the data accumulated above in bitmap
|
||||||
|
//and values to figure out what has changed between the two files
|
||||||
|
|
||||||
|
FrameData first = firstFileIDs[keyone];
|
||||||
|
FrameData second = secondFileIDs[keyone];
|
||||||
|
|
||||||
|
bitmapBaseFirst = new QTreeWidgetItem();
|
||||||
|
bitmapBaseFirst->setText(0, "Bits set only in " + firstFilename);
|
||||||
|
bitmapBaseSecond = new QTreeWidgetItem();
|
||||||
|
bitmapBaseSecond->setText(0, "Bits set only in " + secondFilename);
|
||||||
|
sharedItem->addChild(bitmapBaseFirst);
|
||||||
|
sharedItem->addChild(bitmapBaseSecond);
|
||||||
|
|
||||||
|
//first up, which bits were set in one file but not the other
|
||||||
|
for (int b = 0; b < 64; b++)
|
||||||
|
{
|
||||||
|
detail = new QTreeWidgetItem();
|
||||||
|
detail->setText(0, QString::number(b) + " (" + QString::number(b / 8) + ":" + QString::number(b % 8) + ")");
|
||||||
|
if ( (first.bitmap & (shiftBase<<b)) && !(second.bitmap & (shiftBase<<b)) )
|
||||||
|
{
|
||||||
|
bitmapBaseFirst->addChild(detail);
|
||||||
|
}
|
||||||
|
if ( !(first.bitmap & (shiftBase<<b)) && (second.bitmap & (shiftBase<<b)) )
|
||||||
|
{
|
||||||
|
bitmapBaseSecond->addChild(detail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < qMax(first.dataLen, second.dataLen); i++)
|
||||||
|
{
|
||||||
|
valuesBase = new QTreeWidgetItem();
|
||||||
|
valuesBase->setText(0, "Byte " + QString::number(i));
|
||||||
|
sharedItem->addChild(valuesBase);
|
||||||
|
valuesFirst = new QTreeWidgetItem();
|
||||||
|
valuesFirst->setText(0, "Values found only in " + firstFilename);
|
||||||
|
valuesSecond = new QTreeWidgetItem();
|
||||||
|
valuesSecond->setText(0, "Values found only in " + secondFilename);
|
||||||
|
valuesBase->addChild(valuesFirst);
|
||||||
|
valuesBase->addChild(valuesSecond);
|
||||||
|
for (int j = 0; j < 256; j++)
|
||||||
|
{
|
||||||
|
detail = new QTreeWidgetItem();
|
||||||
|
detail->setText(0, Utility::formatHexNum(j));
|
||||||
|
if (first.values[i][j] > 0 && second.values[i][j] == 0)
|
||||||
|
{
|
||||||
|
valuesFirst->addChild(detail);
|
||||||
|
}
|
||||||
|
if (second.values[i][j] > 0 && first.values[i][j] == 0)
|
||||||
|
{
|
||||||
|
valuesSecond->addChild(detail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, FrameData>::iterator itwo;
|
||||||
|
for (itwo = secondFileIDs.begin(); itwo != secondFileIDs.end(); ++itwo)
|
||||||
|
{
|
||||||
|
int keytwo = itwo.key();
|
||||||
|
if (!firstFileIDs.contains(keytwo))
|
||||||
|
{
|
||||||
|
valuesBase = new QTreeWidgetItem();
|
||||||
|
valuesBase->setText(0, Utility::formatHexNum(keytwo));
|
||||||
|
secondOnlyBase->addChild(valuesBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->treeDetails->addTopLevelItem(firstOnlyBase);
|
||||||
|
ui->treeDetails->addTopLevelItem(secondOnlyBase);
|
||||||
|
ui->treeDetails->addTopLevelItem(sharedBase);
|
||||||
|
|
||||||
|
ui->treeDetails->setSortingEnabled(true);
|
||||||
|
ui->treeDetails->sortByColumn(0, Qt::AscendingOrder);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileComparatorWindow::saveDetails()
|
||||||
|
{
|
||||||
|
QString filename;
|
||||||
|
QFileDialog dialog(this);
|
||||||
|
|
||||||
|
QStringList filters;
|
||||||
|
filters.append(QString(tr("Text File (*.txt)")));
|
||||||
|
|
||||||
|
dialog.setFileMode(QFileDialog::AnyFile);
|
||||||
|
dialog.setNameFilters(filters);
|
||||||
|
dialog.setViewMode(QFileDialog::Detail);
|
||||||
|
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||||
|
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
filename = dialog.selectedFiles()[0];
|
||||||
|
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();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef FILECOMPARATORWINDOW_H
|
||||||
|
#define FILECOMPARATORWINDOW_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTreeWidget>
|
||||||
|
#include "framefileio.h"
|
||||||
|
#include "can_structs.h"
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class FileComparatorWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FrameData
|
||||||
|
{
|
||||||
|
int ID;
|
||||||
|
int dataLen;
|
||||||
|
uint64_t bitmap;
|
||||||
|
int values[8][256]; //first index is the data byte, second is # of times we saw that value
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileComparatorWindow : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FileComparatorWindow(QWidget *parent = 0);
|
||||||
|
~FileComparatorWindow();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void loadFirstFile();
|
||||||
|
void loadSecondFile();
|
||||||
|
void saveDetails();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::FileComparatorWindow *ui;
|
||||||
|
QVector<CANFrame> firstFileFrames;
|
||||||
|
QVector<CANFrame> secondFileFrames;
|
||||||
|
QString firstFilename;
|
||||||
|
QString secondFilename;
|
||||||
|
|
||||||
|
void calculateDetails();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILECOMPARATORWINDOW_H
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>FileComparatorWindow</class>
|
||||||
|
<widget class="QDialog" name="FileComparatorWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>720</width>
|
||||||
|
<height>631</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>File Comparator</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>First File:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblFirstFile">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnFirstFile">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load New File</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Second File:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblSecondFile">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnSecondFile">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load New File</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeWidget" name="treeDetails">
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">1</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnSaveDetails">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save Details to File</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -5,6 +5,43 @@ FrameFileIO::FrameFileIO()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FrameFileIO::loadFrameFile(QVector<CANFrame>* frameCache)
|
||||||
|
{
|
||||||
|
QString filename;
|
||||||
|
QFileDialog dialog;
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
QStringList filters;
|
||||||
|
filters.append(QString(tr("CRTD Logs (*.txt)")));
|
||||||
|
filters.append(QString(tr("GVRET Logs (*.csv)")));
|
||||||
|
filters.append(QString(tr("Generic ID/Data CSV (*.csv)")));
|
||||||
|
filters.append(QString(tr("BusMaster Log (*.log)")));
|
||||||
|
filters.append(QString(tr("Microchip Log (*.log)")));
|
||||||
|
|
||||||
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||||
|
dialog.setNameFilters(filters);
|
||||||
|
dialog.setViewMode(QFileDialog::Detail);
|
||||||
|
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
filename = dialog.selectedFiles()[0];
|
||||||
|
|
||||||
|
if (dialog.selectedNameFilter() == filters[0]) result = loadCRTDFile(filename, frameCache);
|
||||||
|
if (dialog.selectedNameFilter() == filters[1]) result = loadNativeCSVFile(filename, frameCache);
|
||||||
|
if (dialog.selectedNameFilter() == filters[2]) result = loadGenericCSVFile(filename, frameCache);
|
||||||
|
if (dialog.selectedNameFilter() == filters[3]) result = loadLogFile(filename, frameCache);
|
||||||
|
if (dialog.selectedNameFilter() == filters[4]) result = loadMicrochipFile(filename, frameCache);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
QStringList fileList = filename.split('/');
|
||||||
|
filename = fileList[fileList.length() - 1];
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
else return QString("");
|
||||||
|
}
|
||||||
|
return QString("");
|
||||||
|
}
|
||||||
|
|
||||||
//CRTD format from Mark Webb-Johnson / OVMS project
|
//CRTD format from Mark Webb-Johnson / OVMS project
|
||||||
/*
|
/*
|
||||||
Sample data in CRTD format
|
Sample data in CRTD format
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QFileDialog>
|
||||||
#include "can_structs.h"
|
#include "can_structs.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ public:
|
|||||||
static bool saveGenericCSVFile(QString, QVector<CANFrame>*);
|
static bool saveGenericCSVFile(QString, QVector<CANFrame>*);
|
||||||
static bool saveLogFile(QString, QVector<CANFrame>*);
|
static bool saveLogFile(QString, QVector<CANFrame>*);
|
||||||
static bool saveMicrochipFile(QString, QVector<CANFrame>*);
|
static bool saveMicrochipFile(QString, QVector<CANFrame>*);
|
||||||
|
static QString loadFrameFile(QVector<CANFrame>*);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FRAMEFILEIO_H
|
#endif // FRAMEFILEIO_H
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
flowViewWindow = NULL;
|
flowViewWindow = NULL;
|
||||||
frameSenderWindow = NULL;
|
frameSenderWindow = NULL;
|
||||||
dbcMainEditor = NULL;
|
dbcMainEditor = NULL;
|
||||||
|
comparatorWindow = NULL;
|
||||||
dbcHandler = new DBCHandler;
|
dbcHandler = new DBCHandler;
|
||||||
bDirty = false;
|
bDirty = false;
|
||||||
|
|
||||||
@@ -128,6 +129,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
connect(ui->actionRange_State, SIGNAL(triggered(bool)), this, SLOT(showRangeWindow()));
|
connect(ui->actionRange_State, SIGNAL(triggered(bool)), this, SLOT(showRangeWindow()));
|
||||||
connect(ui->actionSave_Decoded_Frames, SIGNAL(triggered(bool)), this, SLOT(handleSaveDecoded()));
|
connect(ui->actionSave_Decoded_Frames, SIGNAL(triggered(bool)), this, SLOT(handleSaveDecoded()));
|
||||||
connect(ui->actionSingle_Multi_State, SIGNAL(triggered(bool)), this, SLOT(showSingleMultiWindow()));
|
connect(ui->actionSingle_Multi_State, SIGNAL(triggered(bool)), this, SLOT(showSingleMultiWindow()));
|
||||||
|
connect(ui->actionFile_Comparison, SIGNAL(triggered(bool)), this, SLOT(showComparisonWindow()));
|
||||||
|
|
||||||
lbStatusConnected.setText(tr("Not connected"));
|
lbStatusConnected.setText(tr("Not connected"));
|
||||||
updateFileStatus();
|
updateFileStatus();
|
||||||
@@ -187,6 +189,12 @@ MainWindow::~MainWindow()
|
|||||||
delete frameSenderWindow;
|
delete frameSenderWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (comparatorWindow)
|
||||||
|
{
|
||||||
|
comparatorWindow->close();
|
||||||
|
delete comparatorWindow;
|
||||||
|
}
|
||||||
|
|
||||||
if (dbcMainEditor)
|
if (dbcMainEditor)
|
||||||
{
|
{
|
||||||
dbcMainEditor->close();
|
dbcMainEditor->close();
|
||||||
@@ -602,6 +610,15 @@ void MainWindow::showPlaybackWindow()
|
|||||||
playbackWindow->show();
|
playbackWindow->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::showComparisonWindow()
|
||||||
|
{
|
||||||
|
if (!comparatorWindow)
|
||||||
|
{
|
||||||
|
comparatorWindow = new FileComparatorWindow();
|
||||||
|
}
|
||||||
|
comparatorWindow->show();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::showSingleMultiWindow()
|
void MainWindow::showSingleMultiWindow()
|
||||||
{
|
{
|
||||||
//not done yet
|
//not done yet
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "frameplaybackwindow.h"
|
#include "frameplaybackwindow.h"
|
||||||
#include "flowviewwindow.h"
|
#include "flowviewwindow.h"
|
||||||
#include "framesenderwindow.h"
|
#include "framesenderwindow.h"
|
||||||
|
#include "filecomparatorwindow.h"
|
||||||
#include "dbchandler.h"
|
#include "dbchandler.h"
|
||||||
#include "dbcmaineditor.h"
|
#include "dbcmaineditor.h"
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ private slots:
|
|||||||
void showSingleMultiWindow();
|
void showSingleMultiWindow();
|
||||||
void showRangeWindow();
|
void showRangeWindow();
|
||||||
void showFuzzyScopeWindow();
|
void showFuzzyScopeWindow();
|
||||||
|
void showComparisonWindow();
|
||||||
void exitApp();
|
void exitApp();
|
||||||
void handleSaveDecoded();
|
void handleSaveDecoded();
|
||||||
void changeBaudRates();
|
void changeBaudRates();
|
||||||
@@ -93,6 +95,7 @@ private:
|
|||||||
FlowViewWindow *flowViewWindow;
|
FlowViewWindow *flowViewWindow;
|
||||||
FrameSenderWindow *frameSenderWindow;
|
FrameSenderWindow *frameSenderWindow;
|
||||||
DBCMainEditor *dbcMainEditor;
|
DBCMainEditor *dbcMainEditor;
|
||||||
|
FileComparatorWindow *comparatorWindow;
|
||||||
|
|
||||||
//various private storage
|
//various private storage
|
||||||
QLabel lbStatusConnected;
|
QLabel lbStatusConnected;
|
||||||
|
|||||||
@@ -252,6 +252,7 @@
|
|||||||
<addaction name="actionFuzzy_Scope"/>
|
<addaction name="actionFuzzy_Scope"/>
|
||||||
<addaction name="actionGraph_Dta"/>
|
<addaction name="actionGraph_Dta"/>
|
||||||
<addaction name="actionFrame_Data_Analysis"/>
|
<addaction name="actionFrame_Data_Analysis"/>
|
||||||
|
<addaction name="actionFile_Comparison"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuSend_Frames">
|
<widget class="QMenu" name="menuSend_Frames">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -362,6 +363,11 @@
|
|||||||
<string>Exit Application</string>
|
<string>Exit Application</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionFile_Comparison">
|
||||||
|
<property name="text">
|
||||||
|
<string>File Comparison</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|||||||
@@ -44,6 +44,18 @@ public:
|
|||||||
QDateTime stamp = QDateTime::currentDateTime();
|
QDateTime stamp = QDateTime::currentDateTime();
|
||||||
return (long)(((stamp.time().hour() * 3600) + (stamp.time().minute() * 60) + (stamp.time().second()) * 1000) + stamp.time().msec());
|
return (long)(((stamp.time().hour() * 3600) + (stamp.time().minute() * 60) + (stamp.time().second()) * 1000) + stamp.time().msec());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//prints hex numbers in uppercase with 0's filling out the number depending
|
||||||
|
//on the size needed. Promotes hex numbers to either 2, 4, or 8 digits
|
||||||
|
static QString formatHexNum(int input)
|
||||||
|
{
|
||||||
|
if (input < 256)
|
||||||
|
return QString::number(input, 16).toUpper().rightJustified(2,'0');
|
||||||
|
if (input < 65536)
|
||||||
|
return QString::number(input, 16).toUpper().rightJustified(4,'0');
|
||||||
|
|
||||||
|
return QString::number(input, 16).toUpper().rightJustified(8,'0');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UTILITY_H
|
#endif // UTILITY_H
|
||||||
|
|||||||
Reference in New Issue
Block a user