MdEditor: support copy in-place preview

This commit is contained in:
Le Tan 2018-08-19 12:06:50 +08:00
parent f98c2f5382
commit 1ce8c05da9
7 changed files with 126 additions and 36 deletions

View File

@ -35,6 +35,20 @@ void VClipboardUtils::setImageLoop(QClipboard *p_clipboard,
} }
} }
void VClipboardUtils::setImageToClipboard(QClipboard *p_clipboard,
const QPixmap &p_image,
QClipboard::Mode p_mode)
{
QImage img(p_image.toImage());
#if defined(Q_OS_WIN)
// On Windows, setImage() may fail. We will repeatedly retry until succeed.
setImageLoop(p_clipboard, img, p_mode);
#else
p_clipboard->setImage(img, p_mode);
#endif
}
void VClipboardUtils::setMimeDataToClipboard(QClipboard *p_clipboard, void VClipboardUtils::setMimeDataToClipboard(QClipboard *p_clipboard,
QMimeData *p_mimeData, QMimeData *p_mimeData,
QClipboard::Mode p_mode) QClipboard::Mode p_mode)

View File

@ -2,6 +2,7 @@
#define VCLIPBOARDUTILS_H #define VCLIPBOARDUTILS_H
#include <QImage> #include <QImage>
#include <QPixmap>
#include <QClipboard> #include <QClipboard>
class QMimeData; class QMimeData;
@ -14,6 +15,10 @@ public:
const QImage &p_image, const QImage &p_image,
QClipboard::Mode p_mode = QClipboard::Clipboard); QClipboard::Mode p_mode = QClipboard::Clipboard);
static void setImageToClipboard(QClipboard *p_clipboard,
const QPixmap &p_image,
QClipboard::Mode p_mode = QClipboard::Clipboard);
static void setImageAndLinkToClipboard(QClipboard *p_clipboard, static void setImageAndLinkToClipboard(QClipboard *p_clipboard,
const QImage &p_image, const QImage &p_image,
const QString &p_link, const QString &p_link,

View File

@ -303,7 +303,9 @@ void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
if (textCursor().hasSelection()) { if (textCursor().hasSelection()) {
initCopyAsMenu(actions.isEmpty() ? NULL : actions.last(), menu.data()); initCopyAsMenu(actions.isEmpty() ? NULL : actions.last(), menu.data());
} else { } else {
initLinkMenu(actions.isEmpty() ? NULL : actions[0], menu.data(), p_event->pos()); initLinkAndPreviewMenu(actions.isEmpty() ? NULL : actions[0],
menu.data(),
p_event->pos());
QAction *saveExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/save_exit.svg"), QAction *saveExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/save_exit.svg"),
tr("&Save Changes And Read"), tr("&Save Changes And Read"),
@ -1462,7 +1464,7 @@ int VMdEditor::lineNumberAreaWidth() const
return VTextEdit::lineNumberAreaWidth(); return VTextEdit::lineNumberAreaWidth();
} }
void VMdEditor::initLinkMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_pos) void VMdEditor::initLinkAndPreviewMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_pos)
{ {
QTextCursor cursor = cursorForPosition(p_pos); QTextCursor cursor = cursorForPosition(p_pos);
int pos = cursor.position(); int pos = cursor.position();
@ -1536,6 +1538,9 @@ void VMdEditor::initLinkMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_p
} }
}); });
p_menu->insertAction(p_before, copyImageAct); p_menu->insertAction(p_before, copyImageAct);
} else {
// Copy in-place preview.
initInPlacePreviewMenu(p_before, p_menu, block, pos);
} }
p_menu->insertSeparator(p_before ? p_before : NULL); p_menu->insertSeparator(p_before ? p_before : NULL);
@ -1560,10 +1565,7 @@ void VMdEditor::initLinkMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_p
} }
} }
if (linkText.isEmpty()) { if (!linkText.isEmpty()) {
return;
}
QString linkUrl = VUtils::linkUrlToPath(m_file->fetchBasePath(), linkText); QString linkUrl = VUtils::linkUrlToPath(m_file->fetchBasePath(), linkText);
bool isLocalFile = QFileInfo::exists(linkUrl); bool isLocalFile = QFileInfo::exists(linkUrl);
@ -1599,4 +1601,55 @@ void VMdEditor::initLinkMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_p
} }
p_menu->insertSeparator(p_before ? p_before : NULL); p_menu->insertSeparator(p_before ? p_before : NULL);
return;
}
if (initInPlacePreviewMenu(p_before, p_menu, block, pos)) {
p_menu->insertSeparator(p_before ? p_before : NULL);
}
}
bool VMdEditor::initInPlacePreviewMenu(QAction *p_before,
QMenu *p_menu,
const QTextBlock &p_block,
int p_pos)
{
VTextBlockData *data = VTextBlockData::blockData(p_block);
if (!data) {
return false;
}
const QVector<VPreviewInfo *> &previews = data->getPreviews();
if (previews.isEmpty()) {
return false;
}
QPixmap image;
int pib = p_pos - p_block.position();
for (auto info : previews) {
const VPreviewedImageInfo &pii = info->m_imageInfo;
if (pii.contains(pib)) {
const QPixmap *img = findImage(pii.m_imageName);
if (img) {
image = *img;
}
break;
}
}
if (image.isNull()) {
return false;
}
QAction *copyImageAct = new QAction(tr("Copy In-Place Preview"), p_menu);
connect(copyImageAct, &QAction::triggered,
this, [this, image]() {
QClipboard *clipboard = QApplication::clipboard();
VClipboardUtils::setImageToClipboard(clipboard,
image,
QClipboard::Clipboard);
});
p_menu->insertAction(p_before, copyImageAct);
return true;
} }

View File

@ -277,7 +277,12 @@ private:
void initPasteAsBlockQuoteMenu(QMenu *p_menu); void initPasteAsBlockQuoteMenu(QMenu *p_menu);
void initLinkMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_pos); void initLinkAndPreviewMenu(QAction *p_before, QMenu *p_menu, const QPoint &p_pos);
bool initInPlacePreviewMenu(QAction *p_before,
QMenu *p_menu,
const QTextBlock &p_block,
int p_pos);
void insertImageLink(const QString &p_text, const QString &p_url); void insertImageLink(const QString &p_text, const QString &p_url);

View File

@ -68,6 +68,11 @@ struct VPreviewedImageInfo
return !(m_endPos <= a.m_startPos || m_startPos >= a.m_endPos); return !(m_endPos <= a.m_startPos || m_startPos >= a.m_endPos);
} }
bool contains(int p_positionInBlock) const
{
return p_positionInBlock >= m_startPos && p_positionInBlock < m_endPos;
}
QString toString() const QString toString() const
{ {
return QString("previewed image (%1): [%2, %3] padding %4 inline %5 (%6,%7) bg(%8)") return QString("previewed image (%1): [%2, %3] padding %4 inline %5 (%6,%7) bg(%8)")

View File

@ -362,6 +362,11 @@ QSize VTextEdit::imageSize(const QString &p_imageName) const
return QSize(); return QSize();
} }
const QPixmap *VTextEdit::findImage(const QString &p_name) const
{
return m_imageMgr->findImage(p_name);
}
void VTextEdit::addImage(const QString &p_imageName, const QPixmap &p_image) void VTextEdit::addImage(const QString &p_imageName, const QPixmap &p_image)
{ {
if (m_blockImageEnabled) { if (m_blockImageEnabled) {

View File

@ -49,6 +49,9 @@ public:
// Get the image size from the resource manager. // Get the image size from the resource manager.
QSize imageSize(const QString &p_imageName) const; QSize imageSize(const QString &p_imageName) const;
// Get the image from the resource manager.
const QPixmap *findImage(const QString &p_name) const;
// Add an image to the resources. // Add an image to the resources.
void addImage(const QString &p_imageName, const QPixmap &p_image); void addImage(const QString &p_imageName, const QPixmap &p_image);