diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h --- a/kerfuffle/archiveinterface.h +++ b/kerfuffle/archiveinterface.h @@ -166,10 +166,14 @@ void progress(double progress); void info(const QString &info); void finished(bool result); - void userQuery(Query *query); void testSuccess(); void compressionMethodFound(const QStringList); + /** + * Emitted when @p query needs to be executed on the GUI thread. + */ + void userQuery(Query *query); + protected: /** diff --git a/kerfuffle/cliinterface.cpp b/kerfuffle/cliinterface.cpp --- a/kerfuffle/cliinterface.cpp +++ b/kerfuffle/cliinterface.cpp @@ -354,8 +354,7 @@ list(); } else if (m_operationMode == List && isCorrupt()) { Kerfuffle::LoadCorruptQuery query(filename()); - emit userQuery(&query); - query.waitForResponse(); + query.execute(); if (!query.responseYes()) { emit cancelled(); emit finished(false); @@ -495,8 +494,7 @@ Kerfuffle::OverwriteQuery query(absDestEntry.absoluteFilePath()); query.setNoRenameMode(true); - emit userQuery(&query); - query.waitForResponse(); + query.execute(); if (query.responseOverwrite() || query.responseOverwriteAll()) { if (query.responseOverwriteAll()) { @@ -604,8 +602,7 @@ Kerfuffle::OverwriteQuery query(absDestEntry.absoluteFilePath()); query.setNoRenameMode(true); - emit userQuery(&query); - query.waitForResponse(); + query.execute(); if (query.responseOverwrite() || query.responseOverwriteAll()) { if (query.responseOverwriteAll()) { @@ -727,8 +724,7 @@ bool CliInterface::passwordQuery() { Kerfuffle::PasswordNeededQuery query(filename()); - emit userQuery(&query); - query.waitForResponse(); + query.execute(); if (query.responseCancelled()) { emit cancelled(); @@ -866,8 +862,7 @@ qCDebug(ARK) << "Found a password prompt"; Kerfuffle::PasswordNeededQuery query(filename()); - emit userQuery(&query); - query.waitForResponse(); + query.execute(); if (query.responseCancelled()) { emit cancelled(); @@ -911,8 +906,7 @@ qCDebug(ARK) << "Found a password prompt"; Kerfuffle::PasswordNeededQuery query(filename()); - emit userQuery(&query); - query.waitForResponse(); + query.execute(); if (query.responseCancelled()) { emit cancelled(); @@ -992,11 +986,7 @@ Kerfuffle::OverwriteQuery query(QDir::current().path() + QLatin1Char( '/' ) + m_storedFileName); query.setNoRenameMode(true); - emit userQuery(&query); - qCDebug(ARK) << "Waiting response"; - query.waitForResponse(); - - qCDebug(ARK) << "Finished response"; + query.execute(); QString responseToProcess; const QStringList choices = m_cliProps->property("fileExistsInput").toStringList(); diff --git a/kerfuffle/jobs.cpp b/kerfuffle/jobs.cpp --- a/kerfuffle/jobs.cpp +++ b/kerfuffle/jobs.cpp @@ -215,6 +215,10 @@ void Job::onUserQuery(Query *query) { + if (archiveInterface()->waitForFinishedSignal()) { + qCWarning(ARK) << "Plugins run from the main thread should call directly query->execute()"; + } + emit userQuery(query); } diff --git a/kerfuffle/queries.h b/kerfuffle/queries.h --- a/kerfuffle/queries.h +++ b/kerfuffle/queries.h @@ -46,14 +46,13 @@ { public: /** - * Execute the response. Will happen in the GUI thread, so it's - * safe to use widgets/gui elements here. Must call setResponse - * when done. + * Execute the response. It needs to be called from the GUI thread. */ virtual void execute() = 0; /** - * Will block until the response have been set + * Will block until the response have been set. + * Useful for worker threads that need to show a dialog. */ void waitForResponse(); diff --git a/kerfuffle/queries.cpp b/kerfuffle/queries.cpp --- a/kerfuffle/queries.cpp +++ b/kerfuffle/queries.cpp @@ -44,7 +44,6 @@ { Query::Query() { - m_responseMutex.lock(); } QVariant Query::response() const @@ -54,11 +53,11 @@ void Query::waitForResponse() { + QMutexLocker locker(&m_responseMutex); //if there is no response set yet, wait if (!m_data.contains(QStringLiteral("response"))) { m_responseCondition.wait(&m_responseMutex); } - m_responseMutex.unlock(); } void Query::setResponse(const QVariant &response)