mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
optimize VImagePreviewer by flags
This commit is contained in:
parent
e55b0af00e
commit
07e8f27776
@ -80,7 +80,7 @@ HGMarkdownHighlighter::~HGMarkdownHighlighter()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HGMarkdownHighlighter::updateBlockUserData(const QString &p_text)
|
void HGMarkdownHighlighter::updateBlockUserData(int p_blockNum, const QString &p_text)
|
||||||
{
|
{
|
||||||
VTextBlockData *blockData = dynamic_cast<VTextBlockData *>(currentBlockUserData());
|
VTextBlockData *blockData = dynamic_cast<VTextBlockData *>(currentBlockUserData());
|
||||||
if (!blockData) {
|
if (!blockData) {
|
||||||
@ -88,7 +88,33 @@ void HGMarkdownHighlighter::updateBlockUserData(const QString &p_text)
|
|||||||
setCurrentBlockUserData(blockData);
|
setCurrentBlockUserData(blockData);
|
||||||
}
|
}
|
||||||
|
|
||||||
blockData->setContainsPreviewImage(p_text.contains(QChar::ObjectReplacementCharacter));
|
bool contains = p_text.contains(QChar::ObjectReplacementCharacter);
|
||||||
|
blockData->setContainsPreviewImage(contains);
|
||||||
|
|
||||||
|
auto curIt = m_potentialPreviewBlocks.find(p_blockNum);
|
||||||
|
if (curIt == m_potentialPreviewBlocks.end()) {
|
||||||
|
if (contains) {
|
||||||
|
m_potentialPreviewBlocks.insert(p_blockNum, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!contains) {
|
||||||
|
m_potentialPreviewBlocks.erase(curIt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete elements beyond current block count.
|
||||||
|
int blocks = document->blockCount();
|
||||||
|
if (!m_potentialPreviewBlocks.isEmpty()) {
|
||||||
|
auto it = m_potentialPreviewBlocks.end();
|
||||||
|
do {
|
||||||
|
--it;
|
||||||
|
if (it.key() >= blocks) {
|
||||||
|
it = m_potentialPreviewBlocks.erase(it);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (it != m_potentialPreviewBlocks.begin());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HGMarkdownHighlighter::highlightBlock(const QString &text)
|
void HGMarkdownHighlighter::highlightBlock(const QString &text)
|
||||||
@ -107,7 +133,7 @@ void HGMarkdownHighlighter::highlightBlock(const QString &text)
|
|||||||
// We can use other highlighting methods to complement it.
|
// We can use other highlighting methods to complement it.
|
||||||
|
|
||||||
// Set current block's user data.
|
// Set current block's user data.
|
||||||
updateBlockUserData(text);
|
updateBlockUserData(blockNum, text);
|
||||||
|
|
||||||
// If it is a block inside HTML comment, just skip it.
|
// If it is a block inside HTML comment, just skip it.
|
||||||
if (isBlockInsideCommentRegion(currentBlock())) {
|
if (isBlockInsideCommentRegion(currentBlock())) {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <QTextCharFormat>
|
#include <QTextCharFormat>
|
||||||
#include <QSyntaxHighlighter>
|
#include <QSyntaxHighlighter>
|
||||||
#include <QAtomicInt>
|
#include <QAtomicInt>
|
||||||
#include <QSet>
|
#include <QMap>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
|
||||||
@ -118,9 +118,12 @@ public:
|
|||||||
int waitInterval,
|
int waitInterval,
|
||||||
QTextDocument *parent = 0);
|
QTextDocument *parent = 0);
|
||||||
~HGMarkdownHighlighter();
|
~HGMarkdownHighlighter();
|
||||||
|
|
||||||
// Request to update highlihgt (re-parse and re-highlight)
|
// Request to update highlihgt (re-parse and re-highlight)
|
||||||
void setCodeBlockHighlights(const QVector<HLUnitPos> &p_units);
|
void setCodeBlockHighlights(const QVector<HLUnitPos> &p_units);
|
||||||
|
|
||||||
|
const QMap<int, bool> &getPotentialPreviewBlocks() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void highlightCompleted();
|
void highlightCompleted();
|
||||||
|
|
||||||
@ -160,6 +163,11 @@ private:
|
|||||||
|
|
||||||
int m_numOfCodeBlockHighlightsToRecv;
|
int m_numOfCodeBlockHighlightsToRecv;
|
||||||
|
|
||||||
|
// If the ith block contains preview, then the set contains i.
|
||||||
|
// If the set contains i, the ith block may contain preview.
|
||||||
|
// We just use the key.
|
||||||
|
QMap<int, bool> m_potentialPreviewBlocks;
|
||||||
|
|
||||||
// All HTML comment regions.
|
// All HTML comment regions.
|
||||||
QVector<VElementRegion> m_commentRegions;
|
QVector<VElementRegion> m_commentRegions;
|
||||||
|
|
||||||
@ -210,7 +218,12 @@ private:
|
|||||||
void highlightChanged();
|
void highlightChanged();
|
||||||
|
|
||||||
// Set the user data of currentBlock().
|
// Set the user data of currentBlock().
|
||||||
void updateBlockUserData(const QString &p_text);
|
void updateBlockUserData(int p_blockNum, const QString &p_text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline const QMap<int, bool> &HGMarkdownHighlighter::getPotentialPreviewBlocks() const
|
||||||
|
{
|
||||||
|
return m_potentialPreviewBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,10 +20,10 @@ extern VConfigManager *g_config;
|
|||||||
|
|
||||||
const int VImagePreviewer::c_minImageWidth = 100;
|
const int VImagePreviewer::c_minImageWidth = 100;
|
||||||
|
|
||||||
VImagePreviewer::VImagePreviewer(VMdEdit *p_edit)
|
VImagePreviewer::VImagePreviewer(VMdEdit *p_edit, const HGMarkdownHighlighter *p_highlighter)
|
||||||
: QObject(p_edit), m_edit(p_edit), m_document(p_edit->document()),
|
: QObject(p_edit), m_edit(p_edit), m_document(p_edit->document()),
|
||||||
m_file(p_edit->getFile()), m_imageWidth(c_minImageWidth),
|
m_file(p_edit->getFile()), m_highlighter(p_highlighter),
|
||||||
m_timeStamp(0), m_previewIndex(0),
|
m_imageWidth(c_minImageWidth), m_timeStamp(0), m_previewIndex(0),
|
||||||
m_previewEnabled(g_config->getEnablePreviewImages()), m_isPreviewing(false)
|
m_previewEnabled(g_config->getEnablePreviewImages()), m_isPreviewing(false)
|
||||||
{
|
{
|
||||||
m_updateTimer = new QTimer(this);
|
m_updateTimer = new QTimer(this);
|
||||||
@ -152,19 +152,28 @@ void VImagePreviewer::clearObsoletePreviewImages(QTextCursor &p_cursor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasObsolete = false;
|
|
||||||
QTextBlock block = m_document->begin();
|
|
||||||
// Clean block data and delete obsolete preview.
|
// Clean block data and delete obsolete preview.
|
||||||
while (block.isValid()) {
|
bool hasObsolete = false;
|
||||||
if (!VTextBlockData::containsPreviewImage(block)) {
|
int blockCount = m_document->blockCount();
|
||||||
block = block.next();
|
// Must copy it.
|
||||||
continue;
|
QMap<int, bool> potentialBlocks = m_highlighter->getPotentialPreviewBlocks();
|
||||||
} else {
|
// From back to front.
|
||||||
QTextBlock nextBlock = block.next();
|
if (!potentialBlocks.isEmpty()) {
|
||||||
// Notice the short circuit.
|
auto it = potentialBlocks.end();
|
||||||
hasObsolete = clearObsoletePreviewImagesOfBlock(block, p_cursor) || hasObsolete;
|
do {
|
||||||
block = nextBlock;
|
--it;
|
||||||
}
|
int blockNum = it.key();
|
||||||
|
if (blockNum >= blockCount) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextBlock block = m_document->findBlockByNumber(blockNum);
|
||||||
|
if (block.isValid()
|
||||||
|
&& VTextBlockData::containsPreviewImage(block)) {
|
||||||
|
// Notice the short circuit.
|
||||||
|
hasObsolete = clearObsoletePreviewImagesOfBlock(block, p_cursor) || hasObsolete;
|
||||||
|
}
|
||||||
|
} while (it != potentialBlocks.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasObsolete) {
|
if (hasObsolete) {
|
||||||
@ -246,11 +255,11 @@ bool VImagePreviewer::clearObsoletePreviewImagesOfBlock(QTextBlock &p_block,
|
|||||||
return hasObsolete;
|
return hasObsolete;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if p_text[p_start, p_end) is all spaces.
|
// Returns true if p_text[p_start, p_end) is all spaces or QChar::ObjectReplacementCharacter.
|
||||||
static bool isAllSpaces(const QString &p_text, int p_start, int p_end)
|
static bool isAllSpacesOrObject(const QString &p_text, int p_start, int p_end)
|
||||||
{
|
{
|
||||||
for (int i = p_start; i < p_end && i < p_text.size(); ++i) {
|
for (int i = p_start; i < p_end && i < p_text.size(); ++i) {
|
||||||
if (!p_text[i].isSpace()) {
|
if (!p_text[i].isSpace() && p_text[i] != QChar::ObjectReplacementCharacter) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,9 +290,9 @@ void VImagePreviewer::fetchImageLinksFromRegions(QVector<ImageLinkInfo> &p_image
|
|||||||
Q_ASSERT(reg.m_endPos <= blockEnd);
|
Q_ASSERT(reg.m_endPos <= blockEnd);
|
||||||
ImageLinkInfo info(reg.m_startPos, reg.m_endPos);
|
ImageLinkInfo info(reg.m_startPos, reg.m_endPos);
|
||||||
if ((reg.m_startPos == blockStart
|
if ((reg.m_startPos == blockStart
|
||||||
|| isAllSpaces(text, 0, reg.m_startPos - blockStart))
|
|| isAllSpacesOrObject(text, 0, reg.m_startPos - blockStart))
|
||||||
&& (reg.m_endPos == blockEnd
|
&& (reg.m_endPos == blockEnd
|
||||||
|| isAllSpaces(text, reg.m_endPos - blockStart, blockEnd - blockStart))) {
|
|| isAllSpacesOrObject(text, reg.m_endPos - blockStart, blockEnd - blockStart))) {
|
||||||
// Image block.
|
// Image block.
|
||||||
info.m_isBlock = true;
|
info.m_isBlock = true;
|
||||||
info.m_linkUrl = fetchImagePathToPreview(text);
|
info.m_linkUrl = fetchImagePathToPreview(text);
|
||||||
|
@ -17,7 +17,7 @@ class VImagePreviewer : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VImagePreviewer(VMdEdit *p_edit);
|
explicit VImagePreviewer(VMdEdit *p_edit, const HGMarkdownHighlighter *p_highlighter);
|
||||||
|
|
||||||
// Whether @p_block is an image previewed block.
|
// Whether @p_block is an image previewed block.
|
||||||
// The image previewed block is a block containing only the special character
|
// The image previewed block is a block containing only the special character
|
||||||
@ -202,6 +202,8 @@ private:
|
|||||||
QTextDocument *m_document;
|
QTextDocument *m_document;
|
||||||
VFile *m_file;
|
VFile *m_file;
|
||||||
|
|
||||||
|
const HGMarkdownHighlighter *m_highlighter;
|
||||||
|
|
||||||
// Map from image full path to QUrl identifier in the QTextDocument's cache.
|
// Map from image full path to QUrl identifier in the QTextDocument's cache.
|
||||||
QHash<QString, ImageInfo> m_imageCache;
|
QHash<QString, ImageInfo> m_imageCache;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ VMdEdit::VMdEdit(VFile *p_file, VDocument *p_vdoc, MarkdownConverterType p_type,
|
|||||||
m_cbHighlighter = new VCodeBlockHighlightHelper(m_mdHighlighter, p_vdoc,
|
m_cbHighlighter = new VCodeBlockHighlightHelper(m_mdHighlighter, p_vdoc,
|
||||||
p_type);
|
p_type);
|
||||||
|
|
||||||
m_imagePreviewer = new VImagePreviewer(this);
|
m_imagePreviewer = new VImagePreviewer(this, m_mdHighlighter);
|
||||||
connect(m_mdHighlighter, &HGMarkdownHighlighter::imageLinksUpdated,
|
connect(m_mdHighlighter, &HGMarkdownHighlighter::imageLinksUpdated,
|
||||||
m_imagePreviewer, &VImagePreviewer::imageLinksChanged);
|
m_imagePreviewer, &VImagePreviewer::imageLinksChanged);
|
||||||
connect(m_imagePreviewer, &VImagePreviewer::requestUpdateImageLinks,
|
connect(m_imagePreviewer, &VImagePreviewer::requestUpdateImageLinks,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user