mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
MarkdownEditor: support context-sensitive context menu for images and links
This commit is contained in:
parent
9fca1cad12
commit
0b58669e39
@ -1 +1 @@
|
||||
Subproject commit 44e6bcbcf4a0be2bfd2333098aa48084ee6fc14c
|
||||
Subproject commit 6c2ff0e78aedb6d4a107cd4825473d47813596cc
|
@ -6,6 +6,7 @@
|
||||
#include <utils/fileutils.h>
|
||||
#include <notebook/node.h>
|
||||
#include <core/file.h>
|
||||
#include <core/exception.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -160,7 +161,11 @@ void FileBufferProvider::removeImage(const QString &p_imagePath)
|
||||
{
|
||||
auto file = m_file->getImageInterface();
|
||||
if (file) {
|
||||
file->removeImage(p_imagePath);
|
||||
try {
|
||||
file->removeImage(p_imagePath);
|
||||
} catch (Exception &e) {
|
||||
qWarning() << "failed to remove image" << p_imagePath << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <notebook/notebook.h>
|
||||
#include <utils/pathutils.h>
|
||||
#include <core/file.h>
|
||||
#include <core/exception.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -140,7 +141,11 @@ void NodeBufferProvider::removeImage(const QString &p_imagePath)
|
||||
{
|
||||
auto file = m_nodeFile->getImageInterface();
|
||||
if (file) {
|
||||
file->removeImage(p_imagePath);
|
||||
try {
|
||||
file->removeImage(p_imagePath);
|
||||
} catch (Exception &e) {
|
||||
qWarning() << "failed to remove image" << p_imagePath << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,7 @@ void BufferMgr::open(const QString &p_filePath, const QSharedPointer<FileOpenPar
|
||||
auto msg = QString("Failed to open file that does not exist (%1)").arg(p_filePath);
|
||||
qWarning() << msg;
|
||||
VNoteX::getInst().showStatusMessageShort(msg);
|
||||
WidgetUtils::openUrlByDesktop(QUrl::fromUserInput(p_filePath));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,10 @@ For more information, please visit [**VNote's Home Page**](https://vnotex.github
|
||||
|
||||
## FAQs
|
||||
* If VNote crashes after update, please delete the `vnotex.json` file under user configuration folder.
|
||||
* For **Windows** users, if VNote hangs frequently or behaves unexpectedly in interface, please check the **OpenGL** option. [Details here](https://github.com/vnotex/vnote/issues/853).
|
||||
* VNote has a series of powerful shortcuts. Please view the user configuration file `vnotex.json` for a complete list of shortcuts.
|
||||
* The key sequence `Ctrl+G, I` means that first press both `Ctrl` and `G` simultaneously, release them, then press `I` and release.
|
||||
* Feedbacks are appreciated! Please [post an issue](https://github.com/vnotex/vnote/issues) on GitHub if there is any.
|
||||
|
||||
### Windows Users
|
||||
* if VNote hangs frequently or behaves unexpectedly in interface, please check the **OpenGL** option. [Details here](https://github.com/vnotex/vnote/issues/853).
|
||||
* Please close *Youdao Dict* or disable its fetching-word feature.
|
||||
|
@ -5,8 +5,10 @@
|
||||
|
||||
## 常见问题
|
||||
* 如果更新后 VNote 崩溃,请删除用户配置文件夹中的 `vnotex.json` 文件。
|
||||
* 对于 **Windows** 用户,如果 VNote 经常卡顿或无响应,或者界面异常,请检查 **OpenGL** 选项。[详情](https://github.com/vnotex/vnote/issues/853) 。
|
||||
* VNote 有着一系列强大的快捷键。请查看用户配置文件 `vnotex.json` 以获取一个完整的快捷键列表。
|
||||
* 按键序列 `Ctrl+G, I` 表示先同时按下 `Ctrl` 和 `G`,释放,然后按下 `I` 并释放。
|
||||
* 使用中有任何问题,欢迎[反馈](https://github.com/vnotex/vnote/issues) 。
|
||||
|
||||
## Windows 用户
|
||||
* 如果 VNote 经常卡顿或无响应,或者界面异常,请检查 **OpenGL** 选项。[详情](https://github.com/vnotex/vnote/issues/853) 。
|
||||
* 请关闭 *有道词典* 或者禁用其取词翻译功能。
|
||||
|
@ -7,16 +7,18 @@
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
#include <QAction>
|
||||
#include <QList>
|
||||
|
||||
#include "utils.h"
|
||||
#include "pathutils.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
QString ClipboardUtils::getTextFromClipboard()
|
||||
{
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
QString subtype("plain");
|
||||
return clipboard->text(subtype);
|
||||
QString subType(QStringLiteral("plain"));
|
||||
return clipboard->text(subType, QClipboard::Clipboard);
|
||||
}
|
||||
|
||||
void ClipboardUtils::setTextToClipboard(const QString &p_text)
|
||||
@ -25,6 +27,12 @@ void ClipboardUtils::setTextToClipboard(const QString &p_text)
|
||||
clipboard->setText(p_text);
|
||||
}
|
||||
|
||||
void ClipboardUtils::setLinkToClipboard(const QString &p_link)
|
||||
{
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
setMimeDataToClipboard(clipboard, linkMimeData(p_link).release());
|
||||
}
|
||||
|
||||
void ClipboardUtils::clearClipboard()
|
||||
{
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
@ -194,3 +202,21 @@ void ClipboardUtils::setImageLoop(QClipboard *p_clipboard,
|
||||
Utils::sleepWait(100 /* ms */);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<QMimeData> ClipboardUtils::linkMimeData(const QString &p_link)
|
||||
{
|
||||
QList<QUrl> urls;
|
||||
urls.append(PathUtils::pathToUrl(p_link));
|
||||
std::unique_ptr<QMimeData> data(new QMimeData());
|
||||
data->setUrls(urls);
|
||||
|
||||
QString text = urls[0].toEncoded();
|
||||
#if defined(Q_OS_WIN)
|
||||
if (urls[0].isLocalFile()) {
|
||||
text = urls[0].toString(QUrl::EncodeSpaces);
|
||||
}
|
||||
#endif
|
||||
|
||||
data->setText(text);
|
||||
return data;
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ namespace vnotex
|
||||
|
||||
static void setTextToClipboard(const QString &p_text);
|
||||
|
||||
static void setLinkToClipboard(const QString &p_link);
|
||||
|
||||
// @p_mimeData will be owned by utils.
|
||||
static void setMimeDataToClipboard(QClipboard *p_clipboard,
|
||||
QMimeData *p_mimeData,
|
||||
@ -39,6 +41,8 @@ namespace vnotex
|
||||
static void setImageLoop(QClipboard *p_clipboard,
|
||||
const QImage &p_image,
|
||||
QClipboard::Mode p_mode);
|
||||
|
||||
static std::unique_ptr<QMimeData> linkMimeData(const QString &p_link);
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
|
@ -12,10 +12,12 @@
|
||||
#include <buffer/filetypehelper.h>
|
||||
|
||||
#include <vtextedit/markdownutils.h>
|
||||
#include <vtextedit/textutils.h>
|
||||
|
||||
#include <utils/pathutils.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <core/file.h>
|
||||
#include <core/exception.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -78,6 +80,8 @@ void ContentMediaUtils::copyMarkdownMediaFiles(const QString &p_content,
|
||||
Q_ASSERT(link.m_urlInLinkPos < lastPos);
|
||||
lastPos = link.m_urlInLinkPos;
|
||||
|
||||
qDebug() << "link" << link.m_path << link.m_urlInLink;
|
||||
|
||||
if (handledImages.contains(link.m_path)) {
|
||||
auto it = renamedImages.find(link.m_path);
|
||||
if (it != renamedImages.end()) {
|
||||
@ -94,7 +98,8 @@ void ContentMediaUtils::copyMarkdownMediaFiles(const QString &p_content,
|
||||
}
|
||||
|
||||
// Get the relative path of the image and apply it to the dest file path.
|
||||
const auto oldDestFilePath = destDir.filePath(link.m_urlInLink);
|
||||
const auto decodedUrlInLink = vte::TextUtils::decodeUrl(link.m_urlInLink);
|
||||
const auto oldDestFilePath = destDir.filePath(decodedUrlInLink);
|
||||
destDir.mkpath(PathUtils::parentDirPath(oldDestFilePath));
|
||||
auto destFilePath = p_backend ? p_backend->renameIfExistsCaseInsensitive(oldDestFilePath)
|
||||
: FileUtils::renameIfExistsCaseInsensitive(oldDestFilePath);
|
||||
@ -102,13 +107,15 @@ void ContentMediaUtils::copyMarkdownMediaFiles(const QString &p_content,
|
||||
// Rename happens.
|
||||
const auto oldFileName = PathUtils::fileName(oldDestFilePath);
|
||||
const auto newFileName = PathUtils::fileName(destFilePath);
|
||||
qWarning() << QString("image name conflicts when copy. Renamed from (%1) to (%2)").arg(oldFileName, newFileName);
|
||||
qWarning() << QString("image name conflicts when copy, renamed from (%1) to (%2)").arg(oldFileName, newFileName);
|
||||
|
||||
// Update the text content.
|
||||
const auto encodedOldFileName = vte::TextUtils::encodeUrl(oldFileName);
|
||||
const auto encodedNewFileName = vte::TextUtils::encodeUrl(newFileName);
|
||||
auto newUrlInLink(link.m_urlInLink);
|
||||
newUrlInLink.replace(newUrlInLink.size() - oldFileName.size(),
|
||||
oldFileName.size(),
|
||||
newFileName);
|
||||
newUrlInLink.replace(newUrlInLink.size() - encodedOldFileName.size(),
|
||||
encodedOldFileName.size(),
|
||||
encodedNewFileName);
|
||||
|
||||
content.replace(link.m_urlInLinkPos, link.m_urlInLink.size(), newUrlInLink);
|
||||
renamedImages.insert(link.m_path, newUrlInLink);
|
||||
@ -158,7 +165,7 @@ void ContentMediaUtils::removeMarkdownMediaFiles(const File *p_file, INotebookBa
|
||||
handledImages.insert(link.m_path);
|
||||
|
||||
if (!QFileInfo::exists(link.m_path)) {
|
||||
qWarning() << "Image of Markdown file does not exist" << link.m_path << link.m_urlInLink;
|
||||
qWarning() << "image of Markdown file does not exist" << link.m_path << link.m_urlInLink;
|
||||
continue;
|
||||
}
|
||||
p_backend->removeFile(link.m_path);
|
||||
@ -175,10 +182,15 @@ void ContentMediaUtils::copyAttachment(Node *p_node,
|
||||
|
||||
// Copy the whole folder.
|
||||
const auto srcAttachmentFolderPath = p_node->fetchAttachmentFolderPath();
|
||||
if (p_backend) {
|
||||
p_backend->copyDir(srcAttachmentFolderPath, p_destAttachmentFolderPath);
|
||||
} else {
|
||||
FileUtils::copyDir(srcAttachmentFolderPath, p_destAttachmentFolderPath);
|
||||
try {
|
||||
if (p_backend) {
|
||||
p_backend->copyDir(srcAttachmentFolderPath, p_destAttachmentFolderPath);
|
||||
} else {
|
||||
FileUtils::copyDir(srcAttachmentFolderPath, p_destAttachmentFolderPath);
|
||||
}
|
||||
} catch (Exception &e) {
|
||||
qWarning() << "failed to copy attachment folder" << srcAttachmentFolderPath << e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we need to modify links in content.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <QTemporaryFile>
|
||||
#include <QTimer>
|
||||
#include <QBuffer>
|
||||
#include <QPainter>
|
||||
|
||||
#include <vtextedit/markdowneditorconfig.h>
|
||||
#include <vtextedit/previewmgr.h>
|
||||
@ -24,6 +25,8 @@
|
||||
#include <vtextedit/markdownutils.h>
|
||||
#include <vtextedit/networkutils.h>
|
||||
#include <vtextedit/theme.h>
|
||||
#include <vtextedit/previewdata.h>
|
||||
#include <vtextedit/textblockdata.h>
|
||||
|
||||
#include <widgets/dialogs/linkinsertdialog.h>
|
||||
#include <widgets/dialogs/imageinsertdialog.h>
|
||||
@ -40,12 +43,14 @@
|
||||
#include <utils/widgetutils.h>
|
||||
#include <utils/webutils.h>
|
||||
#include <utils/imageutils.h>
|
||||
#include <utils/clipboardutils.h>
|
||||
#include <core/exception.h>
|
||||
#include <core/markdowneditorconfig.h>
|
||||
#include <core/texteditorconfig.h>
|
||||
#include <core/configmgr.h>
|
||||
#include <core/editorconfig.h>
|
||||
#include <core/vnotex.h>
|
||||
#include <core/fileopenparameters.h>
|
||||
#include <imagehost/imagehostutils.h>
|
||||
#include <imagehost/imagehost.h>
|
||||
#include <imagehost/imagehostmgr.h>
|
||||
@ -960,7 +965,9 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
|
||||
// QAction *copyAct = WidgetUtils::findActionByObjectName(actions, "edit-copy");
|
||||
QAction *pasteAct = WidgetUtils::findActionByObjectName(actions, "edit-paste");
|
||||
|
||||
if (!m_textEdit->hasSelection()) {
|
||||
const bool hasSelection = m_textEdit->hasSelection();
|
||||
|
||||
if (!hasSelection) {
|
||||
auto readAct = new QAction(tr("&Read"), menu);
|
||||
WidgetUtils::addActionShortcutText(readAct,
|
||||
ConfigMgr::getInst().getEditorConfig().getShortcut(EditorConfig::Shortcut::EditRead));
|
||||
@ -970,6 +977,8 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
|
||||
if (firstAct) {
|
||||
menu->insertSeparator(firstAct);
|
||||
}
|
||||
|
||||
prependContextSensitiveMenu(menu, p_event->pos());
|
||||
}
|
||||
|
||||
if (pasteAct && pasteAct->isEnabled()) {
|
||||
@ -1001,7 +1010,9 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
|
||||
ConfigMgr::getInst().getEditorConfig().getShortcut(EditorConfig::Shortcut::ApplySnippet));
|
||||
}
|
||||
|
||||
appendImageHostMenu(menu);
|
||||
if (!hasSelection) {
|
||||
appendImageHostMenu(menu);
|
||||
}
|
||||
|
||||
appendSpellCheckMenu(p_event, menu);
|
||||
}
|
||||
@ -1443,3 +1454,203 @@ void MarkdownEditor::uploadImagesToImageHost()
|
||||
m_textEdit->setTextCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkdownEditor::prependContextSensitiveMenu(QMenu *p_menu, const QPoint &p_pos)
|
||||
{
|
||||
auto cursor = m_textEdit->cursorForPosition(p_pos);
|
||||
const int pos = cursor.position();
|
||||
const auto block = cursor.block();
|
||||
|
||||
Q_ASSERT(!p_menu->isEmpty());
|
||||
auto firstAct = p_menu->actions().at(0);
|
||||
|
||||
bool ret = prependImageMenu(p_menu, firstAct, pos, block);
|
||||
if (ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = prependLinkMenu(p_menu, firstAct, pos, block);
|
||||
if (ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (prependInPlacePreviewMenu(p_menu, firstAct, pos, block)) {
|
||||
p_menu->insertSeparator(firstAct);
|
||||
}
|
||||
}
|
||||
|
||||
bool MarkdownEditor::prependImageMenu(QMenu *p_menu, QAction *p_before, int p_cursorPos, const QTextBlock &p_block)
|
||||
{
|
||||
const auto text = p_block.text();
|
||||
|
||||
if (!vte::MarkdownUtils::hasImageLink(text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString imgPath;
|
||||
|
||||
const auto ®ions = getHighlighter()->getImageRegions();
|
||||
for (const auto ® : regions) {
|
||||
if (!reg.contains(p_cursorPos) && (!reg.contains(p_cursorPos - 1) || p_cursorPos != p_block.position() + text.size())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reg.m_endPos > p_block.position() + text.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto linkText = text.mid(reg.m_startPos - p_block.position(), reg.m_endPos - reg.m_startPos);
|
||||
int linkWidth = 0;
|
||||
int linkHeight = 0;
|
||||
const auto shortUrl = vte::MarkdownUtils::fetchImageLinkUrl(linkText, linkWidth, linkHeight);
|
||||
if (shortUrl.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
imgPath = vte::MarkdownUtils::linkUrlToPath(getBasePath(), shortUrl);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
auto act = new QAction(tr("View Image"), p_menu);
|
||||
connect(act, &QAction::triggered,
|
||||
p_menu, [imgPath]() {
|
||||
WidgetUtils::openUrlByDesktop(PathUtils::pathToUrl(imgPath));
|
||||
});
|
||||
p_menu->insertAction(p_before, act);
|
||||
}
|
||||
|
||||
{
|
||||
auto act = new QAction(tr("Copy Image URL"), p_menu);
|
||||
connect(act, &QAction::triggered,
|
||||
p_menu, [imgPath]() {
|
||||
ClipboardUtils::setLinkToClipboard(imgPath);
|
||||
});
|
||||
p_menu->insertAction(p_before, act);
|
||||
}
|
||||
|
||||
if (QFileInfo::exists(imgPath)) {
|
||||
// Local image.
|
||||
auto act = new QAction(tr("Copy Image"), p_menu);
|
||||
connect(act, &QAction::triggered,
|
||||
p_menu, [imgPath]() {
|
||||
auto clipboard = QApplication::clipboard();
|
||||
clipboard->clear();
|
||||
|
||||
auto img = FileUtils::imageFromFile(imgPath);
|
||||
if (!img.isNull()) {
|
||||
ClipboardUtils::setImageToClipboard(clipboard, img);
|
||||
}
|
||||
});
|
||||
p_menu->insertAction(p_before, act);
|
||||
} else {
|
||||
// Online image.
|
||||
prependInPlacePreviewMenu(p_menu, p_before, p_cursorPos, p_block);
|
||||
}
|
||||
|
||||
p_menu->insertSeparator(p_before);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MarkdownEditor::prependInPlacePreviewMenu(QMenu *p_menu, QAction *p_before, int p_cursorPos, const QTextBlock &p_block)
|
||||
{
|
||||
auto data = vte::TextBlockData::get(p_block);
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto previewData = data->getBlockPreviewData();
|
||||
if (!previewData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QPixmap image;
|
||||
QRgb background = 0;
|
||||
const int pib = p_cursorPos - p_block.position();
|
||||
for (const auto &info : previewData->getPreviewData()) {
|
||||
const auto *imageData = info->getImageData();
|
||||
if (!imageData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (imageData->contains(pib) || (imageData->contains(pib - 1) && pib == p_block.length() - 1)) {
|
||||
const auto *img = findImageFromDocumentResourceMgr(imageData->m_imageName);
|
||||
if (img) {
|
||||
image = *img;
|
||||
background = imageData->m_backgroundColor;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (image.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto act = new QAction(tr("Copy In-Place Preview"), p_menu);
|
||||
connect(act, &QAction::triggered,
|
||||
p_menu, [this, image, background]() {
|
||||
QColor color(background);
|
||||
if (background == 0) {
|
||||
color = m_textEdit->palette().color(QPalette::Base);
|
||||
}
|
||||
QImage img(image.size(), QImage::Format_ARGB32);
|
||||
img.fill(color);
|
||||
QPainter painter(&img);
|
||||
painter.drawPixmap(img.rect(), image);
|
||||
|
||||
auto clipboard = QApplication::clipboard();
|
||||
clipboard->clear();
|
||||
ClipboardUtils::setImageToClipboard(clipboard, img);
|
||||
});
|
||||
|
||||
p_menu->insertAction(p_before, act);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MarkdownEditor::prependLinkMenu(QMenu *p_menu, QAction *p_before, int p_cursorPos, const QTextBlock &p_block)
|
||||
{
|
||||
const auto text = p_block.text();
|
||||
|
||||
QRegularExpression regExp(vte::MarkdownUtils::c_linkRegExp);
|
||||
QString linkText;
|
||||
const int pib = p_cursorPos - p_block.position();
|
||||
auto matchIter = regExp.globalMatch(text);
|
||||
while (matchIter.hasNext()) {
|
||||
auto match = matchIter.next();
|
||||
if (pib >= match.capturedStart() && pib < match.capturedEnd()) {
|
||||
linkText = match.captured(2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (linkText.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto linkUrl = vte::MarkdownUtils::linkUrlToPath(getBasePath(), linkText);
|
||||
|
||||
{
|
||||
auto act = new QAction(tr("Open Link"), p_menu);
|
||||
connect(act, &QAction::triggered,
|
||||
p_menu, [linkUrl]() {
|
||||
emit VNoteX::getInst().openFileRequested(linkUrl, QSharedPointer<FileOpenParameters>::create());
|
||||
});
|
||||
p_menu->insertAction(p_before, act);
|
||||
}
|
||||
|
||||
{
|
||||
auto act = new QAction(tr("Copy Link"), p_menu);
|
||||
connect(act, &QAction::triggered,
|
||||
p_menu, [linkUrl]() {
|
||||
ClipboardUtils::setLinkToClipboard(linkUrl);
|
||||
});
|
||||
p_menu->insertAction(p_before, act);
|
||||
}
|
||||
|
||||
p_menu->insertSeparator(p_before);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -193,6 +193,14 @@ namespace vnotex
|
||||
|
||||
void uploadImagesToImageHost();
|
||||
|
||||
void prependContextSensitiveMenu(QMenu *p_menu, const QPoint &p_pos);
|
||||
|
||||
bool prependImageMenu(QMenu *p_menu, QAction *p_before, int p_cursorPos, const QTextBlock &p_block);
|
||||
|
||||
bool prependInPlacePreviewMenu(QMenu *p_menu, QAction *p_before, int p_cursorPos, const QTextBlock &p_block);
|
||||
|
||||
bool prependLinkMenu(QMenu *p_menu, QAction *p_before, int p_cursorPos, const QTextBlock &p_block);
|
||||
|
||||
static QString generateImageFileNameToInsertAs(const QString &p_title, const QString &p_suffix);
|
||||
|
||||
const MarkdownEditorConfig &m_config;
|
||||
|
@ -130,7 +130,7 @@ void MarkdownViewWindow::setModeInternal(ViewWindowMode p_mode, bool p_syncBuffe
|
||||
toggleDebug();
|
||||
}
|
||||
|
||||
bool hideViewer = true;
|
||||
bool hideViewer = m_viewerReady;
|
||||
if (!m_editor) {
|
||||
// We need viewer to preview.
|
||||
if (!m_viewer) {
|
||||
@ -485,6 +485,7 @@ void MarkdownViewWindow::setupViewer()
|
||||
});
|
||||
connect(adapter, &MarkdownViewerAdapter::viewerReady,
|
||||
this, [this]() {
|
||||
m_viewerReady = true;
|
||||
if (m_mode == ViewWindowMode::Edit) {
|
||||
m_viewer->hide();
|
||||
}
|
||||
|
@ -208,6 +208,8 @@ namespace vnotex
|
||||
QSharedPointer<OutlineProvider> m_outlineProvider;
|
||||
|
||||
ImageHost *m_imageHost = nullptr;
|
||||
|
||||
bool m_viewerReady = false;
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user