GUI: mux: add progress dialog during file identification

This commit is contained in:
Moritz Bunkus 2024-07-30 20:44:45 +02:00
parent ae95e11b63
commit e393ac8d60
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
6 changed files with 100 additions and 26 deletions

View File

@ -1,5 +1,10 @@
# Version ?
## New features and enhancements
* MKVToolNix GUI: multiplexer: added a progress dialog that is shown during
file identification.
## Bug fixes
* mkvmerge: AAC parser: LOAS/LATM streams: if the first `AudioSpecificConfig`

View File

@ -21,7 +21,7 @@ struct IdentificationPack {
};
AddMode m_addMode{AddMode::UserChoice};
uint64_t m_tabId{};
uint64_t m_tabId{}, m_initialNumberOfFiles{};
QModelIndex m_sourceFileIdx{};
Qt::MouseButtons m_mouseButtons{};
QStringList m_fileNames;

View File

@ -25,8 +25,9 @@ class FileIdentificationWorkerPrivate {
QVector<IdentificationPack> m_toIdentify;
QMutex m_mutex;
QAtomicInteger<bool> m_abortPlaylistScan;
QAtomicInteger<bool> m_abortPlaylistScan, m_abortIdentification;
QRegularExpression m_simpleChaptersRE, m_ffmpegMetaChaptersRE, m_xmlChaptersRE, m_xmlSegmentInfoRE, m_xmlTagsRE;
QAtomicInteger<unsigned int> m_numberOfIdentifiedFiles;
explicit FileIdentificationWorkerPrivate()
{
@ -51,15 +52,19 @@ FileIdentificationWorker::~FileIdentificationWorker() {
}
void
FileIdentificationWorker::addPackToIdentify(IdentificationPack const &pack) {
FileIdentificationWorker::addPackToIdentify(IdentificationPack &pack) {
auto p = p_func();
qDebug() << "FileIdentificationWorker::addFilesToIdentify: adding" << pack.m_fileNames;
QMutexLocker lock{&p->m_mutex};
pack.m_initialNumberOfFiles = pack.m_fileNames.count();
p->m_toIdentify.push_back(pack);
Q_EMIT queueProgressChanged(p->m_numberOfIdentifiedFiles, countNumberOfQueuedFiles());
QTimer::singleShot(0, this, [this]() { identifyFiles(); });
}
@ -108,15 +113,25 @@ FileIdentificationWorker::identifyFiles() {
qDebug() << "FileIdentificationWorker::identifyFiles: starting loop";
Q_EMIT queueStarted();
p->m_abortIdentification = false;
{
QMutexLocker lock{&p->m_mutex};
p->m_numberOfIdentifiedFiles = 0;
Q_EMIT queueStarted(countNumberOfQueuedFiles());
}
while (true) {
QString fileName;
{
QMutexLocker lock{&p->m_mutex};
if (p->m_toIdentify.isEmpty()) {
qDebug() << "FileIdentificationWorker::identifyFiles: exiting loop (nothing left to do)";
if (p->m_toIdentify.isEmpty() || p->m_abortIdentification) {
auto reason = p->m_abortIdentification ? "aborted" : "nothing left to do";
qDebug() << "FileIdentificationWorker::identifyFiles: exiting loop (" << reason << ")";
p->m_toIdentify.clear();
Q_EMIT queueFinished();
@ -140,6 +155,14 @@ FileIdentificationWorker::identifyFiles() {
auto result = identifyThisFile(fileName);
// QThread::sleep(1);
{
QMutexLocker lock{&p->m_mutex};
p->m_numberOfIdentifiedFiles++;
Q_EMIT queueProgressChanged(p->m_numberOfIdentifiedFiles, countNumberOfQueuedFiles());
}
if (result == Result::Wait) {
qDebug() << "FileIdentificationWorker::identifyFiles: exiting loop (result was 'Wait')";
return;
@ -149,17 +172,9 @@ FileIdentificationWorker::identifyFiles() {
void
FileIdentificationWorker::abortIdentification() {
auto p = p_func();
QMutexLocker lock{&p->m_mutex};
if (p->m_toIdentify.isEmpty())
return;
qDebug() << "FileIdentificationWorker::abortIdentification: skipping remaining files";
p->m_toIdentify.clear();
Q_EMIT queueFinished();
p_func()->m_abortIdentification = true;
}
IdentificationPack::FileType
@ -345,6 +360,18 @@ FileIdentificationWorker::identifyThisFile(QString const &fileName) {
return Result::Continue;
}
unsigned int
FileIdentificationWorker::countNumberOfQueuedFiles() {
auto &p = *p_func();
auto numberOfQueuedFiles = 0u;
for (auto const &pack : p.m_toIdentify)
numberOfQueuedFiles += pack.m_initialNumberOfFiles;
return numberOfQueuedFiles;
}
// ----------------------------------------------------------------------
FileIdentificationThread::FileIdentificationThread(QObject *parent)
@ -374,7 +401,7 @@ FileIdentificationThread::continueIdentification() {
void
FileIdentificationThread::abortIdentification() {
QTimer::singleShot(0, &worker(), [this]() { worker().abortIdentification(); });
worker().abortIdentification();
}
void

View File

@ -31,7 +31,7 @@ public:
FileIdentificationWorker(QObject *parent = nullptr);
virtual ~FileIdentificationWorker();
void addPackToIdentify(IdentificationPack const &pack);
void addPackToIdentify(IdentificationPack &pack);
void addIdentifiedFile(SourceFilePtr const &identifiedFile);
void addIdentifiedFile(IdentificationPack::FileType type, QString const &fileName);
@ -45,8 +45,9 @@ public Q_SLOTS:
void abortIdentification();
Q_SIGNALS:
void queueStarted();
void queueStarted(unsigned int numberOfQueuedFiles);
void queueFinished();
void queueProgressChanged(unsigned int numFilesIdentified, unsigned int numberOfQueuedFiles);
void playlistScanStarted(int numFilesToScan);
void playlistScanFinished();
@ -66,6 +67,8 @@ protected:
Result identifyThisFile(QString const &fileName);
Result scanPlaylists(QFileInfoList const &fileNames);
unsigned int countNumberOfQueuedFiles();
};
class FileIdentificationThread : public QThread {

View File

@ -108,7 +108,7 @@ class ToolPrivate {
mtx::gui::Util::FilesDragDropHandler filesDDHandler{Util::FilesDragDropHandler::Mode::Remember};
FileIdentificationThread *identifier{};
QProgressDialog *scanningDirectoryDialog{};
QProgressDialog *scanningDirectoryDialog{}, *identifyingFilesDialog{};
QHash<Tab *, int> lastAddAppendFileNum;
@ -231,6 +231,7 @@ Tool::setupFileIdentificationThread() {
connect(&worker, &FileIdentificationWorker::queueStarted, this, &Tool::fileIdentificationStarted);
connect(&worker, &FileIdentificationWorker::queueFinished, this, &Tool::fileIdentificationFinished);
connect(&worker, &FileIdentificationWorker::queueProgressChanged, this, &Tool::updateFileIdentificationProgress);
connect(&worker, &FileIdentificationWorker::packIdentified, this, &Tool::handleIdentifiedFiles);
connect(&worker, &FileIdentificationWorker::identificationFailed, this, &Tool::showFileIdentificationError);
connect(&worker, &FileIdentificationWorker::playlistScanStarted, this, &Tool::showScanningPlaylistDialog);
@ -947,13 +948,44 @@ Tool::identifyMultipleFiles(QStringList const &fileNamesToIdentify,
}
void
Tool::fileIdentificationStarted() {
p_func()->ui->overlordWidget->setEnabled(false);
Tool::fileIdentificationStarted(unsigned int numberOfQueuedFiles) {
auto &p = *p_func();
qDebug() << "Tool::fileIdentificationStarted with" << numberOfQueuedFiles;
p.ui->overlordWidget->setEnabled(false);
if (!p.identifyingFilesDialog)
p.identifyingFilesDialog = new QProgressDialog{ QY("Identifying files"), QY("Cancel"), 0, static_cast<int>(numberOfQueuedFiles), this };
p.identifyingFilesDialog->setWindowTitle(QY("Identifying files" ));
p.identifyingFilesDialog->show();
connect(p.identifyingFilesDialog, &QProgressDialog::canceled, p.identifier, &FileIdentificationThread::abortIdentification);
}
void
Tool::fileIdentificationFinished() {
p_func()->ui->overlordWidget->setEnabled(true);
auto &p = *p_func();
qDebug() << "Tool::fileIdentificationFinished";
delete p.identifyingFilesDialog;
p.identifyingFilesDialog = nullptr;
p.ui->overlordWidget->setEnabled(true);
}
void
Tool::updateFileIdentificationProgress(unsigned int numberOfIdentifiedFiles,
unsigned int numberOfQueuedFiles) {
auto &p = *p_func();
qDebug() << "Tool::updateFileIdentificationProgress with " << numberOfIdentifiedFiles << "/" << numberOfQueuedFiles;
if (p.identifyingFilesDialog) {
p.identifyingFilesDialog->setValue(static_cast<int>(numberOfIdentifiedFiles));
p.identifyingFilesDialog->setMaximum(static_cast<int>(numberOfQueuedFiles));
}
}
void
@ -1040,11 +1072,11 @@ void
Tool::hideScanningDirectoryDialog() {
auto &p = *p_func();
if (!p.scanningDirectoryDialog)
return;
delete p.scanningDirectoryDialog;
p.scanningDirectoryDialog = nullptr;
if (p.identifyingFilesDialog)
p.identifyingFilesDialog->show();
}
void
@ -1052,6 +1084,9 @@ Tool::showScanningPlaylistDialog(int numFilesToScan) {
auto &p = *p_func();
auto &worker = p.identifier->worker();
if (p.identifyingFilesDialog)
p.identifyingFilesDialog->hide();
if (!p.scanningDirectoryDialog)
p.scanningDirectoryDialog = new QProgressDialog{ QY("Scanning directory"), QY("Cancel"), 0, numFilesToScan, this };
@ -1087,6 +1122,9 @@ Tool::selectPlaylistToAdd(QVector<SourceFilePtr> const &identifiedPlaylists) {
for (auto const &playlist : playlists)
p.identifier->worker().addIdentifiedFile(playlist);
if (p.identifyingFilesDialog)
p.identifyingFilesDialog->show();
p.identifier->continueIdentification();
}

View File

@ -79,8 +79,9 @@ public Q_SLOTS:
virtual void openMultipleConfigFilesFromCommandLine(QStringList const &fileNames);
virtual void fileIdentificationStarted();
virtual void fileIdentificationStarted(unsigned int numberOfQueuedFiles);
virtual void fileIdentificationFinished();
virtual void updateFileIdentificationProgress(unsigned int numberOfIdentifiedFiles, unsigned int numberOfQueuedFiles);
virtual void handleIdentifiedXmlOrSimpleChapters(QString const &fileName);
virtual void handleIdentifiedXmlSegmentInfo(QString const &fileName);
virtual void handleIdentifiedXmlTags(QString const &fileName);