preview: add cache for code block in-place preview

This commit is contained in:
Le Tan 2018-05-15 20:12:29 +08:00
parent f2afe4b4e2
commit 4284d20dea
4 changed files with 181 additions and 200 deletions

View File

@ -1,6 +1,5 @@
#include "vlivepreviewhelper.h" #include "vlivepreviewhelper.h"
#include <QDebug>
#include <QByteArray> #include <QByteArray>
#include "veditor.h" #include "veditor.h"
@ -30,8 +29,6 @@ extern VMainWindow *g_mainWin;
#define INDEX_MASK 0x00ffffffUL #define INDEX_MASK 0x00ffffffUL
#define SCALE_FACTOR_THRESHOLD 1.1
CodeBlockPreviewInfo::CodeBlockPreviewInfo() CodeBlockPreviewInfo::CodeBlockPreviewInfo()
{ {
} }
@ -41,33 +38,12 @@ CodeBlockPreviewInfo::CodeBlockPreviewInfo(const VCodeBlock &p_cb)
{ {
} }
void CodeBlockPreviewInfo::updateNonContent(const QTextDocument *p_doc,
const VCodeBlock &p_cb)
{
m_codeBlock.updateNonContent(p_cb);
if (m_inplacePreview.isNull()) {
return;
}
QTextBlock block = p_doc->findBlockByNumber(m_codeBlock.m_endBlock);
if (block.isValid()) {
m_inplacePreview->m_startPos = block.position();
m_inplacePreview->m_endPos = block.position() + block.length();
m_inplacePreview->m_blockPos = block.position();
m_inplacePreview->m_blockNumber = m_codeBlock.m_endBlock;
// Padding is not changed since content is not changed.
} else {
m_inplacePreview.clear();
}
}
void CodeBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor, void CodeBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor,
const QTextDocument *p_doc, const QTextDocument *p_doc,
qreal p_scaleFactor) const QPixmap &p_image)
{ {
QTextBlock block = p_doc->findBlockByNumber(m_codeBlock.m_endBlock); QTextBlock block = p_doc->findBlockByNumber(m_codeBlock.m_endBlock);
if (block.isValid()) { if (block.isValid()) {
Qt::TransformationMode tMode = Qt::SmoothTransformation;
VImageToPreview *preview = new VImageToPreview(); VImageToPreview *preview = new VImageToPreview();
preview->m_startPos = block.position(); preview->m_startPos = block.position();
@ -79,29 +55,7 @@ void CodeBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor,
preview->m_name = QString::number(getImageIndex()); preview->m_name = QString::number(getImageIndex());
preview->m_isBlock = true; preview->m_isBlock = true;
if (hasImageData()) { preview->m_image = p_image;
if (p_scaleFactor < SCALE_FACTOR_THRESHOLD) {
preview->m_image.loadFromData(m_imgData.toUtf8(),
m_imgFormat.toLocal8Bit().data());
} else {
QPixmap tmpImg;
tmpImg.loadFromData(m_imgData.toUtf8(),
m_imgFormat.toLocal8Bit().data());
preview->m_image = tmpImg.scaledToWidth(tmpImg.width() * p_scaleFactor, tMode);
}
} else if (hasImageDataBa()) {
if (p_scaleFactor < SCALE_FACTOR_THRESHOLD) {
preview->m_image.loadFromData(m_imgDataBa,
m_imgFormat.toLocal8Bit().data());
} else {
QPixmap tmpImg;
tmpImg.loadFromData(m_imgDataBa,
m_imgFormat.toLocal8Bit().data());
preview->m_image = tmpImg.scaledToWidth(tmpImg.width() * p_scaleFactor, tMode);
}
} else {
preview->m_image = QPixmap();
}
m_inplacePreview.reset(preview); m_inplacePreview.reset(preview);
} else { } else {
@ -110,6 +64,9 @@ void CodeBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor,
} }
#define CODE_BLOCK_IMAGE_CACHE_SIZE_DIFF 10
#define CODE_BLOCK_IMAGE_CACHE_TIME_DIFF 5
VLivePreviewHelper::VLivePreviewHelper(VEditor *p_editor, VLivePreviewHelper::VLivePreviewHelper(VEditor *p_editor,
VDocument *p_document, VDocument *p_document,
QObject *p_parent) QObject *p_parent)
@ -144,13 +101,26 @@ VLivePreviewHelper::VLivePreviewHelper(VEditor *p_editor,
this, &VLivePreviewHelper::mathjaxPreviewResultReady); this, &VLivePreviewHelper::mathjaxPreviewResultReady);
} }
bool VLivePreviewHelper::isPreviewLang(const QString &p_lang) const void VLivePreviewHelper::checkLang(const QString &p_lang,
bool &p_livePreview,
bool &p_inplacePreview) const
{ {
return (m_flowchartEnabled && (p_lang == "flow" || p_lang == "flowchart")) if (m_flowchartEnabled && (p_lang == "flow" || p_lang == "flowchart")) {
|| (m_mermaidEnabled && p_lang == "mermaid") p_livePreview = p_inplacePreview = true;
|| (m_plantUMLMode != PlantUMLMode::DisablePlantUML && p_lang == "puml") } else if (m_plantUMLMode != PlantUMLMode::DisablePlantUML && p_lang == "puml") {
|| (m_graphvizEnabled && p_lang == "dot") p_livePreview = true;
|| (m_mathjaxEnabled && p_lang == "mathjax"); p_inplacePreview = m_plantUMLMode == PlantUMLMode::LocalPlantUML;
} else if (m_graphvizEnabled && p_lang == "dot") {
p_livePreview = p_inplacePreview = true;
} else if (m_mermaidEnabled && p_lang == "mermaid") {
p_livePreview = true;
p_inplacePreview = false;
} else if (m_mathjaxEnabled && p_lang == "mathjax") {
p_livePreview = false;
p_inplacePreview = true;
} else {
p_livePreview = p_inplacePreview = false;
}
} }
void VLivePreviewHelper::updateCodeBlocks(const QVector<VCodeBlock> &p_codeBlocks) void VLivePreviewHelper::updateCodeBlocks(const QVector<VCodeBlock> &p_codeBlocks)
@ -164,34 +134,42 @@ void VLivePreviewHelper::updateCodeBlocks(const QVector<VCodeBlock> &p_codeBlock
int lastIndex = m_cbIndex; int lastIndex = m_cbIndex;
m_cbIndex = -1; m_cbIndex = -1;
int cursorBlock = m_editor->textCursorW().block().blockNumber(); int cursorBlock = m_editor->textCursorW().block().blockNumber();
int idx = 0;
bool needUpdate = m_livePreviewEnabled; bool needUpdate = m_livePreviewEnabled;
bool manualInplacePreview = m_inplacePreviewEnabled; bool manualInplacePreview = m_inplacePreviewEnabled;
for (auto const & vcb : p_codeBlocks) { m_codeBlocks.clear();
if (!isPreviewLang(vcb.m_lang)) {
for (int i = 0; i < p_codeBlocks.size(); ++i) {
const VCodeBlock &vcb = p_codeBlocks[i];
bool livePreview = false, inplacePreview = false;
checkLang(vcb.m_lang, livePreview, inplacePreview);
if (!livePreview && !inplacePreview) {
continue; continue;
} }
const QString &text = vcb.m_text;
bool cached = false; bool cached = false;
if (idx < m_codeBlocks.size()) {
CodeBlockPreviewInfo &cb = m_codeBlocks[idx];
if (cb.codeBlock().equalContent(vcb)) {
cb.updateNonContent(m_doc, vcb);
cached = true;
} else {
cb.setCodeBlock(vcb);
}
} else {
m_codeBlocks.append(CodeBlockPreviewInfo(vcb)); m_codeBlocks.append(CodeBlockPreviewInfo(vcb));
int idx = m_codeBlocks.size() - 1;
auto it = m_cache.find(text);
if (it != m_cache.end()) {
QSharedPointer<CodeBlockImageCacheEntry> &entry = it.value();
entry->m_ts = m_timeStamp;
cached = true;
m_codeBlocks[idx].setImageData(entry->m_imgFormat, entry->m_imgData);
m_codeBlocks[idx].updateInplacePreview(m_editor, m_doc, entry->m_image);
} }
if (m_inplacePreviewEnabled if (m_inplacePreviewEnabled
&& inplacePreview
&& (!cached || !m_codeBlocks[idx].inplacePreviewReady())) { && (!cached || !m_codeBlocks[idx].inplacePreviewReady())) {
processForInplacePreview(idx);
manualInplacePreview = false; manualInplacePreview = false;
processForInplacePreview(idx);
} }
if (m_livePreviewEnabled if (m_livePreviewEnabled
&& livePreview
&& vcb.m_startBlock <= cursorBlock && vcb.m_startBlock <= cursorBlock
&& vcb.m_endBlock >= cursorBlock) { && vcb.m_endBlock >= cursorBlock) {
if (lastIndex == idx && cached) { if (lastIndex == idx && cached) {
@ -200,14 +178,6 @@ void VLivePreviewHelper::updateCodeBlocks(const QVector<VCodeBlock> &p_codeBlock
m_cbIndex = idx; m_cbIndex = idx;
} }
++idx;
}
if (idx == m_codeBlocks.size()) {
manualInplacePreview = false;
} else {
m_codeBlocks.resize(idx);
} }
if (manualInplacePreview) { if (manualInplacePreview) {
@ -217,6 +187,8 @@ void VLivePreviewHelper::updateCodeBlocks(const QVector<VCodeBlock> &p_codeBlock
if (needUpdate) { if (needUpdate) {
updateLivePreview(); updateLivePreview();
} }
clearObsoleteCache();
} }
void VLivePreviewHelper::handleCursorPositionChanged() void VLivePreviewHelper::handleCursorPositionChanged()
@ -319,6 +291,7 @@ void VLivePreviewHelper::setLivePreviewEnabled(bool p_enabled)
if (!m_inplacePreviewEnabled) { if (!m_inplacePreviewEnabled) {
m_codeBlocks.clear(); m_codeBlocks.clear();
m_cache.clear();
updateInplacePreview(); updateInplacePreview();
} }
} }
@ -333,6 +306,7 @@ void VLivePreviewHelper::setInplacePreviewEnabled(bool p_enabled)
m_inplacePreviewEnabled = p_enabled; m_inplacePreviewEnabled = p_enabled;
if (!m_inplacePreviewEnabled && !m_livePreviewEnabled) { if (!m_inplacePreviewEnabled && !m_livePreviewEnabled) {
m_codeBlocks.clear(); m_codeBlocks.clear();
m_cache.clear();
} }
updateInplacePreview(); updateInplacePreview();
@ -371,7 +345,17 @@ void VLivePreviewHelper::localAsyncResultReady(int p_id,
} }
CodeBlockPreviewInfo &cb = m_codeBlocks[idx]; CodeBlockPreviewInfo &cb = m_codeBlocks[idx];
const QString &text = cb.codeBlock().m_text;
QSharedPointer<CodeBlockImageCacheEntry> entry(new CodeBlockImageCacheEntry(p_timeStamp,
p_format,
p_result,
getScaleFactor(cb)));
m_cache.insert(text, entry);
cb.setImageData(p_format, p_result); cb.setImageData(p_format, p_result);
cb.updateInplacePreview(m_editor, m_doc, entry->m_image);
if (livePreview) { if (livePreview) {
if (idx != m_cbIndex) { if (idx != m_cbIndex) {
return; return;
@ -380,8 +364,6 @@ void VLivePreviewHelper::localAsyncResultReady(int p_id,
m_document->setPreviewContent(lang, p_result); m_document->setPreviewContent(lang, p_result);
} else { } else {
// Inplace preview. // Inplace preview.
cb.updateInplacePreview(m_editor, m_doc, getScaleFactor(cb));
updateInplacePreview(); updateInplacePreview();
} }
} }
@ -390,7 +372,7 @@ void VLivePreviewHelper::processForInplacePreview(int p_idx)
{ {
CodeBlockPreviewInfo &cb = m_codeBlocks[p_idx]; CodeBlockPreviewInfo &cb = m_codeBlocks[p_idx];
const VCodeBlock &vcb = cb.codeBlock(); const VCodeBlock &vcb = cb.codeBlock();
Q_ASSERT(!(cb.hasImageData() || cb.hasImageDataBa())); Q_ASSERT(!cb.hasImageData());
if (vcb.m_lang == "dot") { if (vcb.m_lang == "dot") {
if (!m_graphvizHelper) { if (!m_graphvizHelper) {
m_graphvizHelper = new VGraphvizHelper(this); m_graphvizHelper = new VGraphvizHelper(this);
@ -474,7 +456,31 @@ void VLivePreviewHelper::mathjaxPreviewResultReady(int p_identitifer,
} }
CodeBlockPreviewInfo &cb = m_codeBlocks[p_id]; CodeBlockPreviewInfo &cb = m_codeBlocks[p_id];
cb.setImageDataBa(p_format, p_data); const QString &text = cb.codeBlock().m_text;
cb.updateInplacePreview(m_editor, m_doc, getScaleFactor(cb));
QSharedPointer<CodeBlockImageCacheEntry> entry(new CodeBlockImageCacheEntry(p_timeStamp,
p_format,
p_data,
getScaleFactor(cb)));
m_cache.insert(text, entry);
cb.updateInplacePreview(m_editor, m_doc, entry->m_image);
updateInplacePreview(); updateInplacePreview();
} }
void VLivePreviewHelper::clearObsoleteCache()
{
if (m_cache.size() - m_codeBlocks.size() <= CODE_BLOCK_IMAGE_CACHE_SIZE_DIFF) {
return;
}
for (auto it = m_cache.begin(); it != m_cache.end();) {
if (m_timeStamp - it.value()->m_ts > CODE_BLOCK_IMAGE_CACHE_TIME_DIFF) {
it.value().clear();
it = m_cache.erase(it);
} else {
++it;
}
}
}

View File

@ -21,19 +21,9 @@ public:
explicit CodeBlockPreviewInfo(const VCodeBlock &p_cb); explicit CodeBlockPreviewInfo(const VCodeBlock &p_cb);
void clearImageData()
{
m_imgData.clear();
m_imgDataBa.clear();
m_inplacePreview.clear();
}
void updateNonContent(const QTextDocument *p_doc,
const VCodeBlock &p_cb);
void updateInplacePreview(const VEditor *p_editor, void updateInplacePreview(const VEditor *p_editor,
const QTextDocument *p_doc, const QTextDocument *p_doc,
qreal p_scaleFactor); const QPixmap &p_image);
VCodeBlock &codeBlock() VCodeBlock &codeBlock()
{ {
@ -45,13 +35,6 @@ public:
return m_codeBlock; return m_codeBlock;
} }
void setCodeBlock(const VCodeBlock &p_cb)
{
m_codeBlock = p_cb;
clearImageData();
}
bool inplacePreviewReady() const bool inplacePreviewReady() const
{ {
return !m_inplacePreview.isNull(); return !m_inplacePreview.isNull();
@ -67,16 +50,6 @@ public:
return m_imgData; return m_imgData;
} }
bool hasImageDataBa() const
{
return !m_imgDataBa.isEmpty();
}
const QByteArray &imageDataBa() const
{
return m_imgDataBa;
}
const QString &imageFormat() const const QString &imageFormat() const
{ {
return m_imgFormat; return m_imgFormat;
@ -84,22 +57,10 @@ public:
void setImageData(const QString &p_format, const QString &p_data) void setImageData(const QString &p_format, const QString &p_data)
{ {
m_imgDataBa.clear();
m_inplacePreview.clear();
m_imgFormat = p_format; m_imgFormat = p_format;
m_imgData = p_data; m_imgData = p_data;
} }
void setImageDataBa(const QString &p_format, const QByteArray &p_data)
{
m_imgData.clear();
m_inplacePreview.clear();
m_imgFormat = p_format;
m_imgDataBa = p_data;
}
const QSharedPointer<VImageToPreview> inplacePreview() const const QSharedPointer<VImageToPreview> inplacePreview() const
{ {
return m_inplacePreview; return m_inplacePreview;
@ -116,8 +77,6 @@ private:
QString m_imgData; QString m_imgData;
QByteArray m_imgDataBa;
QString m_imgFormat; QString m_imgFormat;
QSharedPointer<VImageToPreview> m_inplacePreview; QSharedPointer<VImageToPreview> m_inplacePreview;
@ -161,7 +120,79 @@ private slots:
const QByteArray &p_data); const QByteArray &p_data);
private: private:
bool isPreviewLang(const QString &p_lang) const; struct CodeBlockImageCacheEntry
{
#define SCALE_FACTOR_THRESHOLD 1.1
CodeBlockImageCacheEntry()
: m_ts(0)
{
}
CodeBlockImageCacheEntry(TimeStamp p_ts,
const QString &p_format,
const QByteArray &p_data,
qreal p_scaleFactor)
: m_ts(p_ts)
{
if (!p_data.isEmpty()) {
if (p_scaleFactor < SCALE_FACTOR_THRESHOLD) {
m_image.loadFromData(p_data,
p_format.toLocal8Bit().data());
} else {
QPixmap tmpImg;
tmpImg.loadFromData(p_data,
p_format.toLocal8Bit().data());
m_image = tmpImg.scaledToWidth(tmpImg.width() * p_scaleFactor,
Qt::SmoothTransformation);
}
}
}
CodeBlockImageCacheEntry(TimeStamp p_ts,
const QString &p_format,
const QString &p_data,
qreal p_scaleFactor)
: m_ts(p_ts),
m_imgData(p_data),
m_imgFormat(p_format)
{
if (!p_data.isEmpty()) {
if (p_scaleFactor < SCALE_FACTOR_THRESHOLD) {
m_image.loadFromData(p_data.toUtf8(),
p_format.toLocal8Bit().data());
} else {
QPixmap tmpImg;
tmpImg.loadFromData(p_data.toUtf8(),
p_format.toLocal8Bit().data());
m_image = tmpImg.scaledToWidth(tmpImg.width() * p_scaleFactor,
Qt::SmoothTransformation);
}
}
}
bool hasImageData() const
{
return !m_imgData.isEmpty();
}
bool hasImage() const
{
return !m_image.isNull();
}
TimeStamp m_ts;
// For live preview.
QString m_imgData;
QString m_imgFormat;
// For in-place preview.
QPixmap m_image;
};
void checkLang(const QString &p_lang, bool &p_livePreview, bool &p_inplacePreview) const;
// Get image data for this code block for inplace preview. // Get image data for this code block for inplace preview.
void processForInplacePreview(int p_idx); void processForInplacePreview(int p_idx);
@ -171,6 +202,8 @@ private:
qreal getScaleFactor(const CodeBlockPreviewInfo &p_cb); qreal getScaleFactor(const CodeBlockPreviewInfo &p_cb);
void clearObsoleteCache();
// Sorted by m_startBlock in ascending order. // Sorted by m_startBlock in ascending order.
QVector<CodeBlockPreviewInfo> m_codeBlocks; QVector<CodeBlockPreviewInfo> m_codeBlocks;
@ -206,6 +239,9 @@ private:
TimeStamp m_timeStamp; TimeStamp m_timeStamp;
const qreal m_scaleFactor; const qreal m_scaleFactor;
// Indexed by content.
QHash<QString, QSharedPointer<CodeBlockImageCacheEntry>> m_cache;
}; };
inline bool VLivePreviewHelper::isPreviewEnabled() const inline bool VLivePreviewHelper::isPreviewEnabled() const

View File

@ -19,32 +19,9 @@ MathjaxBlockPreviewInfo::MathjaxBlockPreviewInfo(const VMathjaxBlock &p_mb)
{ {
} }
void MathjaxBlockPreviewInfo::updateNonContent(const QTextDocument *p_doc,
const VEditor *p_editor,
const VMathjaxBlock &p_mb)
{
m_mathjaxBlock.updateNonContent(p_mb);
if (m_inplacePreview.isNull()) {
return;
}
QTextBlock block = p_doc->findBlockByNumber(m_mathjaxBlock.m_blockNumber);
if (block.isValid()) {
m_inplacePreview->m_startPos = block.position() + m_mathjaxBlock.m_index;
m_inplacePreview->m_endPos = m_inplacePreview->m_startPos + m_mathjaxBlock.m_length;
m_inplacePreview->m_blockPos = block.position();
m_inplacePreview->m_blockNumber = m_mathjaxBlock.m_blockNumber;
// Padding may changed.
m_inplacePreview->m_padding = VPreviewManager::calculateBlockMargin(block,
p_editor->tabStopWidthW());
m_inplacePreview->m_isBlock = m_mathjaxBlock.m_previewedAsBlock;
} else {
m_inplacePreview.clear();
}
}
void MathjaxBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor, void MathjaxBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor,
const QTextDocument *p_doc) const QTextDocument *p_doc,
const QPixmap &p_image)
{ {
QTextBlock block = p_doc->findBlockByNumber(m_mathjaxBlock.m_blockNumber); QTextBlock block = p_doc->findBlockByNumber(m_mathjaxBlock.m_blockNumber);
if (block.isValid()) { if (block.isValid()) {
@ -59,12 +36,7 @@ void MathjaxBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor,
preview->m_name = QString::number(getImageIndex()); preview->m_name = QString::number(getImageIndex());
preview->m_isBlock = m_mathjaxBlock.m_previewedAsBlock; preview->m_isBlock = m_mathjaxBlock.m_previewedAsBlock;
if (hasImageDataBa()) { preview->m_image = p_image;
preview->m_image.loadFromData(m_imgDataBa,
m_imgFormat.toLocal8Bit().data());
} else {
preview->m_image = QPixmap();
}
m_inplacePreview.reset(preview); m_inplacePreview.reset(preview);
} else { } else {
@ -133,13 +105,12 @@ void VMathJaxInplacePreviewHelper::updateMathjaxBlocks(const QVector<VMathjaxBlo
QSharedPointer<MathjaxImageCacheEntry> &entry = it.value(); QSharedPointer<MathjaxImageCacheEntry> &entry = it.value();
entry->m_ts = m_timeStamp; entry->m_ts = m_timeStamp;
cached = true; cached = true;
m_mathjaxBlocks[i].setImageDataBa(entry->m_imgFormat, entry->m_imgDataBa); m_mathjaxBlocks.last().updateInplacePreview(m_editor, m_doc, entry->m_image);
m_mathjaxBlocks[i].updateInplacePreview(m_editor, m_doc);
} }
if (!cached || !m_mathjaxBlocks[i].inplacePreviewReady()) { if (!cached || !m_mathjaxBlocks.last().inplacePreviewReady()) {
manualUpdate = false; manualUpdate = false;
processForInplacePreview(i); processForInplacePreview(m_mathjaxBlocks.size() - 1);
} }
} }
@ -222,14 +193,12 @@ void VMathJaxInplacePreviewHelper::mathjaxPreviewResultReady(int p_identitifer,
} }
MathjaxBlockPreviewInfo &mb = m_mathjaxBlocks[p_id]; MathjaxBlockPreviewInfo &mb = m_mathjaxBlocks[p_id];
mb.setImageDataBa(p_format, p_data);
mb.updateInplacePreview(m_editor, m_doc);
// Update the cache. // Update the cache.
QSharedPointer<MathjaxImageCacheEntry> entry(new MathjaxImageCacheEntry(p_timeStamp, QSharedPointer<MathjaxImageCacheEntry> entry(new MathjaxImageCacheEntry(p_timeStamp,
p_data, p_data,
p_format)); p_format));
m_cache.insert(mb.mathjaxBlock().m_text, entry); m_cache.insert(mb.mathjaxBlock().m_text, entry);
mb.updateInplacePreview(m_editor, m_doc, entry->m_image);
updateInplacePreview(); updateInplacePreview();
} }

View File

@ -19,17 +19,9 @@ public:
explicit MathjaxBlockPreviewInfo(const VMathjaxBlock &p_mb); explicit MathjaxBlockPreviewInfo(const VMathjaxBlock &p_mb);
void clearImageData() void updateInplacePreview(const VEditor *p_editor,
{ const QTextDocument *p_doc,
m_imgDataBa.clear(); const QPixmap &p_image);
m_inplacePreview.clear();
}
void updateNonContent(const QTextDocument *p_doc,
const VEditor *p_editor,
const VMathjaxBlock &p_mb);
void updateInplacePreview(const VEditor *p_editor, const QTextDocument *p_doc);
VMathjaxBlock &mathjaxBlock() VMathjaxBlock &mathjaxBlock()
{ {
@ -41,29 +33,11 @@ public:
return m_mathjaxBlock; return m_mathjaxBlock;
} }
void setMathjaxBlock(const VMathjaxBlock &p_mb)
{
m_mathjaxBlock = p_mb;
clearImageData();
}
bool inplacePreviewReady() const bool inplacePreviewReady() const
{ {
return !m_inplacePreview.isNull(); return !m_inplacePreview.isNull();
} }
void setImageDataBa(const QString &p_format, const QByteArray &p_data)
{
m_imgFormat = p_format;
m_imgDataBa = p_data;
m_inplacePreview.clear();
}
bool hasImageDataBa() const
{
return !m_imgDataBa.isEmpty();
}
const QSharedPointer<VImageToPreview> inplacePreview() const const QSharedPointer<VImageToPreview> inplacePreview() const
{ {
return m_inplacePreview; return m_inplacePreview;
@ -78,10 +52,6 @@ private:
VMathjaxBlock m_mathjaxBlock; VMathjaxBlock m_mathjaxBlock;
QByteArray m_imgDataBa;
QString m_imgFormat;
QSharedPointer<VImageToPreview> m_inplacePreview; QSharedPointer<VImageToPreview> m_inplacePreview;
}; };
@ -124,15 +94,15 @@ private:
MathjaxImageCacheEntry(TimeStamp p_ts, MathjaxImageCacheEntry(TimeStamp p_ts,
const QByteArray &p_dataBa, const QByteArray &p_dataBa,
const QString &p_format) const QString &p_format)
: m_ts(p_ts), : m_ts(p_ts)
m_imgDataBa(p_dataBa),
m_imgFormat(p_format)
{ {
if (!p_dataBa.isEmpty()) {
m_image.loadFromData(p_dataBa, p_format.toLocal8Bit().data());
}
} }
TimeStamp m_ts; TimeStamp m_ts;
QByteArray m_imgDataBa; QPixmap m_image;
QString m_imgFormat;
}; };