mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
export: support custom export
This commit is contained in:
parent
9710659a00
commit
d3f9ec48eb
@ -174,11 +174,13 @@ void VExportDialog::setupUI()
|
|||||||
m_generalSettings = setupGeneralAdvancedSettings();
|
m_generalSettings = setupGeneralAdvancedSettings();
|
||||||
m_htmlSettings = setupHTMLAdvancedSettings();
|
m_htmlSettings = setupHTMLAdvancedSettings();
|
||||||
m_pdfSettings = setupPDFAdvancedSettings();
|
m_pdfSettings = setupPDFAdvancedSettings();
|
||||||
|
m_customSettings = setupCustomAdvancedSettings();
|
||||||
|
|
||||||
QVBoxLayout *advLayout = new QVBoxLayout();
|
QVBoxLayout *advLayout = new QVBoxLayout();
|
||||||
advLayout->addWidget(m_generalSettings);
|
advLayout->addWidget(m_generalSettings);
|
||||||
advLayout->addWidget(m_htmlSettings);
|
advLayout->addWidget(m_htmlSettings);
|
||||||
advLayout->addWidget(m_pdfSettings);
|
advLayout->addWidget(m_pdfSettings);
|
||||||
|
advLayout->addWidget(m_customSettings);
|
||||||
|
|
||||||
m_settingBox->setLayout(advLayout);
|
m_settingBox->setLayout(advLayout);
|
||||||
|
|
||||||
@ -235,41 +237,41 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
|
|||||||
// wkhtmltopdf Path.
|
// wkhtmltopdf Path.
|
||||||
m_wkPathEdit = new VLineEdit();
|
m_wkPathEdit = new VLineEdit();
|
||||||
m_wkPathEdit->setToolTip(tr("Tell VNote where to find wkhtmltopdf tool"));
|
m_wkPathEdit->setToolTip(tr("Tell VNote where to find wkhtmltopdf tool"));
|
||||||
m_wkPathEdit->setEnabled(m_wkhtmltopdfCB->isChecked());
|
m_wkPathEdit->setEnabled(false);
|
||||||
|
|
||||||
m_wkPathBrowseBtn = new QPushButton(tr("&Browse"));
|
m_wkPathBrowseBtn = new QPushButton(tr("&Browse"));
|
||||||
m_wkPathBrowseBtn->setEnabled(m_wkhtmltopdfCB->isChecked());
|
|
||||||
connect(m_wkPathBrowseBtn, &QPushButton::clicked,
|
connect(m_wkPathBrowseBtn, &QPushButton::clicked,
|
||||||
this, &VExportDialog::handleWkPathBrowseBtnClicked);
|
this, &VExportDialog::handleWkPathBrowseBtnClicked);
|
||||||
|
m_wkPathBrowseBtn->setEnabled(false);
|
||||||
|
|
||||||
m_wkTitleEdit = new VLineEdit();
|
m_wkTitleEdit = new VLineEdit();
|
||||||
m_wkTitleEdit->setPlaceholderText(tr("Use the name of the first source note"));
|
m_wkTitleEdit->setPlaceholderText(tr("Empty to use the name of the first source file"));
|
||||||
m_wkTitleEdit->setToolTip(tr("Title of the generated PDF file"));
|
m_wkTitleEdit->setToolTip(tr("Title of the generated PDF file"));
|
||||||
m_wkTitleEdit->setEnabled(m_wkhtmltopdfCB->isChecked());
|
m_wkTitleEdit->setEnabled(false);
|
||||||
|
|
||||||
m_wkTargetFileNameEdit = new VLineEdit();
|
m_wkTargetFileNameEdit = new VLineEdit();
|
||||||
m_wkTargetFileNameEdit->setPlaceholderText(tr("Use the name of the first source note"));
|
m_wkTargetFileNameEdit->setPlaceholderText(tr("Empty to use the name of the first source file"));
|
||||||
m_wkTargetFileNameEdit->setToolTip(tr("Name of the generated PDF file"));
|
m_wkTargetFileNameEdit->setToolTip(tr("Name of the generated PDF file"));
|
||||||
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
m_wkTargetFileNameEdit);
|
m_wkTargetFileNameEdit);
|
||||||
m_wkTargetFileNameEdit->setValidator(validator);
|
m_wkTargetFileNameEdit->setValidator(validator);
|
||||||
m_wkTargetFileNameEdit->setEnabled(m_wkhtmltopdfCB->isChecked());
|
m_wkTargetFileNameEdit->setEnabled(false);
|
||||||
|
|
||||||
// wkhtmltopdf enable background.
|
// wkhtmltopdf enable background.
|
||||||
m_wkBackgroundCB = new QCheckBox(tr("Enable background"));
|
m_wkBackgroundCB = new QCheckBox(tr("Enable background"));
|
||||||
m_wkBackgroundCB->setToolTip(tr("Enable background when printing"));
|
m_wkBackgroundCB->setToolTip(tr("Enable background when printing"));
|
||||||
m_wkBackgroundCB->setEnabled(m_wkhtmltopdfCB->isChecked());
|
m_wkBackgroundCB->setEnabled(false);
|
||||||
|
|
||||||
// wkhtmltopdf page number.
|
// wkhtmltopdf page number.
|
||||||
m_wkPageNumberCB = VUtils::getComboBox();
|
m_wkPageNumberCB = VUtils::getComboBox();
|
||||||
m_wkPageNumberCB->setToolTip(tr("Append page number as footer"));
|
m_wkPageNumberCB->setToolTip(tr("Append page number as footer"));
|
||||||
m_wkPageNumberCB->setEnabled(m_wkhtmltopdfCB->isChecked());
|
m_wkPageNumberCB->setEnabled(false);
|
||||||
|
|
||||||
// wkhtmltopdf extra argumnets.
|
// wkhtmltopdf extra argumnets.
|
||||||
m_wkExtraArgsEdit = new VLineEdit();
|
m_wkExtraArgsEdit = new VLineEdit();
|
||||||
m_wkExtraArgsEdit->setToolTip(tr("Additional global options passed to wkhtmltopdf"));
|
m_wkExtraArgsEdit->setToolTip(tr("Additional global options passed to wkhtmltopdf"));
|
||||||
m_wkExtraArgsEdit->setPlaceholderText(tr("Use \" to enclose options containing spaces"));
|
m_wkExtraArgsEdit->setPlaceholderText(tr("Use \" to enclose options containing spaces"));
|
||||||
m_wkExtraArgsEdit->setEnabled(m_wkhtmltopdfCB->isChecked());
|
m_wkExtraArgsEdit->setEnabled(false);
|
||||||
|
|
||||||
QGridLayout *advLayout = new QGridLayout();
|
QGridLayout *advLayout = new QGridLayout();
|
||||||
advLayout->addWidget(new QLabel(tr("Page layout:")), 0, 0);
|
advLayout->addWidget(new QLabel(tr("Page layout:")), 0, 0);
|
||||||
@ -387,6 +389,7 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
|||||||
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->addItem(tr("PDF (All In One)"), (int)ExportFormat::OnePDF);
|
m_formatCB->addItem(tr("PDF (All In One)"), (int)ExportFormat::OnePDF);
|
||||||
|
m_formatCB->addItem(tr("Custom"), (int)ExportFormat::Custom);
|
||||||
m_formatCB->setCurrentIndex(m_formatCB->findData((int)s_opt.m_format));
|
m_formatCB->setCurrentIndex(m_formatCB->findData((int)s_opt.m_format));
|
||||||
|
|
||||||
// Markdown renderer.
|
// Markdown renderer.
|
||||||
@ -451,6 +454,22 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
|
|||||||
m_wkPageNumberCB->setCurrentIndex(m_wkPageNumberCB->findData((int)s_opt.m_pdfOpt.m_wkPageNumber));
|
m_wkPageNumberCB->setCurrentIndex(m_wkPageNumberCB->findData((int)s_opt.m_pdfOpt.m_wkPageNumber));
|
||||||
|
|
||||||
m_wkExtraArgsEdit->setText(g_config->getWkhtmltopdfArgs());
|
m_wkExtraArgsEdit->setText(g_config->getWkhtmltopdfArgs());
|
||||||
|
|
||||||
|
// Custom export.
|
||||||
|
// Read from config every time.
|
||||||
|
ExportCustomOption customOpt(g_config->getCustomExport());
|
||||||
|
|
||||||
|
m_customSrcFormatCB->addItem(tr("Markdown"), (int)ExportCustomOption::SourceFormat::Markdown);
|
||||||
|
m_customSrcFormatCB->addItem(tr("HTML"), (int)ExportCustomOption::SourceFormat::HTML);
|
||||||
|
m_customSrcFormatCB->setCurrentIndex(m_customSrcFormatCB->findData((int)customOpt.m_srcFormat));
|
||||||
|
|
||||||
|
m_customSuffixEdit->setText(customOpt.m_outputSuffix);
|
||||||
|
|
||||||
|
m_customCmdEdit->setPlainText(customOpt.m_cmd);
|
||||||
|
|
||||||
|
m_customAllInOneCB->setChecked(s_opt.m_customOpt.m_allInOne);
|
||||||
|
|
||||||
|
m_customFolderSepEdit->setText(s_opt.m_customOpt.m_folderSep);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VExportDialog::checkWkhtmltopdfExecutable(const QString &p_file)
|
bool VExportDialog::checkWkhtmltopdfExecutable(const QString &p_file)
|
||||||
@ -493,11 +512,14 @@ void VExportDialog::startExport()
|
|||||||
|
|
||||||
QString outputFolder = QDir::cleanPath(QDir(getOutputDirectory()).absolutePath());
|
QString outputFolder = QDir::cleanPath(QDir(getOutputDirectory()).absolutePath());
|
||||||
|
|
||||||
|
QString renderStyle = m_renderStyleCB->currentData().toString();
|
||||||
|
QString cssUrl = g_config->getCssStyleUrl(renderStyle);
|
||||||
|
|
||||||
s_opt = ExportOption(currentSource(),
|
s_opt = ExportOption(currentSource(),
|
||||||
currentFormat(),
|
currentFormat(),
|
||||||
(MarkdownConverterType)m_rendererCB->currentData().toInt(),
|
(MarkdownConverterType)m_rendererCB->currentData().toInt(),
|
||||||
m_renderBgCB->currentData().toString(),
|
m_renderBgCB->currentData().toString(),
|
||||||
m_renderStyleCB->currentData().toString(),
|
renderStyle,
|
||||||
m_renderCodeBlockStyleCB->currentData().toString(),
|
m_renderCodeBlockStyleCB->currentData().toString(),
|
||||||
m_subfolderCB->isChecked(),
|
m_subfolderCB->isChecked(),
|
||||||
ExportPDFOption(&m_pageLayout,
|
ExportPDFOption(&m_pageLayout,
|
||||||
@ -507,11 +529,20 @@ void VExportDialog::startExport()
|
|||||||
m_tableOfContentsCB->isChecked(),
|
m_tableOfContentsCB->isChecked(),
|
||||||
m_wkTitleEdit->text(),
|
m_wkTitleEdit->text(),
|
||||||
m_wkTargetFileNameEdit->text(),
|
m_wkTargetFileNameEdit->text(),
|
||||||
(ExportPageNumber)m_wkPageNumberCB->currentData().toInt(),
|
(ExportPageNumber)
|
||||||
|
m_wkPageNumberCB->currentData().toInt(),
|
||||||
m_wkExtraArgsEdit->text()),
|
m_wkExtraArgsEdit->text()),
|
||||||
ExportHTMLOption(m_embedStyleCB->isChecked(),
|
ExportHTMLOption(m_embedStyleCB->isChecked(),
|
||||||
m_completeHTMLCB->isChecked(),
|
m_completeHTMLCB->isChecked(),
|
||||||
m_mimeHTMLCB->isChecked()));
|
m_mimeHTMLCB->isChecked()),
|
||||||
|
ExportCustomOption((ExportCustomOption::SourceFormat)
|
||||||
|
m_customSrcFormatCB->currentData().toInt(),
|
||||||
|
m_customSuffixEdit->text(),
|
||||||
|
m_customCmdEdit->toPlainText(),
|
||||||
|
cssUrl,
|
||||||
|
m_customAllInOneCB->isChecked(),
|
||||||
|
m_customFolderSepEdit->text(),
|
||||||
|
m_customTargetFileNameEdit->text()));
|
||||||
|
|
||||||
m_consoleEdit->clear();
|
m_consoleEdit->clear();
|
||||||
appendLogLine(tr("Export to %1.").arg(outputFolder));
|
appendLogLine(tr("Export to %1.").arg(outputFolder));
|
||||||
@ -521,7 +552,6 @@ void VExportDialog::startExport()
|
|||||||
|| s_opt.m_format == ExportFormat::HTML) {
|
|| s_opt.m_format == ExportFormat::HTML) {
|
||||||
if (s_opt.m_format != ExportFormat::OnePDF) {
|
if (s_opt.m_format != ExportFormat::OnePDF) {
|
||||||
s_opt.m_pdfOpt.m_wkTitle.clear();
|
s_opt.m_pdfOpt.m_wkTitle.clear();
|
||||||
s_opt.m_pdfOpt.m_wkTargetFileName.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s_opt.m_format == ExportFormat::PDF
|
if ((s_opt.m_format == ExportFormat::PDF
|
||||||
@ -539,6 +569,24 @@ void VExportDialog::startExport()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_exporter->prepareExport(s_opt);
|
m_exporter->prepareExport(s_opt);
|
||||||
|
} else if (s_opt.m_format == ExportFormat::Custom) {
|
||||||
|
const ExportCustomOption &opt = s_opt.m_customOpt;
|
||||||
|
if (opt.m_srcFormat == ExportCustomOption::HTML) {
|
||||||
|
m_exporter->prepareExport(s_opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save it to config.
|
||||||
|
g_config->setCustomExport(opt.toConfig());
|
||||||
|
|
||||||
|
if (opt.m_outputSuffix.isEmpty()
|
||||||
|
|| opt.m_cmd.isEmpty()
|
||||||
|
|| opt.m_allInOne && opt.m_folderSep.isEmpty()) {
|
||||||
|
appendLogLine(tr("Invalid configurations for custom export."));
|
||||||
|
m_inExport = false;
|
||||||
|
m_exportBtn->setEnabled(true);
|
||||||
|
m_proBar->hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -546,39 +594,13 @@ void VExportDialog::startExport()
|
|||||||
|
|
||||||
if (s_opt.m_format == ExportFormat::OnePDF) {
|
if (s_opt.m_format == ExportFormat::OnePDF) {
|
||||||
QList<QString> files;
|
QList<QString> files;
|
||||||
|
|
||||||
// Output HTMLs to a tmp folder.
|
// Output HTMLs to a tmp folder.
|
||||||
QTemporaryDir tmpDir;
|
QTemporaryDir tmpDir;
|
||||||
if (!tmpDir.isValid()) {
|
if (!tmpDir.isValid()) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "output HTMLs to temporary dir" << tmpDir.path();
|
ret = outputAsHTML(tmpDir.path(), &msg, &files);
|
||||||
|
|
||||||
s_opt.m_format = ExportFormat::HTML;
|
|
||||||
switch (s_opt.m_source) {
|
|
||||||
case ExportSource::CurrentNote:
|
|
||||||
ret = doExport(m_file, s_opt, tmpDir.path(), &msg, &files);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportSource::CurrentFolder:
|
|
||||||
ret = doExport(m_directory, s_opt, tmpDir.path(), &msg, &files);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportSource::CurrentNotebook:
|
|
||||||
ret = doExport(m_notebook, s_opt, tmpDir.path(), &msg, &files);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExportSource::Cart:
|
|
||||||
ret = doExport(m_cart, s_opt, tmpDir.path(), &msg, &files);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_opt.m_format = ExportFormat::OnePDF;
|
|
||||||
|
|
||||||
if (m_askedToStop) {
|
if (m_askedToStop) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -588,6 +610,31 @@ void VExportDialog::startExport()
|
|||||||
if (!files.isEmpty()) {
|
if (!files.isEmpty()) {
|
||||||
ret = doExportPDFAllInOne(files, s_opt, outputFolder, &msg);
|
ret = doExportPDFAllInOne(files, s_opt, outputFolder, &msg);
|
||||||
}
|
}
|
||||||
|
} else if (s_opt.m_format == ExportFormat::Custom
|
||||||
|
&& s_opt.m_customOpt.m_allInOne) {
|
||||||
|
QList<QString> files;
|
||||||
|
QTemporaryDir tmpDir;
|
||||||
|
if (!tmpDir.isValid()) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_opt.m_customOpt.m_srcFormat == ExportCustomOption::HTML) {
|
||||||
|
// Output HTMLs to a tmp folder.
|
||||||
|
ret = outputAsHTML(tmpDir.path(), &msg, &files);
|
||||||
|
if (m_askedToStop) {
|
||||||
|
ret = 0;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(ret == files.size());
|
||||||
|
} else {
|
||||||
|
// Collect all markdown files.
|
||||||
|
files = collectFiles(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!files.isEmpty()) {
|
||||||
|
ret = doExportCustomAllInOne(files, s_opt, outputFolder, &msg);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (s_opt.m_source) {
|
switch (s_opt.m_source) {
|
||||||
case ExportSource::CurrentNote:
|
case ExportSource::CurrentNote:
|
||||||
@ -735,6 +782,10 @@ int VExportDialog::doExport(VFile *p_file,
|
|||||||
ret = doExportHTML(p_file, p_opt, p_outputFolder, p_errMsg, p_outputFiles);
|
ret = doExportHTML(p_file, p_opt, p_outputFolder, p_errMsg, p_outputFiles);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ExportFormat::Custom:
|
||||||
|
ret = doExportCustom(p_file, p_opt, p_outputFolder, p_errMsg, p_outputFiles);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1011,6 +1062,45 @@ int VExportDialog::doExportHTML(VFile *p_file,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VExportDialog::doExportCustom(VFile *p_file,
|
||||||
|
const ExportOption &p_opt,
|
||||||
|
const QString &p_outputFolder,
|
||||||
|
QString *p_errMsg,
|
||||||
|
QList<QString> *p_outputFiles)
|
||||||
|
{
|
||||||
|
Q_UNUSED(p_opt);
|
||||||
|
|
||||||
|
QString srcFilePath(p_file->fetchPath());
|
||||||
|
|
||||||
|
if (p_file->getDocType() != DocType::Markdown) {
|
||||||
|
LOGERR(tr("Skip exporting non-Markdown file %1.").arg(srcFilePath));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VUtils::makePath(p_outputFolder)) {
|
||||||
|
LOGERR(tr("Fail to create directory %1.").arg(p_outputFolder));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get output file.
|
||||||
|
QString suffix = "." + p_opt.m_customOpt.m_outputSuffix;
|
||||||
|
QString name = VUtils::getFileNameWithSequence(p_outputFolder,
|
||||||
|
QFileInfo(p_file->getName()).completeBaseName() + suffix);
|
||||||
|
QString outputPath = QDir(p_outputFolder).filePath(name);
|
||||||
|
|
||||||
|
if (m_exporter->exportCustom(p_file, p_opt, outputPath, p_errMsg)) {
|
||||||
|
if (p_outputFiles) {
|
||||||
|
p_outputFiles->append(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
appendLogLine(tr("Note %1 exported to %2.").arg(srcFilePath).arg(outputPath));
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
appendLogLine(tr("Fail to export note %1.").arg(srcFilePath));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool VExportDialog::checkUserAction()
|
bool VExportDialog::checkUserAction()
|
||||||
{
|
{
|
||||||
if (m_askedToStop) {
|
if (m_askedToStop) {
|
||||||
@ -1054,6 +1144,7 @@ void VExportDialog::handleCurrentFormatChanged(int p_index)
|
|||||||
bool pdfEnabled = false;
|
bool pdfEnabled = false;
|
||||||
bool htmlEnabled = false;
|
bool htmlEnabled = false;
|
||||||
bool pdfTitleNameEnabled = false;
|
bool pdfTitleNameEnabled = false;
|
||||||
|
bool customEnabled = false;
|
||||||
|
|
||||||
if (p_index >= 0) {
|
if (p_index >= 0) {
|
||||||
switch (currentFormat()) {
|
switch (currentFormat()) {
|
||||||
@ -1073,6 +1164,10 @@ void VExportDialog::handleCurrentFormatChanged(int p_index)
|
|||||||
m_wkhtmltopdfCB->setEnabled(false);
|
m_wkhtmltopdfCB->setEnabled(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ExportFormat::Custom:
|
||||||
|
customEnabled = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1080,6 +1175,7 @@ void VExportDialog::handleCurrentFormatChanged(int p_index)
|
|||||||
|
|
||||||
m_pdfSettings->setVisible(pdfEnabled);
|
m_pdfSettings->setVisible(pdfEnabled);
|
||||||
m_htmlSettings->setVisible(htmlEnabled);
|
m_htmlSettings->setVisible(htmlEnabled);
|
||||||
|
m_customSettings->setVisible(customEnabled);
|
||||||
|
|
||||||
m_wkTitleEdit->setEnabled(pdfTitleNameEnabled);
|
m_wkTitleEdit->setEnabled(pdfTitleNameEnabled);
|
||||||
m_wkTargetFileNameEdit->setEnabled(pdfTitleNameEnabled);
|
m_wkTargetFileNameEdit->setEnabled(pdfTitleNameEnabled);
|
||||||
@ -1129,8 +1225,6 @@ int VExportDialog::doExportPDFAllInOne(const QList<QString> &p_files,
|
|||||||
|
|
||||||
QString outputPath = QDir(p_outputFolder).filePath(name);
|
QString outputPath = QDir(p_outputFolder).filePath(name);
|
||||||
|
|
||||||
qDebug() << "output" << p_files.size() << "HTML files as PDF to" << outputPath;
|
|
||||||
|
|
||||||
int ret = m_exporter->exportPDFInOne(p_files, p_opt, outputPath, p_errMsg);
|
int ret = m_exporter->exportPDFInOne(p_files, p_opt, outputPath, p_errMsg);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
appendLogLine(tr("%1 notes exported to %2.").arg(ret).arg(outputPath));
|
appendLogLine(tr("%1 notes exported to %2.").arg(ret).arg(outputPath));
|
||||||
@ -1140,3 +1234,183 @@ int VExportDialog::doExportPDFAllInOne(const QList<QString> &p_files,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VExportDialog::doExportCustomAllInOne(const QList<QString> &p_files,
|
||||||
|
const ExportOption &p_opt,
|
||||||
|
const QString &p_outputFolder,
|
||||||
|
QString *p_errMsg)
|
||||||
|
{
|
||||||
|
if (p_files.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VUtils::makePath(p_outputFolder)) {
|
||||||
|
LOGERR(tr("Fail to create directory %1.").arg(p_outputFolder));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get output file.
|
||||||
|
QString suffix = "." + p_opt.m_customOpt.m_outputSuffix;
|
||||||
|
QString name = p_opt.m_customOpt.m_targetFileName;
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
name = VUtils::getFileNameWithSequence(p_outputFolder,
|
||||||
|
QFileInfo(p_files.first()).completeBaseName() + suffix);
|
||||||
|
} else if (!name.endsWith(suffix)) {
|
||||||
|
name += suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString outputPath = QDir(p_outputFolder).filePath(name);
|
||||||
|
|
||||||
|
int ret = m_exporter->exportCustomInOne(p_files, p_opt, outputPath, p_errMsg);
|
||||||
|
if (ret > 0) {
|
||||||
|
appendLogLine(tr("%1 notes exported to %2.").arg(ret).arg(outputPath));
|
||||||
|
} else {
|
||||||
|
appendLogLine(tr("Fail to export %1 notes in one.").arg(p_files.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *VExportDialog::setupCustomAdvancedSettings()
|
||||||
|
{
|
||||||
|
// Source format.
|
||||||
|
m_customSrcFormatCB = VUtils::getComboBox();
|
||||||
|
m_customSrcFormatCB->setToolTip(tr("Choose format of the input"));
|
||||||
|
|
||||||
|
// Output suffix.
|
||||||
|
m_customSuffixEdit = new VLineEdit();
|
||||||
|
m_customSuffixEdit->setPlaceholderText(tr("Without the preceding dot"));
|
||||||
|
m_customSuffixEdit->setToolTip(tr("Suffix of the output file without the preceding dot"));
|
||||||
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
|
m_customSuffixEdit);
|
||||||
|
m_customSuffixEdit->setValidator(validator);
|
||||||
|
|
||||||
|
QLabel *tipsLabel = new QLabel(tr("<span><span style=\"font-weight:bold;\">%0</span> for the input file; "
|
||||||
|
"<span style=\"font-weight:bold;\">%1</span> for the output file; "
|
||||||
|
"<span style=\"font-weight:bold;\">%2</span> for the rendering CSS style file; "
|
||||||
|
"<span style=\"font-weight:bold;\">%3</span> for the input file directory.</span>"));
|
||||||
|
tipsLabel->setWordWrap(true);
|
||||||
|
|
||||||
|
// Enable All In One.
|
||||||
|
m_customAllInOneCB = new QCheckBox(tr("Enable All In One"));
|
||||||
|
m_customAllInOneCB->setToolTip(tr("Pass a list of input files to the custom command"));
|
||||||
|
connect(m_customAllInOneCB, &QCheckBox::stateChanged,
|
||||||
|
this, [this](int p_state) {
|
||||||
|
bool checked = p_state == Qt::Checked;
|
||||||
|
m_customFolderSepEdit->setEnabled(checked);
|
||||||
|
m_customTargetFileNameEdit->setEnabled(checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Input directory separator.
|
||||||
|
m_customFolderSepEdit = new VLineEdit();
|
||||||
|
m_customFolderSepEdit->setPlaceholderText(tr("Separator to concatenate input files directories"));
|
||||||
|
m_customFolderSepEdit->setToolTip(tr("Separator to concatenate input files directories"));
|
||||||
|
m_customFolderSepEdit->setEnabled(false);
|
||||||
|
|
||||||
|
// Target file name for all in one.
|
||||||
|
m_customTargetFileNameEdit = new VLineEdit();
|
||||||
|
m_customTargetFileNameEdit->setPlaceholderText(tr("Empty to use the name of the first source file"));
|
||||||
|
m_customTargetFileNameEdit->setToolTip(tr("Name of the generated All-In-One file"));
|
||||||
|
validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp),
|
||||||
|
m_customTargetFileNameEdit);
|
||||||
|
m_customTargetFileNameEdit->setValidator(validator);
|
||||||
|
m_customTargetFileNameEdit->setEnabled(false);
|
||||||
|
|
||||||
|
// Cmd edit.
|
||||||
|
m_customCmdEdit = new QPlainTextEdit();
|
||||||
|
m_customCmdEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
|
||||||
|
QString cmdExamp("pandoc --resource-path=.:\"%3\" --css=\"%2\" -s -o \"%1\" \"%0\"");
|
||||||
|
m_customCmdEdit->setPlaceholderText(cmdExamp);
|
||||||
|
m_customCmdEdit->setToolTip(tr("Custom command to be executed"));
|
||||||
|
m_customCmdEdit->setProperty("LineEdit", true);
|
||||||
|
|
||||||
|
QGridLayout *advLayout = new QGridLayout();
|
||||||
|
advLayout->addWidget(new QLabel(tr("Source format:")), 0, 0);
|
||||||
|
advLayout->addWidget(m_customSrcFormatCB, 0, 1, 1, 2);
|
||||||
|
|
||||||
|
advLayout->addWidget(new QLabel(tr("Output suffix:")), 0, 3);
|
||||||
|
advLayout->addWidget(m_customSuffixEdit, 0, 4, 1, 2);
|
||||||
|
|
||||||
|
advLayout->addWidget(m_customAllInOneCB, 1, 1, 1, 2);
|
||||||
|
|
||||||
|
advLayout->addWidget(new QLabel(tr("Output file name:")), 2, 0);
|
||||||
|
advLayout->addWidget(m_customTargetFileNameEdit, 2, 1, 1, 2);
|
||||||
|
|
||||||
|
advLayout->addWidget(new QLabel(tr("Input directories separator:")), 2, 3);
|
||||||
|
advLayout->addWidget(m_customFolderSepEdit, 2, 4, 1, 2);
|
||||||
|
|
||||||
|
advLayout->addWidget(tipsLabel, 3, 0, 1, 6);
|
||||||
|
|
||||||
|
advLayout->addWidget(m_customCmdEdit, 4, 0, 1, 6);
|
||||||
|
|
||||||
|
advLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
QWidget *wid = new QWidget();
|
||||||
|
wid->setLayout(advLayout);
|
||||||
|
|
||||||
|
m_customCmdEdit->setMaximumHeight(100);
|
||||||
|
|
||||||
|
return wid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VExportDialog::outputAsHTML(QString &p_outputFolder,
|
||||||
|
QString *p_errMsg,
|
||||||
|
QList<QString> *p_outputFiles)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
ExportFormat fmt = s_opt.m_format;
|
||||||
|
s_opt.m_format = ExportFormat::HTML;
|
||||||
|
switch (s_opt.m_source) {
|
||||||
|
case ExportSource::CurrentNote:
|
||||||
|
ret = doExport(m_file, s_opt, p_outputFolder, p_errMsg, p_outputFiles);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExportSource::CurrentFolder:
|
||||||
|
ret = doExport(m_directory, s_opt, p_outputFolder, p_errMsg, p_outputFiles);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExportSource::CurrentNotebook:
|
||||||
|
ret = doExport(m_notebook, s_opt, p_outputFolder, p_errMsg, p_outputFiles);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExportSource::Cart:
|
||||||
|
ret = doExport(m_cart, s_opt, p_outputFolder, p_errMsg, p_outputFiles);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_opt.m_format = fmt;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> VExportDialog::collectFiles(QString *p_errMsg)
|
||||||
|
{
|
||||||
|
Q_UNUSED(p_errMsg);
|
||||||
|
|
||||||
|
QList<QString> files;
|
||||||
|
switch (s_opt.m_source) {
|
||||||
|
case ExportSource::CurrentNote:
|
||||||
|
files.append(m_file->fetchPath());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExportSource::CurrentFolder:
|
||||||
|
files = m_directory->collectFiles();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExportSource::CurrentNotebook:
|
||||||
|
files = m_notebook->collectFiles();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExportSource::Cart:
|
||||||
|
files = m_cart->getFiles().toList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
@ -38,7 +38,8 @@ enum class ExportFormat
|
|||||||
Markdown = 0,
|
Markdown = 0,
|
||||||
HTML,
|
HTML,
|
||||||
PDF,
|
PDF,
|
||||||
OnePDF
|
OnePDF,
|
||||||
|
Custom
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -119,6 +120,87 @@ struct ExportPDFOption
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ExportCustomOption
|
||||||
|
{
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
#define DEFAULT_SEP ";"
|
||||||
|
#else
|
||||||
|
#define DEFAULT_SEP ":"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum SourceFormat
|
||||||
|
{
|
||||||
|
Markdown = 0,
|
||||||
|
HTML
|
||||||
|
};
|
||||||
|
|
||||||
|
ExportCustomOption()
|
||||||
|
: m_srcFormat(SourceFormat::Markdown),
|
||||||
|
m_allInOne(false),
|
||||||
|
m_folderSep(DEFAULT_SEP)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ExportCustomOption(const QStringList &p_config)
|
||||||
|
: m_srcFormat(SourceFormat::Markdown),
|
||||||
|
m_allInOne(false),
|
||||||
|
m_folderSep(DEFAULT_SEP)
|
||||||
|
{
|
||||||
|
if (p_config.size() < 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_config.at(0).trimmed() != "0") {
|
||||||
|
m_srcFormat = SourceFormat::HTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_outputSuffix = p_config.at(1).trimmed();
|
||||||
|
|
||||||
|
m_cmd = p_config.at(2).trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
ExportCustomOption(ExportCustomOption::SourceFormat p_srcFormat,
|
||||||
|
const QString &p_outputSuffix,
|
||||||
|
const QString &p_cmd,
|
||||||
|
const QString &p_cssUrl,
|
||||||
|
bool p_allInOne,
|
||||||
|
const QString &p_folderSep,
|
||||||
|
const QString &p_targetFileName)
|
||||||
|
: m_srcFormat(p_srcFormat),
|
||||||
|
m_outputSuffix(p_outputSuffix),
|
||||||
|
m_cssUrl(p_cssUrl),
|
||||||
|
m_allInOne(p_allInOne),
|
||||||
|
m_folderSep(p_folderSep),
|
||||||
|
m_targetFileName(p_targetFileName)
|
||||||
|
{
|
||||||
|
QStringList cmds = p_cmd.split('\n');
|
||||||
|
if (!cmds.isEmpty()) {
|
||||||
|
m_cmd = cmds.first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList toConfig() const
|
||||||
|
{
|
||||||
|
QStringList config;
|
||||||
|
config << QString::number((int)m_srcFormat);
|
||||||
|
config << m_outputSuffix;
|
||||||
|
config << m_cmd;
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceFormat m_srcFormat;
|
||||||
|
QString m_outputSuffix;
|
||||||
|
QString m_cmd;
|
||||||
|
|
||||||
|
QString m_cssUrl;
|
||||||
|
bool m_allInOne;
|
||||||
|
|
||||||
|
QString m_folderSep;
|
||||||
|
QString m_targetFileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ExportOption
|
struct ExportOption
|
||||||
{
|
{
|
||||||
ExportOption()
|
ExportOption()
|
||||||
@ -137,7 +219,8 @@ struct ExportOption
|
|||||||
const QString &p_renderCodeBlockStyle,
|
const QString &p_renderCodeBlockStyle,
|
||||||
bool p_processSubfolders,
|
bool p_processSubfolders,
|
||||||
const ExportPDFOption &p_pdfOpt,
|
const ExportPDFOption &p_pdfOpt,
|
||||||
const ExportHTMLOption &p_htmlOpt)
|
const ExportHTMLOption &p_htmlOpt,
|
||||||
|
const ExportCustomOption &p_customOpt)
|
||||||
: m_source(p_source),
|
: m_source(p_source),
|
||||||
m_format(p_format),
|
m_format(p_format),
|
||||||
m_renderer(p_renderer),
|
m_renderer(p_renderer),
|
||||||
@ -146,7 +229,8 @@ struct ExportOption
|
|||||||
m_renderCodeBlockStyle(p_renderCodeBlockStyle),
|
m_renderCodeBlockStyle(p_renderCodeBlockStyle),
|
||||||
m_processSubfolders(p_processSubfolders),
|
m_processSubfolders(p_processSubfolders),
|
||||||
m_pdfOpt(p_pdfOpt),
|
m_pdfOpt(p_pdfOpt),
|
||||||
m_htmlOpt(p_htmlOpt)
|
m_htmlOpt(p_htmlOpt),
|
||||||
|
m_customOpt(p_customOpt)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +250,8 @@ struct ExportOption
|
|||||||
ExportPDFOption m_pdfOpt;
|
ExportPDFOption m_pdfOpt;
|
||||||
|
|
||||||
ExportHTMLOption m_htmlOpt;
|
ExportHTMLOption m_htmlOpt;
|
||||||
|
|
||||||
|
ExportCustomOption m_customOpt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -204,6 +290,8 @@ private:
|
|||||||
|
|
||||||
QWidget *setupGeneralAdvancedSettings();
|
QWidget *setupGeneralAdvancedSettings();
|
||||||
|
|
||||||
|
QWidget *setupCustomAdvancedSettings();
|
||||||
|
|
||||||
void initUIFields(MarkdownConverterType p_renderer);
|
void initUIFields(MarkdownConverterType p_renderer);
|
||||||
|
|
||||||
QString getOutputDirectory() const;
|
QString getOutputDirectory() const;
|
||||||
@ -258,6 +346,17 @@ private:
|
|||||||
const QString &p_outputFolder,
|
const QString &p_outputFolder,
|
||||||
QString *p_errMsg = NULL);
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
|
int doExportCustomAllInOne(const QList<QString> &p_files,
|
||||||
|
const ExportOption &p_opt,
|
||||||
|
const QString &p_outputFolder,
|
||||||
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
|
int doExportCustom(VFile *p_file,
|
||||||
|
const ExportOption &p_opt,
|
||||||
|
const QString &p_outputFolder,
|
||||||
|
QString *p_errMsg = NULL,
|
||||||
|
QList<QString> *p_outputFiles = NULL);
|
||||||
|
|
||||||
// Return false if we could not continue.
|
// Return false if we could not continue.
|
||||||
bool checkUserAction();
|
bool checkUserAction();
|
||||||
|
|
||||||
@ -269,6 +368,13 @@ private:
|
|||||||
|
|
||||||
ExportFormat currentFormat() const;
|
ExportFormat currentFormat() const;
|
||||||
|
|
||||||
|
int outputAsHTML(QString &p_outputFolder,
|
||||||
|
QString *p_errMsg = NULL,
|
||||||
|
QList<QString> *p_outputFiles = NULL);
|
||||||
|
|
||||||
|
// Collect files to be handled.
|
||||||
|
QList<QString> collectFiles(QString *p_errMsg = NULL);
|
||||||
|
|
||||||
QComboBox *m_srcCB;
|
QComboBox *m_srcCB;
|
||||||
|
|
||||||
QComboBox *m_formatCB;
|
QComboBox *m_formatCB;
|
||||||
@ -293,6 +399,8 @@ private:
|
|||||||
|
|
||||||
QWidget *m_generalSettings;
|
QWidget *m_generalSettings;
|
||||||
|
|
||||||
|
QWidget *m_customSettings;
|
||||||
|
|
||||||
QPlainTextEdit *m_consoleEdit;
|
QPlainTextEdit *m_consoleEdit;
|
||||||
|
|
||||||
QDialogButtonBox *m_btnBox;
|
QDialogButtonBox *m_btnBox;
|
||||||
@ -329,6 +437,18 @@ private:
|
|||||||
|
|
||||||
QCheckBox *m_subfolderCB;
|
QCheckBox *m_subfolderCB;
|
||||||
|
|
||||||
|
QComboBox *m_customSrcFormatCB;
|
||||||
|
|
||||||
|
VLineEdit *m_customSuffixEdit;
|
||||||
|
|
||||||
|
QCheckBox *m_customAllInOneCB;
|
||||||
|
|
||||||
|
QPlainTextEdit *m_customCmdEdit;
|
||||||
|
|
||||||
|
VLineEdit *m_customFolderSepEdit;
|
||||||
|
|
||||||
|
VLineEdit *m_customTargetFileNameEdit;
|
||||||
|
|
||||||
VNotebook *m_notebook;
|
VNotebook *m_notebook;
|
||||||
|
|
||||||
VDirectory *m_directory;
|
VDirectory *m_directory;
|
||||||
|
@ -209,6 +209,13 @@ wkhtmltopdf=wkhtmltopdf
|
|||||||
; Double quotes to enclose arguments with spaces
|
; Double quotes to enclose arguments with spaces
|
||||||
wkhtmltopdfArgs=
|
wkhtmltopdfArgs=
|
||||||
|
|
||||||
|
; A string list separated by ,
|
||||||
|
; SourceFormat,OutputSuffix,CMD
|
||||||
|
; SourceFormat: 0 for Markdown, 1 for HTML
|
||||||
|
; OutputSuffix: suffix WITHOUT the preceding dot
|
||||||
|
; CMD: command to execute, %0 for the input file, %1 for the output file
|
||||||
|
custom_export=
|
||||||
|
|
||||||
[web]
|
[web]
|
||||||
; Location and configuration for Mathjax
|
; Location and configuration for Mathjax
|
||||||
mathjax_javascript=https://cdn.bootcss.com/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_HTMLorMML
|
mathjax_javascript=https://cdn.bootcss.com/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_HTMLorMML
|
||||||
|
@ -463,6 +463,9 @@ public:
|
|||||||
bool getEnableFlashAnchor() const;
|
bool getEnableFlashAnchor() const;
|
||||||
void setEnableFlashAnchor(bool p_enabled);
|
void setEnableFlashAnchor(bool p_enabled);
|
||||||
|
|
||||||
|
QStringList getCustomExport() const;
|
||||||
|
void setCustomExport(const QStringList &p_exp);
|
||||||
|
|
||||||
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;
|
||||||
@ -2132,4 +2135,15 @@ inline void VConfigManager::setEnableFlashAnchor(bool p_enabled)
|
|||||||
m_enableFlashAnchor = p_enabled;
|
m_enableFlashAnchor = p_enabled;
|
||||||
setConfigToSettings("web", "enable_flash_anchor", m_enableFlashAnchor);
|
setConfigToSettings("web", "enable_flash_anchor", m_enableFlashAnchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QStringList VConfigManager::getCustomExport() const
|
||||||
|
{
|
||||||
|
return getConfigFromSettings("export",
|
||||||
|
"custom_export").toStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setCustomExport(const QStringList &p_exp)
|
||||||
|
{
|
||||||
|
setConfigToSettings("export", "custom_export", p_exp);
|
||||||
|
}
|
||||||
#endif // VCONFIGMANAGER_H
|
#endif // VCONFIGMANAGER_H
|
||||||
|
@ -716,3 +716,29 @@ bool VDirectory::sortSubDirectories(const QVector<int> &p_sortedIdx)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QString> VDirectory::collectFiles()
|
||||||
|
{
|
||||||
|
QList<QString> files;
|
||||||
|
bool opened = isOpened();
|
||||||
|
if (!opened && !open()) {
|
||||||
|
qWarning() << "fail to open directory" << fetchPath();
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Files.
|
||||||
|
for (auto const & file : m_files) {
|
||||||
|
files.append(file->fetchPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subfolders.
|
||||||
|
for (auto const & dir : m_subDirs) {
|
||||||
|
files.append(dir->collectFiles());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!opened) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
@ -114,6 +114,9 @@ public:
|
|||||||
// Reorder sub-directories in m_subDirs by index.
|
// Reorder sub-directories in m_subDirs by index.
|
||||||
bool sortSubDirectories(const QVector<int> &p_sortedIdx);
|
bool sortSubDirectories(const QVector<int> &p_sortedIdx);
|
||||||
|
|
||||||
|
// Return path of files in this directory recursively.
|
||||||
|
QList<QString> collectFiles();
|
||||||
|
|
||||||
// Delete directory @p_dir.
|
// Delete directory @p_dir.
|
||||||
static bool deleteDirectory(VDirectory *p_dir,
|
static bool deleteDirectory(VDirectory *p_dir,
|
||||||
bool p_skipRecycleBin = false,
|
bool p_skipRecycleBin = false,
|
||||||
|
@ -40,7 +40,8 @@ static QString marginToStrMM(qreal p_margin)
|
|||||||
void VExporter::prepareExport(const ExportOption &p_opt)
|
void VExporter::prepareExport(const ExportOption &p_opt)
|
||||||
{
|
{
|
||||||
bool isPdf = p_opt.m_format == ExportFormat::PDF
|
bool isPdf = p_opt.m_format == ExportFormat::PDF
|
||||||
|| p_opt.m_format == ExportFormat::OnePDF;
|
|| p_opt.m_format == ExportFormat::OnePDF
|
||||||
|
|| p_opt.m_format == ExportFormat::Custom;
|
||||||
bool extraToc = isPdf
|
bool extraToc = isPdf
|
||||||
&& !p_opt.m_pdfOpt.m_wkhtmltopdf
|
&& !p_opt.m_pdfOpt.m_wkhtmltopdf
|
||||||
&& p_opt.m_pdfOpt.m_enableTableOfContents;
|
&& p_opt.m_pdfOpt.m_enableTableOfContents;
|
||||||
@ -178,6 +179,69 @@ bool VExporter::exportHTML(VFile *p_file,
|
|||||||
return exportViaWebView(p_file, p_opt, p_outputFile, p_errMsg);
|
return exportViaWebView(p_file, p_opt, p_outputFile, p_errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void replaceArgument(QString &p_cmd, const QString &p_arg, const QString &p_val)
|
||||||
|
{
|
||||||
|
if (p_val.startsWith("\"")) {
|
||||||
|
// Check if the arg has been already surrounded by ".
|
||||||
|
int pos = 0;
|
||||||
|
while (pos < p_cmd.size()) {
|
||||||
|
int idx = p_cmd.indexOf(p_arg, pos);
|
||||||
|
if (idx == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = p_arg.size();
|
||||||
|
int nidx = idx;
|
||||||
|
if (idx > 0 && p_cmd[idx - 1] == '"') {
|
||||||
|
--nidx;
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx + p_arg.size() < p_cmd.size()
|
||||||
|
&& p_cmd[idx + p_arg.size()] == '"') {
|
||||||
|
len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_cmd.replace(nidx, len, p_val);
|
||||||
|
pos = nidx + p_val.size() - len;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p_cmd.replace(p_arg, p_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString evaluateCommand(const ExportCustomOption &p_opt,
|
||||||
|
const QString &p_input,
|
||||||
|
const QString &p_inputFolder,
|
||||||
|
const QString &p_output)
|
||||||
|
{
|
||||||
|
QString cssStyle = QDir::toNativeSeparators(p_opt.m_cssUrl);
|
||||||
|
|
||||||
|
QString cmd(p_opt.m_cmd);
|
||||||
|
replaceArgument(cmd, "%0", p_input);
|
||||||
|
replaceArgument(cmd, "%1", p_output);
|
||||||
|
replaceArgument(cmd, "%2", cssStyle);
|
||||||
|
replaceArgument(cmd, "%3", p_inputFolder);
|
||||||
|
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VExporter::exportCustom(VFile *p_file,
|
||||||
|
const ExportOption &p_opt,
|
||||||
|
const QString &p_outputFile,
|
||||||
|
QString *p_errMsg)
|
||||||
|
{
|
||||||
|
const ExportCustomOption &customOpt = p_opt.m_customOpt;
|
||||||
|
if (customOpt.m_srcFormat == ExportCustomOption::Markdown) {
|
||||||
|
// Use Markdown file as input.
|
||||||
|
QList<QString> files;
|
||||||
|
files.append(QDir::toNativeSeparators(p_file->fetchPath()));
|
||||||
|
return convertFilesViaCustom(files, p_outputFile, customOpt, p_errMsg);
|
||||||
|
} else {
|
||||||
|
return exportViaWebView(p_file, p_opt, p_outputFile, p_errMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VExporter::initWebViewer(VFile *p_file, const ExportOption &p_opt)
|
void VExporter::initWebViewer(VFile *p_file, const ExportOption &p_opt)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!m_webViewer);
|
Q_ASSERT(!m_webViewer);
|
||||||
@ -308,36 +372,16 @@ bool VExporter::exportToPDFViaWK(VDocument *p_webDocument,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString htmlPath = tmpDir.filePath("vnote_tmp.html");
|
QString htmlPath = tmpDir.filePath("vnote_tmp.html");
|
||||||
|
if (!outputToHTMLFile(htmlPath,
|
||||||
QFile file(htmlPath);
|
p_headContent,
|
||||||
if (!file.open(QFile::WriteOnly)) {
|
p_styleContent,
|
||||||
|
p_bodyContent,
|
||||||
|
true,
|
||||||
|
true)) {
|
||||||
pdfExported = -1;
|
pdfExported = -1;
|
||||||
return;
|
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 via wkhtmltopdf.
|
// Convert via wkhtmltopdf.
|
||||||
QList<QString> files;
|
QList<QString> files;
|
||||||
files.append(htmlPath);
|
files.append(htmlPath);
|
||||||
@ -361,6 +405,65 @@ bool VExporter::exportToPDFViaWK(VDocument *p_webDocument,
|
|||||||
return pdfExported == 1;
|
return pdfExported == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VExporter::exportToCustom(VDocument *p_webDocument,
|
||||||
|
const ExportCustomOption &p_opt,
|
||||||
|
const QString &p_filePath,
|
||||||
|
QString *p_errMsg)
|
||||||
|
{
|
||||||
|
int exported = 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) {
|
||||||
|
exported = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(!p_filePath.isEmpty());
|
||||||
|
|
||||||
|
// Save HTML to a temp dir.
|
||||||
|
QTemporaryDir tmpDir;
|
||||||
|
if (!tmpDir.isValid()) {
|
||||||
|
exported = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString htmlPath = tmpDir.filePath("vnote_tmp.html");
|
||||||
|
if (!outputToHTMLFile(htmlPath,
|
||||||
|
p_headContent,
|
||||||
|
p_styleContent,
|
||||||
|
p_bodyContent,
|
||||||
|
true,
|
||||||
|
true)) {
|
||||||
|
exported = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert via custom command.
|
||||||
|
QList<QString> files;
|
||||||
|
files.append(htmlPath);
|
||||||
|
if (!convertFilesViaCustom(files, p_filePath, p_opt, p_errMsg)) {
|
||||||
|
exported = -1;
|
||||||
|
} else {
|
||||||
|
exported = 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
p_webDocument->getHtmlContentAsync();
|
||||||
|
|
||||||
|
while (exported == 0) {
|
||||||
|
VUtils::sleepWait(100);
|
||||||
|
|
||||||
|
if (m_state == ExportState::Cancelled) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exported == 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,
|
||||||
@ -440,6 +543,13 @@ bool VExporter::exportViaWebView(VFile *p_file,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ExportFormat::Custom:
|
||||||
|
exportRet = exportToCustom(m_webDocument,
|
||||||
|
p_opt.m_customOpt,
|
||||||
|
p_outputFile,
|
||||||
|
p_errMsg);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -487,46 +597,16 @@ bool VExporter::exportToHTML(VDocument *p_webDocument,
|
|||||||
|
|
||||||
Q_ASSERT(!p_filePath.isEmpty());
|
Q_ASSERT(!p_filePath.isEmpty());
|
||||||
|
|
||||||
QFile file(p_filePath);
|
if (!outputToHTMLFile(p_filePath,
|
||||||
if (!file.open(QFile::WriteOnly)) {
|
p_headContent,
|
||||||
|
p_styleContent,
|
||||||
|
p_bodyContent,
|
||||||
|
p_opt.m_embedCssStyle,
|
||||||
|
p_opt.m_completeHTML)) {
|
||||||
htmlExported = -1;
|
htmlExported = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString resFolder = QFileInfo(p_filePath).completeBaseName() + "_files";
|
|
||||||
QString resFolderPath = QDir(VUtils::basePathFromPath(p_filePath)).filePath(resFolder);
|
|
||||||
|
|
||||||
qDebug() << "HTML files folder" << resFolderPath;
|
|
||||||
|
|
||||||
QString html(m_exportHtmlTemplate);
|
|
||||||
if (!p_styleContent.isEmpty() && p_opt.m_embedCssStyle) {
|
|
||||||
QString content(p_styleContent);
|
|
||||||
fixStyleResources(resFolderPath, content);
|
|
||||||
html.replace(HtmlHolder::c_styleHolder, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!p_headContent.isEmpty()) {
|
|
||||||
html.replace(HtmlHolder::c_headHolder, p_headContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_opt.m_completeHTML) {
|
|
||||||
QString content(p_bodyContent);
|
|
||||||
fixBodyResources(m_baseUrl, resFolderPath, content);
|
|
||||||
html.replace(HtmlHolder::c_bodyHolder, content);
|
|
||||||
} else {
|
|
||||||
html.replace(HtmlHolder::c_bodyHolder, p_bodyContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.write(html.toUtf8());
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
// Delete empty resource folder.
|
|
||||||
QDir dir(resFolderPath);
|
|
||||||
if (dir.isEmpty()) {
|
|
||||||
dir.cdUp();
|
|
||||||
dir.rmdir(resFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
htmlExported = 1;
|
htmlExported = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -711,6 +791,56 @@ bool VExporter::htmlsToPDFViaWK(const QList<QString> &p_htmlFiles,
|
|||||||
return ret == 0;
|
return ret == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VExporter::convertFilesViaCustom(const QList<QString> &p_files,
|
||||||
|
const QString &p_filePath,
|
||||||
|
const ExportCustomOption &p_opt,
|
||||||
|
QString *p_errMsg)
|
||||||
|
{
|
||||||
|
QString input;
|
||||||
|
QString inputFolder;
|
||||||
|
for (auto const & it : p_files) {
|
||||||
|
if (!input.isEmpty()) {
|
||||||
|
input += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inputFolder.isEmpty()) {
|
||||||
|
inputFolder += p_opt.m_folderSep;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString tmp = QDir::toNativeSeparators(it);
|
||||||
|
input += ("\"" + tmp + "\"");
|
||||||
|
inputFolder += ("\"" + VUtils::basePathFromPath(tmp) + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString output = QDir::toNativeSeparators(p_filePath);
|
||||||
|
QString cmd = evaluateCommand(p_opt,
|
||||||
|
input,
|
||||||
|
inputFolder,
|
||||||
|
output);
|
||||||
|
emit outputLog(cmd);
|
||||||
|
qDebug() << "custom cmd:" << cmd;
|
||||||
|
int ret = startProcess(cmd);
|
||||||
|
qDebug() << "custom cmd returned" << ret;
|
||||||
|
if (m_askedToStop) {
|
||||||
|
return ret == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case -2:
|
||||||
|
VUtils::addErrMsg(p_errMsg, tr("Fail to start custom command (%1).").arg(cmd));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
VUtils::addErrMsg(p_errMsg, tr("Custom command crashed (%1).").arg(cmd));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret == 0;
|
||||||
|
}
|
||||||
|
|
||||||
int VExporter::exportPDFInOne(const QList<QString> &p_htmlFiles,
|
int VExporter::exportPDFInOne(const QList<QString> &p_htmlFiles,
|
||||||
const ExportOption &p_opt,
|
const ExportOption &p_opt,
|
||||||
const QString &p_outputFile,
|
const QString &p_outputFile,
|
||||||
@ -796,3 +926,74 @@ int VExporter::startProcess(const QString &p_program, const QStringList &p_args)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VExporter::startProcess(const QString &p_cmd)
|
||||||
|
{
|
||||||
|
QStringList args = parseCombinedArgString(p_cmd);
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return startProcess(args.first(), args.mid(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VExporter::outputToHTMLFile(const QString &p_file,
|
||||||
|
const QString &p_headContent,
|
||||||
|
const QString &p_styleContent,
|
||||||
|
const QString &p_bodyContent,
|
||||||
|
bool p_embedCssStyle,
|
||||||
|
bool p_completeHTML)
|
||||||
|
{
|
||||||
|
QFile file(p_file);
|
||||||
|
if (!file.open(QFile::WriteOnly)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString resFolder = QFileInfo(p_file).completeBaseName() + "_files";
|
||||||
|
QString resFolderPath = QDir(VUtils::basePathFromPath(p_file)).filePath(resFolder);
|
||||||
|
|
||||||
|
qDebug() << "HTML files folder" << resFolderPath;
|
||||||
|
|
||||||
|
QString html(m_exportHtmlTemplate);
|
||||||
|
if (!p_styleContent.isEmpty() && p_embedCssStyle) {
|
||||||
|
QString content(p_styleContent);
|
||||||
|
fixStyleResources(resFolderPath, content);
|
||||||
|
html.replace(HtmlHolder::c_styleHolder, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p_headContent.isEmpty()) {
|
||||||
|
html.replace(HtmlHolder::c_headHolder, p_headContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_completeHTML) {
|
||||||
|
QString content(p_bodyContent);
|
||||||
|
fixBodyResources(m_baseUrl, resFolderPath, content);
|
||||||
|
html.replace(HtmlHolder::c_bodyHolder, content);
|
||||||
|
} else {
|
||||||
|
html.replace(HtmlHolder::c_bodyHolder, p_bodyContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.write(html.toUtf8());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// Delete empty resource folder.
|
||||||
|
QDir dir(resFolderPath);
|
||||||
|
if (dir.isEmpty()) {
|
||||||
|
dir.cdUp();
|
||||||
|
dir.rmdir(resFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VExporter::exportCustomInOne(const QList<QString> &p_files,
|
||||||
|
const ExportOption &p_opt,
|
||||||
|
const QString &p_outputFile,
|
||||||
|
QString *p_errMsg)
|
||||||
|
{
|
||||||
|
if (!convertFilesViaCustom(p_files, p_outputFile, p_opt.m_customOpt, p_errMsg)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_files.size();
|
||||||
|
}
|
||||||
|
@ -31,11 +31,21 @@ public:
|
|||||||
const QString &p_outputFile,
|
const QString &p_outputFile,
|
||||||
QString *p_errMsg = NULL);
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
|
bool exportCustom(VFile *p_file,
|
||||||
|
const ExportOption &p_opt,
|
||||||
|
const QString &p_outputFile,
|
||||||
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
int exportPDFInOne(const QList<QString> &p_htmlFiles,
|
int exportPDFInOne(const QList<QString> &p_htmlFiles,
|
||||||
const ExportOption &p_opt,
|
const ExportOption &p_opt,
|
||||||
const QString &p_outputFile,
|
const QString &p_outputFile,
|
||||||
QString *p_errMsg = NULL);
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
|
int exportCustomInOne(const QList<QString> &p_files,
|
||||||
|
const ExportOption &p_opt,
|
||||||
|
const QString &p_outputFile,
|
||||||
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
void setAskedToStop(bool p_askedToStop);
|
void setAskedToStop(bool p_askedToStop);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@ -94,6 +104,11 @@ private:
|
|||||||
const QString &p_filePath,
|
const QString &p_filePath,
|
||||||
QString *p_errMsg = NULL);
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
|
bool exportToCustom(VDocument *p_webDocument,
|
||||||
|
const ExportCustomOption &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);
|
||||||
@ -107,10 +122,24 @@ private:
|
|||||||
const ExportPDFOption &p_opt,
|
const ExportPDFOption &p_opt,
|
||||||
QString *p_errMsg = NULL);
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
|
bool convertFilesViaCustom(const QList<QString> &p_files,
|
||||||
|
const QString &p_filePath,
|
||||||
|
const ExportCustomOption &p_opt,
|
||||||
|
QString *p_errMsg = NULL);
|
||||||
|
|
||||||
void prepareWKArguments(const ExportPDFOption &p_opt);
|
void prepareWKArguments(const ExportPDFOption &p_opt);
|
||||||
|
|
||||||
int startProcess(const QString &p_program, const QStringList &p_args);
|
int startProcess(const QString &p_program, const QStringList &p_args);
|
||||||
|
|
||||||
|
int startProcess(const QString &p_cmd);
|
||||||
|
|
||||||
|
bool outputToHTMLFile(const QString &p_file,
|
||||||
|
const QString &p_headContent,
|
||||||
|
const QString &p_styleContent,
|
||||||
|
const QString &p_bodyContent,
|
||||||
|
bool p_embedCssStyle,
|
||||||
|
bool p_completeHTML);
|
||||||
|
|
||||||
// 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.
|
||||||
static bool fixStyleResources(const QString &p_folder,
|
static bool fixStyleResources(const QString &p_folder,
|
||||||
|
@ -367,3 +367,22 @@ QString VNotebook::getRecycleBinFolderPath() const
|
|||||||
return QDir(m_path).filePath(m_recycleBinFolder);
|
return QDir(m_path).filePath(m_recycleBinFolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QString> VNotebook::collectFiles()
|
||||||
|
{
|
||||||
|
QList<QString> files;
|
||||||
|
|
||||||
|
bool opened = isOpened();
|
||||||
|
if (!opened && !open()) {
|
||||||
|
qWarning() << "fail to open notebook %1" << m_path;
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
files = m_rootDir->collectFiles();
|
||||||
|
|
||||||
|
if (!opened) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
@ -95,6 +95,8 @@ public:
|
|||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
|
QList<QString> collectFiles();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Serialize current instance to json.
|
// Serialize current instance to json.
|
||||||
QJsonObject toConfigJson() const;
|
QJsonObject toConfigJson() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user