export: call tool process asynchronously

This commit is contained in:
Le Tan 2018-03-03 12:29:55 +08:00
parent 635ac0a10b
commit 8e06c24fc1
3 changed files with 102 additions and 2 deletions

View File

@ -133,6 +133,8 @@ void VExportDialog::setupUI()
if (m_inExport) {
// Just cancel the export. Do not exit.
m_askedToStop = true;
m_exporter->setAskedToStop(true);
appendLogLine(tr("Cancelling the export..."));
} else {
QDialog::reject();
}
@ -489,6 +491,7 @@ void VExportDialog::startExport()
m_exportBtn->setEnabled(false);
m_proBar->show();
m_askedToStop = false;
m_exporter->setAskedToStop(false);
m_inExport = true;
QString outputFolder = QDir::cleanPath(QDir(getOutputDirectory()).absolutePath());
@ -579,6 +582,11 @@ void VExportDialog::startExport()
s_opt.m_format = ExportFormat::OnePDF;
if (m_askedToStop) {
ret = 0;
goto exit;
}
Q_ASSERT(ret == files.size());
if (!files.isEmpty()) {
ret = doExportPDFAllInOne(files, s_opt, outputFolder, &msg);
@ -611,6 +619,7 @@ exit:
if (m_askedToStop) {
appendLogLine(tr("User cancelled the export. Aborted!"));
m_askedToStop = false;
m_exporter->setAskedToStop(false);
}
if (!msg.isEmpty()) {

View File

@ -7,6 +7,8 @@
#include <QRegExp>
#include <QProcess>
#include <QTemporaryDir>
#include <QScopedPointer>
#include <QCoreApplication>
#include "vconfigmanager.h"
#include "vfile.h"
@ -25,7 +27,8 @@ extern VWebUtils *g_webUtils;
VExporter::VExporter(QWidget *p_parent)
: QObject(p_parent),
m_webViewer(NULL),
m_state(ExportState::Idle)
m_state(ExportState::Idle),
m_askedToStop(false)
{
}
@ -666,8 +669,12 @@ bool VExporter::htmlsToPDFViaWK(const QList<QString> &p_htmlFiles,
QString cmd = p_opt.m_wkPath + " " + combineArgs(args);
emit outputLog(cmd);
qDebug() << "wkhtmltopdf cmd:" << cmd;
int ret = QProcess::execute(p_opt.m_wkPath, args);
int ret = startProcess(p_opt.m_wkPath, args);
qDebug() << "wkhtmltopdf returned" << ret;
if (m_askedToStop) {
return ret == 0;
}
switch (ret) {
case -2:
VUtils::addErrMsg(p_errMsg, tr("Fail to start wkhtmltopdf (%1).").arg(cmd));
@ -695,3 +702,77 @@ int VExporter::exportPDFInOne(const QList<QString> &p_htmlFiles,
return p_htmlFiles.size();
}
int VExporter::startProcess(const QString &p_program, const QStringList &p_args)
{
int ret = 0;
QScopedPointer<QProcess> process(new QProcess(this));
process->start(p_program, p_args);
bool finished = false;
bool started = false;
while (true) {
QProcess::ProcessError err = process->error();
if (err == QProcess::FailedToStart
|| err == QProcess::Crashed) {
emit outputLog(tr("QProcess error %1.").arg(err));
if (err == QProcess::FailedToStart) {
ret = -2;
} else {
ret = -1;
}
break;
}
if (started) {
if (process->state() == QProcess::NotRunning) {
finished = true;
}
} else {
if (process->state() != QProcess::NotRunning) {
started = true;
}
}
if (process->waitForFinished(500)) {
// Finished.
finished = true;
}
QByteArray outBa = process->readAllStandardOutput();
QByteArray errBa = process->readAllStandardError();
QString msg;
if (!outBa.isEmpty()) {
msg += QString::fromLocal8Bit(outBa);
}
if (!errBa.isEmpty()) {
msg += QString::fromLocal8Bit(errBa);
}
if (!msg.isEmpty()) {
emit outputLog(msg);
}
if (finished) {
QProcess::ExitStatus sta = process->exitStatus();
if (sta == QProcess::CrashExit) {
ret = -1;
break;
}
ret = process->exitCode();
break;
}
QCoreApplication::processEvents();
if (m_askedToStop) {
process->kill();
ret = -1;
break;
}
}
return ret;
}

View File

@ -36,6 +36,8 @@ public:
const QString &p_outputFile,
QString *p_errMsg = NULL);
void setAskedToStop(bool p_askedToStop);
signals:
// Request to output log.
void outputLog(const QString &p_log);
@ -107,6 +109,8 @@ private:
void prepareWKArguments(const ExportPDFOption &p_opt);
int startProcess(const QString &p_program, const QStringList &p_args);
// Fix @p_html's resources like url("...") with "file" or "qrc" schema.
// Copy the resource to @p_folder and fix the url string.
static bool fixStyleResources(const QString &p_folder,
@ -144,6 +148,8 @@ private:
// Arguments for wkhtmltopdf.
QStringList m_wkArgs;
bool m_askedToStop;
};
inline void VExporter::clearNoteState()
@ -161,4 +167,8 @@ inline bool VExporter::isNoteStateFailed() const
return m_noteState & NoteState::Failed;
}
inline void VExporter::setAskedToStop(bool p_askedToStop)
{
m_askedToStop = p_askedToStop;
}
#endif // VEXPORTER_H