Expanded file comparator window to be able to compare one file to many
other files. Also, it can now filter to only show IDs that had data unique to the one file of interest. This all should make it easier to find data.
This commit is contained in:
+111
-91
@@ -9,12 +9,13 @@ FileComparatorWindow::FileComparatorWindow(QWidget *parent) :
|
|||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
connect(ui->btnFirstFile, SIGNAL(clicked(bool)), this, SLOT(loadFirstFile()));
|
connect(ui->btnInterestedFile, SIGNAL(clicked(bool)), this, SLOT(loadInterestedFile()));
|
||||||
connect(ui->btnSecondFile, SIGNAL(clicked(bool)), this, SLOT(loadSecondFile()));
|
connect(ui->btnLoadRefFile, SIGNAL(clicked(bool)), this, SLOT(loadReferenceFile()));
|
||||||
connect(ui->btnSaveDetails, SIGNAL(clicked(bool)), this, SLOT(saveDetails()));
|
connect(ui->btnSaveDetails, SIGNAL(clicked(bool)), this, SLOT(saveDetails()));
|
||||||
|
connect(ui->btnClear, SIGNAL(clicked(bool)), this, SLOT(clearReference()));
|
||||||
|
|
||||||
ui->lblFirstFile->setText("");
|
ui->lblFirstFile->setText("");
|
||||||
ui->lblSecondFile->setText("");
|
ui->lblRefFrames->setText("0");
|
||||||
}
|
}
|
||||||
|
|
||||||
FileComparatorWindow::~FileComparatorWindow()
|
FileComparatorWindow::~FileComparatorWindow()
|
||||||
@@ -53,62 +54,70 @@ void FileComparatorWindow::writeSettings()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileComparatorWindow::loadFirstFile()
|
void FileComparatorWindow::loadInterestedFile()
|
||||||
{
|
{
|
||||||
firstFileFrames.clear();
|
interestedFrames.clear();
|
||||||
QString result = FrameFileIO::loadFrameFile(&firstFileFrames);
|
QString result = FrameFileIO::loadFrameFile(&interestedFrames);
|
||||||
if (result.length() > 0)
|
if (result.length() > 0)
|
||||||
{
|
{
|
||||||
ui->lblFirstFile->setText(result);
|
ui->lblFirstFile->setText(result);
|
||||||
firstFilename = result;
|
interestedFilename = result;
|
||||||
if (firstFileFrames.count() > 0 && secondFileFrames.count() > 0) calculateDetails();
|
if (interestedFrames.count() > 0 && referenceFrames.count() > 0) calculateDetails();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileComparatorWindow::loadSecondFile()
|
void FileComparatorWindow::loadReferenceFile()
|
||||||
{
|
{
|
||||||
secondFileFrames.clear();
|
//secondFileFrames.clear();
|
||||||
QString result = FrameFileIO::loadFrameFile(&secondFileFrames);
|
QString result = FrameFileIO::loadFrameFile(&referenceFrames);
|
||||||
if (result.length() > 0)
|
if (result.length() > 0)
|
||||||
{
|
{
|
||||||
ui->lblSecondFile->setText(result);
|
ui->lblRefFrames->setText(QString::number(referenceFrames.length()));
|
||||||
secondFilename = result;
|
if (interestedFrames.count() > 0 && referenceFrames.count() > 0) calculateDetails();
|
||||||
if (firstFileFrames.count() > 0 && secondFileFrames.count() > 0) calculateDetails();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileComparatorWindow::clearReference()
|
||||||
|
{
|
||||||
|
referenceFrames.clear();
|
||||||
|
ui->treeDetails->clear();
|
||||||
|
}
|
||||||
|
|
||||||
void FileComparatorWindow::calculateDetails()
|
void FileComparatorWindow::calculateDetails()
|
||||||
{
|
{
|
||||||
QHash<int, FrameData> firstFileIDs;
|
QMap<int, FrameData> interestedIDs;
|
||||||
QHash<int, FrameData> secondFileIDs;
|
QMap<int, FrameData> referenceIDs;
|
||||||
QTreeWidgetItem *firstOnlyBase, *secondOnlyBase, *sharedBase, *bitmapBaseFirst, *bitmapBaseSecond;
|
QTreeWidgetItem *interestedOnlyBase, *referenceOnlyBase, *sharedBase, *bitmapBaseInterested, *bitmapBaseReference;
|
||||||
QTreeWidgetItem *valuesBase, *detail, *sharedItem, *valuesFirst, *valuesSecond;
|
QTreeWidgetItem *valuesBase, *detail, *sharedItem, *valuesInterested, *valuesReference;
|
||||||
uint64_t tmp;
|
uint64_t tmp;
|
||||||
|
|
||||||
int idx = 0;
|
bool uniqueInterested = ui->ckUniqueToInterested->isChecked();
|
||||||
|
|
||||||
ui->treeDetails->clear();
|
ui->treeDetails->clear();
|
||||||
|
|
||||||
firstOnlyBase = new QTreeWidgetItem();
|
interestedOnlyBase = new QTreeWidgetItem();
|
||||||
firstOnlyBase->setText(0,"IDs found only in " + firstFilename);
|
interestedOnlyBase->setText(0,"IDs found only in " + interestedFilename);
|
||||||
secondOnlyBase = new QTreeWidgetItem();
|
if (!uniqueInterested)
|
||||||
secondOnlyBase->setText(0, "IDs found only in " + secondFilename);
|
{
|
||||||
|
referenceOnlyBase = new QTreeWidgetItem();
|
||||||
|
referenceOnlyBase->setText(0, "IDs found only in reference frames");
|
||||||
|
}
|
||||||
sharedBase = new QTreeWidgetItem();
|
sharedBase = new QTreeWidgetItem();
|
||||||
sharedBase->setText(0,"IDs found in both files");
|
sharedBase->setText(0,"IDs found in both places");
|
||||||
|
|
||||||
//first we have to fill out the data structures to get ready to do the report
|
//first we have to fill out the data structures to get ready to do the report
|
||||||
for (int x = 0; x < firstFileFrames.count(); x++)
|
for (int x = 0; x < interestedFrames.count(); x++)
|
||||||
{
|
{
|
||||||
CANFrame frame = firstFileFrames.at(x);
|
CANFrame frame = interestedFrames.at(x);
|
||||||
if (firstFileIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there
|
if (interestedIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there
|
||||||
{
|
{
|
||||||
for (int y = 0; y < frame.len; y++)
|
for (int y = 0; y < frame.len; y++)
|
||||||
{
|
{
|
||||||
firstFileIDs[frame.ID].values[y][frame.data[y]]++;
|
interestedIDs[frame.ID].values[y][frame.data[y]]++;
|
||||||
tmp = frame.data[y];
|
tmp = frame.data[y];
|
||||||
tmp = tmp << (8 * y);
|
tmp = tmp << (8 * y);
|
||||||
firstFileIDs[frame.ID].bitmap |= tmp;
|
interestedIDs[frame.ID].bitmap |= tmp;
|
||||||
qDebug() << "bitmap: " << QString::number(firstFileIDs[frame.ID].bitmap, 16);
|
//qDebug() << "bitmap: " << QString::number(interestedIDs[frame.ID].bitmap, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //never seen this ID before so add one
|
else //never seen this ID before so add one
|
||||||
@@ -133,24 +142,24 @@ void FileComparatorWindow::calculateDetails()
|
|||||||
tmp = frame.data[y];
|
tmp = frame.data[y];
|
||||||
tmp = tmp << (8 * y);
|
tmp = tmp << (8 * y);
|
||||||
newData->bitmap |= tmp;
|
newData->bitmap |= tmp;
|
||||||
qDebug() << "bitmap: " << QString::number(newData->bitmap, 16);
|
//qDebug() << "bitmap: " << QString::number(newData->bitmap, 16);
|
||||||
}
|
}
|
||||||
firstFileIDs.insert(frame.ID, *newData);
|
interestedIDs.insert(frame.ID, *newData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < secondFileFrames.count(); x++)
|
for (int x = 0; x < referenceFrames.count(); x++)
|
||||||
{
|
{
|
||||||
CANFrame frame = secondFileFrames.at(x);
|
CANFrame frame = referenceFrames.at(x);
|
||||||
if (secondFileIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there
|
if (referenceIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there
|
||||||
{
|
{
|
||||||
for (int y = 0; y < frame.len; y++)
|
for (int y = 0; y < frame.len; y++)
|
||||||
{
|
{
|
||||||
secondFileIDs[frame.ID].values[y][frame.data[y]]++;
|
referenceIDs[frame.ID].values[y][frame.data[y]]++;
|
||||||
tmp = frame.data[y];
|
tmp = frame.data[y];
|
||||||
tmp = tmp << (8 * y);
|
tmp = tmp << (8 * y);
|
||||||
secondFileIDs[frame.ID].bitmap |= tmp;
|
referenceIDs[frame.ID].bitmap |= tmp;
|
||||||
qDebug() << "bitmap: " << QString::number(secondFileIDs[frame.ID].bitmap, 16);
|
//qDebug() << "bitmap: " << QString::number(referenceIDs[frame.ID].bitmap, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //never seen this ID before so add one
|
else //never seen this ID before so add one
|
||||||
@@ -173,107 +182,118 @@ void FileComparatorWindow::calculateDetails()
|
|||||||
tmp = frame.data[y];
|
tmp = frame.data[y];
|
||||||
tmp = tmp << (8 * y);
|
tmp = tmp << (8 * y);
|
||||||
newData->bitmap |= tmp;
|
newData->bitmap |= tmp;
|
||||||
qDebug() << "bitmap: " << QString::number(newData->bitmap, 16);
|
//qDebug() << "bitmap: " << QString::number(newData->bitmap, 16);
|
||||||
}
|
}
|
||||||
secondFileIDs.insert(frame.ID, *newData);
|
referenceIDs.insert(frame.ID, *newData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//now we iterate through the IDs within both files and see which are unique to one file and which
|
//now we iterate through the IDs within both files and see which are unique to one file and which
|
||||||
//are shared
|
//are shared
|
||||||
QHash<int, FrameData>::iterator i;
|
bool interestedHadUnique = false;
|
||||||
for (i = firstFileIDs.begin(); i != firstFileIDs.end(); ++i)
|
QMap<int, FrameData>::iterator i;
|
||||||
|
for (i = interestedIDs.begin(); i != interestedIDs.end(); ++i)
|
||||||
{
|
{
|
||||||
int keyone = i.key();
|
int keyone = i.key();
|
||||||
if (!secondFileIDs.contains(keyone))
|
if (!referenceIDs.contains(keyone))
|
||||||
{
|
{
|
||||||
valuesBase = new QTreeWidgetItem();
|
valuesBase = new QTreeWidgetItem();
|
||||||
valuesBase->setText(0, QString::number(keyone, 16));
|
valuesBase->setText(0, QString::number(keyone, 16));
|
||||||
firstOnlyBase->addChild(valuesBase);
|
interestedOnlyBase->addChild(valuesBase);
|
||||||
}
|
}
|
||||||
else //ID was in both files
|
else //ID was in both files
|
||||||
{
|
{
|
||||||
|
interestedHadUnique = false;
|
||||||
sharedItem = new QTreeWidgetItem();
|
sharedItem = new QTreeWidgetItem();
|
||||||
sharedItem->setText(0, Utility::formatHexNum(keyone));
|
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
|
//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
|
//and values to figure out what has changed between the two files
|
||||||
|
|
||||||
FrameData first = firstFileIDs[keyone];
|
FrameData interested = interestedIDs[keyone];
|
||||||
FrameData second = secondFileIDs[keyone];
|
FrameData reference = referenceIDs[keyone];
|
||||||
|
|
||||||
bitmapBaseFirst = new QTreeWidgetItem();
|
bitmapBaseInterested = new QTreeWidgetItem();
|
||||||
bitmapBaseFirst->setText(0, "Bits set only in " + firstFilename);
|
bitmapBaseInterested->setText(0, "Bits set only in " + interestedFilename);
|
||||||
bitmapBaseSecond = new QTreeWidgetItem();
|
if (!uniqueInterested)
|
||||||
bitmapBaseSecond->setText(0, "Bits set only in " + secondFilename);
|
{
|
||||||
sharedItem->addChild(bitmapBaseFirst);
|
bitmapBaseReference = new QTreeWidgetItem();
|
||||||
sharedItem->addChild(bitmapBaseSecond);
|
bitmapBaseReference->setText(0, "Bits set only in reference frames");
|
||||||
|
}
|
||||||
|
sharedItem->addChild(bitmapBaseInterested);
|
||||||
|
sharedItem->addChild(bitmapBaseReference);
|
||||||
|
|
||||||
uint64_t firstBits = first.bitmap;
|
uint64_t interestedBits = interested.bitmap;
|
||||||
uint64_t secondBits = second.bitmap;
|
uint64_t referenceBits = reference.bitmap;
|
||||||
|
|
||||||
//qDebug() << "ID: " << first.ID;
|
|
||||||
|
|
||||||
//first up, which bits were set in one file but not the other
|
//first up, which bits were set in one file but not the other
|
||||||
for (int b = 0; b < (8 * first.dataLen); b++)
|
for (int b = 0; b < (8 * interested.dataLen); b++)
|
||||||
{
|
{
|
||||||
detail = new QTreeWidgetItem();
|
detail = new QTreeWidgetItem();
|
||||||
detail->setText(0, QString::number(b) + " (" + QString::number(b / 8) + ":" + QString::number(b % 8) + ")");
|
detail->setText(0, QString::number(b) + " (" + QString::number(b / 8) + ":" + QString::number(b % 8) + ")");
|
||||||
if ( (firstBits & 1) && !(secondBits & 1) )
|
if ( (interestedBits & 1) && !(referenceBits & 1) )
|
||||||
{
|
{
|
||||||
bitmapBaseFirst->addChild(detail);
|
bitmapBaseInterested->addChild(detail);
|
||||||
|
interestedHadUnique = true;
|
||||||
}
|
}
|
||||||
else if ( !(firstBits & 1) && (secondBits & 1) )
|
else if ( !(interestedBits & 1) && (referenceBits & 1) )
|
||||||
{
|
{
|
||||||
bitmapBaseSecond->addChild(detail);
|
if (!uniqueInterested) bitmapBaseReference->addChild(detail);
|
||||||
}
|
}
|
||||||
qDebug() << b << " " << QString::number(firstBits, 16) << " " << QString::number(secondBits, 16);
|
//qDebug() << b << " " << QString::number(interestedBits, 16) << " " << QString::number(referenceBits, 16);
|
||||||
firstBits = firstBits >> 1;
|
interestedBits = interestedBits >> 1;
|
||||||
secondBits = secondBits >> 1;
|
referenceBits = referenceBits >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < qMax(first.dataLen, second.dataLen); i++)
|
for (int i = 0; i < qMax(interested.dataLen, reference.dataLen); i++)
|
||||||
{
|
{
|
||||||
valuesBase = new QTreeWidgetItem();
|
valuesBase = new QTreeWidgetItem();
|
||||||
valuesBase->setText(0, "Byte " + QString::number(i));
|
valuesBase->setText(0, "Byte " + QString::number(i));
|
||||||
sharedItem->addChild(valuesBase);
|
sharedItem->addChild(valuesBase);
|
||||||
valuesFirst = new QTreeWidgetItem();
|
valuesInterested = new QTreeWidgetItem();
|
||||||
valuesFirst->setText(0, "Values found only in " + firstFilename);
|
valuesInterested->setText(0, "Values found only in " + interestedFilename);
|
||||||
valuesSecond = new QTreeWidgetItem();
|
if (!uniqueInterested)
|
||||||
valuesSecond->setText(0, "Values found only in " + secondFilename);
|
{
|
||||||
valuesBase->addChild(valuesFirst);
|
valuesReference = new QTreeWidgetItem();
|
||||||
valuesBase->addChild(valuesSecond);
|
valuesReference->setText(0, "Values found only in reference frames");
|
||||||
|
}
|
||||||
|
valuesBase->addChild(valuesInterested);
|
||||||
|
if (!uniqueInterested) valuesBase->addChild(valuesReference);
|
||||||
for (int j = 0; j < 256; j++)
|
for (int j = 0; j < 256; j++)
|
||||||
{
|
{
|
||||||
detail = new QTreeWidgetItem();
|
detail = new QTreeWidgetItem();
|
||||||
detail->setText(0, Utility::formatHexNum(j));
|
detail->setText(0, Utility::formatHexNum(j));
|
||||||
if ((first.values[i][j] > 0) && (second.values[i][j] == 0) )
|
if ((interested.values[i][j] > 0) && (reference.values[i][j] == 0) )
|
||||||
{
|
{
|
||||||
valuesFirst->addChild(detail);
|
valuesInterested->addChild(detail);
|
||||||
|
interestedHadUnique = true;
|
||||||
}
|
}
|
||||||
if ((second.values[i][j] > 0) && (first.values[i][j] == 0) )
|
if ((reference.values[i][j] > 0) && (interested.values[i][j] == 0) )
|
||||||
{
|
{
|
||||||
valuesSecond->addChild(detail);
|
if (!uniqueInterested) valuesReference->addChild(detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (interestedHadUnique || !uniqueInterested) sharedBase->addChild(sharedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uniqueInterested)
|
||||||
|
{
|
||||||
|
QMap<int, FrameData>::iterator itwo;
|
||||||
|
for (itwo = referenceIDs.begin(); itwo != referenceIDs.end(); ++itwo)
|
||||||
|
{
|
||||||
|
int keytwo = itwo.key();
|
||||||
|
if (!interestedIDs.contains(keytwo))
|
||||||
|
{
|
||||||
|
valuesBase = new QTreeWidgetItem();
|
||||||
|
valuesBase->setText(0, Utility::formatHexNum(keytwo));
|
||||||
|
referenceOnlyBase->addChild(valuesBase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, FrameData>::iterator itwo;
|
ui->treeDetails->addTopLevelItem(interestedOnlyBase);
|
||||||
for (itwo = secondFileIDs.begin(); itwo != secondFileIDs.end(); ++itwo)
|
if (!uniqueInterested) ui->treeDetails->addTopLevelItem(referenceOnlyBase);
|
||||||
{
|
|
||||||
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->addTopLevelItem(sharedBase);
|
||||||
|
|
||||||
//ui->treeDetails->setSortingEnabled(true);
|
//ui->treeDetails->setSortingEnabled(true);
|
||||||
|
|||||||
@@ -29,16 +29,16 @@ public:
|
|||||||
~FileComparatorWindow();
|
~FileComparatorWindow();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void loadFirstFile();
|
void loadInterestedFile();
|
||||||
void loadSecondFile();
|
void loadReferenceFile();
|
||||||
|
void clearReference();
|
||||||
void saveDetails();
|
void saveDetails();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::FileComparatorWindow *ui;
|
Ui::FileComparatorWindow *ui;
|
||||||
QVector<CANFrame> firstFileFrames;
|
QVector<CANFrame> interestedFrames;
|
||||||
QVector<CANFrame> secondFileFrames;
|
QVector<CANFrame> referenceFrames;
|
||||||
QString firstFilename;
|
QString interestedFilename;
|
||||||
QString secondFilename;
|
|
||||||
|
|
||||||
void calculateDetails();
|
void calculateDetails();
|
||||||
void showEvent(QShowEvent *);
|
void showEvent(QShowEvent *);
|
||||||
|
|||||||
+27
-9
@@ -21,7 +21,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>First File:</string>
|
<string>File of interest:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="btnFirstFile">
|
<widget class="QPushButton" name="btnInterestedFile">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Load New File</string>
|
<string>Load New File</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -46,28 +46,46 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Second File:</string>
|
<string><html><head/><body><p>Loaded reference frames:</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="lblSecondFile">
|
<widget class="QLabel" name="lblRefFrames">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="btnSecondFile">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Load New File</string>
|
<widget class="QPushButton" name="btnLoadRefFile">
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>Load A File</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnClear">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear Frames</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="ckUniqueToInterested">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show only unique data for interested file</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeWidget" name="treeDetails">
|
<widget class="QTreeWidget" name="treeDetails">
|
||||||
<column>
|
<column>
|
||||||
|
|||||||
Reference in New Issue
Block a user