mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59: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());
|
||||
if (!blockData) {
|
||||
@ -88,7 +88,33 @@ void HGMarkdownHighlighter::updateBlockUserData(const QString &p_text)
|
||||
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)
|
||||
@ -107,7 +133,7 @@ void HGMarkdownHighlighter::highlightBlock(const QString &text)
|
||||
// We can use other highlighting methods to complement it.
|
||||
|
||||
// Set current block's user data.
|
||||
updateBlockUserData(text);
|
||||
updateBlockUserData(blockNum, text);
|
||||
|
||||
// If it is a block inside HTML comment, just skip it.
|
||||
if (isBlockInsideCommentRegion(currentBlock())) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QTextCharFormat>
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QAtomicInt>
|
||||
#include <QSet>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
|
||||
@ -118,9 +118,12 @@ public:
|
||||
int waitInterval,
|
||||
QTextDocument *parent = 0);
|
||||
~HGMarkdownHighlighter();
|
||||
|
||||
// Request to update highlihgt (re-parse and re-highlight)
|
||||
void setCodeBlockHighlights(const QVector<HLUnitPos> &p_units);
|
||||
|
||||
const QMap<int, bool> &getPotentialPreviewBlocks() const;
|
||||
|
||||
signals:
|
||||
void highlightCompleted();
|
||||
|
||||
@ -160,6 +163,11 @@ private:
|
||||
|
||||
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.
|
||||
QVector<VElementRegion> m_commentRegions;
|
||||
|
||||
@ -210,7 +218,12 @@ private:
|
||||
void highlightChanged();
|
||||
|
||||
// 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
|
||||
|
@ -20,10 +20,10 @@ extern VConfigManager *g_config;
|
||||
|
||||
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()),
|
||||
m_file(p_edit->getFile()), m_imageWidth(c_minImageWidth),
|
||||
m_timeStamp(0), m_previewIndex(0),
|
||||
m_file(p_edit->getFile()), m_highlighter(p_highlighter),
|
||||
m_imageWidth(c_minImageWidth), m_timeStamp(0), m_previewIndex(0),
|
||||
m_previewEnabled(g_config->getEnablePreviewImages()), m_isPreviewing(false)
|
||||
{
|
||||
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.
|
||||
while (block.isValid()) {
|
||||
if (!VTextBlockData::containsPreviewImage(block)) {
|
||||
block = block.next();
|
||||
continue;
|
||||
} else {
|
||||
QTextBlock nextBlock = block.next();
|
||||
// Notice the short circuit.
|
||||
hasObsolete = clearObsoletePreviewImagesOfBlock(block, p_cursor) || hasObsolete;
|
||||
block = nextBlock;
|
||||
}
|
||||
bool hasObsolete = false;
|
||||
int blockCount = m_document->blockCount();
|
||||
// Must copy it.
|
||||
QMap<int, bool> potentialBlocks = m_highlighter->getPotentialPreviewBlocks();
|
||||
// From back to front.
|
||||
if (!potentialBlocks.isEmpty()) {
|
||||
auto it = potentialBlocks.end();
|
||||
do {
|
||||
--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) {
|
||||
@ -246,11 +255,11 @@ bool VImagePreviewer::clearObsoletePreviewImagesOfBlock(QTextBlock &p_block,
|
||||
return hasObsolete;
|
||||
}
|
||||
|
||||
// Returns true if p_text[p_start, p_end) is all spaces.
|
||||
static bool isAllSpaces(const QString &p_text, int p_start, int p_end)
|
||||
// Returns true if p_text[p_start, p_end) is all spaces or QChar::ObjectReplacementCharacter.
|
||||
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) {
|
||||
if (!p_text[i].isSpace()) {
|
||||
if (!p_text[i].isSpace() && p_text[i] != QChar::ObjectReplacementCharacter) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -281,9 +290,9 @@ void VImagePreviewer::fetchImageLinksFromRegions(QVector<ImageLinkInfo> &p_image
|
||||
Q_ASSERT(reg.m_endPos <= blockEnd);
|
||||
ImageLinkInfo info(reg.m_startPos, reg.m_endPos);
|
||||
if ((reg.m_startPos == blockStart
|
||||
|| isAllSpaces(text, 0, reg.m_startPos - blockStart))
|
||||
|| isAllSpacesOrObject(text, 0, reg.m_startPos - blockStart))
|
||||
&& (reg.m_endPos == blockEnd
|
||||
|| isAllSpaces(text, reg.m_endPos - blockStart, blockEnd - blockStart))) {
|
||||
|| isAllSpacesOrObject(text, reg.m_endPos - blockStart, blockEnd - blockStart))) {
|
||||
// Image block.
|
||||
info.m_isBlock = true;
|
||||
info.m_linkUrl = fetchImagePathToPreview(text);
|
||||
|
@ -17,7 +17,7 @@ class VImagePreviewer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VImagePreviewer(VMdEdit *p_edit);
|
||||
explicit VImagePreviewer(VMdEdit *p_edit, const HGMarkdownHighlighter *p_highlighter);
|
||||
|
||||
// Whether @p_block is an image previewed block.
|
||||
// The image previewed block is a block containing only the special character
|
||||
@ -202,6 +202,8 @@ private:
|
||||
QTextDocument *m_document;
|
||||
VFile *m_file;
|
||||
|
||||
const HGMarkdownHighlighter *m_highlighter;
|
||||
|
||||
// Map from image full path to QUrl identifier in the QTextDocument's cache.
|
||||
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,
|
||||
p_type);
|
||||
|
||||
m_imagePreviewer = new VImagePreviewer(this);
|
||||
m_imagePreviewer = new VImagePreviewer(this, m_mdHighlighter);
|
||||
connect(m_mdHighlighter, &HGMarkdownHighlighter::imageLinksUpdated,
|
||||
m_imagePreviewer, &VImagePreviewer::imageLinksChanged);
|
||||
connect(m_imagePreviewer, &VImagePreviewer::requestUpdateImageLinks,
|
||||
|
Loading…
x
Reference in New Issue
Block a user