mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-06 14:29:54 +08:00
export: support exporting PDF via wkhtmltopdf tool
This commit is contained in:
parent
3bee0365e9
commit
935bb4d3b4
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#ifndef QT_NO_PRINTER
|
#ifndef QT_NO_PRINTER
|
||||||
#include <QPrinter>
|
#include <QPrinter>
|
||||||
@ -18,6 +19,7 @@
|
|||||||
#include "vnotefile.h"
|
#include "vnotefile.h"
|
||||||
#include "vnote.h"
|
#include "vnote.h"
|
||||||
#include "vexporter.h"
|
#include "vexporter.h"
|
||||||
|
#include "vlineedit.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
@ -25,7 +27,7 @@ extern VNote *g_vnote;
|
|||||||
|
|
||||||
QString VExportDialog::s_lastOutputFolder;
|
QString VExportDialog::s_lastOutputFolder;
|
||||||
|
|
||||||
ExportFormat VExportDialog::s_lastExportFormat = ExportFormat::Markdown;
|
ExportOption VExportDialog::s_opt;
|
||||||
|
|
||||||
#define LOGERR(x) do { QString msg = (x); \
|
#define LOGERR(x) do { QString msg = (x); \
|
||||||
VUtils::addErrMsg(p_errMsg, msg); \
|
VUtils::addErrMsg(p_errMsg, msg); \
|
||||||
@ -45,7 +47,8 @@ VExportDialog::VExportDialog(VNotebook *p_notebook,
|
|||||||
m_cart(p_cart),
|
m_cart(p_cart),
|
||||||
m_pageLayout(QPageLayout(QPageSize(QPageSize::A4),
|
m_pageLayout(QPageLayout(QPageSize(QPageSize::A4),
|
||||||
QPageLayout::Portrait,
|
QPageLayout::Portrait,
|
||||||
QMarginsF(0.3, 0.3, 0.3, 0.3))),
|
QMarginsF(10, 16, 10, 10),
|
||||||
|
QPageLayout::Millimeter)),
|
||||||
m_inExport(false),
|
m_inExport(false),
|
||||||
m_askedToStop(false)
|
m_askedToStop(false)
|
||||||
{
|
{
|
||||||
@ -56,6 +59,10 @@ VExportDialog::VExportDialog(VNotebook *p_notebook,
|
|||||||
setupUI();
|
setupUI();
|
||||||
|
|
||||||
m_exporter = new VExporter(this);
|
m_exporter = new VExporter(this);
|
||||||
|
connect(m_exporter, &VExporter::outputLog,
|
||||||
|
this, [this](const QString &p_log) {
|
||||||
|
appendLogLine(p_log);
|
||||||
|
});
|
||||||
|
|
||||||
initUIFields(p_renderer);
|
initUIFields(p_renderer);
|
||||||
|
|
||||||
@ -68,6 +75,8 @@ void VExportDialog::setupUI()
|
|||||||
m_srcCB = VUtils::getComboBox();
|
m_srcCB = VUtils::getComboBox();
|
||||||
m_srcCB->setToolTip(tr("Choose notes to export"));
|
m_srcCB->setToolTip(tr("Choose notes to export"));
|
||||||
m_srcCB->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
m_srcCB->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
||||||
|
connect(m_srcCB, SIGNAL(currentIndexChanged(int)),
|
||||||
|
this, SLOT(handleCurrentSrcChanged(int)));
|
||||||
|
|
||||||
// Target format.
|
// Target format.
|
||||||
m_formatCB = VUtils::getComboBox();
|
m_formatCB = VUtils::getComboBox();
|
||||||
@ -97,12 +106,12 @@ void VExportDialog::setupUI()
|
|||||||
m_outputEdit = new VLineEdit(s_lastOutputFolder);
|
m_outputEdit = new VLineEdit(s_lastOutputFolder);
|
||||||
connect(m_outputEdit, &QLineEdit::textChanged,
|
connect(m_outputEdit, &QLineEdit::textChanged,
|
||||||
this, &VExportDialog::handleInputChanged);
|
this, &VExportDialog::handleInputChanged);
|
||||||
m_browseBtn = new QPushButton(tr("&Browse"));
|
QPushButton *browseBtn = new QPushButton(tr("&Browse"));
|
||||||
connect(m_browseBtn, &QPushButton::clicked,
|
connect(browseBtn, &QPushButton::clicked,
|
||||||
this, &VExportDialog::handleBrowseBtnClicked);
|
this, &VExportDialog::handleOutputBrowseBtnClicked);
|
||||||
QHBoxLayout *outputLayout = new QHBoxLayout();
|
QHBoxLayout *outputLayout = new QHBoxLayout();
|
||||||
outputLayout->addWidget(m_outputEdit);
|
outputLayout->addWidget(m_outputEdit);
|
||||||
outputLayout->addWidget(m_browseBtn);
|
outputLayout->addWidget(browseBtn);
|
||||||
|
|
||||||
m_basicBox = new QGroupBox(tr("Information"));
|
m_basicBox = new QGroupBox(tr("Information"));
|
||||||
|
|
||||||
@ -150,10 +159,12 @@ void VExportDialog::setupUI()
|
|||||||
m_basicBox->setLayout(basicLayout);
|
m_basicBox->setLayout(basicLayout);
|
||||||
|
|
||||||
// Settings box.
|
// Settings box.
|
||||||
|
m_generalSettings = setupGeneralAdvancedSettings();
|
||||||
m_htmlSettings = setupHTMLAdvancedSettings();
|
m_htmlSettings = setupHTMLAdvancedSettings();
|
||||||
m_pdfSettings = setupPDFAdvancedSettings();
|
m_pdfSettings = setupPDFAdvancedSettings();
|
||||||
|
|
||||||
QVBoxLayout *advLayout = new QVBoxLayout();
|
QVBoxLayout *advLayout = new QVBoxLayout();
|
||||||
|
advLayout->addWidget(m_generalSettings);
|
||||||
advLayout->addWidget(m_htmlSettings);
|
advLayout->addWidget(m_htmlSettings);
|
||||||
advLayout->addWidget(m_pdfSettings);
|
advLayout->addWidget(m_pdfSettings);
|
||||||
|
|
||||||
@ -190,8 +201,75 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
|
|||||||
layoutLayout->addWidget(layoutBtn);
|
layoutLayout->addWidget(layoutBtn);
|
||||||
layoutLayout->addStretch();
|
layoutLayout->addStretch();
|
||||||
|
|
||||||
|
// Use wkhtmltopdf.
|
||||||
|
m_wkhtmltopdfCB = new QCheckBox(tr("Use wkhtmltopdf"));
|
||||||
|
m_wkhtmltopdfCB->setToolTip(tr("Use wkhtmltopdf tool to generate PDF (wkhtmltopdf needed to be installed)"));
|
||||||
|
connect(m_wkhtmltopdfCB, &QCheckBox::stateChanged,
|
||||||
|
this, [this](int p_state) {
|
||||||
|
bool checked = p_state == Qt::Checked;
|
||||||
|
m_wkPathEdit->setEnabled(checked);
|
||||||
|
m_wkPathBrowseBtn->setEnabled(checked);
|
||||||
|
m_wkBackgroundCB->setEnabled(checked);
|
||||||
|
m_wkTableOfContentsCB->setEnabled(checked);
|
||||||
|
m_wkPageNumberCB->setEnabled(checked);
|
||||||
|
m_wkExtraArgsEdit->setEnabled(checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
QPushButton *wkBtn = new QPushButton(tr("Download wkhtmltopdf"));
|
||||||
|
connect(wkBtn, &QPushButton::clicked,
|
||||||
|
this, [this]() {
|
||||||
|
QString url("https://wkhtmltopdf.org/downloads.html");
|
||||||
|
QDesktopServices::openUrl(QUrl(url));
|
||||||
|
});
|
||||||
|
|
||||||
|
QHBoxLayout *wkLayout = new QHBoxLayout();
|
||||||
|
wkLayout->addWidget(m_wkhtmltopdfCB);
|
||||||
|
wkLayout->addStretch();
|
||||||
|
wkLayout->addWidget(wkBtn);
|
||||||
|
|
||||||
|
// wkhtmltopdf Path.
|
||||||
|
m_wkPathEdit = new VLineEdit();
|
||||||
|
m_wkPathEdit->setToolTip(tr("Tell VNote where to find wkhtmlpdf tool"));
|
||||||
|
m_wkPathEdit->setEnabled(m_wkhtmltopdfCB->isChecked());
|
||||||
|
|
||||||
|
m_wkPathBrowseBtn = new QPushButton(tr("&Browse"));
|
||||||
|
m_wkPathBrowseBtn->setEnabled(m_wkhtmltopdfCB->isChecked());
|
||||||
|
connect(m_wkPathBrowseBtn, &QPushButton::clicked,
|
||||||
|
this, &VExportDialog::handleWkPathBrowseBtnClicked);
|
||||||
|
|
||||||
|
QHBoxLayout *wkPathLayout = new QHBoxLayout();
|
||||||
|
wkPathLayout->addWidget(m_wkPathEdit);
|
||||||
|
wkPathLayout->addWidget(m_wkPathBrowseBtn);
|
||||||
|
|
||||||
|
// wkhtmltopdf enable background.
|
||||||
|
m_wkBackgroundCB = new QCheckBox(tr("Enable background"));
|
||||||
|
m_wkBackgroundCB->setToolTip(tr("Enable background when printing"));
|
||||||
|
m_wkBackgroundCB->setEnabled(m_wkhtmltopdfCB->isChecked());
|
||||||
|
|
||||||
|
// wkhtmltopdf enable table of contents.
|
||||||
|
m_wkTableOfContentsCB = new QCheckBox(tr("Enable Table Of Contents"));
|
||||||
|
m_wkTableOfContentsCB->setToolTip(tr("Add a table of contents to the document"));
|
||||||
|
m_wkTableOfContentsCB->setEnabled(m_wkhtmltopdfCB->isChecked());
|
||||||
|
|
||||||
|
// wkhtmltopdf page number.
|
||||||
|
m_wkPageNumberCB = VUtils::getComboBox();
|
||||||
|
m_wkPageNumberCB->setToolTip(tr("Append page number as footer"));
|
||||||
|
m_wkPageNumberCB->setEnabled(m_wkhtmltopdfCB->isChecked());
|
||||||
|
|
||||||
|
// wkhtmltopdf extra argumnets.
|
||||||
|
m_wkExtraArgsEdit = new VLineEdit();
|
||||||
|
m_wkExtraArgsEdit->setToolTip(tr("Additional arguments passed to wkhtmltopdf"));
|
||||||
|
m_wkExtraArgsEdit->setPlaceholderText(tr("Use \" to enclose arguments containing space"));
|
||||||
|
m_wkExtraArgsEdit->setEnabled(m_wkhtmltopdfCB->isChecked());
|
||||||
|
|
||||||
QFormLayout *advLayout = new QFormLayout();
|
QFormLayout *advLayout = new QFormLayout();
|
||||||
advLayout->addRow(tr("Page layout:"), layoutLayout);
|
advLayout->addRow(tr("Page layout:"), layoutLayout);
|
||||||
|
advLayout->addRow(wkLayout);
|
||||||
|
advLayout->addRow(tr("wkhtmltopdf path:"), wkPathLayout);
|
||||||
|
advLayout->addRow(m_wkBackgroundCB);
|
||||||
|
advLayout->addRow(m_wkTableOfContentsCB);
|
||||||
|
advLayout->addRow(tr("Page number:"), m_wkPageNumberCB);
|
||||||
|
advLayout->addRow(tr("Additional arguments:"), m_wkExtraArgsEdit);
|
||||||
|
|
||||||
advLayout->setContentsMargins(0, 0, 0, 0);
|
advLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
@ -206,14 +284,12 @@ QWidget *VExportDialog::setupHTMLAdvancedSettings()
|
|||||||
// Embed CSS styles.
|
// Embed CSS styles.
|
||||||
m_embedStyleCB = new QCheckBox(tr("Embed CSS styles"), this);
|
m_embedStyleCB = new QCheckBox(tr("Embed CSS styles"), this);
|
||||||
m_embedStyleCB->setToolTip(tr("Embed CSS styles in HTML file"));
|
m_embedStyleCB->setToolTip(tr("Embed CSS styles in HTML file"));
|
||||||
m_embedStyleCB->setChecked(true);
|
|
||||||
|
|
||||||
// Complete HTML.
|
// Complete HTML.
|
||||||
m_completeHTMLCB = new QCheckBox(tr("Complete page"), this);
|
m_completeHTMLCB = new QCheckBox(tr("Complete page"), this);
|
||||||
m_completeHTMLCB->setToolTip(tr("Export the whole web page along with pictures "
|
m_completeHTMLCB->setToolTip(tr("Export the whole web page along with pictures "
|
||||||
"which may not keep the HTML link structure of "
|
"which may not keep the HTML link structure of "
|
||||||
"the original page"));
|
"the original page"));
|
||||||
m_completeHTMLCB->setChecked(true);
|
|
||||||
|
|
||||||
// Mime HTML.
|
// Mime HTML.
|
||||||
m_mimeHTMLCB = new QCheckBox(tr("MIME HTML"), this);
|
m_mimeHTMLCB = new QCheckBox(tr("MIME HTML"), this);
|
||||||
@ -238,6 +314,24 @@ QWidget *VExportDialog::setupHTMLAdvancedSettings()
|
|||||||
return wid;
|
return wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *VExportDialog::setupGeneralAdvancedSettings()
|
||||||
|
{
|
||||||
|
// Include subfolders.
|
||||||
|
m_subfolderCB = new QCheckBox(tr("Process subfolders"));
|
||||||
|
m_subfolderCB->setToolTip(tr("Process subfolders recursively"));
|
||||||
|
m_subfolderCB->setChecked(true);
|
||||||
|
|
||||||
|
QFormLayout *advLayout = new QFormLayout();
|
||||||
|
advLayout->addRow(m_subfolderCB);
|
||||||
|
|
||||||
|
advLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
QWidget *wid = new QWidget();
|
||||||
|
wid->setLayout(advLayout);
|
||||||
|
|
||||||
|
return wid;
|
||||||
|
}
|
||||||
|
|
||||||
void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
||||||
{
|
{
|
||||||
// Notes to export.
|
// Notes to export.
|
||||||
@ -248,7 +342,7 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
|||||||
|
|
||||||
if (m_directory) {
|
if (m_directory) {
|
||||||
m_srcCB->addItem(tr("Current Folder (%1)").arg(m_directory->getName()),
|
m_srcCB->addItem(tr("Current Folder (%1)").arg(m_directory->getName()),
|
||||||
(int)ExportSource::CurrentDirectory);
|
(int)ExportSource::CurrentFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_notebook) {
|
if (m_notebook) {
|
||||||
@ -265,7 +359,7 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
|||||||
m_formatCB->addItem(tr("Markdown"), (int)ExportFormat::Markdown);
|
m_formatCB->addItem(tr("Markdown"), (int)ExportFormat::Markdown);
|
||||||
m_formatCB->addItem(tr("HTML"), (int)ExportFormat::HTML);
|
m_formatCB->addItem(tr("HTML"), (int)ExportFormat::HTML);
|
||||||
m_formatCB->addItem(tr("PDF"), (int)ExportFormat::PDF);
|
m_formatCB->addItem(tr("PDF"), (int)ExportFormat::PDF);
|
||||||
m_formatCB->setCurrentIndex(m_formatCB->findData((int)s_lastExportFormat));
|
m_formatCB->setCurrentIndex(m_formatCB->findData((int)s_opt.m_format));
|
||||||
|
|
||||||
// Markdown renderer.
|
// Markdown renderer.
|
||||||
m_rendererCB->addItem(tr("Hoedown"), MarkdownConverterType::Hoedown);
|
m_rendererCB->addItem(tr("Hoedown"), MarkdownConverterType::Hoedown);
|
||||||
@ -281,8 +375,11 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
|||||||
m_renderBgCB->addItem(bgColors[i].m_name, bgColors[i].m_name);
|
m_renderBgCB->addItem(bgColors[i].m_name, bgColors[i].m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_renderBgCB->setCurrentIndex(
|
if (s_opt.m_renderBg.isEmpty()) {
|
||||||
m_renderBgCB->findData(g_config->getCurRenderBackgroundColor()));
|
s_opt.m_renderBg = g_config->getCurRenderBackgroundColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_renderBgCB->setCurrentIndex(m_renderBgCB->findData(s_opt.m_renderBg));
|
||||||
|
|
||||||
// Markdown rendering style.
|
// Markdown rendering style.
|
||||||
QList<QString> styles = g_config->getCssStyles();
|
QList<QString> styles = g_config->getCssStyles();
|
||||||
@ -301,6 +398,56 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
|||||||
|
|
||||||
m_renderCodeBlockStyleCB->setCurrentIndex(
|
m_renderCodeBlockStyleCB->setCurrentIndex(
|
||||||
m_renderCodeBlockStyleCB->findData(g_config->getCodeBlockCssStyle()));
|
m_renderCodeBlockStyleCB->findData(g_config->getCodeBlockCssStyle()));
|
||||||
|
|
||||||
|
m_embedStyleCB->setChecked(s_opt.m_htmlOpt.m_embedCssStyle);
|
||||||
|
|
||||||
|
m_completeHTMLCB->setChecked(s_opt.m_htmlOpt.m_completeHTML);
|
||||||
|
|
||||||
|
m_mimeHTMLCB->setChecked(s_opt.m_htmlOpt.m_mimeHTML);
|
||||||
|
|
||||||
|
m_wkhtmltopdfCB->setChecked(s_opt.m_pdfOpt.m_wkhtmltopdf);
|
||||||
|
|
||||||
|
// wkhtmltopdf path.
|
||||||
|
m_wkPathEdit->setText(g_config->getWkhtmltopdfPath());
|
||||||
|
|
||||||
|
m_wkBackgroundCB->setChecked(s_opt.m_pdfOpt.m_wkEnableBackground);
|
||||||
|
|
||||||
|
m_wkTableOfContentsCB->setChecked(s_opt.m_pdfOpt.m_wkEnableTableOfContents);
|
||||||
|
|
||||||
|
// wkhtmltopdf page number.
|
||||||
|
m_wkPageNumberCB->addItem(tr("None"), (int)ExportPageNumber::None);
|
||||||
|
m_wkPageNumberCB->addItem(tr("Left"), (int)ExportPageNumber::Left);
|
||||||
|
m_wkPageNumberCB->addItem(tr("Center"), (int)ExportPageNumber::Center);
|
||||||
|
m_wkPageNumberCB->addItem(tr("Right"), (int)ExportPageNumber::Right);
|
||||||
|
m_wkPageNumberCB->setCurrentIndex(m_wkPageNumberCB->findData((int)s_opt.m_pdfOpt.m_wkPageNumber));
|
||||||
|
|
||||||
|
m_wkExtraArgsEdit->setText(g_config->getWkhtmltopdfArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VExportDialog::checkWkhtmltopdfExecutable(const QString &p_file)
|
||||||
|
{
|
||||||
|
QStringList args;
|
||||||
|
args << "--version";
|
||||||
|
int ret = QProcess::execute(p_file, args);
|
||||||
|
switch (ret) {
|
||||||
|
case -2:
|
||||||
|
appendLogLine(tr("Fail to start wkhtmltopdf."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
appendLogLine(tr("wkhtmltopdf crashed."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
appendLogLine(tr("Use %1.").arg(p_file));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
appendLogLine(tr("wkhtmltopdf returned %1.").arg(ret));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VExportDialog::startExport()
|
void VExportDialog::startExport()
|
||||||
@ -315,45 +462,62 @@ void VExportDialog::startExport()
|
|||||||
|
|
||||||
QString outputFolder = QDir::cleanPath(QDir(getOutputDirectory()).absolutePath());
|
QString outputFolder = QDir::cleanPath(QDir(getOutputDirectory()).absolutePath());
|
||||||
|
|
||||||
ExportOption opt((ExportSource)m_srcCB->currentData().toInt(),
|
s_opt = ExportOption((ExportSource)m_srcCB->currentData().toInt(),
|
||||||
(ExportFormat)m_formatCB->currentData().toInt(),
|
(ExportFormat)m_formatCB->currentData().toInt(),
|
||||||
(MarkdownConverterType)m_rendererCB->currentData().toInt(),
|
(MarkdownConverterType)m_rendererCB->currentData().toInt(),
|
||||||
m_renderBgCB->currentData().toString(),
|
m_renderBgCB->currentData().toString(),
|
||||||
m_renderStyleCB->currentData().toString(),
|
m_renderStyleCB->currentData().toString(),
|
||||||
m_renderCodeBlockStyleCB->currentData().toString(),
|
m_renderCodeBlockStyleCB->currentData().toString(),
|
||||||
&m_pageLayout,
|
m_subfolderCB->isChecked(),
|
||||||
ExportHTMLOption(m_embedStyleCB->isChecked(),
|
ExportPDFOption(&m_pageLayout,
|
||||||
m_completeHTMLCB->isChecked(),
|
m_wkhtmltopdfCB->isChecked(),
|
||||||
m_mimeHTMLCB->isChecked()));
|
QDir::toNativeSeparators(m_wkPathEdit->text()),
|
||||||
|
m_wkBackgroundCB->isChecked(),
|
||||||
s_lastExportFormat = opt.m_format;
|
m_wkTableOfContentsCB->isChecked(),
|
||||||
|
(ExportPageNumber)m_wkPageNumberCB->currentData().toInt(),
|
||||||
|
m_wkExtraArgsEdit->text()),
|
||||||
|
ExportHTMLOption(m_embedStyleCB->isChecked(),
|
||||||
|
m_completeHTMLCB->isChecked(),
|
||||||
|
m_mimeHTMLCB->isChecked()));
|
||||||
|
|
||||||
m_consoleEdit->clear();
|
m_consoleEdit->clear();
|
||||||
appendLogLine(tr("Export to %1.").arg(outputFolder));
|
appendLogLine(tr("Export to %1.").arg(outputFolder));
|
||||||
|
|
||||||
if (opt.m_format == ExportFormat::PDF
|
if (s_opt.m_format == ExportFormat::PDF
|
||||||
|| opt.m_format == ExportFormat::HTML) {
|
|| s_opt.m_format == ExportFormat::HTML) {
|
||||||
m_exporter->prepareExport(opt);
|
m_exporter->prepareExport(s_opt);
|
||||||
|
|
||||||
|
if (s_opt.m_format == ExportFormat::PDF
|
||||||
|
&& s_opt.m_pdfOpt.m_wkhtmltopdf) {
|
||||||
|
g_config->setWkhtmltopdfPath(s_opt.m_pdfOpt.m_wkPath);
|
||||||
|
g_config->setWkhtmltopdfArgs(s_opt.m_pdfOpt.m_wkExtraArgs);
|
||||||
|
|
||||||
|
if (!checkWkhtmltopdfExecutable(s_opt.m_pdfOpt.m_wkPath)) {
|
||||||
|
m_inExport = false;
|
||||||
|
m_exportBtn->setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
QString msg;
|
QString msg;
|
||||||
|
|
||||||
switch ((int)opt.m_source) {
|
switch (s_opt.m_source) {
|
||||||
case (int)ExportSource::CurrentNote:
|
case ExportSource::CurrentNote:
|
||||||
ret = doExport(m_file, opt, outputFolder, &msg);
|
ret = doExport(m_file, s_opt, outputFolder, &msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ExportSource::CurrentDirectory:
|
case ExportSource::CurrentFolder:
|
||||||
ret = doExport(m_directory, opt, outputFolder, &msg);
|
ret = doExport(m_directory, s_opt, outputFolder, &msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ExportSource::CurrentNotebook:
|
case ExportSource::CurrentNotebook:
|
||||||
ret = doExport(m_notebook, opt, outputFolder, &msg);
|
ret = doExport(m_notebook, s_opt, outputFolder, &msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ExportSource::Cart:
|
case ExportSource::Cart:
|
||||||
ret = doExport(m_cart, opt, outputFolder, &msg);
|
ret = doExport(m_cart, s_opt, outputFolder, &msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -386,7 +550,7 @@ QString VExportDialog::getOutputDirectory() const
|
|||||||
return m_outputEdit->text();
|
return m_outputEdit->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VExportDialog::handleBrowseBtnClicked()
|
void VExportDialog::handleOutputBrowseBtnClicked()
|
||||||
{
|
{
|
||||||
QString initPath = getOutputDirectory();
|
QString initPath = getOutputDirectory();
|
||||||
if (!QFileInfo::exists(initPath)) {
|
if (!QFileInfo::exists(initPath)) {
|
||||||
@ -405,6 +569,29 @@ void VExportDialog::handleBrowseBtnClicked()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VExportDialog::handleWkPathBrowseBtnClicked()
|
||||||
|
{
|
||||||
|
QString initPath = m_wkPathEdit->text();
|
||||||
|
if (!QFileInfo::exists(initPath)) {
|
||||||
|
initPath = QCoreApplication::applicationDirPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
QString filter = tr("Executable (*.exe)");
|
||||||
|
#else
|
||||||
|
QString filter;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QString filePath = QFileDialog::getOpenFileName(this,
|
||||||
|
tr("Select wkhtmltopdf Executable"),
|
||||||
|
initPath,
|
||||||
|
filter);
|
||||||
|
|
||||||
|
if (!filePath.isEmpty()) {
|
||||||
|
m_wkPathEdit->setText(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VExportDialog::handleInputChanged()
|
void VExportDialog::handleInputChanged()
|
||||||
{
|
{
|
||||||
// Source.
|
// Source.
|
||||||
@ -492,13 +679,15 @@ int VExportDialog::doExport(VDirectory *p_directory,
|
|||||||
ret += doExport(file, p_opt, outputPath, p_errMsg);
|
ret += doExport(file, p_opt, outputPath, p_errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export subfolder.
|
// Export subfolders.
|
||||||
for (auto const & dir : p_directory->getSubDirs()) {
|
if (p_opt.m_processSubfolders) {
|
||||||
if (!checkUserAction()) {
|
for (auto const & dir : p_directory->getSubDirs()) {
|
||||||
goto exit;
|
if (!checkUserAction()) {
|
||||||
}
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
ret += doExport(dir, p_opt, outputPath, p_errMsg);
|
ret += doExport(dir, p_opt, outputPath, p_errMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@ -731,8 +920,9 @@ void VExportDialog::handleLayoutBtnClicked()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pageLayout.setUnits(QPageLayout::Millimeter);
|
||||||
m_pageLayout.setPageSize(printer.pageLayout().pageSize());
|
m_pageLayout.setPageSize(printer.pageLayout().pageSize());
|
||||||
m_pageLayout.setMargins(printer.pageLayout().margins());
|
m_pageLayout.setMargins(printer.pageLayout().margins(QPageLayout::Millimeter));
|
||||||
m_pageLayout.setOrientation(printer.pageLayout().orientation());
|
m_pageLayout.setOrientation(printer.pageLayout().orientation());
|
||||||
|
|
||||||
updatePageLayoutLabel();
|
updatePageLayoutLabel();
|
||||||
@ -741,8 +931,6 @@ void VExportDialog::handleLayoutBtnClicked()
|
|||||||
|
|
||||||
void VExportDialog::updatePageLayoutLabel()
|
void VExportDialog::updatePageLayoutLabel()
|
||||||
{
|
{
|
||||||
qDebug() << "page layout margins:" << m_pageLayout.margins();
|
|
||||||
|
|
||||||
m_layoutLabel->setText(QString("%1, %2").arg(m_pageLayout.pageSize().name())
|
m_layoutLabel->setText(QString("%1, %2").arg(m_pageLayout.pageSize().name())
|
||||||
.arg(m_pageLayout.orientation() == QPageLayout::Portrait ?
|
.arg(m_pageLayout.orientation() == QPageLayout::Portrait ?
|
||||||
tr("Portrait") : tr("Landscape")));
|
tr("Portrait") : tr("Landscape")));
|
||||||
@ -771,3 +959,21 @@ void VExportDialog::handleCurrentFormatChanged(int p_index)
|
|||||||
m_pdfSettings->setVisible(pdfEnabled);
|
m_pdfSettings->setVisible(pdfEnabled);
|
||||||
m_htmlSettings->setVisible(htmlEnabled);
|
m_htmlSettings->setVisible(htmlEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VExportDialog::handleCurrentSrcChanged(int p_index)
|
||||||
|
{
|
||||||
|
bool subfolderEnabled = false;
|
||||||
|
|
||||||
|
if (p_index >= 0) {
|
||||||
|
switch (m_srcCB->currentData().toInt()) {
|
||||||
|
case (int)ExportSource::CurrentFolder:
|
||||||
|
subfolderEnabled = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_subfolderCB->setVisible(subfolderEnabled);
|
||||||
|
}
|
||||||
|
@ -19,12 +19,13 @@ class VFile;
|
|||||||
class VCart;
|
class VCart;
|
||||||
class VExporter;
|
class VExporter;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
|
class VLineEdit;
|
||||||
|
|
||||||
|
|
||||||
enum class ExportSource
|
enum class ExportSource
|
||||||
{
|
{
|
||||||
CurrentNote = 0,
|
CurrentNote = 0,
|
||||||
CurrentDirectory,
|
CurrentFolder,
|
||||||
CurrentNotebook,
|
CurrentNotebook,
|
||||||
Cart
|
Cart
|
||||||
};
|
};
|
||||||
@ -38,8 +39,24 @@ enum class ExportFormat
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum class ExportPageNumber
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Left,
|
||||||
|
Center,
|
||||||
|
Right
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ExportHTMLOption
|
struct ExportHTMLOption
|
||||||
{
|
{
|
||||||
|
ExportHTMLOption()
|
||||||
|
: m_embedCssStyle(true),
|
||||||
|
m_completeHTML(true),
|
||||||
|
m_mimeHTML(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ExportHTMLOption(bool p_embedCssStyle,
|
ExportHTMLOption(bool p_embedCssStyle,
|
||||||
bool p_completeHTML,
|
bool p_completeHTML,
|
||||||
bool p_mimeHTML)
|
bool p_mimeHTML)
|
||||||
@ -55,15 +72,62 @@ struct ExportHTMLOption
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ExportPDFOption
|
||||||
|
{
|
||||||
|
ExportPDFOption()
|
||||||
|
: m_layout(NULL),
|
||||||
|
m_wkhtmltopdf(false),
|
||||||
|
m_wkEnableBackground(true),
|
||||||
|
m_wkEnableTableOfContents(false),
|
||||||
|
m_wkPageNumber(ExportPageNumber::None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ExportPDFOption(QPageLayout *p_layout,
|
||||||
|
bool p_wkhtmltopdf,
|
||||||
|
const QString &p_wkPath,
|
||||||
|
bool p_wkEnableBackground,
|
||||||
|
bool p_wkEnableTableOfContents,
|
||||||
|
ExportPageNumber p_wkPageNumber,
|
||||||
|
const QString &p_wkExtraArgs)
|
||||||
|
: m_layout(p_layout),
|
||||||
|
m_wkhtmltopdf(p_wkhtmltopdf),
|
||||||
|
m_wkPath(p_wkPath),
|
||||||
|
m_wkEnableBackground(p_wkEnableBackground),
|
||||||
|
m_wkEnableTableOfContents(p_wkEnableTableOfContents),
|
||||||
|
m_wkPageNumber(p_wkPageNumber),
|
||||||
|
m_wkExtraArgs(p_wkExtraArgs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QPageLayout *m_layout;
|
||||||
|
bool m_wkhtmltopdf;
|
||||||
|
QString m_wkPath;
|
||||||
|
bool m_wkEnableBackground;
|
||||||
|
bool m_wkEnableTableOfContents;
|
||||||
|
ExportPageNumber m_wkPageNumber;
|
||||||
|
QString m_wkExtraArgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ExportOption
|
struct ExportOption
|
||||||
{
|
{
|
||||||
|
ExportOption()
|
||||||
|
: m_source(ExportSource::CurrentNote),
|
||||||
|
m_format(ExportFormat::Markdown),
|
||||||
|
m_renderer(MarkdownConverterType::MarkdownIt),
|
||||||
|
m_processSubfolders(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ExportOption(ExportSource p_source,
|
ExportOption(ExportSource p_source,
|
||||||
ExportFormat p_format,
|
ExportFormat p_format,
|
||||||
MarkdownConverterType p_renderer,
|
MarkdownConverterType p_renderer,
|
||||||
const QString &p_renderBg,
|
const QString &p_renderBg,
|
||||||
const QString &p_renderStyle,
|
const QString &p_renderStyle,
|
||||||
const QString &p_renderCodeBlockStyle,
|
const QString &p_renderCodeBlockStyle,
|
||||||
QPageLayout *p_layout,
|
bool p_processSubfolders,
|
||||||
|
const ExportPDFOption &p_pdfOpt,
|
||||||
const ExportHTMLOption &p_htmlOpt)
|
const ExportHTMLOption &p_htmlOpt)
|
||||||
: m_source(p_source),
|
: m_source(p_source),
|
||||||
m_format(p_format),
|
m_format(p_format),
|
||||||
@ -71,7 +135,8 @@ struct ExportOption
|
|||||||
m_renderBg(p_renderBg),
|
m_renderBg(p_renderBg),
|
||||||
m_renderStyle(p_renderStyle),
|
m_renderStyle(p_renderStyle),
|
||||||
m_renderCodeBlockStyle(p_renderCodeBlockStyle),
|
m_renderCodeBlockStyle(p_renderCodeBlockStyle),
|
||||||
m_layout(p_layout),
|
m_processSubfolders(p_processSubfolders),
|
||||||
|
m_pdfOpt(p_pdfOpt),
|
||||||
m_htmlOpt(p_htmlOpt)
|
m_htmlOpt(p_htmlOpt)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -85,7 +150,11 @@ struct ExportOption
|
|||||||
|
|
||||||
QString m_renderStyle;
|
QString m_renderStyle;
|
||||||
QString m_renderCodeBlockStyle;
|
QString m_renderCodeBlockStyle;
|
||||||
QPageLayout *m_layout;
|
|
||||||
|
// Whether process subfolders recursively when source is CurrentFolder.
|
||||||
|
bool m_processSubfolders;
|
||||||
|
|
||||||
|
ExportPDFOption m_pdfOpt;
|
||||||
|
|
||||||
ExportHTMLOption m_htmlOpt;
|
ExportHTMLOption m_htmlOpt;
|
||||||
};
|
};
|
||||||
@ -105,7 +174,9 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void startExport();
|
void startExport();
|
||||||
|
|
||||||
void handleBrowseBtnClicked();
|
void handleOutputBrowseBtnClicked();
|
||||||
|
|
||||||
|
void handleWkPathBrowseBtnClicked();
|
||||||
|
|
||||||
void handleInputChanged();
|
void handleInputChanged();
|
||||||
|
|
||||||
@ -113,6 +184,8 @@ private slots:
|
|||||||
|
|
||||||
void handleCurrentFormatChanged(int p_index);
|
void handleCurrentFormatChanged(int p_index);
|
||||||
|
|
||||||
|
void handleCurrentSrcChanged(int p_index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupUI();
|
void setupUI();
|
||||||
|
|
||||||
@ -120,6 +193,8 @@ private:
|
|||||||
|
|
||||||
QWidget *setupHTMLAdvancedSettings();
|
QWidget *setupHTMLAdvancedSettings();
|
||||||
|
|
||||||
|
QWidget *setupGeneralAdvancedSettings();
|
||||||
|
|
||||||
void initUIFields(MarkdownConverterType p_renderer);
|
void initUIFields(MarkdownConverterType p_renderer);
|
||||||
|
|
||||||
QString getOutputDirectory() const;
|
QString getOutputDirectory() const;
|
||||||
@ -167,6 +242,8 @@ private:
|
|||||||
|
|
||||||
void updatePageLayoutLabel();
|
void updatePageLayoutLabel();
|
||||||
|
|
||||||
|
bool checkWkhtmltopdfExecutable(const QString &p_file);
|
||||||
|
|
||||||
QComboBox *m_srcCB;
|
QComboBox *m_srcCB;
|
||||||
|
|
||||||
QComboBox *m_formatCB;
|
QComboBox *m_formatCB;
|
||||||
@ -181,8 +258,6 @@ private:
|
|||||||
|
|
||||||
VLineEdit *m_outputEdit;
|
VLineEdit *m_outputEdit;
|
||||||
|
|
||||||
QPushButton *m_browseBtn;
|
|
||||||
|
|
||||||
QGroupBox *m_basicBox;
|
QGroupBox *m_basicBox;
|
||||||
|
|
||||||
QGroupBox *m_settingBox;
|
QGroupBox *m_settingBox;
|
||||||
@ -191,6 +266,8 @@ private:
|
|||||||
|
|
||||||
QWidget *m_htmlSettings;
|
QWidget *m_htmlSettings;
|
||||||
|
|
||||||
|
QWidget *m_generalSettings;
|
||||||
|
|
||||||
QPlainTextEdit *m_consoleEdit;
|
QPlainTextEdit *m_consoleEdit;
|
||||||
|
|
||||||
QDialogButtonBox *m_btnBox;
|
QDialogButtonBox *m_btnBox;
|
||||||
@ -201,12 +278,28 @@ private:
|
|||||||
|
|
||||||
QLabel *m_layoutLabel;
|
QLabel *m_layoutLabel;
|
||||||
|
|
||||||
|
QCheckBox *m_wkhtmltopdfCB;
|
||||||
|
|
||||||
|
VLineEdit *m_wkPathEdit;
|
||||||
|
|
||||||
|
QPushButton *m_wkPathBrowseBtn;
|
||||||
|
|
||||||
|
QCheckBox *m_wkBackgroundCB;
|
||||||
|
|
||||||
|
QCheckBox *m_wkTableOfContentsCB;
|
||||||
|
|
||||||
|
QComboBox *m_wkPageNumberCB;
|
||||||
|
|
||||||
|
VLineEdit *m_wkExtraArgsEdit;
|
||||||
|
|
||||||
QCheckBox *m_embedStyleCB;
|
QCheckBox *m_embedStyleCB;
|
||||||
|
|
||||||
QCheckBox *m_completeHTMLCB;;
|
QCheckBox *m_completeHTMLCB;;
|
||||||
|
|
||||||
QCheckBox *m_mimeHTMLCB;
|
QCheckBox *m_mimeHTMLCB;
|
||||||
|
|
||||||
|
QCheckBox *m_subfolderCB;
|
||||||
|
|
||||||
VNotebook *m_notebook;
|
VNotebook *m_notebook;
|
||||||
|
|
||||||
VDirectory *m_directory;
|
VDirectory *m_directory;
|
||||||
@ -229,8 +322,7 @@ private:
|
|||||||
// Last output folder path.
|
// Last output folder path.
|
||||||
static QString s_lastOutputFolder;
|
static QString s_lastOutputFolder;
|
||||||
|
|
||||||
// Last export format.
|
static ExportOption s_opt;
|
||||||
static ExportFormat s_lastExportFormat;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VEXPORTDIALOG_H
|
#endif // VEXPORTDIALOG_H
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<head>
|
<head>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<head>
|
<head>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
|
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<polygon fill="#4D5765" points="128,192 256,320 384,192 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 548 B |
@ -226,6 +226,7 @@ button_icon_danger_fg=@danger_icon_fg
|
|||||||
combobox_border=@border_bg
|
combobox_border=@border_bg
|
||||||
combobox_fg=@content_fg
|
combobox_fg=@content_fg
|
||||||
combobox_bg=@content_bg
|
combobox_bg=@content_bg
|
||||||
|
combobox_disabled_fg=@disabled_fg
|
||||||
combobox_view_border=@border_bg
|
combobox_view_border=@border_bg
|
||||||
combobox_view_selected_bg=@selected_bg
|
combobox_view_selected_bg=@selected_bg
|
||||||
combobox_view_selected_fg=@selected_fg
|
combobox_view_selected_fg=@selected_fg
|
||||||
@ -252,6 +253,7 @@ label_titlelabel_bg=@title_bg
|
|||||||
lineedit_border=@border_bg
|
lineedit_border=@border_bg
|
||||||
lineedit_fg=@edit_fg
|
lineedit_fg=@edit_fg
|
||||||
lineedit_bg=@edit_bg
|
lineedit_bg=@edit_bg
|
||||||
|
lineedit_disabled_fg=@disabled_fg
|
||||||
lineedit_focus_bg=@edit_focus_bg
|
lineedit_focus_bg=@edit_focus_bg
|
||||||
lineedit_focus_border=@edit_focus_border
|
lineedit_focus_border=@edit_focus_border
|
||||||
lineedit_selection_fg=@edit_selection_fg
|
lineedit_selection_fg=@edit_selection_fg
|
||||||
|
@ -521,6 +521,10 @@ QComboBox {
|
|||||||
border: 1px solid @combobox_border;
|
border: 1px solid @combobox_border;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QComboBox:disabled {
|
||||||
|
color: @combobox_disabled_fg;
|
||||||
|
}
|
||||||
|
|
||||||
QComboBox:focus, QComboBox:on {
|
QComboBox:focus, QComboBox:on {
|
||||||
background-color: @combobox_focus_bg;
|
background-color: @combobox_focus_bg;
|
||||||
border: 2px solid @combobox_focus_border;
|
border: 2px solid @combobox_focus_border;
|
||||||
@ -540,6 +544,12 @@ QComboBox::down-arrow {
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QComboBox::down-arrow:disabled {
|
||||||
|
image: url(arrow_dropdown_disabled.svg);
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
QComboBox QAbstractItemView {
|
QComboBox QAbstractItemView {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
border: 1px solid @combobox_view_border;
|
border: 1px solid @combobox_view_border;
|
||||||
@ -697,6 +707,10 @@ QLineEdit:focus {
|
|||||||
background: @lineedit_focus_bg;
|
background: @lineedit_focus_bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QLineEdit:disabled {
|
||||||
|
color: @lineedit_disabled_fg;
|
||||||
|
}
|
||||||
|
|
||||||
QLineEdit[VimCommandLine="true"] {
|
QLineEdit[VimCommandLine="true"] {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
9
src/resources/themes/v_pure/arrow_dropdown_disabled.svg
Normal file
9
src/resources/themes/v_pure/arrow_dropdown_disabled.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<polygon fill="#C0C0C0" points="128,192 256,320 384,192 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 548 B |
@ -220,6 +220,7 @@ buttonmenuitem_decoration_text_fg=@master_dark_bg
|
|||||||
combobox_border=@border_bg
|
combobox_border=@border_bg
|
||||||
combobox_fg=@content_fg
|
combobox_fg=@content_fg
|
||||||
combobox_bg=@content_bg
|
combobox_bg=@content_bg
|
||||||
|
combobox_disabled_fg=@disabled_fg
|
||||||
combobox_view_border=@border_bg
|
combobox_view_border=@border_bg
|
||||||
combobox_view_selected_bg=@selected_bg
|
combobox_view_selected_bg=@selected_bg
|
||||||
combobox_view_selected_fg=@selected_fg
|
combobox_view_selected_fg=@selected_fg
|
||||||
@ -246,6 +247,7 @@ label_titlelabel_bg=@title_bg
|
|||||||
lineedit_border=@border_bg
|
lineedit_border=@border_bg
|
||||||
lineedit_fg=@edit_fg
|
lineedit_fg=@edit_fg
|
||||||
lineedit_bg=@edit_bg
|
lineedit_bg=@edit_bg
|
||||||
|
lineedit_disabled_fg=@disabled_fg
|
||||||
lineedit_focus_bg=@edit_focus_bg
|
lineedit_focus_bg=@edit_focus_bg
|
||||||
lineedit_focus_border=@edit_focus_border
|
lineedit_focus_border=@edit_focus_border
|
||||||
lineedit_selection_fg=@edit_selection_fg
|
lineedit_selection_fg=@edit_selection_fg
|
||||||
|
@ -521,6 +521,10 @@ QComboBox {
|
|||||||
border: 1px solid @combobox_border;
|
border: 1px solid @combobox_border;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QComboBox:disabled {
|
||||||
|
color: @combobox_disabled_fg;
|
||||||
|
}
|
||||||
|
|
||||||
QComboBox:focus, QComboBox:on {
|
QComboBox:focus, QComboBox:on {
|
||||||
background-color: @combobox_focus_bg;
|
background-color: @combobox_focus_bg;
|
||||||
border: 2px solid @combobox_focus_border;
|
border: 2px solid @combobox_focus_border;
|
||||||
@ -540,6 +544,12 @@ QComboBox::down-arrow {
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QComboBox::down-arrow:disabled {
|
||||||
|
image: url(arrow_dropdown_disabled.svg);
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
QComboBox QAbstractItemView {
|
QComboBox QAbstractItemView {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
border: 1px solid @combobox_view_border;
|
border: 1px solid @combobox_view_border;
|
||||||
@ -697,6 +707,10 @@ QLineEdit:focus {
|
|||||||
background: @lineedit_focus_bg;
|
background: @lineedit_focus_bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QLineEdit:disabled {
|
||||||
|
color: @lineedit_disabled_fg;
|
||||||
|
}
|
||||||
|
|
||||||
QLineEdit[VimCommandLine="true"] {
|
QLineEdit[VimCommandLine="true"] {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||||
<g>
|
<g>
|
||||||
<polygon points="128,192 256,320 384,192 "/>
|
<polygon points="128,192 256,320 384,192 " fill="#333333"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 533 B After Width: | Height: | Size: 548 B |
9
src/resources/themes/v_white/arrow_dropdown_disabled.svg
Normal file
9
src/resources/themes/v_white/arrow_dropdown_disabled.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<polygon points="128,192 256,320 384,192 " fill="#C0C0C0"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 548 B |
@ -193,6 +193,7 @@ buttonmenuitem_decoration_text_fg=#00796B
|
|||||||
combobox_border=@border_bg
|
combobox_border=@border_bg
|
||||||
combobox_fg=@content_fg
|
combobox_fg=@content_fg
|
||||||
combobox_bg=@content_bg
|
combobox_bg=@content_bg
|
||||||
|
combobox_disabled_fg=@disabled_fg
|
||||||
combobox_view_border=@border_bg
|
combobox_view_border=@border_bg
|
||||||
combobox_view_selected_bg=@selected_bg
|
combobox_view_selected_bg=@selected_bg
|
||||||
combobox_view_selected_fg=@selected_fg
|
combobox_view_selected_fg=@selected_fg
|
||||||
@ -210,6 +211,7 @@ label_titlelabel_bg=@title_bg
|
|||||||
lineedit_border=@border_bg
|
lineedit_border=@border_bg
|
||||||
lineedit_fg=@content_fg
|
lineedit_fg=@content_fg
|
||||||
lineedit_bg=@content_bg
|
lineedit_bg=@content_bg
|
||||||
|
lineedit_disabled_fg=@disabled_fg
|
||||||
lineedit_selection_fg=@selection_fg
|
lineedit_selection_fg=@selection_fg
|
||||||
lineedit_selection_bg=@selection_bg
|
lineedit_selection_bg=@selection_bg
|
||||||
|
|
||||||
|
@ -453,6 +453,10 @@ QComboBox {
|
|||||||
border: 1px solid @combobox_border;
|
border: 1px solid @combobox_border;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QComboBox:disabled {
|
||||||
|
color: @combobox_disabled_fg;
|
||||||
|
}
|
||||||
|
|
||||||
QComboBox:focus {
|
QComboBox:focus {
|
||||||
background-color: @combobox_focus_bg;
|
background-color: @combobox_focus_bg;
|
||||||
}
|
}
|
||||||
@ -471,6 +475,12 @@ QComboBox::down-arrow {
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QComboBox::down-arrow:disabled {
|
||||||
|
image: url(arrow_dropdown_disabled.svg);
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
QComboBox QAbstractItemView {
|
QComboBox QAbstractItemView {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
border: 1px solid @combobox_view_border;
|
border: 1px solid @combobox_view_border;
|
||||||
@ -602,6 +612,10 @@ QLineEdit {
|
|||||||
selection-background-color: @lineedit_selection_bg;
|
selection-background-color: @lineedit_selection_bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QLineEdit:disabled {
|
||||||
|
color: @lineedit_disabled_fg;
|
||||||
|
}
|
||||||
|
|
||||||
QLineEdit[VimCommandLine="true"] {
|
QLineEdit[VimCommandLine="true"] {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
@ -201,6 +201,14 @@ single_click_close_previous_tab=true
|
|||||||
; Whether enable auto wildcard match in simple search like list and tree widgets
|
; Whether enable auto wildcard match in simple search like list and tree widgets
|
||||||
enable_wildcard_in_simple_search=true
|
enable_wildcard_in_simple_search=true
|
||||||
|
|
||||||
|
[export]
|
||||||
|
; Path of the wkhtmltopdf tool
|
||||||
|
wkhtmltopdf=wkhtmltopdf
|
||||||
|
|
||||||
|
; Additional arguments to wkhtmltopdf
|
||||||
|
; Double quotes to enclose arguments with spaces
|
||||||
|
wkhtmltopdfArgs=
|
||||||
|
|
||||||
[web]
|
[web]
|
||||||
; Location and configuration for Mathjax
|
; Location and configuration for Mathjax
|
||||||
mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_HTMLorMML
|
mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_HTMLorMML
|
||||||
|
@ -454,6 +454,12 @@ public:
|
|||||||
bool getEnableAutoSave() const;
|
bool getEnableAutoSave() const;
|
||||||
void setEnableAutoSave(bool p_enabled);
|
void setEnableAutoSave(bool p_enabled);
|
||||||
|
|
||||||
|
QString getWkhtmltopdfPath() const;
|
||||||
|
void setWkhtmltopdfPath(const QString &p_path);
|
||||||
|
|
||||||
|
QString getWkhtmltopdfArgs() const;
|
||||||
|
void setWkhtmltopdfArgs(const QString &p_args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Look up a config from user and default settings.
|
// Look up a config from user and default settings.
|
||||||
QVariant getConfigFromSettings(const QString §ion, const QString &key) const;
|
QVariant getConfigFromSettings(const QString §ion, const QString &key) const;
|
||||||
@ -2083,4 +2089,26 @@ inline void VConfigManager::setEnableAutoSave(bool p_enabled)
|
|||||||
{
|
{
|
||||||
setConfigToSettings("global", "enable_auto_save", p_enabled);
|
setConfigToSettings("global", "enable_auto_save", p_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QString VConfigManager::getWkhtmltopdfPath() const
|
||||||
|
{
|
||||||
|
return getConfigFromSettings("export",
|
||||||
|
"wkhtmltopdf").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setWkhtmltopdfPath(const QString &p_file)
|
||||||
|
{
|
||||||
|
setConfigToSettings("export", "wkhtmltopdf", p_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QString VConfigManager::getWkhtmltopdfArgs() const
|
||||||
|
{
|
||||||
|
return getConfigFromSettings("export",
|
||||||
|
"wkhtmltopdfArgs").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setWkhtmltopdfArgs(const QString &p_file)
|
||||||
|
{
|
||||||
|
setConfigToSettings("export", "wkhtmltopdfArgs", p_file);
|
||||||
|
}
|
||||||
#endif // VCONFIGMANAGER_H
|
#endif // VCONFIGMANAGER_H
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QWebChannel>
|
#include <QWebChannel>
|
||||||
#include <QWebEngineProfile>
|
#include <QWebEngineProfile>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
@ -27,6 +28,11 @@ VExporter::VExporter(QWidget *p_parent)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString marginToStrMM(qreal p_margin)
|
||||||
|
{
|
||||||
|
return QString("%1mm").arg(p_margin);
|
||||||
|
}
|
||||||
|
|
||||||
void VExporter::prepareExport(const ExportOption &p_opt)
|
void VExporter::prepareExport(const ExportOption &p_opt)
|
||||||
{
|
{
|
||||||
m_htmlTemplate = VUtils::generateHtmlTemplate(p_opt.m_renderer,
|
m_htmlTemplate = VUtils::generateHtmlTemplate(p_opt.m_renderer,
|
||||||
@ -37,7 +43,100 @@ void VExporter::prepareExport(const ExportOption &p_opt)
|
|||||||
|
|
||||||
m_exportHtmlTemplate = VUtils::generateExportHtmlTemplate(p_opt.m_renderBg);
|
m_exportHtmlTemplate = VUtils::generateExportHtmlTemplate(p_opt.m_renderBg);
|
||||||
|
|
||||||
m_pageLayout = *(p_opt.m_layout);
|
m_pageLayout = *(p_opt.m_pdfOpt.m_layout);
|
||||||
|
|
||||||
|
prepareWKArguments(p_opt.m_pdfOpt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From QProcess code.
|
||||||
|
static QStringList parseCombinedArgString(const QString &program)
|
||||||
|
{
|
||||||
|
QStringList args;
|
||||||
|
QString tmp;
|
||||||
|
int quoteCount = 0;
|
||||||
|
bool inQuote = false;
|
||||||
|
|
||||||
|
// handle quoting. tokens can be surrounded by double quotes
|
||||||
|
// "hello world". three consecutive double quotes represent
|
||||||
|
// the quote character itself.
|
||||||
|
for (int i = 0; i < program.size(); ++i) {
|
||||||
|
if (program.at(i) == QLatin1Char('"')) {
|
||||||
|
++quoteCount;
|
||||||
|
if (quoteCount == 3) {
|
||||||
|
// third consecutive quote
|
||||||
|
quoteCount = 0;
|
||||||
|
tmp += program.at(i);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (quoteCount) {
|
||||||
|
if (quoteCount == 1)
|
||||||
|
inQuote = !inQuote;
|
||||||
|
quoteCount = 0;
|
||||||
|
}
|
||||||
|
if (!inQuote && program.at(i).isSpace()) {
|
||||||
|
if (!tmp.isEmpty()) {
|
||||||
|
args += tmp;
|
||||||
|
tmp.clear();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmp += program.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tmp.isEmpty())
|
||||||
|
args += tmp;
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VExporter::prepareWKArguments(const ExportPDFOption &p_opt)
|
||||||
|
{
|
||||||
|
m_wkArgs.clear();
|
||||||
|
m_wkArgs << "--quiet";
|
||||||
|
m_wkArgs << "--encoding" << "utf-8";
|
||||||
|
m_wkArgs << "--page-size" << m_pageLayout.pageSize().key();
|
||||||
|
m_wkArgs << "--orientation"
|
||||||
|
<< (m_pageLayout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape");
|
||||||
|
|
||||||
|
QMarginsF marginsMM = m_pageLayout.margins(QPageLayout::Millimeter);
|
||||||
|
m_wkArgs << "--margin-bottom" << marginToStrMM(marginsMM.bottom());
|
||||||
|
m_wkArgs << "--margin-left" << marginToStrMM(marginsMM.left());
|
||||||
|
m_wkArgs << "--margin-right" << marginToStrMM(marginsMM.right());
|
||||||
|
m_wkArgs << "--margin-top" << marginToStrMM(marginsMM.top());
|
||||||
|
|
||||||
|
m_wkArgs << (p_opt.m_wkEnableBackground ? "--background" : "--no-background");
|
||||||
|
|
||||||
|
QString footer;
|
||||||
|
switch (p_opt.m_wkPageNumber) {
|
||||||
|
case ExportPageNumber::Left:
|
||||||
|
footer = "--footer-left";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExportPageNumber::Center:
|
||||||
|
footer = "--footer-center";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExportPageNumber::Right:
|
||||||
|
footer = "--footer-right";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!footer.isEmpty()) {
|
||||||
|
m_wkArgs << footer << "[page]"
|
||||||
|
<< "--footer-spacing" << QString::number(marginsMM.bottom() / 3, 'f', 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append additional arguments.
|
||||||
|
if (!p_opt.m_wkExtraArgs.isEmpty()) {
|
||||||
|
m_wkArgs.append(parseCombinedArgString(p_opt.m_wkExtraArgs));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_opt.m_wkEnableTableOfContents) {
|
||||||
|
m_wkArgs << "toc" << "--toc-text-size-shrink" << "1.0";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VExporter::exportPDF(VFile *p_file,
|
bool VExporter::exportPDF(VFile *p_file,
|
||||||
@ -149,6 +248,81 @@ bool VExporter::exportToPDF(VWebView *p_webViewer,
|
|||||||
return pdfPrinted == 1;
|
return pdfPrinted == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VExporter::exportToPDFViaWK(VDocument *p_webDocument,
|
||||||
|
const ExportPDFOption &p_opt,
|
||||||
|
const QString &p_filePath,
|
||||||
|
QString *p_errMsg)
|
||||||
|
{
|
||||||
|
int pdfExported = 0;
|
||||||
|
|
||||||
|
connect(p_webDocument, &VDocument::htmlContentFinished,
|
||||||
|
this, [&, this](const QString &p_headContent,
|
||||||
|
const QString &p_styleContent,
|
||||||
|
const QString &p_bodyContent) {
|
||||||
|
if (p_bodyContent.isEmpty() || this->m_state == ExportState::Cancelled) {
|
||||||
|
pdfExported = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(!p_filePath.isEmpty());
|
||||||
|
QString htmlPath = p_filePath + ".vnote.html";
|
||||||
|
|
||||||
|
QFile file(htmlPath);
|
||||||
|
if (!file.open(QFile::WriteOnly)) {
|
||||||
|
pdfExported = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString resFolder = QFileInfo(htmlPath).completeBaseName() + "_files";
|
||||||
|
QString resFolderPath = QDir(VUtils::basePathFromPath(htmlPath)).filePath(resFolder);
|
||||||
|
|
||||||
|
qDebug() << "temp HTML files folder" << resFolderPath;
|
||||||
|
|
||||||
|
QString html(m_exportHtmlTemplate);
|
||||||
|
if (!p_styleContent.isEmpty()) {
|
||||||
|
QString content(p_styleContent);
|
||||||
|
fixStyleResources(resFolderPath, content);
|
||||||
|
html.replace(HtmlHolder::c_styleHolder, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p_headContent.isEmpty()) {
|
||||||
|
html.replace(HtmlHolder::c_headHolder, p_headContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString content(p_bodyContent);
|
||||||
|
fixBodyResources(m_baseUrl, resFolderPath, content);
|
||||||
|
html.replace(HtmlHolder::c_bodyHolder, content);
|
||||||
|
|
||||||
|
file.write(html.toUtf8());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// Convert vis wkhtmltopdf.
|
||||||
|
if (!htmlToPDFViaWK(htmlPath, p_filePath, p_opt, p_errMsg)) {
|
||||||
|
pdfExported = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up.
|
||||||
|
VUtils::deleteFile(htmlPath);
|
||||||
|
VUtils::deleteDirectory(resFolderPath);
|
||||||
|
|
||||||
|
if (pdfExported == 0) {
|
||||||
|
pdfExported = 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
p_webDocument->getHtmlContentAsync();
|
||||||
|
|
||||||
|
while (pdfExported == 0) {
|
||||||
|
VUtils::sleepWait(100);
|
||||||
|
|
||||||
|
if (m_state == ExportState::Cancelled) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pdfExported == 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool VExporter::exportViaWebView(VFile *p_file,
|
bool VExporter::exportViaWebView(VFile *p_file,
|
||||||
const ExportOption &p_opt,
|
const ExportOption &p_opt,
|
||||||
const QString &p_outputFile,
|
const QString &p_outputFile,
|
||||||
@ -195,9 +369,17 @@ bool VExporter::exportViaWebView(VFile *p_file,
|
|||||||
bool exportRet = false;
|
bool exportRet = false;
|
||||||
switch (p_opt.m_format) {
|
switch (p_opt.m_format) {
|
||||||
case ExportFormat::PDF:
|
case ExportFormat::PDF:
|
||||||
exportRet = exportToPDF(m_webViewer,
|
if (p_opt.m_pdfOpt.m_wkhtmltopdf) {
|
||||||
p_outputFile,
|
exportRet = exportToPDFViaWK(m_webDocument,
|
||||||
m_pageLayout);
|
p_opt.m_pdfOpt,
|
||||||
|
p_outputFile,
|
||||||
|
p_errMsg);
|
||||||
|
} else {
|
||||||
|
exportRet = exportToPDF(m_webViewer,
|
||||||
|
p_outputFile,
|
||||||
|
m_pageLayout);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ExportFormat::HTML:
|
case ExportFormat::HTML:
|
||||||
@ -261,7 +443,6 @@ bool VExporter::exportToHTML(VDocument *p_webDocument,
|
|||||||
Q_ASSERT(!p_filePath.isEmpty());
|
Q_ASSERT(!p_filePath.isEmpty());
|
||||||
|
|
||||||
QFile file(p_filePath);
|
QFile file(p_filePath);
|
||||||
|
|
||||||
if (!file.open(QFile::WriteOnly)) {
|
if (!file.open(QFile::WriteOnly)) {
|
||||||
htmlExported = -1;
|
htmlExported = -1;
|
||||||
return;
|
return;
|
||||||
@ -421,3 +602,55 @@ void VExporter::handleDownloadRequested(QWebEngineDownloadItem *p_item)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString combineArgs(QStringList &p_args)
|
||||||
|
{
|
||||||
|
QString str;
|
||||||
|
for (const QString &arg : p_args) {
|
||||||
|
QString tmp;
|
||||||
|
if (arg.contains(' ')) {
|
||||||
|
tmp = '"' + arg + '"';
|
||||||
|
} else {
|
||||||
|
tmp = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str.isEmpty()) {
|
||||||
|
str = tmp;
|
||||||
|
} else {
|
||||||
|
str = str + ' ' + tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VExporter::htmlToPDFViaWK(const QString &p_htmlFile,
|
||||||
|
const QString &p_filePath,
|
||||||
|
const ExportPDFOption &p_opt,
|
||||||
|
QString *p_errMsg)
|
||||||
|
{
|
||||||
|
// Note: system's locale settings (Language for non-Unicode programs) is important to wkhtmltopdf.
|
||||||
|
// Input file could be encoded via QUrl::fromLocalFile(p_htmlFile).toString(QUrl::EncodeUnicode) to
|
||||||
|
// handle non-ASCII path.
|
||||||
|
QStringList args(m_wkArgs);
|
||||||
|
args << QDir::toNativeSeparators(p_htmlFile);
|
||||||
|
args << QDir::toNativeSeparators(p_filePath);
|
||||||
|
QString cmd = p_opt.m_wkPath + " " + combineArgs(args);
|
||||||
|
emit outputLog(cmd);
|
||||||
|
int ret = QProcess::execute(p_opt.m_wkPath, args);
|
||||||
|
qDebug() << "wkhtmltopdf returned" << ret << cmd;
|
||||||
|
switch (ret) {
|
||||||
|
case -2:
|
||||||
|
VUtils::addErrMsg(p_errMsg, tr("Fail to start wkhtmltopdf (%1).").arg(cmd));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
VUtils::addErrMsg(p_errMsg, tr("wkhtmltopdf crashed (%1).").arg(cmd));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret == 0;
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QPageLayout>
|
#include <QPageLayout>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QWebEngineDownloadItem>
|
#include <QWebEngineDownloadItem>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
#include "dialog/vexportdialog.h"
|
#include "dialog/vexportdialog.h"
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ class VDocument;
|
|||||||
|
|
||||||
class VExporter : public QObject
|
class VExporter : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VExporter(QWidget *p_parent = nullptr);
|
explicit VExporter(QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
@ -29,6 +31,10 @@ public:
|
|||||||
const QString &p_outputFile,
|
const QString &p_outputFile,
|
||||||
QString *p_errMsg = NULL);
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// Request to output log.
|
||||||
|
void outputLog(const QString &p_log);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleLogicsFinished();
|
void handleLogicsFinished();
|
||||||
|
|
||||||
@ -76,6 +82,11 @@ private:
|
|||||||
const QString &p_filePath,
|
const QString &p_filePath,
|
||||||
const QPageLayout &p_layout);
|
const QPageLayout &p_layout);
|
||||||
|
|
||||||
|
bool exportToPDFViaWK(VDocument *p_webDocument,
|
||||||
|
const ExportPDFOption &p_opt,
|
||||||
|
const QString &p_filePath,
|
||||||
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
bool exportToHTML(VDocument *p_webDocument,
|
bool exportToHTML(VDocument *p_webDocument,
|
||||||
const ExportHTMLOption &p_opt,
|
const ExportHTMLOption &p_opt,
|
||||||
const QString &p_filePath);
|
const QString &p_filePath);
|
||||||
@ -84,6 +95,12 @@ private:
|
|||||||
const ExportHTMLOption &p_opt,
|
const ExportHTMLOption &p_opt,
|
||||||
const QString &p_filePath);
|
const QString &p_filePath);
|
||||||
|
|
||||||
|
bool htmlToPDFViaWK(const QString &p_htmlFile,
|
||||||
|
const QString &p_filePath,
|
||||||
|
const ExportPDFOption &p_opt,
|
||||||
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
|
void prepareWKArguments(const ExportPDFOption &p_opt);
|
||||||
|
|
||||||
// Fix @p_html's resources like url("...") with "file" or "qrc" schema.
|
// Fix @p_html's resources like url("...") with "file" or "qrc" schema.
|
||||||
// Copy the resource to @p_folder and fix the url string.
|
// Copy the resource to @p_folder and fix the url string.
|
||||||
@ -119,6 +136,9 @@ private:
|
|||||||
|
|
||||||
// Download state used for MIME HTML.
|
// Download state used for MIME HTML.
|
||||||
QWebEngineDownloadItem::DownloadState m_downloadState;
|
QWebEngineDownloadItem::DownloadState m_downloadState;
|
||||||
|
|
||||||
|
// Arguments for wkhtmltopdf.
|
||||||
|
QStringList m_wkArgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void VExporter::clearNoteState()
|
inline void VExporter::clearNoteState()
|
||||||
|
@ -240,5 +240,8 @@
|
|||||||
<file>resources/themes/v_pure/v_pure_mermaid.css</file>
|
<file>resources/themes/v_pure/v_pure_mermaid.css</file>
|
||||||
<file>resources/themes/v_white/v_white_mermaid.css</file>
|
<file>resources/themes/v_white/v_white_mermaid.css</file>
|
||||||
<file>resources/themes/v_moonlight/v_moonlight_mermaid.css</file>
|
<file>resources/themes/v_moonlight/v_moonlight_mermaid.css</file>
|
||||||
|
<file>resources/themes/v_moonlight/arrow_dropdown_disabled.svg</file>
|
||||||
|
<file>resources/themes/v_pure/arrow_dropdown_disabled.svg</file>
|
||||||
|
<file>resources/themes/v_white/arrow_dropdown_disabled.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user