mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-06 14:29:54 +08:00
bug-fix: fix images when cutting files
1. De-duplicate the images occur multiple times in the note; 2. Refresh the read mode and edit mode preview after the directory path change; 3. Update init images and inserted images after the directory path change;
This commit is contained in:
parent
7fd5ec26e5
commit
03122a24db
@ -51,7 +51,8 @@ var mdit = window.markdownit({
|
|||||||
return hljs.highlightAuto(str).value;
|
return hljs.highlightAuto(str).value;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return str;
|
// Use external default escaping.
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -67,7 +68,7 @@ mdit = mdit.use(window.markdownitHeadingAnchor, {
|
|||||||
toc.push({
|
toc.push({
|
||||||
level: getHeadingLevel(openToken.tag),
|
level: getHeadingLevel(openToken.tag),
|
||||||
anchor: anchor,
|
anchor: anchor,
|
||||||
title: escapeHtml(inlineToken.content)
|
title: mdit.utils.escapeHtml(inlineToken.content)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -216,6 +216,9 @@ QVector<ImageLink> VUtils::fetchImagesFromMarkdownFile(VFile *p_file,
|
|||||||
return images;
|
return images;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used to de-duplicate the links. Url as the key.
|
||||||
|
QSet<QString> fetchedLinks;
|
||||||
|
|
||||||
QVector<VElementRegion> regions = fetchImageRegionsUsingParser(text);
|
QVector<VElementRegion> regions = fetchImageRegionsUsingParser(text);
|
||||||
QRegExp regExp(c_imageLinkRegExp);
|
QRegExp regExp(c_imageLinkRegExp);
|
||||||
QString basePath = p_file->fetchBasePath();
|
QString basePath = p_file->fetchBasePath();
|
||||||
@ -231,6 +234,7 @@ QVector<ImageLink> VUtils::fetchImagesFromMarkdownFile(VFile *p_file,
|
|||||||
QString imageUrl = regExp.capturedTexts()[2].trimmed();
|
QString imageUrl = regExp.capturedTexts()[2].trimmed();
|
||||||
|
|
||||||
ImageLink link;
|
ImageLink link;
|
||||||
|
link.m_url = imageUrl;
|
||||||
QFileInfo info(basePath, imageUrl);
|
QFileInfo info(basePath, imageUrl);
|
||||||
if (info.exists()) {
|
if (info.exists()) {
|
||||||
if (info.isNativePath()) {
|
if (info.isNativePath()) {
|
||||||
@ -254,8 +258,11 @@ QVector<ImageLink> VUtils::fetchImagesFromMarkdownFile(VFile *p_file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (link.m_type & p_type) {
|
if (link.m_type & p_type) {
|
||||||
images.push_back(link);
|
if (!fetchedLinks.contains(link.m_url)) {
|
||||||
qDebug() << "fetch one image:" << link.m_type << link.m_path;
|
fetchedLinks.insert(link.m_url);
|
||||||
|
images.push_back(link);
|
||||||
|
qDebug() << "fetch one image:" << link.m_type << link.m_path << link.m_url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +273,24 @@ QVector<ImageLink> VUtils::fetchImagesFromMarkdownFile(VFile *p_file,
|
|||||||
return images;
|
return images;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString VUtils::imageLinkUrlToPath(const QString &p_basePath, const QString &p_url)
|
||||||
|
{
|
||||||
|
QString path;
|
||||||
|
QFileInfo info(p_basePath, p_url);
|
||||||
|
if (info.exists()) {
|
||||||
|
if (info.isNativePath()) {
|
||||||
|
// Local file.
|
||||||
|
path = QDir::cleanPath(info.absoluteFilePath());
|
||||||
|
} else {
|
||||||
|
path = p_url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
path = QUrl(p_url).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
bool VUtils::makePath(const QString &p_path)
|
bool VUtils::makePath(const QString &p_path)
|
||||||
{
|
{
|
||||||
if (p_path.isEmpty()) {
|
if (p_path.isEmpty()) {
|
||||||
|
@ -67,6 +67,10 @@ struct ImageLink
|
|||||||
};
|
};
|
||||||
|
|
||||||
QString m_path;
|
QString m_path;
|
||||||
|
|
||||||
|
// The url text in the link.
|
||||||
|
QString m_url;
|
||||||
|
|
||||||
ImageLinkType m_type;
|
ImageLinkType m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -121,6 +125,9 @@ public:
|
|||||||
static QVector<ImageLink> fetchImagesFromMarkdownFile(VFile *p_file,
|
static QVector<ImageLink> fetchImagesFromMarkdownFile(VFile *p_file,
|
||||||
ImageLink::ImageLinkType p_type = ImageLink::All);
|
ImageLink::ImageLinkType p_type = ImageLink::All);
|
||||||
|
|
||||||
|
// Return the absolute path of @p_url according to @p_basePath.
|
||||||
|
static QString imageLinkUrlToPath(const QString &p_basePath, const QString &p_url);
|
||||||
|
|
||||||
// Create directories along the @p_path.
|
// Create directories along the @p_path.
|
||||||
// @p_path could be /home/tamlok/abc, /home/tamlok/abc/.
|
// @p_path could be /home/tamlok/abc, /home/tamlok/abc/.
|
||||||
static bool makePath(const QString &p_path);
|
static bool makePath(const QString &p_path);
|
||||||
|
@ -128,4 +128,13 @@ enum class CursorBlock
|
|||||||
LeftSide
|
LeftSide
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class UpdateAction
|
||||||
|
{
|
||||||
|
// The info of a file/directory has been changed.
|
||||||
|
InfoChanged = 0,
|
||||||
|
|
||||||
|
// The file/directory has been moved.
|
||||||
|
Moved
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -602,7 +602,7 @@ void VDirectoryTree::editDirectoryInfo()
|
|||||||
|
|
||||||
fillTreeItem(curItem, curDir);
|
fillTreeItem(curItem, curDir);
|
||||||
|
|
||||||
emit directoryUpdated(curDir);
|
emit directoryUpdated(curDir, UpdateAction::InfoChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,7 +856,7 @@ void VDirectoryTree::pasteDirectories(VDirectory *p_destDir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast this update
|
// Broadcast this update
|
||||||
emit directoryUpdated(destDir);
|
emit directoryUpdated(destDir, p_isCut ? UpdateAction::Moved : UpdateAction::InfoChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "vdirectory.h"
|
#include "vdirectory.h"
|
||||||
#include "vnotebook.h"
|
#include "vnotebook.h"
|
||||||
#include "vnavigationmode.h"
|
#include "vnavigationmode.h"
|
||||||
|
#include "vconstants.h"
|
||||||
|
|
||||||
class VEditArea;
|
class VEditArea;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
@ -35,7 +36,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void currentDirectoryChanged(VDirectory *p_directory);
|
void currentDirectoryChanged(VDirectory *p_directory);
|
||||||
|
|
||||||
void directoryUpdated(const VDirectory *p_directory);
|
void directoryUpdated(const VDirectory *p_directory, UpdateAction p_act);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Set directory tree to display a given notebook @p_notebook.
|
// Set directory tree to display a given notebook @p_notebook.
|
||||||
|
@ -521,19 +521,19 @@ bool VEditArea::isFileOpened(const VFile *p_file)
|
|||||||
return !findTabsByFile(p_file).isEmpty();
|
return !findTabsByFile(p_file).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditArea::handleFileUpdated(const VFile *p_file)
|
void VEditArea::handleFileUpdated(const VFile *p_file, UpdateAction p_act)
|
||||||
{
|
{
|
||||||
int nrWin = splitter->count();
|
int nrWin = splitter->count();
|
||||||
for (int i = 0; i < nrWin; ++i) {
|
for (int i = 0; i < nrWin; ++i) {
|
||||||
getWindow(i)->updateFileInfo(p_file);
|
getWindow(i)->updateFileInfo(p_file, p_act);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditArea::handleDirectoryUpdated(const VDirectory *p_dir)
|
void VEditArea::handleDirectoryUpdated(const VDirectory *p_dir, UpdateAction p_act)
|
||||||
{
|
{
|
||||||
int nrWin = splitter->count();
|
int nrWin = splitter->count();
|
||||||
for (int i = 0; i < nrWin; ++i) {
|
for (int i = 0; i < nrWin; ++i) {
|
||||||
getWindow(i)->updateDirectoryInfo(p_dir);
|
getWindow(i)->updateDirectoryInfo(p_dir, p_act);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,8 +115,10 @@ public slots:
|
|||||||
// Scroll current tab to @p_header.
|
// Scroll current tab to @p_header.
|
||||||
void scrollToHeader(const VHeaderPointer &p_header);
|
void scrollToHeader(const VHeaderPointer &p_header);
|
||||||
|
|
||||||
void handleFileUpdated(const VFile *p_file);
|
void handleFileUpdated(const VFile *p_file, UpdateAction p_act);
|
||||||
void handleDirectoryUpdated(const VDirectory *p_dir);
|
|
||||||
|
void handleDirectoryUpdated(const VDirectory *p_dir, UpdateAction p_act);
|
||||||
|
|
||||||
void handleNotebookUpdated(const VNotebook *p_notebook);
|
void handleNotebookUpdated(const VNotebook *p_notebook);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -188,3 +188,9 @@ void VEditTab::reloadFromDisk()
|
|||||||
void VEditTab::writeBackupFile()
|
void VEditTab::writeBackupFile()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VEditTab::handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act)
|
||||||
|
{
|
||||||
|
Q_UNUSED(p_isFile);
|
||||||
|
Q_UNUSED(p_act);
|
||||||
|
}
|
||||||
|
@ -111,6 +111,9 @@ public:
|
|||||||
// Reload file from disk and reload the editor.
|
// Reload file from disk and reload the editor.
|
||||||
void reloadFromDisk();
|
void reloadFromDisk();
|
||||||
|
|
||||||
|
// Handle the change of file or directory, such as the file has been moved.
|
||||||
|
virtual void handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode
|
// Enter edit mode
|
||||||
virtual void editFile() = 0;
|
virtual void editFile() = 0;
|
||||||
|
@ -793,18 +793,20 @@ void VEditWindow::handleTabVimStatusUpdated(const VVim *p_vim)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditWindow::updateFileInfo(const VFile *p_file)
|
void VEditWindow::updateFileInfo(const VFile *p_file, UpdateAction p_act)
|
||||||
{
|
{
|
||||||
if (!p_file) {
|
if (!p_file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx = findTabByFile(p_file);
|
int idx = findTabByFile(p_file);
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
updateTabStatus(idx);
|
updateTabStatus(idx);
|
||||||
|
getTab(idx)->handleFileOrDirectoryChange(true, p_act);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditWindow::updateDirectoryInfo(const VDirectory *p_dir)
|
void VEditWindow::updateDirectoryInfo(const VDirectory *p_dir, UpdateAction p_act)
|
||||||
{
|
{
|
||||||
if (!p_dir) {
|
if (!p_dir) {
|
||||||
return;
|
return;
|
||||||
@ -816,6 +818,7 @@ void VEditWindow::updateDirectoryInfo(const VDirectory *p_dir)
|
|||||||
QPointer<VFile> file = editor->getFile();
|
QPointer<VFile> file = editor->getFile();
|
||||||
if (p_dir->containsFile(file)) {
|
if (p_dir->containsFile(file)) {
|
||||||
updateTabStatus(i);
|
updateTabStatus(i);
|
||||||
|
editor->handleFileOrDirectoryChange(false, p_act);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,10 @@ public:
|
|||||||
// Scroll current tab to header @p_header.
|
// Scroll current tab to header @p_header.
|
||||||
void scrollToHeader(const VHeaderPointer &p_header);
|
void scrollToHeader(const VHeaderPointer &p_header);
|
||||||
|
|
||||||
void updateFileInfo(const VFile *p_file);
|
void updateFileInfo(const VFile *p_file, UpdateAction p_act);
|
||||||
void updateDirectoryInfo(const VDirectory *p_dir);
|
|
||||||
|
void updateDirectoryInfo(const VDirectory *p_dir, UpdateAction p_act);
|
||||||
|
|
||||||
void updateNotebookInfo(const VNotebook *p_notebook);
|
void updateNotebookInfo(const VNotebook *p_notebook);
|
||||||
|
|
||||||
VEditTab *getCurrentTab() const;
|
VEditTab *getCurrentTab() const;
|
||||||
|
@ -247,7 +247,7 @@ void VFileList::fileInfo(VNoteFile *p_file)
|
|||||||
fillItem(item, p_file);
|
fillItem(item, p_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit fileUpdated(p_file);
|
emit fileUpdated(p_file, UpdateAction::InfoChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,7 +800,7 @@ void VFileList::pasteFiles(VDirectory *p_destDir,
|
|||||||
|
|
||||||
if (destFile) {
|
if (destFile) {
|
||||||
++nrPasted;
|
++nrPasted;
|
||||||
emit fileUpdated(destFile);
|
emit fileUpdated(destFile, p_isCut ? UpdateAction::Moved : UpdateAction::InfoChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ signals:
|
|||||||
OpenFileMode p_mode = OpenFileMode::Read,
|
OpenFileMode p_mode = OpenFileMode::Read,
|
||||||
bool p_forceMode = false);
|
bool p_forceMode = false);
|
||||||
|
|
||||||
void fileUpdated(const VNoteFile *p_file);
|
void fileUpdated(const VNoteFile *p_file, UpdateAction p_act);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void contextMenuRequested(QPoint pos);
|
void contextMenuRequested(QPoint pos);
|
||||||
|
@ -86,14 +86,15 @@ void VMdEditOperations::insertImageFromQImage(const QString &title, const QStrin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString md = QString("").arg(title).arg(folderInLink).arg(fileName);
|
QString url = QString("%1/%2").arg(folderInLink).arg(fileName);
|
||||||
|
QString md = QString("").arg(title).arg(url);
|
||||||
insertTextAtCurPos(md);
|
insertTextAtCurPos(md);
|
||||||
|
|
||||||
qDebug() << "insert image" << title << filePath;
|
qDebug() << "insert image" << title << filePath;
|
||||||
|
|
||||||
VMdEditor *mdEditor = dynamic_cast<VMdEditor *>(m_editor);
|
VMdEditor *mdEditor = dynamic_cast<VMdEditor *>(m_editor);
|
||||||
Q_ASSERT(mdEditor);
|
Q_ASSERT(mdEditor);
|
||||||
mdEditor->imageInserted(filePath);
|
mdEditor->imageInserted(filePath, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMdEditOperations::insertImageFromPath(const QString &title, const QString &path,
|
void VMdEditOperations::insertImageFromPath(const QString &title, const QString &path,
|
||||||
@ -126,14 +127,15 @@ void VMdEditOperations::insertImageFromPath(const QString &title, const QString
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString md = QString("").arg(title).arg(folderInLink).arg(fileName);
|
QString url = QString("%1/%2").arg(folderInLink).arg(fileName);
|
||||||
|
QString md = QString("").arg(title).arg(url);
|
||||||
insertTextAtCurPos(md);
|
insertTextAtCurPos(md);
|
||||||
|
|
||||||
qDebug() << "insert image" << title << filePath;
|
qDebug() << "insert image" << title << filePath;
|
||||||
|
|
||||||
VMdEditor *mdEditor = dynamic_cast<VMdEditor *>(m_editor);
|
VMdEditor *mdEditor = dynamic_cast<VMdEditor *>(m_editor);
|
||||||
Q_ASSERT(mdEditor);
|
Q_ASSERT(mdEditor);
|
||||||
mdEditor->imageInserted(filePath);
|
mdEditor->imageInserted(filePath, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl)
|
bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl)
|
||||||
|
@ -125,6 +125,7 @@ void VMdEditor::beginEdit()
|
|||||||
void VMdEditor::endEdit()
|
void VMdEditor::endEdit()
|
||||||
{
|
{
|
||||||
setReadOnlyAndHighlightCurrentLine(true);
|
setReadOnlyAndHighlightCurrentLine(true);
|
||||||
|
|
||||||
clearUnusedImages();
|
clearUnusedImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +139,10 @@ void VMdEditor::saveFile()
|
|||||||
|
|
||||||
m_file->setContent(toPlainText());
|
m_file->setContent(toPlainText());
|
||||||
setModified(false);
|
setModified(false);
|
||||||
|
|
||||||
|
clearUnusedImages();
|
||||||
|
|
||||||
|
initInitImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMdEditor::reloadFile()
|
void VMdEditor::reloadFile()
|
||||||
@ -544,7 +549,7 @@ void VMdEditor::clearUnusedImages()
|
|||||||
QVector<ImageLink> images = VUtils::fetchImagesFromMarkdownFile(m_file,
|
QVector<ImageLink> images = VUtils::fetchImagesFromMarkdownFile(m_file,
|
||||||
ImageLink::LocalRelativeInternal);
|
ImageLink::LocalRelativeInternal);
|
||||||
|
|
||||||
QVector<QString> unusedImages;
|
QSet<QString> unusedImages;
|
||||||
|
|
||||||
if (!m_insertedImages.isEmpty()) {
|
if (!m_insertedImages.isEmpty()) {
|
||||||
for (int i = 0; i < m_insertedImages.size(); ++i) {
|
for (int i = 0; i < m_insertedImages.size(); ++i) {
|
||||||
@ -563,7 +568,7 @@ void VMdEditor::clearUnusedImages()
|
|||||||
|
|
||||||
// This inserted image is no longer in the file.
|
// This inserted image is no longer in the file.
|
||||||
if (j == images.size()) {
|
if (j == images.size()) {
|
||||||
unusedImages.push_back(link.m_path);
|
unusedImages.insert(link.m_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,7 +589,7 @@ void VMdEditor::clearUnusedImages()
|
|||||||
|
|
||||||
// Original local relative image is no longer in the file.
|
// Original local relative image is no longer in the file.
|
||||||
if (j == images.size()) {
|
if (j == images.size()) {
|
||||||
unusedImages.push_back(link.m_path);
|
unusedImages.insert(link.m_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,27 +626,27 @@ void VMdEditor::clearUnusedImages()
|
|||||||
g_config->setConfirmImagesCleanUp(dialog.getAskAgainEnabled());
|
g_config->setConfirmImagesCleanUp(dialog.getAskAgainEnabled());
|
||||||
|
|
||||||
for (auto const & item : items) {
|
for (auto const & item : items) {
|
||||||
unusedImages.push_back(item.m_name);
|
unusedImages.insert(item.m_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < unusedImages.size(); ++i) {
|
for (auto const & item : unusedImages) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_file->getType() == FileType::Note) {
|
if (m_file->getType() == FileType::Note) {
|
||||||
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>((VFile *)m_file);
|
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>((VFile *)m_file);
|
||||||
ret = VUtils::deleteFile(tmpFile->getNotebook(), unusedImages[i], false);
|
ret = VUtils::deleteFile(tmpFile->getNotebook(), item, false);
|
||||||
} else if (m_file->getType() == FileType::Orphan) {
|
} else if (m_file->getType() == FileType::Orphan) {
|
||||||
const VOrphanFile *tmpFile = dynamic_cast<const VOrphanFile *>((VFile *)m_file);
|
const VOrphanFile *tmpFile = dynamic_cast<const VOrphanFile *>((VFile *)m_file);
|
||||||
ret = VUtils::deleteFile(tmpFile, unusedImages[i], false);
|
ret = VUtils::deleteFile(tmpFile, item, false);
|
||||||
} else {
|
} else {
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
qWarning() << "fail to delete unused original image" << unusedImages[i];
|
qWarning() << "fail to delete unused original image" << item;
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "delete unused image" << unusedImages[i];
|
qDebug() << "delete unused image" << item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -731,10 +736,11 @@ void VMdEditor::insertFromMimeData(const QMimeData *p_source)
|
|||||||
VTextEdit::insertFromMimeData(p_source);
|
VTextEdit::insertFromMimeData(p_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMdEditor::imageInserted(const QString &p_path)
|
void VMdEditor::imageInserted(const QString &p_path, const QString &p_url)
|
||||||
{
|
{
|
||||||
ImageLink link;
|
ImageLink link;
|
||||||
link.m_path = p_path;
|
link.m_path = p_path;
|
||||||
|
link.m_url = p_url;
|
||||||
if (m_file->useRelativeImageFolder()) {
|
if (m_file->useRelativeImageFolder()) {
|
||||||
link.m_type = ImageLink::LocalRelativeInternal;
|
link.m_type = ImageLink::LocalRelativeInternal;
|
||||||
} else {
|
} else {
|
||||||
@ -907,3 +913,80 @@ void VMdEditor::setContent(const QString &p_content, bool p_modified)
|
|||||||
setPlainText(p_content);
|
setPlainText(p_content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMdEditor::refreshPreview()
|
||||||
|
{
|
||||||
|
m_previewMgr->refreshPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VMdEditor::updateInitAndInsertedImages(bool p_fileChanged, UpdateAction p_act)
|
||||||
|
{
|
||||||
|
if (p_fileChanged && p_act == UpdateAction::InfoChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isModified()) {
|
||||||
|
Q_ASSERT(m_insertedImages.isEmpty());
|
||||||
|
m_insertedImages.clear();
|
||||||
|
|
||||||
|
if (!m_initImages.isEmpty()) {
|
||||||
|
// Re-generate init images.
|
||||||
|
initInitImages();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update init images.
|
||||||
|
QVector<ImageLink> tmp = m_initImages;
|
||||||
|
initInitImages();
|
||||||
|
Q_ASSERT(tmp.size() == m_initImages.size());
|
||||||
|
|
||||||
|
QDir dir(m_file->fetchBasePath());
|
||||||
|
|
||||||
|
// File has been moved.
|
||||||
|
if (p_fileChanged) {
|
||||||
|
// Since we clear unused images once user save the note, all images
|
||||||
|
// in m_initImages now are moved already.
|
||||||
|
|
||||||
|
// Update inserted images.
|
||||||
|
// Inserted images should be moved manually here. Then update all the
|
||||||
|
// paths.
|
||||||
|
for (auto & link : m_insertedImages) {
|
||||||
|
if (link.m_type == ImageLink::LocalAbsolute) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString newPath = QDir::cleanPath(dir.absoluteFilePath(link.m_url));
|
||||||
|
if (VUtils::equalPath(link.m_path, newPath)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VUtils::copyFile(link.m_path, newPath, true)) {
|
||||||
|
VUtils::showMessage(QMessageBox::Warning,
|
||||||
|
tr("Warning"),
|
||||||
|
tr("Fail to move unsaved inserted image %1 to %2.")
|
||||||
|
.arg(link.m_path)
|
||||||
|
.arg(newPath),
|
||||||
|
tr("Please check it manually to avoid image loss."),
|
||||||
|
QMessageBox::Ok,
|
||||||
|
QMessageBox::Ok,
|
||||||
|
this);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
link.m_path = newPath;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Directory changed.
|
||||||
|
// Update inserted images.
|
||||||
|
for (auto & link : m_insertedImages) {
|
||||||
|
if (link.m_type == ImageLink::LocalAbsolute) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString newPath = QDir::cleanPath(dir.absoluteFilePath(link.m_url));
|
||||||
|
link.m_path = newPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -45,7 +45,8 @@ public:
|
|||||||
|
|
||||||
// An image has been inserted. The image is relative.
|
// An image has been inserted. The image is relative.
|
||||||
// @p_path is the absolute path of the inserted image.
|
// @p_path is the absolute path of the inserted image.
|
||||||
void imageInserted(const QString &p_path);
|
// @p_url is the URL text within ().
|
||||||
|
void imageInserted(const QString &p_path, const QString &p_url);
|
||||||
|
|
||||||
// Scroll to header @p_blockNumber.
|
// Scroll to header @p_blockNumber.
|
||||||
// Return true if @p_blockNumber is valid to scroll to.
|
// Return true if @p_blockNumber is valid to scroll to.
|
||||||
@ -59,6 +60,11 @@ public:
|
|||||||
|
|
||||||
void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE;
|
void setContent(const QString &p_content, bool p_modified = false) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void refreshPreview();
|
||||||
|
|
||||||
|
// Update m_initImages and m_insertedImages to handle the change of the note path.
|
||||||
|
void updateInitAndInsertedImages(bool p_fileChanged, UpdateAction p_act);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) Q_DECL_OVERRIDE;
|
bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
@ -217,5 +223,4 @@ private:
|
|||||||
|
|
||||||
bool m_freshEdit;
|
bool m_freshEdit;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VMDEDITOR_H
|
#endif // VMDEDITOR_H
|
||||||
|
@ -982,3 +982,18 @@ void VMdTab::updateCursorStatus()
|
|||||||
{
|
{
|
||||||
emit statusUpdated(fetchTabInfo(VEditTabInfo::InfoType::Cursor));
|
emit statusUpdated(fetchTabInfo(VEditTabInfo::InfoType::Cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMdTab::handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act)
|
||||||
|
{
|
||||||
|
// Reload the web view with new base URL.
|
||||||
|
m_headerFromEditMode = m_currentHeader;
|
||||||
|
m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType, false),
|
||||||
|
m_file->getBaseUrl());
|
||||||
|
|
||||||
|
if (m_editor) {
|
||||||
|
m_editor->updateInitAndInsertedImages(p_isFile, p_act);
|
||||||
|
|
||||||
|
// Refresh the previewed images in edit mode.
|
||||||
|
m_editor->refreshPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -85,6 +85,8 @@ public:
|
|||||||
|
|
||||||
void reload() Q_DECL_OVERRIDE;
|
void reload() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Enter edit mode.
|
// Enter edit mode.
|
||||||
void editFile() Q_DECL_OVERRIDE;
|
void editFile() Q_DECL_OVERRIDE;
|
||||||
|
@ -511,8 +511,15 @@ bool VNoteFile::copyFile(VDirectory *p_destDir,
|
|||||||
|
|
||||||
// Copy images.
|
// Copy images.
|
||||||
QDir parentDir(destFile->fetchBasePath());
|
QDir parentDir(destFile->fetchBasePath());
|
||||||
|
QSet<QString> processedImages;
|
||||||
for (int i = 0; i < images.size(); ++i) {
|
for (int i = 0; i < images.size(); ++i) {
|
||||||
const ImageLink &link = images[i];
|
const ImageLink &link = images[i];
|
||||||
|
if (processedImages.contains(link.m_path)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
processedImages.insert(link.m_path);
|
||||||
|
|
||||||
if (!QFileInfo::exists(link.m_path)) {
|
if (!QFileInfo::exists(link.m_path)) {
|
||||||
VUtils::addErrMsg(p_errMsg, tr("Source image %1 does not exist.")
|
VUtils::addErrMsg(p_errMsg, tr("Source image %1 does not exist.")
|
||||||
.arg(link.m_path));
|
.arg(link.m_path));
|
||||||
|
@ -375,3 +375,14 @@ void VPreviewManager::clearBlockObsoletePreviewInfo(long long p_timeStamp,
|
|||||||
|
|
||||||
m_editor->relayout(affectedBlocks);
|
m_editor->relayout(affectedBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VPreviewManager::refreshPreview()
|
||||||
|
{
|
||||||
|
if (!m_previewEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearPreview();
|
||||||
|
|
||||||
|
requestUpdateImageLinks();
|
||||||
|
}
|
||||||
|
@ -26,6 +26,9 @@ public:
|
|||||||
// Clear all the preview.
|
// Clear all the preview.
|
||||||
void clearPreview();
|
void clearPreview();
|
||||||
|
|
||||||
|
// Refresh all the preview.
|
||||||
|
void refreshPreview();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Image links were updated from the highlighter.
|
// Image links were updated from the highlighter.
|
||||||
void imageLinksUpdated(const QVector<VElementRegion> &p_imageRegions);
|
void imageLinksUpdated(const QVector<VElementRegion> &p_imageRegions);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user