From f7f9ed7157e9abb4d21010808176eb908829e525 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Tue, 23 May 2017 19:44:35 +0800 Subject: [PATCH] add open file location button in VExporter --- src/vedittab.cpp | 4 +- src/vexporter.cpp | 235 +++++++++++++++++++++++++++------------------- src/vexporter.h | 19 ++-- 3 files changed, 151 insertions(+), 107 deletions(-) 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;