diff --git a/src/vedittab.cpp b/src/vedittab.cpp
index defc72df..d07bcd11 100644
--- a/src/vedittab.cpp
+++ b/src/vedittab.cpp
@@ -290,11 +290,11 @@ void VEditTab::setupMarkdownPreview()
connect(webPreviewer, &VWebView::editNote,
this, &VEditTab::editFile);
- VPreviewPage *page = new VPreviewPage(this);
+ VPreviewPage *page = new VPreviewPage(webPreviewer);
webPreviewer->setPage(page);
webPreviewer->setZoomFactor(vconfig.getWebZoomFactor());
- QWebChannel *channel = new QWebChannel(this);
+ QWebChannel *channel = new QWebChannel(webPreviewer);
channel->registerObject(QStringLiteral("content"), &document);
connect(&document, &VDocument::tocChanged,
this, &VEditTab::updateTocFromHtml);
diff --git a/src/vexporter.cpp b/src/vexporter.cpp
index dff67206..f243a3bb 100644
--- a/src/vexporter.cpp
+++ b/src/vexporter.cpp
@@ -21,24 +21,86 @@
#include "vconstants.h"
#include "vnote.h"
#include "vmarkdownconverter.h"
+#include "vdocument.h"
extern VConfigManager vconfig;
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),
+ : QDialog(p_parent), m_webViewer(NULL), m_mdType(p_mdType),
m_file(NULL), m_type(ExportType::PDF), m_source(ExportSource::Invalid),
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)))
{
+ initMarkdownTemplate();
+
setupUI();
}
+void VExporter::initMarkdownTemplate()
+{
+ QString jsFile, extraFile;
+ switch (m_mdType) {
+ case MarkdownConverterType::Marked:
+ jsFile = "qrc" + VNote::c_markedJsFile;
+ extraFile = "\n";
+ break;
+
+ case MarkdownConverterType::Hoedown:
+ jsFile = "qrc" + VNote::c_hoedownJsFile;
+ // Use Marked to highlight code blocks.
+ extraFile = "\n";
+ break;
+
+ case MarkdownConverterType::MarkdownIt:
+ jsFile = "qrc" + VNote::c_markdownitJsFile;
+ extraFile = "\n" +
+ "\n" +
+ "\n";
+ break;
+
+ case MarkdownConverterType::Showdown:
+ jsFile = "qrc" + VNote::c_showdownJsFile;
+ extraFile = "\n" +
+ "\n";
+
+ break;
+
+ default:
+ Q_ASSERT(false);
+ }
+
+ if (vconfig.getEnableMermaid()) {
+ extraFile += "\n" + "\n" +
+ "\n";
+ }
+
+ if (vconfig.getEnableMathjax()) {
+ extraFile += "\n"
+ "\n" +
+ "\n";
+ }
+
+ if (vconfig.getEnableImageCaption()) {
+ extraFile += "\n";
+ }
+
+ m_htmlTemplate = VNote::s_markdownTemplatePDF;
+ m_htmlTemplate.replace(c_htmlJSHolder, jsFile);
+ if (!extraFile.isEmpty()) {
+ m_htmlTemplate.replace(c_htmlExtraHolder, extraFile);
+ }
+}
+
void VExporter::setupUI()
{
- setupMarkdownViewer();
-
m_infoLabel = new QLabel();
m_infoLabel->setWordWrap(true);
@@ -68,27 +130,25 @@ void VExporter::setupUI()
// Ok is the default button.
m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ m_openBtn = m_btnBox->addButton(tr("Open File Location"), QDialogButtonBox::ActionRole);
connect(m_btnBox, &QDialogButtonBox::accepted, this, &VExporter::startExport);
connect(m_btnBox, &QDialogButtonBox::rejected, this, &VExporter::cancelExport);
+ connect(m_openBtn, &QPushButton::clicked, this, &VExporter::openTargetPath);
QPushButton *okBtn = m_btnBox->button(QDialogButtonBox::Ok);
m_pathEdit->setMinimumWidth(okBtn->sizeHint().width() * 3);
QGridLayout *mainLayout = new QGridLayout();
- mainLayout->addWidget(m_webViewer, 0, 0, 1, 3);
- mainLayout->addWidget(m_infoLabel, 1, 0, 1, 3);
- mainLayout->addWidget(pathLabel, 2, 0);
- mainLayout->addWidget(m_pathEdit, 2, 1);
- mainLayout->addWidget(m_browseBtn, 2, 2);
- mainLayout->addWidget(layoutLabel, 3, 0);
- mainLayout->addWidget(m_layoutLabel, 3, 1);
- mainLayout->addWidget(m_layoutBtn, 3, 2);
- mainLayout->addWidget(m_proLabel, 4, 1, 1, 2);
- mainLayout->addWidget(m_proBar, 5, 1, 1, 2);
- mainLayout->addWidget(m_btnBox, 6, 1, 1, 2);
-
- // Only use VWebView to do the conversion.
- m_webViewer->hide();
+ mainLayout->addWidget(m_infoLabel, 0, 0, 1, 3);
+ mainLayout->addWidget(pathLabel, 1, 0);
+ mainLayout->addWidget(m_pathEdit, 1, 1);
+ mainLayout->addWidget(m_browseBtn, 1, 2);
+ mainLayout->addWidget(layoutLabel, 2, 0);
+ mainLayout->addWidget(m_layoutLabel, 2, 1);
+ mainLayout->addWidget(m_layoutBtn, 2, 2);
+ mainLayout->addWidget(m_proLabel, 3, 1, 1, 2);
+ mainLayout->addWidget(m_proBar, 4, 1, 1, 2);
+ mainLayout->addWidget(m_btnBox, 5, 1, 1, 2);
m_proLabel->hide();
m_proBar->hide();
@@ -97,6 +157,8 @@ void VExporter::setupUI()
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
setWindowTitle(tr("Export Note"));
+ m_openBtn->hide();
+
updatePageLayoutLabel();
}
@@ -124,6 +186,8 @@ void VExporter::handleBrowseBtnClicked()
setFilePath(path);
s_defaultPathDir = VUtils::basePathFromPath(path);
+
+ m_openBtn->hide();
}
void VExporter::handleLayoutBtnClicked()
@@ -184,84 +248,27 @@ void VExporter::exportNote(VFile *p_file, ExportType p_type)
"." + exportTypeStr(p_type).toLower()));
}
-void VExporter::setupMarkdownViewer()
+void VExporter::initWebViewer(VFile *p_file)
{
- m_webViewer = new VWebView(NULL, this);
- VPreviewPage *page = new VPreviewPage(this);
+ V_ASSERT(!m_webViewer);
+
+ m_webViewer = new VWebView(p_file, this);
+ m_webViewer->hide();
+ VPreviewPage *page = new VPreviewPage(m_webViewer);
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::logicsFinished,
+ VDocument *document = new VDocument(p_file, m_webViewer);
+ connect(document, &VDocument::logicsFinished,
this, &VExporter::handleLogicsFinished);
- QString jsFile, extraFile;
- switch (m_mdType) {
- case MarkdownConverterType::Marked:
- jsFile = "qrc" + VNote::c_markedJsFile;
- extraFile = "\n";
- break;
+ QWebChannel *channel = new QWebChannel(m_webViewer);
+ channel->registerObject(QStringLiteral("content"), document);
+ page->setWebChannel(channel);
- case MarkdownConverterType::Hoedown:
- jsFile = "qrc" + VNote::c_hoedownJsFile;
- // Use Marked to highlight code blocks.
- extraFile = "\n";
- break;
-
- case MarkdownConverterType::MarkdownIt:
- jsFile = "qrc" + VNote::c_markdownitJsFile;
- extraFile = "\n" +
- "\n" +
- "\n";
- break;
-
- case MarkdownConverterType::Showdown:
- jsFile = "qrc" + VNote::c_showdownJsFile;
- extraFile = "\n" +
- "\n";
-
- break;
-
- default:
- Q_ASSERT(false);
- }
-
- if (vconfig.getEnableMermaid()) {
- extraFile += "\n" + "\n" +
- "\n";
- }
-
- if (vconfig.getEnableMathjax()) {
- extraFile += "\n"
- "\n" +
- "\n";
- }
-
- if (vconfig.getEnableImageCaption()) {
- extraFile += "\n";
- }
-
- m_htmlTemplate = VNote::s_markdownTemplatePDF;
- m_htmlTemplate.replace(c_htmlJSHolder, jsFile);
- if (!extraFile.isEmpty()) {
- m_htmlTemplate.replace(c_htmlExtraHolder, extraFile);
- }
-}
-
-void VExporter::updateWebViewer(VFile *p_file)
-{
- m_document.setFile(p_file);
+ qDebug() << "VPreviewPage" << page->parent() << "QWebChannel" << channel->parent();
// Need to generate HTML using Hoedown.
if (m_mdType == MarkdownConverterType::Hoedown) {
@@ -270,12 +277,20 @@ void VExporter::updateWebViewer(VFile *p_file)
QString html = mdConverter.generateHtml(p_file->getContent(),
vconfig.getMarkdownExtensions(),
toc);
- m_document.setHtml(html);
+ document->setHtml(html);
}
m_webViewer->setHtml(m_htmlTemplate, p_file->getBaseUrl());
}
+void VExporter::clearWebViewer()
+{
+ if (m_webViewer) {
+ delete m_webViewer;
+ m_webViewer = NULL;
+ }
+}
+
void VExporter::handleLogicsFinished()
{
Q_ASSERT(!(m_noteState & NoteState::WebLogicsReady));
@@ -311,10 +326,13 @@ bool VExporter::isNoteStateFailed() const
void VExporter::startExport()
{
+ int exportedNum = 0;
enableUserInput(false);
V_ASSERT(m_state == ExportState::Idle);
m_state = ExportState::Busy;
+ m_openBtn->hide();
+
if (m_source == ExportSource::Note) {
V_ASSERT(m_file);
bool isOpened = m_file->isOpened();
@@ -323,10 +341,11 @@ void VExporter::startExport()
}
clearNoteState();
- updateWebViewer(m_file);
+ initWebViewer(m_file);
// Update progress info.
m_proLabel->setText(tr("Exporting %1").arg(m_file->getName()));
+ m_proBar->setEnabled(true);
m_proBar->setMinimum(0);
m_proBar->setMaximum(100);
m_proBar->reset();
@@ -339,7 +358,12 @@ void VExporter::startExport()
m_proBar->setValue(m_proBar->value() + 1);
}
- if (m_state == ExportState::Cancelled || isNoteStateFailed()) {
+ if (m_state == ExportState::Cancelled) {
+ goto exit;
+ }
+
+ if (isNoteStateFailed()) {
+ m_state = ExportState::Failed;
goto exit;
}
}
@@ -353,28 +377,37 @@ void VExporter::startExport()
m_proBar->setValue(80);
- exportToPDF(m_webViewer, getFilePath(), m_pageLayout);
-
- m_proBar->setValue(100);
+ bool exportRet = exportToPDF(m_webViewer, getFilePath(), m_pageLayout);
clearNoteState();
if (!isOpened) {
m_file->close();
}
+
+ if (exportRet) {
+ m_proBar->setValue(100);
+ m_state = ExportState::Successful;
+ exportedNum++;
+ } else {
+ m_proBar->setEnabled(false);
+ m_state = ExportState::Failed;
+ }
}
exit:
+ clearWebViewer();
+
m_proLabel->setText("");
- m_proBar->reset();
m_proLabel->hide();
- m_proBar->hide();
enableUserInput(true);
if (m_state == ExportState::Cancelled) {
reject();
- } else {
- accept();
+ }
+
+ if (exportedNum) {
+ m_openBtn->show();
}
m_state = ExportState::Idle;
@@ -389,7 +422,7 @@ void VExporter::cancelExport()
}
}
-void VExporter::exportToPDF(VWebView *p_webViewer, const QString &p_filePath,
+bool VExporter::exportToPDF(VWebView *p_webViewer, const QString &p_filePath,
const QPageLayout &p_layout)
{
int pdfPrinted = 0;
@@ -422,7 +455,7 @@ void VExporter::exportToPDF(VWebView *p_webViewer, const QString &p_filePath,
}
}
- qDebug() << "export to PDF" << p_filePath << "state" << pdfPrinted;
+ return pdfPrinted == 1;
}
void VExporter::enableUserInput(bool p_enabled)
@@ -432,3 +465,9 @@ void VExporter::enableUserInput(bool p_enabled)
m_browseBtn->setEnabled(p_enabled);
m_layoutBtn->setEnabled(p_enabled);
}
+
+void VExporter::openTargetPath() const
+{
+ QUrl url = QUrl::fromLocalFile(VUtils::basePathFromPath(getFilePath()));
+ QDesktopServices::openUrl(url);
+}
diff --git a/src/vexporter.h b/src/vexporter.h
index eb223fef..5bf42b4f 100644
--- a/src/vexporter.h
+++ b/src/vexporter.h
@@ -5,7 +5,6 @@
#include
#include
#include "vconfigmanager.h"
-#include "vdocument.h"
class VWebView;
class VFile;
@@ -36,6 +35,7 @@ private slots:
void cancelExport();
void handleLogicsFinished();
void handleLoadFinished(bool p_ok);
+ void openTargetPath() const;
private:
enum class ExportSource
@@ -50,7 +50,9 @@ private:
{
Idle = 0,
Cancelled,
- Busy
+ Busy,
+ Failed,
+ Successful
};
enum NoteState
@@ -64,8 +66,7 @@ private:
void setupUI();
- // Init m_webViewer, m_document, and m_htmlTemplate.
- void setupMarkdownViewer();
+ void initMarkdownTemplate();
void updatePageLayoutLabel();
@@ -73,18 +74,21 @@ private:
QString getFilePath() const;
- void updateWebViewer(VFile *p_file);
+ void initWebViewer(VFile *p_file);
+
+ void clearWebViewer();
void enableUserInput(bool p_enabled);
- void exportToPDF(VWebView *p_webViewer, const QString &p_filePath, const QPageLayout &p_layout);
+ bool exportToPDF(VWebView *p_webViewer, const QString &p_filePath, const QPageLayout &p_layout);
void clearNoteState();
bool isNoteStateReady() const;
bool isNoteStateFailed() const;
+ // Will be allocated and free for each conversion.
VWebView *m_webViewer;
- VDocument m_document;
+
MarkdownConverterType m_mdType;
QString m_htmlTemplate;
VFile *m_file;
@@ -100,6 +104,7 @@ private:
QLabel *m_layoutLabel;
QPushButton *m_layoutBtn;
QDialogButtonBox *m_btnBox;
+ QPushButton *m_openBtn;
// Progress label and bar.
QLabel *m_proLabel;