mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
export: handle HTML resources
This commit is contained in:
parent
b7e6301136
commit
fe7c446e5f
@ -208,8 +208,16 @@ QWidget *VExportDialog::setupHTMLAdvancedSettings()
|
|||||||
m_embedStyleCB->setToolTip(tr("Embed CSS styles in HTML file"));
|
m_embedStyleCB->setToolTip(tr("Embed CSS styles in HTML file"));
|
||||||
m_embedStyleCB->setChecked(true);
|
m_embedStyleCB->setChecked(true);
|
||||||
|
|
||||||
|
// Complete HTML.
|
||||||
|
m_completeHTMLCB = new QCheckBox(tr("Complete page"), this);
|
||||||
|
m_completeHTMLCB->setToolTip(tr("Export the whole web page along with pictures "
|
||||||
|
"which may not keep the HTML link structure of "
|
||||||
|
"the original page"));
|
||||||
|
m_completeHTMLCB->setChecked(true);
|
||||||
|
|
||||||
QFormLayout *advLayout = new QFormLayout();
|
QFormLayout *advLayout = new QFormLayout();
|
||||||
advLayout->addRow(m_embedStyleCB);
|
advLayout->addRow(m_embedStyleCB);
|
||||||
|
advLayout->addRow(m_completeHTMLCB);
|
||||||
|
|
||||||
advLayout->setContentsMargins(0, 0, 0, 0);
|
advLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
@ -303,7 +311,8 @@ void VExportDialog::startExport()
|
|||||||
m_renderStyleCB->currentData().toString(),
|
m_renderStyleCB->currentData().toString(),
|
||||||
m_renderCodeBlockStyleCB->currentData().toString(),
|
m_renderCodeBlockStyleCB->currentData().toString(),
|
||||||
&m_pageLayout,
|
&m_pageLayout,
|
||||||
m_embedStyleCB->isChecked());
|
m_embedStyleCB->isChecked(),
|
||||||
|
m_completeHTMLCB->isChecked());
|
||||||
|
|
||||||
s_lastExportFormat = opt.m_format;
|
s_lastExportFormat = opt.m_format;
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ struct ExportOption
|
|||||||
const QString &p_renderStyle,
|
const QString &p_renderStyle,
|
||||||
const QString &p_renderCodeBlockStyle,
|
const QString &p_renderCodeBlockStyle,
|
||||||
QPageLayout *p_layout,
|
QPageLayout *p_layout,
|
||||||
bool p_embedCssStyle)
|
bool p_embedCssStyle,
|
||||||
|
bool p_completeHTML)
|
||||||
: m_source(p_source),
|
: m_source(p_source),
|
||||||
m_format(p_format),
|
m_format(p_format),
|
||||||
m_renderer(p_renderer),
|
m_renderer(p_renderer),
|
||||||
@ -55,7 +56,8 @@ struct ExportOption
|
|||||||
m_renderStyle(p_renderStyle),
|
m_renderStyle(p_renderStyle),
|
||||||
m_renderCodeBlockStyle(p_renderCodeBlockStyle),
|
m_renderCodeBlockStyle(p_renderCodeBlockStyle),
|
||||||
m_layout(p_layout),
|
m_layout(p_layout),
|
||||||
m_embedCssStyle(p_embedCssStyle)
|
m_embedCssStyle(p_embedCssStyle),
|
||||||
|
m_completeHTML(p_completeHTML)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +73,7 @@ struct ExportOption
|
|||||||
QPageLayout *m_layout;
|
QPageLayout *m_layout;
|
||||||
|
|
||||||
bool m_embedCssStyle;
|
bool m_embedCssStyle;
|
||||||
|
bool m_completeHTML;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -186,6 +189,8 @@ private:
|
|||||||
|
|
||||||
QCheckBox *m_embedStyleCB;
|
QCheckBox *m_embedStyleCB;
|
||||||
|
|
||||||
|
QCheckBox *m_completeHTMLCB;;
|
||||||
|
|
||||||
VNotebook *m_notebook;
|
VNotebook *m_notebook;
|
||||||
|
|
||||||
VDirectory *m_directory;
|
VDirectory *m_directory;
|
||||||
|
@ -40,19 +40,56 @@ if (typeof VEnableImageCaption == 'undefined') {
|
|||||||
VEnableImageCaption = false;
|
VEnableImageCaption = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var getUrlScheme = function(url) {
|
||||||
|
var idx = url.indexOf(':');
|
||||||
|
if (idx > -1) {
|
||||||
|
return url.substr(0, idx);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var replaceCssUrl = function(baseUrl, match, p1, offset, str) {
|
||||||
|
if (getUrlScheme(p1)) {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = baseUrl + '/' + p1;
|
||||||
|
return "url(\"" + url + "\");";
|
||||||
|
};
|
||||||
|
|
||||||
|
var translateCssUrlToAbsolute = function(baseUrl, css) {
|
||||||
|
return css.replace(/\burl\(\"([^\"\)]+)\"\);/g, replaceCssUrl.bind(undefined, baseUrl));
|
||||||
|
};
|
||||||
|
|
||||||
var styleContent = function() {
|
var styleContent = function() {
|
||||||
var styles = "";
|
var styles = "";
|
||||||
for (var i = 0; i < document.styleSheets.length; ++i) {
|
for (var i = 0; i < document.styleSheets.length; ++i) {
|
||||||
var styleSheet = document.styleSheets[i];
|
var styleSheet = document.styleSheets[i];
|
||||||
if (styleSheet.cssRules) {
|
if (styleSheet.cssRules) {
|
||||||
|
var baseUrl = null;
|
||||||
|
if (styleSheet.href) {
|
||||||
|
var scheme = getUrlScheme(styleSheet.href);
|
||||||
|
// We only translate local resources.
|
||||||
|
if (scheme == 'file' || scheme == 'qrc') {
|
||||||
|
baseUrl = styleSheet.href.substr(0, styleSheet.href.lastIndexOf('/'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var j = 0; j < styleSheet.cssRules.length; ++j) {
|
for (var j = 0; j < styleSheet.cssRules.length; ++j) {
|
||||||
styles = styles + styleSheet.cssRules[j].cssText + "\n";
|
var css = styleSheet.cssRules[j].cssText;
|
||||||
|
if (baseUrl) {
|
||||||
|
// Try to replace the url() with absolute path.
|
||||||
|
css = translateCssUrlToAbsolute(baseUrl, css);
|
||||||
|
}
|
||||||
|
|
||||||
|
styles = styles + css + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return styles;
|
return styles;
|
||||||
}
|
};
|
||||||
|
|
||||||
var htmlContent = function() {
|
var htmlContent = function() {
|
||||||
content.htmlContentCB("", styleContent(), placeholder.innerHTML);
|
content.htmlContentCB("", styleContent(), placeholder.innerHTML);
|
||||||
|
@ -74,17 +74,32 @@ QString VUtils::readFileFromDisk(const QString &filePath)
|
|||||||
return fileText;
|
return fileText;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VUtils::writeFileToDisk(const QString &filePath, const QString &text)
|
bool VUtils::writeFileToDisk(const QString &p_filePath, const QString &p_text)
|
||||||
{
|
{
|
||||||
QFile file(filePath);
|
QFile file(p_filePath);
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
qWarning() << "fail to open file" << filePath << "to write";
|
qWarning() << "fail to open file" << p_filePath << "to write";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
stream << text;
|
stream << p_text;
|
||||||
file.close();
|
file.close();
|
||||||
qDebug() << "write file content:" << filePath;
|
qDebug() << "write file content:" << p_filePath;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VUtils::writeFileToDisk(const QString &p_filePath, const QByteArray &p_data)
|
||||||
|
{
|
||||||
|
QFile file(p_filePath);
|
||||||
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
|
qWarning() << "fail to open file" << p_filePath << "to write";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.write(p_data);
|
||||||
|
file.close();
|
||||||
|
qDebug() << "write file content:" << p_filePath;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,9 @@ class VUtils
|
|||||||
public:
|
public:
|
||||||
static QString readFileFromDisk(const QString &filePath);
|
static QString readFileFromDisk(const QString &filePath);
|
||||||
|
|
||||||
static bool writeFileToDisk(const QString &filePath, const QString &text);
|
static bool writeFileToDisk(const QString &p_filePath, const QString &p_text);
|
||||||
|
|
||||||
|
static bool writeFileToDisk(const QString &p_filePath, const QByteArray &p_data);
|
||||||
|
|
||||||
static bool writeJsonToDisk(const QString &p_filePath, const QJsonObject &p_json);
|
static bool writeJsonToDisk(const QString &p_filePath, const QJsonObject &p_json);
|
||||||
|
|
||||||
|
@ -3,9 +3,13 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
#include "vpalette.h"
|
#include "vpalette.h"
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
|
#include "utils/vutils.h"
|
||||||
|
#include "vdownloader.h"
|
||||||
|
|
||||||
extern VPalette *g_palette;
|
extern VPalette *g_palette;
|
||||||
|
|
||||||
@ -891,3 +895,32 @@ bool VWebUtils::fixXHtmlTags(QString &p_html)
|
|||||||
|
|
||||||
return altered;
|
return altered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString VWebUtils::copyResource(const QUrl &p_url, const QString &p_folder) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(!p_url.isRelative());
|
||||||
|
|
||||||
|
QDir dir(p_folder);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
VUtils::makePath(p_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString file = p_url.isLocalFile() ? p_url.toLocalFile() : p_url.toString();
|
||||||
|
QString fileName = VUtils::fileNameFromPath(file);
|
||||||
|
fileName = VUtils::getFileNameWithSequence(p_folder, fileName, true);
|
||||||
|
QString targetFile = dir.absoluteFilePath(fileName);
|
||||||
|
|
||||||
|
bool succ = false;
|
||||||
|
if (p_url.scheme() == "https" || p_url.scheme() == "http") {
|
||||||
|
// Download it.
|
||||||
|
QByteArray data = VDownloader::downloadSync(p_url);
|
||||||
|
if (!data.isEmpty()) {
|
||||||
|
succ = VUtils::writeFileToDisk(targetFile, data);
|
||||||
|
}
|
||||||
|
} else if (QFileInfo::exists(file)) {
|
||||||
|
// Do a copy.
|
||||||
|
succ = VUtils::copyFile(file, targetFile, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return succ ? targetFile : QString();
|
||||||
|
}
|
||||||
|
@ -21,6 +21,10 @@ public:
|
|||||||
// Returns true if @p_html is modified.
|
// Returns true if @p_html is modified.
|
||||||
bool alterHtmlAsTarget(const QUrl &p_baseUrl, QString &p_html, const QString &p_target) const;
|
bool alterHtmlAsTarget(const QUrl &p_baseUrl, QString &p_html, const QString &p_target) const;
|
||||||
|
|
||||||
|
// Download or copy @p_url to @p_folder.
|
||||||
|
// Return the target file path on success or empty string on failure.
|
||||||
|
QString copyResource(const QUrl &p_url, const QString &p_folder) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CopyTargetAction
|
struct CopyTargetAction
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "vdownloader.h"
|
#include "vdownloader.h"
|
||||||
|
|
||||||
|
#include "utils/vutils.h"
|
||||||
|
|
||||||
VDownloader::VDownloader(QObject *parent)
|
VDownloader::VDownloader(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
@ -11,7 +13,6 @@ void VDownloader::handleDownloadFinished(QNetworkReply *reply)
|
|||||||
{
|
{
|
||||||
data = reply->readAll();
|
data = reply->readAll();
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
qDebug() << "VDownloader receive" << reply->url().toString();
|
|
||||||
emit downloadFinished(data, reply->url().toString());
|
emit downloadFinished(data, reply->url().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,5 +24,29 @@ void VDownloader::download(const QUrl &p_url)
|
|||||||
|
|
||||||
QNetworkRequest request(p_url);
|
QNetworkRequest request(p_url);
|
||||||
webCtrl.get(request);
|
webCtrl.get(request);
|
||||||
qDebug() << "VDownloader get" << p_url.toString();
|
}
|
||||||
|
|
||||||
|
QByteArray VDownloader::downloadSync(const QUrl &p_url)
|
||||||
|
{
|
||||||
|
QByteArray data;
|
||||||
|
if (!p_url.isValid()) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool finished = false;
|
||||||
|
QNetworkAccessManager nam;
|
||||||
|
connect(&nam, &QNetworkAccessManager::finished,
|
||||||
|
[&data, &finished](QNetworkReply *p_reply) {
|
||||||
|
data = p_reply->readAll();
|
||||||
|
p_reply->deleteLater();
|
||||||
|
finished = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
nam.get(QNetworkRequest(p_url));
|
||||||
|
|
||||||
|
while (!finished) {
|
||||||
|
VUtils::sleepWait(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ public:
|
|||||||
explicit VDownloader(QObject *parent = 0);
|
explicit VDownloader(QObject *parent = 0);
|
||||||
void download(const QUrl &p_url);
|
void download(const QUrl &p_url);
|
||||||
|
|
||||||
|
static QByteArray downloadSync(const QUrl &p_url);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void downloadFinished(const QByteArray &data, const QString &url);
|
void downloadFinished(const QByteArray &data, const QString &url);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QWebChannel>
|
#include <QWebChannel>
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
#include "vconfigmanager.h"
|
#include "vconfigmanager.h"
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
@ -12,9 +13,12 @@
|
|||||||
#include "vconstants.h"
|
#include "vconstants.h"
|
||||||
#include "vmarkdownconverter.h"
|
#include "vmarkdownconverter.h"
|
||||||
#include "vdocument.h"
|
#include "vdocument.h"
|
||||||
|
#include "utils/vwebutils.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
|
extern VWebUtils *g_webUtils;
|
||||||
|
|
||||||
VExporter::VExporter(QWidget *p_parent)
|
VExporter::VExporter(QWidget *p_parent)
|
||||||
: QObject(p_parent),
|
: QObject(p_parent),
|
||||||
m_webViewer(NULL),
|
m_webViewer(NULL),
|
||||||
@ -82,7 +86,8 @@ void VExporter::initWebViewer(VFile *p_file, const ExportOption &p_opt)
|
|||||||
m_webDocument->setHtml(html);
|
m_webDocument->setHtml(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_webViewer->setHtml(m_htmlTemplate, p_file->getBaseUrl());
|
m_baseUrl = p_file->getBaseUrl();
|
||||||
|
m_webViewer->setHtml(m_htmlTemplate, m_baseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VExporter::handleLogicsFinished()
|
void VExporter::handleLogicsFinished()
|
||||||
@ -107,6 +112,7 @@ void VExporter::clearWebViewer()
|
|||||||
delete m_webViewer;
|
delete m_webViewer;
|
||||||
m_webViewer = NULL;
|
m_webViewer = NULL;
|
||||||
m_webDocument = NULL;
|
m_webDocument = NULL;
|
||||||
|
m_baseUrl.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VExporter::exportToPDF(VWebView *p_webViewer,
|
bool VExporter::exportToPDF(VWebView *p_webViewer,
|
||||||
@ -122,16 +128,11 @@ bool VExporter::exportToPDF(VWebView *p_webViewer,
|
|||||||
|
|
||||||
V_ASSERT(!p_filePath.isEmpty());
|
V_ASSERT(!p_filePath.isEmpty());
|
||||||
|
|
||||||
QFile file(p_filePath);
|
if (!VUtils::writeFileToDisk(p_filePath, p_result)) {
|
||||||
|
|
||||||
if (!file.open(QFile::WriteOnly)) {
|
|
||||||
pdfPrinted = -1;
|
pdfPrinted = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file.write(p_result.data(), p_result.size());
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
pdfPrinted = 1;
|
pdfPrinted = 1;
|
||||||
}, p_layout);
|
}, p_layout);
|
||||||
|
|
||||||
@ -201,6 +202,7 @@ bool VExporter::exportViaWebView(VFile *p_file,
|
|||||||
exportRet = exportToHTML(m_webViewer,
|
exportRet = exportToHTML(m_webViewer,
|
||||||
m_webDocument,
|
m_webDocument,
|
||||||
p_opt.m_embedCssStyle,
|
p_opt.m_embedCssStyle,
|
||||||
|
p_opt.m_completeHTML,
|
||||||
p_outputFile);
|
p_outputFile);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -237,6 +239,7 @@ exit:
|
|||||||
bool VExporter::exportToHTML(VWebView *p_webViewer,
|
bool VExporter::exportToHTML(VWebView *p_webViewer,
|
||||||
VDocument *p_webDocument,
|
VDocument *p_webDocument,
|
||||||
bool p_embedCssStyle,
|
bool p_embedCssStyle,
|
||||||
|
bool p_completeHTML,
|
||||||
const QString &p_filePath)
|
const QString &p_filePath)
|
||||||
{
|
{
|
||||||
Q_UNUSED(p_webViewer);
|
Q_UNUSED(p_webViewer);
|
||||||
@ -260,20 +263,40 @@ bool VExporter::exportToHTML(VWebView *p_webViewer,
|
|||||||
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);
|
QString html(m_exportHtmlTemplate);
|
||||||
if (!p_styleContent.isEmpty() && p_embedCssStyle) {
|
if (!p_styleContent.isEmpty() && p_embedCssStyle) {
|
||||||
html.replace(HtmlHolder::c_styleHolder, p_styleContent);
|
QString content(p_styleContent);
|
||||||
|
fixStyleResources(resFolderPath, content);
|
||||||
|
html.replace(HtmlHolder::c_styleHolder, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p_headContent.isEmpty()) {
|
if (!p_headContent.isEmpty()) {
|
||||||
html.replace(HtmlHolder::c_headHolder, p_headContent);
|
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);
|
html.replace(HtmlHolder::c_bodyHolder, p_bodyContent);
|
||||||
|
}
|
||||||
|
|
||||||
file.write(html.toUtf8());
|
file.write(html.toUtf8());
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
// Delete empty resource folder.
|
||||||
|
QDir dir(resFolderPath);
|
||||||
|
if (dir.isEmpty()) {
|
||||||
|
dir.cdUp();
|
||||||
|
dir.rmdir(resFolder);
|
||||||
|
}
|
||||||
|
|
||||||
htmlExported = 1;
|
htmlExported = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -289,3 +312,80 @@ bool VExporter::exportToHTML(VWebView *p_webViewer,
|
|||||||
|
|
||||||
return htmlExported == 1;
|
return htmlExported == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VExporter::fixStyleResources(const QString &p_folder,
|
||||||
|
QString &p_html)
|
||||||
|
{
|
||||||
|
bool altered = false;
|
||||||
|
QRegExp reg("\\burl\\(\"((file|qrc):[^\"\\)]+)\"\\);");
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
while (pos < p_html.size()) {
|
||||||
|
int idx = p_html.indexOf(reg, pos);
|
||||||
|
if (idx == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString targetFile = g_webUtils->copyResource(QUrl(reg.cap(1)), p_folder);
|
||||||
|
if (targetFile.isEmpty()) {
|
||||||
|
pos = idx + reg.matchedLength();
|
||||||
|
} else {
|
||||||
|
// Replace the url string in html.
|
||||||
|
QString newUrl = QString("url(\"%1\");").arg(getResourceRelativePath(targetFile));
|
||||||
|
p_html.replace(idx, reg.matchedLength(), newUrl);
|
||||||
|
pos = idx + newUrl.size();
|
||||||
|
altered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return altered;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VExporter::fixBodyResources(const QUrl &p_baseUrl,
|
||||||
|
const QString &p_folder,
|
||||||
|
QString &p_html)
|
||||||
|
{
|
||||||
|
bool altered = false;
|
||||||
|
if (p_baseUrl.isEmpty()) {
|
||||||
|
return altered;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegExp reg("<img ([^>]*)src=\"([^\"]+)\"([^>]*)>");
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
while (pos < p_html.size()) {
|
||||||
|
int idx = p_html.indexOf(reg, pos);
|
||||||
|
if (idx == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg.cap(2).isEmpty()) {
|
||||||
|
pos = idx + reg.matchedLength();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl srcUrl(p_baseUrl.resolved(reg.cap(2)));
|
||||||
|
QString targetFile = g_webUtils->copyResource(srcUrl, p_folder);
|
||||||
|
if (targetFile.isEmpty()) {
|
||||||
|
pos = idx + reg.matchedLength();
|
||||||
|
} else {
|
||||||
|
// Replace the url string in html.
|
||||||
|
QString newUrl = QString("<img %1src=\"%2\"%3>").arg(reg.cap(1))
|
||||||
|
.arg(getResourceRelativePath(targetFile))
|
||||||
|
.arg(reg.cap(3));
|
||||||
|
p_html.replace(idx, reg.matchedLength(), newUrl);
|
||||||
|
pos = idx + newUrl.size();
|
||||||
|
altered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return altered;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VExporter::getResourceRelativePath(const QString &p_file)
|
||||||
|
{
|
||||||
|
int idx = p_file.lastIndexOf('/');
|
||||||
|
int idx2 = p_file.lastIndexOf('/', idx - 1);
|
||||||
|
Q_ASSERT(idx > 0 && idx2 < idx);
|
||||||
|
return "." + p_file.mid(idx2);
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPageLayout>
|
#include <QPageLayout>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
#include "dialog/vexportdialog.h"
|
#include "dialog/vexportdialog.h"
|
||||||
|
|
||||||
@ -75,8 +76,22 @@ private:
|
|||||||
bool exportToHTML(VWebView *p_webViewer,
|
bool exportToHTML(VWebView *p_webViewer,
|
||||||
VDocument *p_webDocument,
|
VDocument *p_webDocument,
|
||||||
bool p_embedCssStyle,
|
bool p_embedCssStyle,
|
||||||
|
bool p_completeHTML,
|
||||||
const QString &p_filePath);
|
const QString &p_filePath);
|
||||||
|
|
||||||
|
// Fix @p_html's resources like url("...") with "file" or "qrc" schema.
|
||||||
|
// Copy the resource to @p_folder and fix the url string.
|
||||||
|
static bool fixStyleResources(const QString &p_folder,
|
||||||
|
QString &p_html);
|
||||||
|
|
||||||
|
// Fix @p_html's resources like <img>.
|
||||||
|
// Copy the resource to @p_folder and fix the url string.
|
||||||
|
static bool fixBodyResources(const QUrl &p_baseUrl,
|
||||||
|
const QString &p_folder,
|
||||||
|
QString &p_html);
|
||||||
|
|
||||||
|
static QString getResourceRelativePath(const QString &p_file);
|
||||||
|
|
||||||
QPageLayout m_pageLayout;
|
QPageLayout m_pageLayout;
|
||||||
|
|
||||||
// Will be allocated and free for each conversion.
|
// Will be allocated and free for each conversion.
|
||||||
@ -84,6 +99,9 @@ private:
|
|||||||
|
|
||||||
VDocument *m_webDocument;
|
VDocument *m_webDocument;
|
||||||
|
|
||||||
|
// Base URL of VWebView.
|
||||||
|
QUrl m_baseUrl;
|
||||||
|
|
||||||
QString m_htmlTemplate;
|
QString m_htmlTemplate;
|
||||||
|
|
||||||
// Template to hold the export HTML result.
|
// Template to hold the export HTML result.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user