From 1b95b636e7f94cee68aa912603b5bf21e7578449 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Sun, 14 Oct 2018 11:59:25 +0800 Subject: [PATCH] image related fixes - Support previewing cross-line image link; - Do not consider image title when generating image name and use current time at the front to make it easy to sort. --- src/utils/vutils.cpp | 53 +++++++++++++++++++----------------- src/utils/vutils.h | 2 ++ src/vmdeditor.cpp | 2 +- src/vpreviewmanager.cpp | 59 ++++++++++++++++++++++++++--------------- 4 files changed, 69 insertions(+), 47 deletions(-) diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp index 022ec90b..e15c38da 100644 --- a/src/utils/vutils.cpp +++ b/src/utils/vutils.cpp @@ -43,7 +43,7 @@ extern VConfigManager *g_config; QVector> VUtils::s_availableLanguages; -const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]" +const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\[\\]]*)\\]" "\\(\\s*" "([^\\)\"'\\s]+)" "(\\s*(\"[^\"\\)\\n]*\")|('[^'\\)\\n]*'))?" @@ -158,33 +158,30 @@ QString VUtils::generateImageFileName(const QString &path, const QString &title, const QString &format) { - QRegExp regExp("\\W"); - QString baseName(title.toLower()); + const QChar sep('_'); - // Remove non-character chars. - baseName.remove(regExp); - - // Constrain the length of the name. - baseName.truncate(10); - - baseName.prepend(g_config->getImageNamePrefix()); - - if (!baseName.isEmpty()) { - baseName.append('_'); + QString baseName(g_config->getImageNamePrefix()); + if (!baseName.isEmpty() + && !(baseName.size() == 1 && baseName[0] == sep)) { + baseName += sep; } - // Add current time and random number to make the name be most likely unique - baseName += QString::number(QDateTime::currentDateTime().toTime_t()) - + '_' - + QString::number(qrand()); + // Add current time at fixed length. + baseName += QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz"); - QDir dir(path); - QString imageName = baseName + "." + format.toLower(); + // Add random number to make the name be most likely unique. + baseName += (sep + QString::number(qrand())); + + QString suffix; + if (!format.isEmpty()) { + suffix = "." + format.toLower(); + } + + QString imageName(baseName + suffix); int index = 1; - + QDir dir(path); while (fileExists(dir, imageName, true)) { - imageName = QString("%1_%2.%3").arg(baseName).arg(index++) - .arg(format.toLower()); + imageName = QString("%1_%2%3").arg(baseName).arg(index++).arg(suffix); } return imageName; @@ -1016,11 +1013,12 @@ QString VUtils::getRandomFileName(const QString &p_directory) { Q_ASSERT(!p_directory.isEmpty()); - QString name; + QString baseName(QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz")); + QDir dir(p_directory); + QString name; do { - name = QString::number(QDateTime::currentDateTimeUtc().toTime_t()); - name = name + '_' + QString::number(qrand()); + name = baseName + '_' + QString::number(qrand()); } while (fileExists(dir, name, true)); return name; @@ -1826,3 +1824,8 @@ QTemporaryFile *VUtils::createTemporaryFile(QString p_suffix) + xx + p_suffix); } + +QString VUtils::purifyImageTitle(QString p_title) +{ + return p_title.remove(QRegExp("[\\r\\n\\[\\]]")); +} diff --git a/src/utils/vutils.h b/src/utils/vutils.h index 3446deaa..e2cac5f5 100644 --- a/src/utils/vutils.h +++ b/src/utils/vutils.h @@ -390,6 +390,8 @@ public: static QTemporaryFile *createTemporaryFile(QString p_suffix); + static QString purifyImageTitle(QString p_title); + // Regular expression for image link. // ![image title]( http://github.com/tamlok/vnote.jpg "alt text" =200x100) // Captured texts (need to be trimmed): diff --git a/src/vmdeditor.cpp b/src/vmdeditor.cpp index a5215163..5dde8f46 100644 --- a/src/vmdeditor.cpp +++ b/src/vmdeditor.cpp @@ -2055,7 +2055,7 @@ void VMdEditor::replaceTextWithLocalImages(QString &p_text) continue; } - QString imageTitle = regExp.cap(1).trimmed(); + QString imageTitle = VUtils::purifyImageTitle(regExp.cap(1).trimmed()); QString imageUrl = regExp.cap(2).trimmed(); const int maxUrlLength = 100; diff --git a/src/vpreviewmanager.cpp b/src/vpreviewmanager.cpp index 413636a0..d601a7e9 100644 --- a/src/vpreviewmanager.cpp +++ b/src/vpreviewmanager.cpp @@ -136,41 +136,58 @@ void VPreviewManager::fetchImageLinksFromRegions(QVector p_image for (int i = 0; i < p_imageRegions.size(); ++i) { const VElementRegion ® = p_imageRegions[i]; - QTextBlock block = doc->findBlock(reg.m_startPos); - if (!block.isValid()) { + QTextBlock firstBlock = doc->findBlock(reg.m_startPos); + if (!firstBlock.isValid()) { continue; } - int blockStart = block.position(); - int blockEnd = blockStart + block.length() - 1; - QString text = block.text(); - - // Since the image links update signal is emitted after a timer, during which - // the content may be changed. - if (reg.m_endPos > blockEnd) { + // Image link may cross multiple regions. + QTextBlock lastBlock = doc->findBlock(reg.m_endPos - 1); + if (!lastBlock.isValid()) { continue; } - ImageLinkInfo info(reg.m_startPos, + int firstBlockStart = firstBlock.position(); + int lastBlockStart = lastBlock.position(); + int lastBlockEnd = lastBlockStart + lastBlock.length() - 1; + + QString text; + if (firstBlock.blockNumber() == lastBlock.blockNumber()) { + text = firstBlock.text().mid(reg.m_startPos - firstBlockStart, + reg.m_endPos - reg.m_startPos); + } else { + text = firstBlock.text().mid(reg.m_startPos - firstBlockStart); + + QTextBlock block = firstBlock.next(); + while (block.isValid() && block.blockNumber() < lastBlock.blockNumber()) { + text += "\n" + block.text(); + block = block.next(); + } + + text += "\n" + lastBlock.text().left(reg.m_endPos - lastBlockStart); + } + + // Preview the image at the last block. + ImageLinkInfo info(qMax(reg.m_startPos, lastBlockStart), reg.m_endPos, - blockStart, - block.blockNumber(), - calculateBlockMargin(block, m_editor->tabStopWidthW())); - if ((reg.m_startPos == blockStart - || isAllSpaces(text, 0, reg.m_startPos - blockStart)) - && (reg.m_endPos == blockEnd - || isAllSpaces(text, reg.m_endPos - blockStart, blockEnd - blockStart))) { + lastBlockStart, + lastBlock.blockNumber(), + calculateBlockMargin(firstBlock, m_editor->tabStopWidthW())); + if ((reg.m_startPos == firstBlockStart + || isAllSpaces(firstBlock.text(), 0, reg.m_startPos - firstBlockStart)) + && (reg.m_endPos == lastBlockEnd + || isAllSpaces(lastBlock.text(), + reg.m_endPos - lastBlockStart, + lastBlockEnd - lastBlockStart))) { // Image block. info.m_isBlock = true; - fetchImageInfoToPreview(text, info); } else { // Inline image. info.m_isBlock = false; - fetchImageInfoToPreview(text.mid(reg.m_startPos - blockStart, - reg.m_endPos - reg.m_startPos), - info); } + fetchImageInfoToPreview(text, info); + if (info.m_linkUrl.isEmpty() || info.m_linkShortUrl.isEmpty()) { continue; }