Some bug fixes, much more work on ISOTP/UDS decoder window.
This commit is contained in:
@@ -124,7 +124,7 @@ void ISOTP_HANDLER::rapidFrames(const CANConnection* conn, const QVector<CANFram
|
|||||||
Q_UNUSED(conn)
|
Q_UNUSED(conn)
|
||||||
if (pFrames.length() <= 0) return;
|
if (pFrames.length() <= 0) return;
|
||||||
|
|
||||||
qDebug() << "received messages in ISOTP handler";
|
//qDebug() << "received messages in ISOTP handler";
|
||||||
|
|
||||||
foreach(const CANFrame& thisFrame, pFrames)
|
foreach(const CANFrame& thisFrame, pFrames)
|
||||||
{
|
{
|
||||||
@@ -190,7 +190,7 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
|
|||||||
msg.timestamp = frame.timestamp;
|
msg.timestamp = frame.timestamp;
|
||||||
if (useExtendedAddressing) for (int j = 0; j < frameLen; j++) msg.data.append(frame.data[j+2]);
|
if (useExtendedAddressing) for (int j = 0; j < frameLen; j++) msg.data.append(frame.data[j+2]);
|
||||||
else for (int j = 0; j < frameLen; j++) msg.data.append(frame.data[j+1]);
|
else for (int j = 0; j < frameLen; j++) msg.data.append(frame.data[j+1]);
|
||||||
qDebug() << "Emitting single frame ISOTP message";
|
//qDebug() << "Emitting single frame ISOTP message";
|
||||||
emit newISOMessage(msg);
|
emit newISOMessage(msg);
|
||||||
break;
|
break;
|
||||||
case 1: //first frame of a multi-frame message
|
case 1: //first frame of a multi-frame message
|
||||||
@@ -259,7 +259,7 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
|
|||||||
}
|
}
|
||||||
if (pMsg->len <= pMsg->data.count())
|
if (pMsg->len <= pMsg->data.count())
|
||||||
{
|
{
|
||||||
qDebug() << "Emitting multiframe ISOTP message";
|
//qDebug() << "Emitting multiframe ISOTP message";
|
||||||
emit newISOMessage(*pMsg);
|
emit newISOMessage(*pMsg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -298,7 +298,7 @@ void ISOTP_HANDLER::checkNeedFlush(uint64_t ID)
|
|||||||
if (messageBuffer[i].ID == ID)
|
if (messageBuffer[i].ID == ID)
|
||||||
{
|
{
|
||||||
//used to pass by reference but now newISOMessage should pass by value which makes it easier to use cross thread
|
//used to pass by reference but now newISOMessage should pass by value which makes it easier to use cross thread
|
||||||
qDebug() << "Flushing a partial frame";
|
//qDebug() << "Flushing a partial frame";
|
||||||
emit newISOMessage(messageBuffer[i]);
|
emit newISOMessage(messageBuffer[i]);
|
||||||
messageBuffer.removeAt(i);
|
messageBuffer.removeAt(i);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -320,7 +320,13 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
|
|||||||
QString buildString;
|
QString buildString;
|
||||||
bool isResponse = true;
|
bool isResponse = true;
|
||||||
|
|
||||||
if (msg.service < 0x3F || (msg.service > 0x7F && msg.service < 0xAF)) {
|
if (msg.isErrorReply)
|
||||||
|
{
|
||||||
|
isResponse = true;
|
||||||
|
buildString.append("UDS ERROR Response\n");
|
||||||
|
buildString.append("Service: " + getServiceLongDesc(msg.service) + "\n");
|
||||||
|
}
|
||||||
|
else if (msg.service < 0x3F || (msg.service > 0x7F && msg.service < 0xAF)) {
|
||||||
isResponse = false;
|
isResponse = false;
|
||||||
buildString.append("UDS Request\n");
|
buildString.append("UDS Request\n");
|
||||||
buildString.append("Service: " + getServiceLongDesc(msg.service) + "\n");
|
buildString.append("Service: " + getServiceLongDesc(msg.service) + "\n");
|
||||||
@@ -328,7 +334,7 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
isResponse = true;
|
isResponse = true;
|
||||||
buildString.append("UDS Response\n");
|
buildString.append("UDS Positive Response\n");
|
||||||
buildString.append("Service: " + getServiceLongDesc(msg.service - 0x40) + "\n");
|
buildString.append("Service: " + getServiceLongDesc(msg.service - 0x40) + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,16 +354,16 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
|
|||||||
case UDS_SERVICES::DIAG_CONTROL + 0x40: //positive response
|
case UDS_SERVICES::DIAG_CONTROL + 0x40: //positive response
|
||||||
buildString.append("Session Request: " + getLongDesc(UDS_DIAG_CTRL_SUB, msg.subFunc));
|
buildString.append("Session Request: " + getLongDesc(UDS_DIAG_CTRL_SUB, msg.subFunc));
|
||||||
//there should be four extra bytes now
|
//there should be four extra bytes now
|
||||||
if (msg.data.length() < 4)
|
if (msg.data.length() < 5) //5 because subfunc codes are left in data so it starts with one subfunc byte
|
||||||
{
|
{
|
||||||
//buildString.append("\nReturned data payload wasn't at least \n4 bytes like it should have been");
|
//buildString.append("\nReturned data payload wasn't at least \n4 bytes like it should have been");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int p2 = msg.data[0] * 256 + msg.data[1];
|
int p2 = msg.data[1] * 256 + msg.data[2];
|
||||||
buildString.append("\nP2MAX: " + QString::number(p2));
|
buildString.append("\nP2MAX: " + QString::number(p2) + "ms");
|
||||||
p2 = msg.data[2] * 256 + msg.data[3];
|
p2 = (msg.data[3] * 256 + msg.data[4]) * 10;
|
||||||
buildString.append("\nP2*MAX: " + QString::number(p2));
|
buildString.append("\nP2*MAX: " + QString::number(p2) + "ms");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UDS_SERVICES::ECU_RESET:
|
case UDS_SERVICES::ECU_RESET:
|
||||||
@@ -367,11 +373,11 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
|
|||||||
case UDS_SERVICES::ECU_RESET + 0x40:
|
case UDS_SERVICES::ECU_RESET + 0x40:
|
||||||
buildString.append("Reset Type: " + getLongDesc(UDS_ECU_RESET_SUB, msg.subFunc));
|
buildString.append("Reset Type: " + getLongDesc(UDS_ECU_RESET_SUB, msg.subFunc));
|
||||||
//There should be one additional byte which encodes power down time
|
//There should be one additional byte which encodes power down time
|
||||||
if (msg.data.length() > 0)
|
if (msg.data.length() > 1)
|
||||||
{
|
{
|
||||||
if (msg.data[0] < 0xFF)
|
if (msg.data[1] < 0xFF)
|
||||||
{
|
{
|
||||||
buildString.append("\nMinimum powered down time: " + QString::number(msg.data[0]));
|
buildString.append("\nMinimum powered down time: " + QString::number(msg.data[1]));
|
||||||
}
|
}
|
||||||
else buildString.append("\nPowerdown time not available");
|
else buildString.append("\nPowerdown time not available");
|
||||||
}
|
}
|
||||||
@@ -385,19 +391,19 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
|
|||||||
if ((msg.subFunc % 2) == 1)
|
if ((msg.subFunc % 2) == 1)
|
||||||
{
|
{
|
||||||
buildString.append("Seed request for security level: " + QString::number(msg.subFunc) + "\n");
|
buildString.append("Seed request for security level: " + QString::number(msg.subFunc) + "\n");
|
||||||
if (msg.data.length()> 0)
|
if (msg.data.length()> 1)
|
||||||
{
|
{
|
||||||
buildString.append("Data payload: ");
|
buildString.append("Data payload: ");
|
||||||
for (int j = 0; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
|
for (int j = 1; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buildString.append("Key sending for security level: " + QString::number(msg.subFunc - 1));
|
buildString.append("Key sending for security level: " + QString::number(msg.subFunc - 1));
|
||||||
if (msg.data.length()> 0) //and it sure as hell should be!
|
if (msg.data.length()> 1) //and it sure as hell should be!
|
||||||
{
|
{
|
||||||
buildString.append("KEY: ");
|
buildString.append("KEY: ");
|
||||||
for (int j = 0; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
|
for (int j = 1; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -405,10 +411,10 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
|
|||||||
if ((msg.subFunc % 2) == 1)
|
if ((msg.subFunc % 2) == 1)
|
||||||
{
|
{
|
||||||
buildString.append("Seed response for security level: " + QString::number(msg.subFunc) + "\n");
|
buildString.append("Seed response for security level: " + QString::number(msg.subFunc) + "\n");
|
||||||
if (msg.data.length()> 0) //be kinda pointless if it weren't
|
if (msg.data.length()> 1) //be kinda pointless if it weren't
|
||||||
{
|
{
|
||||||
buildString.append("SEED: ");
|
buildString.append("SEED: ");
|
||||||
for (int j = 0; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
|
for (int j = 1; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
+10
-10
@@ -85,20 +85,20 @@ void CANFrameModel::setHexMode(bool mode)
|
|||||||
|
|
||||||
void CANFrameModel::setSecondsMode(bool mode)
|
void CANFrameModel::setSecondsMode(bool mode)
|
||||||
{
|
{
|
||||||
if (timeSeconds != mode)
|
if (Utility::secondsMode != mode)
|
||||||
{
|
{
|
||||||
this->beginResetModel();
|
this->beginResetModel();
|
||||||
timeSeconds = mode;
|
Utility::secondsMode = mode;
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CANFrameModel::setSysTimeMode(bool mode)
|
void CANFrameModel::setSysTimeMode(bool mode)
|
||||||
{
|
{
|
||||||
if (useSystemTime != mode)
|
if (Utility::sysTimeMode != mode)
|
||||||
{
|
{
|
||||||
this->beginResetModel();
|
this->beginResetModel();
|
||||||
useSystemTime = mode;
|
Utility::sysTimeMode = mode;
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ void CANFrameModel::setInterpetMode(bool mode)
|
|||||||
|
|
||||||
void CANFrameModel::setTimeFormat(QString format)
|
void CANFrameModel::setTimeFormat(QString format)
|
||||||
{
|
{
|
||||||
timeFormat = format;
|
Utility::timeFormat = format;
|
||||||
beginResetModel(); //reset model to show new time format
|
beginResetModel(); //reset model to show new time format
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
@@ -127,6 +127,10 @@ void CANFrameModel::normalizeTiming()
|
|||||||
mutex.lock();
|
mutex.lock();
|
||||||
if (frames.count() == 0) return;
|
if (frames.count() == 0) return;
|
||||||
timeOffset = frames[0].timestamp;
|
timeOffset = frames[0].timestamp;
|
||||||
|
for (int j = 0; j < frames.count(); j++)
|
||||||
|
{
|
||||||
|
if (frames[j].timestamp < timeOffset) timeOffset = frames[j].timestamp;
|
||||||
|
}
|
||||||
for (int i = 0; i < frames.count(); i++)
|
for (int i = 0; i < frames.count(); i++)
|
||||||
{
|
{
|
||||||
frames[i].timestamp -= timeOffset;
|
frames[i].timestamp -= timeOffset;
|
||||||
@@ -256,11 +260,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
|
|||||||
switch (index.column())
|
switch (index.column())
|
||||||
{
|
{
|
||||||
case 0: //timestamp
|
case 0: //timestamp
|
||||||
if (!useSystemTime) {
|
return Utility::formatTimestamp(thisFrame.timestamp);
|
||||||
if (!timeSeconds) return QString::number(thisFrame.timestamp);
|
|
||||||
else return QString::number((double)thisFrame.timestamp / 1000000.0, 'f', 6);
|
|
||||||
}
|
|
||||||
else return QDateTime::fromMSecsSinceEpoch(thisFrame.timestamp / 1000).toString(timeFormat);
|
|
||||||
break;
|
break;
|
||||||
case 1: //id
|
case 1: //id
|
||||||
return Utility::formatNumber(thisFrame.ID);
|
return Utility::formatNumber(thisFrame.ID);
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ ISOTP_InterpreterWindow::ISOTP_InterpreterWindow(const QVector<CANFrame> *frames
|
|||||||
connect(MainWindow::getReference(), &MainWindow::framesUpdated, decoder, &ISOTP_HANDLER::updatedFrames);
|
connect(MainWindow::getReference(), &MainWindow::framesUpdated, decoder, &ISOTP_HANDLER::updatedFrames);
|
||||||
connect(decoder, &ISOTP_HANDLER::newISOMessage, this, &ISOTP_InterpreterWindow::newISOMessage);
|
connect(decoder, &ISOTP_HANDLER::newISOMessage, this, &ISOTP_InterpreterWindow::newISOMessage);
|
||||||
connect(udsDecoder, &UDS_HANDLER::newUDSMessage, this, &ISOTP_InterpreterWindow::newUDSMessage);
|
connect(udsDecoder, &UDS_HANDLER::newUDSMessage, this, &ISOTP_InterpreterWindow::newUDSMessage);
|
||||||
|
connect(ui->listFilter, &QListWidget::itemChanged, this, &ISOTP_InterpreterWindow::listFilterItemChanged);
|
||||||
|
connect(ui->btnAll, &QPushButton::clicked, this, &ISOTP_InterpreterWindow::filterAll);
|
||||||
|
connect(ui->btnNone, &QPushButton::clicked, this, &ISOTP_InterpreterWindow::filterNone);
|
||||||
|
connect(ui->btnCaptured, &QPushButton::clicked, this, &ISOTP_InterpreterWindow::interpretCapturedFrames);
|
||||||
|
|
||||||
connect(ui->tableIsoFrames, &QTableWidget::itemSelectionChanged, this, &ISOTP_InterpreterWindow::showDetailView);
|
connect(ui->tableIsoFrames, &QTableWidget::itemSelectionChanged, this, &ISOTP_InterpreterWindow::showDetailView);
|
||||||
connect(ui->btnClearList, &QPushButton::clicked, this, &ISOTP_InterpreterWindow::clearList);
|
connect(ui->btnClearList, &QPushButton::clicked, this, &ISOTP_InterpreterWindow::clearList);
|
||||||
@@ -83,24 +87,60 @@ void ISOTP_InterpreterWindow::writeSettings()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//erase current list then repopulate as if all the previously captured frames just came in again.
|
||||||
|
void ISOTP_InterpreterWindow::interpretCapturedFrames()
|
||||||
|
{
|
||||||
|
clearList();
|
||||||
|
decoder->rapidFrames(NULL, *modelFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISOTP_InterpreterWindow::listFilterItemChanged(QListWidgetItem *item)
|
||||||
|
{
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
int id = item->text().toInt(NULL, 16);
|
||||||
|
bool state = item->checkState();
|
||||||
|
//qDebug() << id << "*" << state;
|
||||||
|
idFilters[id] = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISOTP_InterpreterWindow::filterAll()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < ui->listFilter->count(); i++)
|
||||||
|
{
|
||||||
|
ui->listFilter->item(i)->setCheckState(Qt::Checked);
|
||||||
|
idFilters[ui->listFilter->item(1)->text().toInt(NULL, 16)] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISOTP_InterpreterWindow::filterNone()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < ui->listFilter->count(); i++)
|
||||||
|
{
|
||||||
|
ui->listFilter->item(i)->setCheckState(Qt::Unchecked);
|
||||||
|
idFilters[ui->listFilter->item(1)->text().toInt(NULL, 16)] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ISOTP_InterpreterWindow::clearList()
|
void ISOTP_InterpreterWindow::clearList()
|
||||||
{
|
{
|
||||||
qDebug() << "Clearing the table";
|
qDebug() << "Clearing the table";
|
||||||
while (ui->tableIsoFrames->rowCount() > 0)
|
ui->tableIsoFrames->clearContents();
|
||||||
ui->tableIsoFrames->removeRow(0);
|
ui->tableIsoFrames->model()->removeRows(0, ui->tableIsoFrames->rowCount());
|
||||||
|
messages.clear();
|
||||||
|
//idFilters.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISOTP_InterpreterWindow::updatedFrames(int numFrames)
|
void ISOTP_InterpreterWindow::updatedFrames(int numFrames)
|
||||||
{
|
{
|
||||||
if (numFrames == -1) //all frames deleted. Kill the display
|
if (numFrames == -1) //all frames deleted. Kill the display
|
||||||
{
|
{
|
||||||
messages.clear();
|
clearList();
|
||||||
ui->tableIsoFrames->clear();
|
|
||||||
}
|
}
|
||||||
else if (numFrames == -2) //all new set of frames. Reset
|
else if (numFrames == -2) //all new set of frames. Reset
|
||||||
{
|
{
|
||||||
messages.clear();
|
clearList();
|
||||||
ui->tableIsoFrames->clear();
|
|
||||||
}
|
}
|
||||||
else //just got some new frames. See if they are relevant.
|
else //just got some new frames. See if they are relevant.
|
||||||
{
|
{
|
||||||
@@ -174,12 +214,21 @@ void ISOTP_InterpreterWindow::newISOMessage(ISOTP_MESSAGE msg)
|
|||||||
|
|
||||||
if ((msg.len != msg.data.count()) && !ui->cbShowIncomplete->isChecked()) return;
|
if ((msg.len != msg.data.count()) && !ui->cbShowIncomplete->isChecked()) return;
|
||||||
|
|
||||||
|
if (idFilters.find(msg.ID) == idFilters.end())
|
||||||
|
{
|
||||||
|
idFilters.insert(msg.ID, true);
|
||||||
|
|
||||||
|
QListWidgetItem* listItem = new QListWidgetItem(Utility::formatNumber(msg.ID), ui->listFilter);
|
||||||
|
listItem->setFlags(listItem->flags() | Qt::ItemIsUserCheckable); // set checkable flag
|
||||||
|
listItem->setCheckState(Qt::Checked);
|
||||||
|
}
|
||||||
|
if (!idFilters[msg.ID]) return;
|
||||||
messages.append(msg);
|
messages.append(msg);
|
||||||
|
|
||||||
rowNum = ui->tableIsoFrames->rowCount();
|
rowNum = ui->tableIsoFrames->rowCount();
|
||||||
ui->tableIsoFrames->insertRow(rowNum);
|
ui->tableIsoFrames->insertRow(rowNum);
|
||||||
|
|
||||||
ui->tableIsoFrames->setItem(rowNum, 0, new QTableWidgetItem(QString::number(msg.timestamp)));
|
ui->tableIsoFrames->setItem(rowNum, 0, new QTableWidgetItem(Utility::formatTimestamp(msg.timestamp)));
|
||||||
ui->tableIsoFrames->setItem(rowNum, 1, new QTableWidgetItem(QString::number(msg.ID, 16)));
|
ui->tableIsoFrames->setItem(rowNum, 1, new QTableWidgetItem(QString::number(msg.ID, 16)));
|
||||||
ui->tableIsoFrames->setItem(rowNum, 2, new QTableWidgetItem(QString::number(msg.bus)));
|
ui->tableIsoFrames->setItem(rowNum, 2, new QTableWidgetItem(QString::number(msg.bus)));
|
||||||
if (msg.isReceived) ui->tableIsoFrames->setItem(rowNum, 3, new QTableWidgetItem("Rx"));
|
if (msg.isReceived) ui->tableIsoFrames->setItem(rowNum, 3, new QTableWidgetItem("Rx"));
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ private slots:
|
|||||||
void showDetailView();
|
void showDetailView();
|
||||||
void updatedFrames(int);
|
void updatedFrames(int);
|
||||||
void clearList();
|
void clearList();
|
||||||
|
void listFilterItemChanged(QListWidgetItem *item);
|
||||||
|
void filterAll();
|
||||||
|
void filterNone();
|
||||||
|
void interpretCapturedFrames();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ISOTP_InterpreterWindow *ui;
|
Ui::ISOTP_InterpreterWindow *ui;
|
||||||
@@ -34,6 +38,7 @@ private:
|
|||||||
|
|
||||||
const QVector<CANFrame> *modelFrames;
|
const QVector<CANFrame> *modelFrames;
|
||||||
QVector<ISOTP_MESSAGE> messages;
|
QVector<ISOTP_MESSAGE> messages;
|
||||||
|
QHash<int, bool> idFilters;
|
||||||
|
|
||||||
void closeEvent(QCloseEvent *event);
|
void closeEvent(QCloseEvent *event);
|
||||||
void readSettings();
|
void readSettings();
|
||||||
|
|||||||
@@ -25,11 +25,22 @@
|
|||||||
<widget class="QTableWidget" name="tableIsoFrames"/>
|
<widget class="QTableWidget" name="tableIsoFrames"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="btnClearList">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Clear Messages List</string>
|
<widget class="QPushButton" name="btnCaptured">
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>Interpret Previously Captured Frames</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnClearList">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear Messages List</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignHCenter">
|
<item alignment="Qt::AlignHCenter">
|
||||||
<widget class="QCheckBox" name="cbShowIncomplete">
|
<widget class="QCheckBox" name="cbShowIncomplete">
|
||||||
|
|||||||
+3
-1
@@ -1,4 +1,6 @@
|
|||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
bool Utility::decimalMode = false;
|
bool Utility::decimalMode = false;
|
||||||
|
bool Utility::secondsMode = true;
|
||||||
|
bool Utility::sysTimeMode = false;
|
||||||
|
QString Utility::timeFormat = "MMM-dd HH:mm:ss.zzz";
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ class Utility
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
static bool decimalMode;
|
static bool decimalMode;
|
||||||
|
static bool secondsMode;
|
||||||
|
static bool sysTimeMode;
|
||||||
|
static QString timeFormat;
|
||||||
|
|
||||||
static QString unQuote(QString inStr)
|
static QString unQuote(QString inStr)
|
||||||
{
|
{
|
||||||
@@ -104,6 +107,15 @@ public:
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString formatTimestamp(uint64_t timestamp)
|
||||||
|
{
|
||||||
|
if (!sysTimeMode) {
|
||||||
|
if (!secondsMode) return QString::number(timestamp);
|
||||||
|
else return QString::number((double)timestamp / 1000000.0, 'f', 6);
|
||||||
|
}
|
||||||
|
else return QDateTime::fromMSecsSinceEpoch(timestamp / 1000).toString(timeFormat);
|
||||||
|
}
|
||||||
|
|
||||||
//parses the input string to grab as much of it as possible while staying alpha numeric
|
//parses the input string to grab as much of it as possible while staying alpha numeric
|
||||||
static QString grabAlphaNumeric(QString &input)
|
static QString grabAlphaNumeric(QString &input)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user