diff --git a/src/dialog/vinsertimagedialog.cpp b/src/dialog/vinsertimagedialog.cpp index cd9b7c83..f6d23b16 100644 --- a/src/dialog/vinsertimagedialog.cpp +++ b/src/dialog/vinsertimagedialog.cpp @@ -243,21 +243,20 @@ void VInsertImageDialog::handlePathEditChanged() return; } - QImage image(text); - if (image.isNull()) { + QImage image; + if (url.isLocalFile()) { + image = VUtils::imageFromFile(url.toLocalFile()); + setImage(image); + m_imageType = ImageType::LocalFile; + qDebug() << "fetch local file image to insert" << text; + } else { setImage(QImage()); - // Try to treat it as network image. m_imageType = ImageType::ImageData; VDownloader *downloader = new VDownloader(this); connect(downloader, &VDownloader::downloadFinished, this, &VInsertImageDialog::imageDownloaded); downloader->download(url.toString()); qDebug() << "try to fetch network image to insert" << text; - } else { - // Local image path. - setImage(image); - m_imageType = ImageType::LocalFile; - qDebug() << "fetch local file image to insert" << text; } handleInputChanged(); diff --git a/src/resources/markdown-it.js b/src/resources/markdown-it.js index 5726e6b1..4d2a406f 100644 --- a/src/resources/markdown-it.js +++ b/src/resources/markdown-it.js @@ -72,6 +72,14 @@ mdit = mdit.use(window.markdownitHeadingAnchor, { } }); +// Enable file: scheme. +var validateLinkMDIT = mdit.validateLink; +var fileSchemeRE = /^file:/; +mdit.validateLink = function(url) { + var str = url.trim().toLowerCase(); + return fileSchemeRE.test(str) ? true : validateLinkMDIT(url); +}; + mdit = mdit.use(window.markdownitTaskLists); if (VMarkdownitOption.sub) { diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp index d15019dc..dacaa019 100644 --- a/src/utils/vutils.cpp +++ b/src/utils/vutils.cpp @@ -1476,3 +1476,31 @@ const QTreeWidgetItem *VUtils::topLevelTreeItem(const QTreeWidgetItem *p_item) return p_item; } } + +QImage VUtils::imageFromFile(const QString &p_filePath) +{ + QImage img; + QFile file(p_filePath); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "fail to open image file" << p_filePath; + return img; + } + + img.loadFromData(file.readAll()); + qDebug() << "imageFromFile" << p_filePath << img.isNull() << img.format(); + return img; +} + +QPixmap VUtils::pixmapFromFile(const QString &p_filePath) +{ + QPixmap pixmap; + QFile file(p_filePath); + if (!file.open(QIODevice::ReadOnly)) { + qWarning() << "fail to open pixmap file" << p_filePath; + return pixmap; + } + + pixmap.loadFromData(file.readAll()); + qDebug() << "pixmapFromFile" << p_filePath << pixmap.isNull(); + return pixmap; +} diff --git a/src/utils/vutils.h b/src/utils/vutils.h index 4e776efd..05b7263a 100644 --- a/src/utils/vutils.h +++ b/src/utils/vutils.h @@ -320,6 +320,13 @@ public: static const QTreeWidgetItem *topLevelTreeItem(const QTreeWidgetItem *p_item); + // Read QImage from local file @p_filePath. + // Directly calling QImage(p_filePath) will judge the image format from the suffix, + // resulting a null image in wrong suffix case. + static QImage imageFromFile(const QString &p_filePath); + + static QPixmap pixmapFromFile(const QString &p_filePath); + // Regular expression for image link. // ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" ) // Captured texts (need to be trimmed): diff --git a/src/vmdeditoperations.cpp b/src/vmdeditoperations.cpp index 6238d7a9..e565702e 100644 --- a/src/vmdeditoperations.cpp +++ b/src/vmdeditoperations.cpp @@ -148,12 +148,12 @@ bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl) // Whether it is a local file or web URL if (isLocal) { imagePath = imageUrl.toLocalFile(); - image = QImage(imagePath); - + image = VUtils::imageFromFile(imagePath); if (image.isNull()) { - qWarning() << "image is null"; + qWarning() << "inserted image is null" << imagePath; return false; } + title = "Insert Image From File"; } else { imagePath = imageUrl.toString(); diff --git a/src/vpreviewmanager.cpp b/src/vpreviewmanager.cpp index 55dd6f87..ad472372 100644 --- a/src/vpreviewmanager.cpp +++ b/src/vpreviewmanager.cpp @@ -222,7 +222,11 @@ QString VPreviewManager::fetchImagePathToPreview(const QString &p_text, QString } } else { QUrl url(p_url); - imagePath = url.toString(); + if (url.isLocalFile()) { + imagePath = url.toLocalFile(); + } else { + imagePath = url.toString(); + } } } @@ -238,12 +242,11 @@ QString VPreviewManager::imageResourceName(const ImageLinkInfo &p_link) } // Add it to the resource. - QString imgPath = p_link.m_linkUrl; - QFileInfo info(imgPath); QPixmap image; - if (info.exists()) { + QString imgPath = p_link.m_linkUrl; + if (QFileInfo::exists(imgPath)) { // Local file. - image = QPixmap(imgPath); + image = VUtils::pixmapFromFile(imgPath); } else { // URL. Try to download it. m_downloader->download(imgPath); diff --git a/src/vwebview.cpp b/src/vwebview.cpp index 99863851..2fca84cb 100644 --- a/src/vwebview.cpp +++ b/src/vwebview.cpp @@ -16,6 +16,7 @@ #include "utils/viconutils.h" #include "vconfigmanager.h" #include "utils/vwebutils.h" +#include "utils/vutils.h" extern VConfigManager *g_config; @@ -139,7 +140,7 @@ void VWebView::copyImage() } if (!imgPath.isEmpty()) { - QImage img(imgPath); + QImage img = VUtils::imageFromFile(imgPath); if (!img.isNull()) { m_afterCopyImage = false; VClipboardUtils::setImageToClipboard(clipboard, img, QClipboard::Clipboard);