From 2fd02e485bf6a242b3d4774090d0bbbe54ada119 Mon Sep 17 00:00:00 2001 From: Renu-Priya411 Date: Fri, 18 Jul 2025 15:34:13 +0530 Subject: [PATCH 1/3] File Splitting Settings has been implemented The given dlt file can be split into smaller sizes and can be saved in local as per user's convenience Signed-off by : Renu Priya Krishnamoorthy --- src/mainwindow.cpp | 157 +++++++++++++++++++++++++++++++++++++++++++++ src/mainwindow.h | 5 ++ src/mainwindow.ui | 73 ++++++++++++++++++++- 3 files changed, 234 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 92b114259..1c55c6a1f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1425,6 +1425,7 @@ bool MainWindow::openDltFile(QStringList fileNames) qDebug() << "Open filename error in " << __FILE__ << __LINE__; return false; } + outputFilePath = fileNames; /* Color of the scrollbar when dark mode is enabled */ if (QDltSettingsManager::UI_Colour::UI_Dark == QDltSettingsManager::getInstance()->uiColour) { @@ -2236,6 +2237,162 @@ void MainWindow::on_actionExport_triggered() startExportThread(exporterThread, selectionForThread); } +//The function is triggered when Split DLT File is clicked which is under File Menu. +//A dialog box asking for the splitting size is opened where the user can specify the size in KB,MB or GB. +//The size is casted toqint64 and them parsed to splitOutputFile function. +//The destination path can also be selected by user which will also be parsend to splitOutFile function. +void MainWindow::on_actionSplitDLTFile_triggered(){ + + QDialog dialog(this); + dialog.setWindowTitle("Enter Split Size"); + + QLabel *sizeLabel = new QLabel("Size (number):"); + QLineEdit *sizeEdit = new QLineEdit(); + sizeEdit->setValidator(new QDoubleValidator(0, 999999, 2, this)); // Accepts decimal input + + QLabel *unitLabel = new QLabel("Unit:"); + QComboBox *unitCombo = new QComboBox(); + unitCombo->addItem("KB"); + unitCombo->addItem("MB"); + unitCombo->addItem("GB"); + + QPushButton *okButton = new QPushButton("OK"); + QPushButton *cancelButton = new QPushButton("Cancel"); + + QHBoxLayout *inputLayout = new QHBoxLayout(); + inputLayout->addWidget(sizeLabel); + inputLayout->addWidget(sizeEdit); + inputLayout->addWidget(unitLabel); + inputLayout->addWidget(unitCombo); + + QHBoxLayout *buttonLayout = new QHBoxLayout(); + buttonLayout->addStretch(); + buttonLayout->addWidget(okButton); + buttonLayout->addWidget(cancelButton); + + QVBoxLayout *mainLayout = new QVBoxLayout(); + mainLayout->addLayout(inputLayout); + mainLayout->addLayout(buttonLayout); + dialog.setLayout(mainLayout); + + connect(okButton, &QPushButton::clicked, &dialog, &QDialog::accept); + connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject); + + if (dialog.exec() == QDialog::Accepted) { + double sizeValue = sizeEdit->text().toDouble(); + QString sizeUnit = unitCombo->currentText(); + + qint64 multiplier = 1; + if (sizeUnit == "KB") multiplier = 1024LL; + else if (sizeUnit == "MB") multiplier = 1024LL * 1024; + else if (sizeUnit == "GB") multiplier = 1024LL * 1024 * 1024; + + qint64 maxChunkSizeBytes = static_cast(sizeValue * multiplier); + +//FileSaveDialog Implementation + QString folderPath = QFileDialog::getExistingDirectory( + this, + "Select Folder to Save Split Files", + QDir::homePath(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks + ); + + if (folderPath.isEmpty()) { + QMessageBox::warning(this, "No Folder Selected", "Split operation canceled."); + return; + } + + + if (folderPath.isEmpty()) { + QMessageBox::warning(this, "No Folder Selected", "Split operation canceled."); + return; + } + + splitOutputFile(maxChunkSizeBytes, folderPath); + } +} + +//The outputfile (i.e) DLT File is opened in ReadOnly mode and splitted on basis of requirement given by the user. +//If the same files are splitted twice the olde files will be deleted. +//chunk carry is done to avoid data loss +void MainWindow::splitOutputFile(qint64 maxChunkSizeBytes, const QString &destinationFolder){ + + if (!outputfile.open(QIODevice::ReadOnly)) { + qWarning() << "Failed to open Output File for File Splitting"; + return; + } + + QString fullPath = outputFilePath[0]; + + QFileInfo fileInfo(fullPath); + QString baseName = fileInfo.completeBaseName(); + QString extension = fileInfo.completeSuffix(); + + QDir dir(destinationFolder); + QString pattern = QString("%1_%2.%3").arg(baseName).arg("*").arg(extension); + QStringList oldFiles = dir.entryList(QStringList() << pattern, QDir::Files); + for (const QString &file : oldFiles) { + QString fullFilePath = dir.filePath(file); + if (QFile::remove(fullFilePath)) { + qDebug() << "Deleted old split:" << QDir::toNativeSeparators(fullFilePath); + } else { + qWarning() << "Failed to delete:" << fullFilePath; + } + } + + int fileIndex = 1; + outputfile.seek(0); + + QByteArray carryOver; // Store remaining partial data from previous chunk + + while (!outputfile.atEnd()) { + QByteArray chunk = outputfile.read(maxChunkSizeBytes); + if (chunk.isEmpty()) break; + + // Combine leftover from previous chunk (if any) + chunk = carryOver + chunk; + + // Find the last complete line + int lastNewlineIndex = chunk.lastIndexOf('\n'); + if (lastNewlineIndex == -1) lastNewlineIndex = chunk.size(); // no newline found, write all + + QByteArray toWrite = chunk.left(lastNewlineIndex + 1); // include newline + carryOver = chunk.mid(lastNewlineIndex + 1); // store remaining for next file + + QString outputFileName = QString("%1/%2_%3.%4") + .arg(destinationFolder) + .arg(baseName) + .arg(fileIndex++) + .arg(extension); + + QFile output(outputFileName); + if (output.open(QIODevice::WriteOnly)) { + output.write(toWrite); + output.close(); + } else { + qWarning() << "Failed to create" << outputFileName; + break; + } + } + + // Write any remaining data after loop ends + if (!carryOver.isEmpty()) { + QString outputFileName = QString("%1/%2_%3.%4") + .arg(destinationFolder) + .arg(baseName) + .arg(fileIndex++) + .arg(extension); + QFile output(outputFileName); + if (output.open(QIODevice::WriteOnly)) { + output.write(carryOver); + output.close(); + } + } + + outputfile.close(); +} + + void MainWindow::on_action_menuFile_SaveAs_triggered() { diff --git a/src/mainwindow.h b/src/mainwindow.h index 552133228..a4c04ddd1 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -412,6 +412,9 @@ class MainWindow : public QMainWindow void writeDLTMessageToFile(const QByteArray& bufferHeader, std::string_view payload, const EcuItem* ecuitem); + //File Splitting Settings + QStringList outputFilePath; + void findFilteredLines(); @@ -459,6 +462,7 @@ private slots: void on_pluginWidget_itemExpanded(QTreeWidgetItem* item); void onPluginWidgetPluginPriorityChanged(const QString name, int prio); + void splitOutputFile(qint64 maxChunkSizeBytes, const QString &destinationFolder); // File methods @@ -473,6 +477,7 @@ private slots: void on_actionAppend_triggered(); void on_actionExport_triggered(); void on_action_menuFile_DLTFilesize_triggered(); + void on_actionSplitDLTFile_triggered(); //Split DLT Files public slots: diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 25a9be944..df9523005 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -93,7 +93,7 @@ 0 0 1001 - 25 + 23 @@ -117,6 +117,7 @@ + @@ -440,6 +441,73 @@ 2 + + + + 0 + + + + + + 50 + 16777215 + + + + Sort files: + + + + + + + + By Filename + + + + + By Timestamp + + + + + + + + + 50 + 16777215 + + + + + Asc. + + + + + Desc. + + + + + + + + + + QAbstractItemView::SelectionMode::ExtendedSelection + + + true + + + false + + + @@ -1590,6 +1658,9 @@ Submit Feedback + + + Split DLT File From fb42ca6f496d0b26d29a3a8c870a4726e0acf3b7 Mon Sep 17 00:00:00 2001 From: Renu-Priya411 Date: Thu, 11 Sep 2025 14:47:40 +0530 Subject: [PATCH 2/3] Splitting the DLT File wrt DLT Messages File spliting into smaller sizes using DLT message. Logic removed from mainwindow and written to a new .cpp and .h file Signed-off by : Renu Priya Krishnamoorthy --- src/CMakeLists.txt | 2 + src/filespliting.cpp | 203 +++++++++++++++++++++++++++++++++++++++++++ src/filespliting.h | 28 ++++++ src/mainwindow.cpp | 153 ++------------------------------ src/mainwindow.h | 1 - 5 files changed, 239 insertions(+), 148 deletions(-) create mode 100644 src/filespliting.cpp create mode 100644 src/filespliting.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e809364a1..9fe192a1d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,6 +106,8 @@ add_executable(dlt-viewer searchdialog.ui updatechecker.h updatechecker.cpp + filespliting.cpp + filespliting.h ) target_link_libraries(dlt-viewer diff --git a/src/filespliting.cpp b/src/filespliting.cpp new file mode 100644 index 000000000..e4ad816cf --- /dev/null +++ b/src/filespliting.cpp @@ -0,0 +1,203 @@ +#include +#include + +#include "qmessagebox.h" +#include +#include +#include +#include +#include +#include + +FileSpliting::FileSpliting(QWidget *parent) + : QWidget(parent){ + +} + +void FileSpliting::setFile(QFile *file) +{ + m_file = file; +} + + +//The function is triggered when Split DLT File is clicked which is under File Menu. +//A dialog box asking for the splitting size is opened where the user can specify the size in KB,MB or GB. +//The size is casted toqint64 and them parsed to splitOutputFile function. +//The destination path can also be selected by user which will also be parsend to splitOutFile function. + +void FileSpliting::splitDLTFile_triggered(QFile &file,QStringList path){ + qDebug() << "Split File Triggered"; + + QDialog dialog(this); + dialog.setWindowTitle("Enter Split Size"); + + QLabel *sizeLabel = new QLabel("Size (number):"); + QLineEdit *sizeEdit = new QLineEdit(); + sizeEdit->setValidator(new QDoubleValidator(0, 999999, 2, this)); // Accepts decimal input + + QLabel *unitLabel = new QLabel("Unit:"); + QComboBox *unitCombo = new QComboBox(); + unitCombo->addItem("KB"); + unitCombo->addItem("MB"); + unitCombo->addItem("GB"); + + QPushButton *okButton = new QPushButton("OK"); + QPushButton *cancelButton = new QPushButton("Cancel"); + + QHBoxLayout *inputLayout = new QHBoxLayout(); + inputLayout->addWidget(sizeLabel); + inputLayout->addWidget(sizeEdit); + inputLayout->addWidget(unitLabel); + inputLayout->addWidget(unitCombo); + + QHBoxLayout *buttonLayout = new QHBoxLayout(); + buttonLayout->addStretch(); + buttonLayout->addWidget(okButton); + buttonLayout->addWidget(cancelButton); + + QVBoxLayout *mainLayout = new QVBoxLayout(); + mainLayout->addLayout(inputLayout); + mainLayout->addLayout(buttonLayout); + dialog.setLayout(mainLayout); + + connect(okButton, &QPushButton::clicked, &dialog, &QDialog::accept); + connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject); + + if (dialog.exec() == QDialog::Accepted) { + double sizeValue = sizeEdit->text().toDouble(); + QString sizeUnit = unitCombo->currentText(); + + qint64 multiplier = 1; + if (sizeUnit == "KB") multiplier = 1024LL; + else if (sizeUnit == "MB") multiplier = 1024LL * 1024; + else if (sizeUnit == "GB") multiplier = 1024LL * 1024 * 1024; + + qint64 maxChunkSizeBytes = static_cast(sizeValue * multiplier); + + //FileSaveDialog Implementation + QString folderPath = QFileDialog::getExistingDirectory( + this, + "Select Folder to Save Split Files", + QDir::homePath(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks + ); + + if (folderPath.isEmpty()) { + QMessageBox::warning(this, "No Folder Selected", "Split operation canceled."); + return; + } + + + if (folderPath.isEmpty()) { + QMessageBox::warning(this, "No Folder Selected", "Split operation canceled."); + return; + } + + splitOutputFile(path,maxChunkSizeBytes, folderPath); + } +} + +//The outputfile (i.e) DLT File is opened in ReadOnly mode and splitted on basis of requirement given by the user. +//If the same files are splitted twice the olde files will be deleted. +//chunk carry is done to avoid data loss +void FileSpliting::splitOutputFile(QStringList filePath,qint64 maxChunkSizeBytes, const QString &destinationFolder){ + + if (!m_file->isOpen()) { + qWarning() << "Failed to open Output File for File Splitting"; + return; + } + + QString fullPath = filePath[0]; + + QFileInfo fileInfo(fullPath); + QString baseName = fileInfo.completeBaseName(); + QString extension = fileInfo.completeSuffix(); + + QDir dir(destinationFolder); + QString pattern = QString("%1_%2.%3").arg(baseName).arg("*").arg(extension); + QStringList oldFiles = dir.entryList(QStringList() << pattern, QDir::Files); + for (const QString &file : oldFiles) { + QString fullFilePath = dir.filePath(file); + if (QFile::remove(fullFilePath)) { + qDebug() << "Deleted old split:" << QDir::toNativeSeparators(fullFilePath); + } else { + qWarning() << "Failed to delete:" << fullFilePath; + } + } + + int fileIndex = 1; + qint64 accumulatedSize = 0; + QByteArray buffer; + + // Reset to start + m_file->seek(0); + + while (!m_file->atEnd()) { + // Read DLT standard header (first 4 bytes) + QByteArray header = m_file->read(4); + if (header.size() < 4) { + qDebug() << "Reached EOF while reading header."; + break; + } + + // Extract payload length from bytes 2 and 3 + quint16 payloadLen = ((quint8)header[2] << 8) | (quint8)header[3]; + quint32 msgLen = payloadLen + 4; // total = header + payload + + // Check if enough bytes remain in file + if (m_file->bytesAvailable() < (msgLen - 4)) { + qWarning() << "Unexpected EOF: file ends before message fully read."; + break; + } + + // Read payload + QByteArray payload = m_file->read(msgLen - 4); + QByteArray completeMessage = header + payload; + + // Check if adding this message exceeds current chunk size + if (accumulatedSize + completeMessage.size() > maxChunkSizeBytes && !buffer.isEmpty()) { + // Write buffer to new file + QString outputFileName = QString("%1/%2_%3.%4") + .arg(destinationFolder) + .arg(baseName) + .arg(fileIndex++) + .arg(extension); + + QFile output(outputFileName); + if (output.open(QIODevice::WriteOnly)) { + output.write(buffer); + output.close(); + qDebug() << "Written split:" << QDir::toNativeSeparators(outputFileName); + } else { + qWarning() << "Failed to create" << outputFileName; + break; + } + + // Reset buffer + buffer.clear(); + accumulatedSize = 0; + } + + // Append message to buffer + buffer.append(completeMessage); + accumulatedSize += completeMessage.size(); + } + + // Write remaining buffer if not empty + if (!buffer.isEmpty()) { + QString outputFileName = QString("%1/%2_%3.%4") + .arg(destinationFolder) + .arg(baseName) + .arg(fileIndex++) + .arg(extension); + + QFile output(outputFileName); + if (output.open(QIODevice::WriteOnly)) { + output.write(buffer); + output.close(); + qDebug() << "Written last split:" << QDir::toNativeSeparators(outputFileName); + } + } + + m_file->close(); +} diff --git a/src/filespliting.h b/src/filespliting.h new file mode 100644 index 000000000..9b664cb0a --- /dev/null +++ b/src/filespliting.h @@ -0,0 +1,28 @@ +#ifndef FILESPLITING_H +#define FILESPLITING_H + +#include +#include + +class FileSpliting : public QWidget +{ + Q_OBJECT + + public: + + explicit FileSpliting(QWidget *parent = nullptr); + + void splitDLTFile_triggered(QFile &file,QStringList path); //Split DLT Files + void splitOutputFile(QStringList filePath,qint64 maxChunkSizeBytes, const QString &destinationFolder); + + void setFile(QFile *file); + + + + private: + + QFile *m_file = nullptr; + +}; + +#endif // FILESPLITING_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1c55c6a1f..f54218b18 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -85,6 +85,8 @@ #include #include "ecutree.h" #include "updatechecker.h" +#include "filespliting.h" + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -2237,162 +2239,19 @@ void MainWindow::on_actionExport_triggered() startExportThread(exporterThread, selectionForThread); } -//The function is triggered when Split DLT File is clicked which is under File Menu. -//A dialog box asking for the splitting size is opened where the user can specify the size in KB,MB or GB. -//The size is casted toqint64 and them parsed to splitOutputFile function. -//The destination path can also be selected by user which will also be parsend to splitOutFile function. +//call for spliting the DLT File void MainWindow::on_actionSplitDLTFile_triggered(){ - QDialog dialog(this); - dialog.setWindowTitle("Enter Split Size"); - - QLabel *sizeLabel = new QLabel("Size (number):"); - QLineEdit *sizeEdit = new QLineEdit(); - sizeEdit->setValidator(new QDoubleValidator(0, 999999, 2, this)); // Accepts decimal input - - QLabel *unitLabel = new QLabel("Unit:"); - QComboBox *unitCombo = new QComboBox(); - unitCombo->addItem("KB"); - unitCombo->addItem("MB"); - unitCombo->addItem("GB"); - - QPushButton *okButton = new QPushButton("OK"); - QPushButton *cancelButton = new QPushButton("Cancel"); - - QHBoxLayout *inputLayout = new QHBoxLayout(); - inputLayout->addWidget(sizeLabel); - inputLayout->addWidget(sizeEdit); - inputLayout->addWidget(unitLabel); - inputLayout->addWidget(unitCombo); - - QHBoxLayout *buttonLayout = new QHBoxLayout(); - buttonLayout->addStretch(); - buttonLayout->addWidget(okButton); - buttonLayout->addWidget(cancelButton); - - QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addLayout(inputLayout); - mainLayout->addLayout(buttonLayout); - dialog.setLayout(mainLayout); - - connect(okButton, &QPushButton::clicked, &dialog, &QDialog::accept); - connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject); - - if (dialog.exec() == QDialog::Accepted) { - double sizeValue = sizeEdit->text().toDouble(); - QString sizeUnit = unitCombo->currentText(); - - qint64 multiplier = 1; - if (sizeUnit == "KB") multiplier = 1024LL; - else if (sizeUnit == "MB") multiplier = 1024LL * 1024; - else if (sizeUnit == "GB") multiplier = 1024LL * 1024 * 1024; - - qint64 maxChunkSizeBytes = static_cast(sizeValue * multiplier); - -//FileSaveDialog Implementation - QString folderPath = QFileDialog::getExistingDirectory( - this, - "Select Folder to Save Split Files", - QDir::homePath(), - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks - ); - - if (folderPath.isEmpty()) { - QMessageBox::warning(this, "No Folder Selected", "Split operation canceled."); - return; - } - - - if (folderPath.isEmpty()) { - QMessageBox::warning(this, "No Folder Selected", "Split operation canceled."); - return; - } - - splitOutputFile(maxChunkSizeBytes, folderPath); - } -} - -//The outputfile (i.e) DLT File is opened in ReadOnly mode and splitted on basis of requirement given by the user. -//If the same files are splitted twice the olde files will be deleted. -//chunk carry is done to avoid data loss -void MainWindow::splitOutputFile(qint64 maxChunkSizeBytes, const QString &destinationFolder){ - if (!outputfile.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open Output File for File Splitting"; return; } + FileSpliting *splitFile = new FileSpliting(this); + splitFile->setFile(&outputfile); + splitFile->splitDLTFile_triggered(outputfile,outputFilePath); - QString fullPath = outputFilePath[0]; - - QFileInfo fileInfo(fullPath); - QString baseName = fileInfo.completeBaseName(); - QString extension = fileInfo.completeSuffix(); - - QDir dir(destinationFolder); - QString pattern = QString("%1_%2.%3").arg(baseName).arg("*").arg(extension); - QStringList oldFiles = dir.entryList(QStringList() << pattern, QDir::Files); - for (const QString &file : oldFiles) { - QString fullFilePath = dir.filePath(file); - if (QFile::remove(fullFilePath)) { - qDebug() << "Deleted old split:" << QDir::toNativeSeparators(fullFilePath); - } else { - qWarning() << "Failed to delete:" << fullFilePath; - } - } - - int fileIndex = 1; - outputfile.seek(0); - - QByteArray carryOver; // Store remaining partial data from previous chunk - - while (!outputfile.atEnd()) { - QByteArray chunk = outputfile.read(maxChunkSizeBytes); - if (chunk.isEmpty()) break; - - // Combine leftover from previous chunk (if any) - chunk = carryOver + chunk; - - // Find the last complete line - int lastNewlineIndex = chunk.lastIndexOf('\n'); - if (lastNewlineIndex == -1) lastNewlineIndex = chunk.size(); // no newline found, write all - - QByteArray toWrite = chunk.left(lastNewlineIndex + 1); // include newline - carryOver = chunk.mid(lastNewlineIndex + 1); // store remaining for next file - - QString outputFileName = QString("%1/%2_%3.%4") - .arg(destinationFolder) - .arg(baseName) - .arg(fileIndex++) - .arg(extension); - - QFile output(outputFileName); - if (output.open(QIODevice::WriteOnly)) { - output.write(toWrite); - output.close(); - } else { - qWarning() << "Failed to create" << outputFileName; - break; - } - } - - // Write any remaining data after loop ends - if (!carryOver.isEmpty()) { - QString outputFileName = QString("%1/%2_%3.%4") - .arg(destinationFolder) - .arg(baseName) - .arg(fileIndex++) - .arg(extension); - QFile output(outputFileName); - if (output.open(QIODevice::WriteOnly)) { - output.write(carryOver); - output.close(); - } - } - - outputfile.close(); } - void MainWindow::on_action_menuFile_SaveAs_triggered() { diff --git a/src/mainwindow.h b/src/mainwindow.h index a4c04ddd1..34210edc2 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -462,7 +462,6 @@ private slots: void on_pluginWidget_itemExpanded(QTreeWidgetItem* item); void onPluginWidgetPluginPriorityChanged(const QString name, int prio); - void splitOutputFile(qint64 maxChunkSizeBytes, const QString &destinationFolder); // File methods From 96070cb9e40a483e84dd73b5adf4680bf4edab58 Mon Sep 17 00:00:00 2001 From: Renu Priya K Date: Mon, 8 Jun 2026 16:18:27 +0530 Subject: [PATCH 3/3] Fix the data loss while splitting, Bugs during Live Logging Fix the data loss while splitting, Bugs during Live Logging --- src/filespliting.cpp | 72 ++++++++++++++++++++++++++++++-------- src/filespliting.h | 2 +- src/mainwindow.cpp | 22 ++++++++++-- src/mainwindow.ui | 83 ++------------------------------------------ 4 files changed, 80 insertions(+), 99 deletions(-) diff --git a/src/filespliting.cpp b/src/filespliting.cpp index e4ad816cf..79d4a3423 100644 --- a/src/filespliting.cpp +++ b/src/filespliting.cpp @@ -2,8 +2,10 @@ #include #include "qmessagebox.h" +#include #include #include +#include #include #include #include @@ -21,13 +23,23 @@ void FileSpliting::setFile(QFile *file) //The function is triggered when Split DLT File is clicked which is under File Menu. -//A dialog box asking for the splitting size is opened where the user can specify the size in KB,MB or GB. +//A dialog box asking for the splitting size is opened where the user can specify the size in MB or GB. //The size is casted toqint64 and them parsed to splitOutputFile function. //The destination path can also be selected by user which will also be parsend to splitOutFile function. -void FileSpliting::splitDLTFile_triggered(QFile &file,QStringList path){ +void FileSpliting::splitDLTFile_triggered(QStringList path){ qDebug() << "Split File Triggered"; + if (m_file == nullptr) { + QMessageBox::warning(this, "DLT Viewer", "No DLT file opened"); + return; + } + + if (path.isEmpty() || path.first().isEmpty()) { + QMessageBox::warning(this, "DLT Viewer", "No DLT file opened"); + return; + } + QDialog dialog(this); dialog.setWindowTitle("Enter Split Size"); @@ -37,7 +49,6 @@ void FileSpliting::splitDLTFile_triggered(QFile &file,QStringList path){ QLabel *unitLabel = new QLabel("Unit:"); QComboBox *unitCombo = new QComboBox(); - unitCombo->addItem("KB"); unitCombo->addItem("MB"); unitCombo->addItem("GB"); @@ -64,12 +75,18 @@ void FileSpliting::splitDLTFile_triggered(QFile &file,QStringList path){ connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject); if (dialog.exec() == QDialog::Accepted) { - double sizeValue = sizeEdit->text().toDouble(); + const QString sizeText = sizeEdit->text().trimmed(); + double sizeValue = sizeText.toDouble(); + + if (sizeText.isEmpty() || sizeValue <= 0.0) { + QMessageBox::warning(this, "Invalid Split Size", "Please enter a valid split size greater than 0."); + return; + } + QString sizeUnit = unitCombo->currentText(); qint64 multiplier = 1; - if (sizeUnit == "KB") multiplier = 1024LL; - else if (sizeUnit == "MB") multiplier = 1024LL * 1024; + if (sizeUnit == "MB") multiplier = 1024LL * 1024; else if (sizeUnit == "GB") multiplier = 1024LL * 1024 * 1024; qint64 maxChunkSizeBytes = static_cast(sizeValue * multiplier); @@ -87,12 +104,6 @@ void FileSpliting::splitDLTFile_triggered(QFile &file,QStringList path){ return; } - - if (folderPath.isEmpty()) { - QMessageBox::warning(this, "No Folder Selected", "Split operation canceled."); - return; - } - splitOutputFile(path,maxChunkSizeBytes, folderPath); } } @@ -102,6 +113,16 @@ void FileSpliting::splitDLTFile_triggered(QFile &file,QStringList path){ //chunk carry is done to avoid data loss void FileSpliting::splitOutputFile(QStringList filePath,qint64 maxChunkSizeBytes, const QString &destinationFolder){ + if (m_file == nullptr) { + qWarning() << "No input file available for splitting"; + return; + } + + if (filePath.isEmpty() || filePath.first().isEmpty()) { + QMessageBox::warning(this, "DLT Viewer", "No DLT file opened"); + return; + } + if (!m_file->isOpen()) { qWarning() << "Failed to open Output File for File Splitting"; return; @@ -128,6 +149,17 @@ void FileSpliting::splitOutputFile(QStringList filePath,qint64 maxChunkSizeBytes int fileIndex = 1; qint64 accumulatedSize = 0; QByteArray buffer; + qint64 processedBytes = 0; + + const qint64 totalBytes = m_file->size(); + QProgressDialog progressDialog("Splitting DLT file...", QString(), 0, 100, this); + progressDialog.setWindowTitle("DLT Viewer"); + progressDialog.setCancelButton(nullptr); + progressDialog.setWindowModality(Qt::ApplicationModal); + progressDialog.setMinimumDuration(0); + progressDialog.setValue(0); + progressDialog.show(); + QApplication::processEvents(); // Reset to start m_file->seek(0); @@ -135,23 +167,25 @@ void FileSpliting::splitOutputFile(QStringList filePath,qint64 maxChunkSizeBytes while (!m_file->atEnd()) { // Read DLT standard header (first 4 bytes) QByteArray header = m_file->read(4); + processedBytes += header.size(); if (header.size() < 4) { qDebug() << "Reached EOF while reading header."; break; } - // Extract payload length from bytes 2 and 3 + // Extract payload length from bytes 2 and 3 quint16 payloadLen = ((quint8)header[2] << 8) | (quint8)header[3]; quint32 msgLen = payloadLen + 4; // total = header + payload - // Check if enough bytes remain in file + // Check if enough bytes remain in file if (m_file->bytesAvailable() < (msgLen - 4)) { qWarning() << "Unexpected EOF: file ends before message fully read."; break; } - // Read payload + // Read payload QByteArray payload = m_file->read(msgLen - 4); + processedBytes += payload.size(); QByteArray completeMessage = header + payload; // Check if adding this message exceeds current chunk size @@ -181,6 +215,12 @@ void FileSpliting::splitOutputFile(QStringList filePath,qint64 maxChunkSizeBytes // Append message to buffer buffer.append(completeMessage); accumulatedSize += completeMessage.size(); + + if (totalBytes > 0) { + const int percent = static_cast((processedBytes * 100) / totalBytes); + progressDialog.setValue(qMin(percent, 100)); + QApplication::processEvents(); + } } // Write remaining buffer if not empty @@ -199,5 +239,7 @@ void FileSpliting::splitOutputFile(QStringList filePath,qint64 maxChunkSizeBytes } } + progressDialog.setValue(100); + m_file->close(); } diff --git a/src/filespliting.h b/src/filespliting.h index 9b664cb0a..0e0044a81 100644 --- a/src/filespliting.h +++ b/src/filespliting.h @@ -12,7 +12,7 @@ class FileSpliting : public QWidget explicit FileSpliting(QWidget *parent = nullptr); - void splitDLTFile_triggered(QFile &file,QStringList path); //Split DLT Files + void splitDLTFile_triggered(QStringList path); //Split DLT Files void splitOutputFile(QStringList filePath,qint64 maxChunkSizeBytes, const QString &destinationFolder); void setFile(QFile *file); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f54218b18..984d3f88b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2242,13 +2242,31 @@ void MainWindow::on_actionExport_triggered() //call for spliting the DLT File void MainWindow::on_actionSplitDLTFile_triggered(){ + if (isLiveLoggingActive()) { + QMessageBox::warning(this, QString("DLT Viewer"), + QString("Cannot Split During Live Logging")); + return; + } + + if (outputfile.fileName().isEmpty() || outputfile.size() <= 0) { + QMessageBox::warning(this, QString("DLT Viewer"), + QString("No DLT file opened")); + return; + } + if (!outputfile.open(QIODevice::ReadOnly)) { - qWarning() << "Failed to open Output File for File Splitting"; + QMessageBox::warning(this, QString("DLT Viewer"), + QString("No DLT file opened")); return; } FileSpliting *splitFile = new FileSpliting(this); splitFile->setFile(&outputfile); - splitFile->splitDLTFile_triggered(outputfile,outputFilePath); + splitFile->splitDLTFile_triggered(outputFilePath); + + // Ensure split flow never leaves the output file in ReadOnly mode. + if (outputfile.isOpen()) { + outputfile.close(); + } } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index df9523005..2978de29a 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -428,87 +428,6 @@ Explore - - - 2 - - - 2 - - - 2 - - - 2 - - - - - 0 - - - - - - 50 - 16777215 - - - - Sort files: - - - - - - - - By Filename - - - - - By Timestamp - - - - - - - - - 50 - 16777215 - - - - - Asc. - - - - - Desc. - - - - - - - - - - QAbstractItemView::SelectionMode::ExtendedSelection - - - true - - - false - - - - @@ -1658,6 +1577,8 @@ Submit Feedback + + Split DLT File