From 2b021749ce4dc3ec8e160a5800e323f7a45047db Mon Sep 17 00:00:00 2001 From: Chris MacLeod Date: Sat, 5 Aug 2023 04:39:01 -0400 Subject: Batch export logs (#2485) * Implement most basic functional batch export For the future: * The loop still needs to be made asynchronous so the process doesn't hang. * Ideally, there should be some sort of progress window. * There is redundant code that should be reduced. * Make batch export asynchronous Reminder: The comment about overwrite protection no longer applies Todo: Progress dialog * Avoid possible dangling pointer, improve type safety and const correctness in the process In reality, the log exporting code has no reason to be in the GUI class to begin with. `exportLog` makes sense as a Qt slot, but `createLog` should be a member function of the `LogFile` class and operate on `this` rather than a `LogFile` argument. A future commit should amend this, but for now I will avoid changing anything unnecessary until a working progress dialog is in place and I have tested the finished feature thoroughly. * Add progress dialog * Make LogViewWindow::createLog a member function of LogFile * Reduce memory usage by sharing `LogFile`s with the GUI thread * Correct progress dialog modality * Collect log files directly instead of reiterating through view items later Also adds a little documentation * Fix batch export for paths with reserved characters * avoid sigsegv * fix tags removal before nickname in html export * Fix directory selection and output path for icons in html export --------- Co-authored-by: ctrlaltca --- src/modules/logview/ExportOperation.cpp | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/modules/logview/ExportOperation.cpp (limited to 'src/modules/logview/ExportOperation.cpp') diff --git a/src/modules/logview/ExportOperation.cpp b/src/modules/logview/ExportOperation.cpp new file mode 100644 index 000000000..49c9f47be --- /dev/null +++ b/src/modules/logview/ExportOperation.cpp @@ -0,0 +1,45 @@ +#include "ExportOperation.h" + +#include +#include +#include +#include + +#include "LogFile.h" +#include "LogViewWindow.h" +#include "KviFileUtils.h" + +ExportOperation::ExportOperation(const std::vector> & logs, LogFile::ExportType type, QString szDir, QObject * parent) + : QObject(parent) + , m_logs(logs) + , m_type(type) + , m_szDir(szDir) +{ +} + +void ExportOperation::start() +{ + QProgressDialog * pProgressDialog = new QProgressDialog("Exporting logs...", "Cancel", 0, m_logs.size()); + QFutureWatcher * pFutureWatcher = new QFutureWatcher(); + + QObject::connect(pFutureWatcher, &QFutureWatcher::finished, pProgressDialog, &QProgressDialog::deleteLater); + QObject::connect(pFutureWatcher, &QFutureWatcher::finished, pFutureWatcher, &QFutureWatcher::deleteLater); + QObject::connect(pFutureWatcher, &QFutureWatcher::finished, this, &ExportOperation::deleteLater); + + QObject::connect(pProgressDialog, &QProgressDialog::canceled, pFutureWatcher, &QFutureWatcher::cancel); + QObject::connect(pFutureWatcher, &QFutureWatcher::progressValueChanged, pProgressDialog, &QProgressDialog::setValue); + + // The directory string and the export type could be captured by value if + // this function was inlined. However, because the QtConcurrent functions + // aside from QtConcurrent::run only operate on references the list of + // pointers might expire, hence the purpose of this class. + pFutureWatcher->setFuture(QtConcurrent::map(m_logs, [this](const std::shared_ptr & pLog) { + const QString szDate = pLog->date().toString("yyyy.MM.dd"); + QString filename = QString("%1_%2.%3_%4").arg(pLog->typeString(), pLog->name(), pLog->network(), szDate); + filename.replace(QRegExp("[\\\\/:*?\"<>|]"), "_"); + QString szLog = m_szDir + KVI_PATH_SEPARATOR_CHAR + filename; + KviFileUtils::adjustFilePath(szLog); + pLog->createLog(m_type, szLog); + })); + pProgressDialog->show(); +} -- cgit v1.3.1-10-gc9f91