From 5b4984f59a3d8a378712c6f2c6630be5e81637c0 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Tue, 23 May 2017 19:22:49 +0800 Subject: [PATCH] bugfix: wait for images loaded before exporting PDF --- src/resources/hoedown.js | 6 ++-- src/resources/markdown-it.js | 6 ++-- src/resources/markdown_template.js | 6 ++-- src/resources/marked.js | 6 ++-- src/resources/showdown.js | 6 ++-- src/vdocument.cpp | 6 ++-- src/vdocument.h | 7 +++-- src/vexporter.cpp | 50 ++++++++++++++++++++++++------ src/vexporter.h | 49 ++++++++++++++++++----------- 9 files changed, 93 insertions(+), 49 deletions(-) diff --git a/src/resources/hoedown.js b/src/resources/hoedown.js index b6f41096..85a7108b 100644 --- a/src/resources/hoedown.js +++ b/src/resources/hoedown.js @@ -54,13 +54,13 @@ var updateHtml = function(html) { // MathJax may be not loaded for now. if (VEnableMathjax && (typeof MathJax != "undefined")) { try { - MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLoading]); + MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLogics]); } catch (err) { content.setLog("err: " + err); - finishLoading(); + finishLogics(); } } else { - finishLoading(); + finishLogics(); } }; diff --git a/src/resources/markdown-it.js b/src/resources/markdown-it.js index 6ea2f022..54490c95 100644 --- a/src/resources/markdown-it.js +++ b/src/resources/markdown-it.js @@ -174,13 +174,13 @@ var updateText = function(text) { // finishLoading logic. if (VEnableMathjax) { try { - MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLoading]); + MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLogics]); } catch (err) { content.setLog("err: " + err); - finishLoading(); + finishLogics(); } } else { - finishLoading(); + finishLogics(); } }; diff --git a/src/resources/markdown_template.js b/src/resources/markdown_template.js index 67cd1409..36fa6aec 100644 --- a/src/resources/markdown_template.js +++ b/src/resources/markdown_template.js @@ -309,7 +309,7 @@ var insertImageCaption = function() { } // The renderer specific code should call this function once thay have finished -// loading the page. -var finishLoading = function() { - content.finishLoading(); +// markdown-specifi handle logics, such as Mermaid, MathJax. +var finishLogics = function() { + content.finishLogics(); }; diff --git a/src/resources/marked.js b/src/resources/marked.js index d9c6f6b5..5bdd4e8a 100644 --- a/src/resources/marked.js +++ b/src/resources/marked.js @@ -132,13 +132,13 @@ var updateText = function(text) { // finishLoading logic. if (VEnableMathjax) { try { - MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLoading]); + MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLogics]); } catch (err) { content.setLog("err: " + err); - finishLoading(); + finishLogics(); } } else { - finishLoading(); + finishLogics(); } }; diff --git a/src/resources/showdown.js b/src/resources/showdown.js index beaa4607..33e77cb7 100644 --- a/src/resources/showdown.js +++ b/src/resources/showdown.js @@ -156,13 +156,13 @@ var updateText = function(text) { // finishLoading logic. if (VEnableMathjax) { try { - MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLoading]); + MathJax.Hub.Queue(["Typeset", MathJax.Hub, placeholder, finishLogics]); } catch (err) { content.setLog("err: " + err); - finishLoading(); + finishLogics(); } } else { - finishLoading(); + finishLogics(); } }; diff --git a/src/vdocument.cpp b/src/vdocument.cpp index fa0734b6..98d4cc23 100644 --- a/src/vdocument.cpp +++ b/src/vdocument.cpp @@ -82,8 +82,8 @@ void VDocument::setFile(const VFile *p_file) m_file = p_file; } -void VDocument::finishLoading() +void VDocument::finishLogics() { - qDebug() << "Web side finished loading"; - emit loadFinished(); + qDebug() << "Web side finished logics"; + emit logicsFinished(); } diff --git a/src/vdocument.h b/src/vdocument.h index 3d376017..abae4062 100644 --- a/src/vdocument.h +++ b/src/vdocument.h @@ -35,8 +35,9 @@ public slots: void highlightTextCB(const QString &p_html, int p_id, int p_timeStamp); void noticeReadyToHighlightText(); - // Page is finished loading. - void finishLoading(); + // Web-side handle logics (MathJax etc.) is finished. + // But the page may not finish loading, such as images. + void finishLogics(); signals: void textChanged(const QString &text); @@ -49,7 +50,7 @@ signals: void requestHighlightText(const QString &p_text, int p_id, int p_timeStamp); void textHighlighted(const QString &p_html, int p_id, int p_timeStamp); void readyToHighlightText(); - void loadFinished(); + void logicsFinished(); private: QString m_toc; diff --git a/src/vexporter.cpp b/src/vexporter.cpp index ffc90b2f..dff67206 100644 --- a/src/vexporter.cpp +++ b/src/vexporter.cpp @@ -29,7 +29,7 @@ QString VExporter::s_defaultPathDir = QDir::homePath(); VExporter::VExporter(MarkdownConverterType p_mdType, QWidget *p_parent) : QDialog(p_parent), m_document(NULL, this), m_mdType(p_mdType), m_file(NULL), m_type(ExportType::PDF), m_source(ExportSource::Invalid), - m_webReady(false), m_state(ExportState::Idle), + m_noteState(NoteState::NotReady), m_state(ExportState::Idle), m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0.0, 0.0, 0.0, 0.0))) { setupUI(); @@ -190,12 +190,15 @@ void VExporter::setupMarkdownViewer() VPreviewPage *page = new VPreviewPage(this); m_webViewer->setPage(page); + connect(page, &VPreviewPage::loadFinished, + this, &VExporter::handleLoadFinished); + QWebChannel *channel = new QWebChannel(this); channel->registerObject(QStringLiteral("content"), &m_document); page->setWebChannel(channel); - connect(&m_document, &VDocument::loadFinished, - this, &VExporter::readyToExport); + connect(&m_document, &VDocument::logicsFinished, + this, &VExporter::handleLogicsFinished); QString jsFile, extraFile; switch (m_mdType) { @@ -273,10 +276,37 @@ void VExporter::updateWebViewer(VFile *p_file) m_webViewer->setHtml(m_htmlTemplate, p_file->getBaseUrl()); } -void VExporter::readyToExport() +void VExporter::handleLogicsFinished() { - Q_ASSERT(!m_webReady); - m_webReady = true; + Q_ASSERT(!(m_noteState & NoteState::WebLogicsReady)); + m_noteState = NoteState(m_noteState | NoteState::WebLogicsReady); +} + +void VExporter::handleLoadFinished(bool p_ok) +{ + qDebug() << "Web load finished" << p_ok; + + Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished)); + m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished); + + if (!p_ok) { + m_noteState = NoteState(m_noteState | NoteState::Failed); + } +} + +void VExporter::clearNoteState() +{ + m_noteState = NoteState::NotReady; +} + +bool VExporter::isNoteStateReady() const +{ + return m_noteState == NoteState::Ready; +} + +bool VExporter::isNoteStateFailed() const +{ + return m_noteState & NoteState::Failed; } void VExporter::startExport() @@ -292,7 +322,7 @@ void VExporter::startExport() goto exit; } - m_webReady = false; + clearNoteState(); updateWebViewer(m_file); // Update progress info. @@ -303,13 +333,13 @@ void VExporter::startExport() m_proLabel->show(); m_proBar->show(); - while (!m_webReady) { + while (!isNoteStateReady()) { VUtils::sleepWait(100); if (m_proBar->value() < 70) { m_proBar->setValue(m_proBar->value() + 1); } - if (m_state == ExportState::Cancelled) { + if (m_state == ExportState::Cancelled || isNoteStateFailed()) { goto exit; } } @@ -327,7 +357,7 @@ void VExporter::startExport() m_proBar->setValue(100); - m_webReady = false; + clearNoteState(); if (!isOpened) { m_file->close(); diff --git a/src/vexporter.h b/src/vexporter.h index 76ded249..eb223fef 100644 --- a/src/vexporter.h +++ b/src/vexporter.h @@ -21,21 +21,6 @@ enum class ExportType HTML }; -enum class ExportSource -{ - Note = 0, - Directory, - Notebook, - Invalid -}; - -enum class ExportState -{ - Idle = 0, - Cancelled, - Busy -}; - class VExporter : public QDialog { Q_OBJECT @@ -49,8 +34,34 @@ private slots: void handleLayoutBtnClicked(); void startExport(); void cancelExport(); + void handleLogicsFinished(); + void handleLoadFinished(bool p_ok); private: + enum class ExportSource + { + Note = 0, + Directory, + Notebook, + Invalid + }; + + enum class ExportState + { + Idle = 0, + Cancelled, + Busy + }; + + enum NoteState + { + NotReady = 0, + WebLogicsReady = 0x1, + WebLoadFinished = 0x2, + Ready = 0x3, + Failed = 0x4 + }; + void setupUI(); // Init m_webViewer, m_document, and m_htmlTemplate. @@ -64,12 +75,14 @@ private: void updateWebViewer(VFile *p_file); - void readyToExport(); - void enableUserInput(bool p_enabled); void exportToPDF(VWebView *p_webViewer, const QString &p_filePath, const QPageLayout &p_layout); + void clearNoteState(); + bool isNoteStateReady() const; + bool isNoteStateFailed() const; + VWebView *m_webViewer; VDocument m_document; MarkdownConverterType m_mdType; @@ -77,7 +90,7 @@ private: VFile *m_file; ExportType m_type; ExportSource m_source; - bool m_webReady; + NoteState m_noteState; ExportState m_state;