editor: add PasteAsBlockQuote menu action

This commit is contained in:
Le Tan 2018-03-16 21:38:53 +08:00
parent de7ea32104
commit e38ec22263
4 changed files with 86 additions and 7 deletions

View File

@ -962,3 +962,29 @@ void VEditUtils::insertBlock(QTextCursor &p_cursor,
p_cursor.movePosition(QTextCursor::EndOfBlock); p_cursor.movePosition(QTextCursor::EndOfBlock);
} }
void VEditUtils::insertBeforeEachLine(QString &p_text, const QString &p_str)
{
int pos = 0;
while (pos < p_text.size()) {
int idx = p_text.indexOf("\n", pos);
if (idx == -1) {
break;
}
++idx;
if (idx == p_text.size()) {
break;
}
p_text.insert(idx, p_str);
pos = idx + p_str.size();
}
p_text.prepend(p_str);
}
bool VEditUtils::isEmptyBlock(const QTextBlock &p_block)
{
return p_block.length() == 1;
}

View File

@ -189,6 +189,12 @@ public:
static void insertBlock(QTextCursor &p_cursor, static void insertBlock(QTextCursor &p_cursor,
bool p_above); bool p_above);
// Insert @p_str in the front of each line of @p_text.
static void insertBeforeEachLine(QString &p_text, const QString &p_str);
// Whether @p_block is empty.
static bool isEmptyBlock(const QTextBlock &p_block);
private: private:
VEditUtils() {} VEditUtils() {}
}; };

View File

@ -3,6 +3,8 @@
#include <QtWidgets> #include <QtWidgets>
#include <QMenu> #include <QMenu>
#include <QDebug> #include <QDebug>
#include <QScopedPointer>
#include <QClipboard>
#include "vdocument.h" #include "vdocument.h"
#include "utils/veditutils.h" #include "utils/veditutils.h"
@ -272,7 +274,7 @@ void VMdEditor::makeBlockVisible(const QTextBlock &p_block)
void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event) void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
{ {
QMenu *menu = createStandardContextMenu(); QScopedPointer<QMenu> menu(createStandardContextMenu());
menu->setToolTipsVisible(true); menu->setToolTipsVisible(true);
VEditTab *editTab = dynamic_cast<VEditTab *>(parent()); VEditTab *editTab = dynamic_cast<VEditTab *>(parent());
@ -281,11 +283,11 @@ void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
const QList<QAction *> actions = menu->actions(); const QList<QAction *> actions = menu->actions();
if (textCursor().hasSelection()) { if (textCursor().hasSelection()) {
initCopyAsMenu(actions.isEmpty() ? NULL : actions.last(), menu); initCopyAsMenu(actions.isEmpty() ? NULL : actions.last(), menu.data());
} else { } else {
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"),
menu); menu.data());
saveExitAct->setToolTip(tr("Save changes and exit edit mode")); saveExitAct->setToolTip(tr("Save changes and exit edit mode"));
connect(saveExitAct, &QAction::triggered, connect(saveExitAct, &QAction::triggered,
this, [this]() { this, [this]() {
@ -294,7 +296,7 @@ void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
QAction *discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"), QAction *discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"),
tr("&Discard Changes And Read"), tr("&Discard Changes And Read"),
menu); menu.data());
discardExitAct->setToolTip(tr("Discard changes and exit edit mode")); discardExitAct->setToolTip(tr("Discard changes and exit edit mode"));
connect(discardExitAct, &QAction::triggered, connect(discardExitAct, &QAction::triggered,
this, [this]() { this, [this]() {
@ -303,15 +305,20 @@ void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
menu->insertAction(actions.isEmpty() ? NULL : actions[0], discardExitAct); menu->insertAction(actions.isEmpty() ? NULL : actions[0], discardExitAct);
menu->insertAction(discardExitAct, saveExitAct); menu->insertAction(discardExitAct, saveExitAct);
if (!actions.isEmpty()) {
menu->insertSeparator(actions[0]);
}
} }
if (!actions.isEmpty()) { QClipboard *clipboard = QApplication::clipboard();
menu->insertSeparator(actions[0]); const QMimeData *mimeData = clipboard->mimeData();
if (mimeData->hasText()) {
initPasteAsBlockQuoteMenu(menu.data());
} }
} }
menu->exec(p_event->globalPos()); menu->exec(p_event->globalPos());
delete menu;
} }
void VMdEditor::mousePressEvent(QMouseEvent *p_event) void VMdEditor::mousePressEvent(QMouseEvent *p_event)
@ -1219,6 +1226,44 @@ void VMdEditor::initCopyAsMenu(QAction *p_before, QMenu *p_menu)
} }
} }
void VMdEditor::initPasteAsBlockQuoteMenu(QMenu *p_menu)
{
QAction *pbqAct = new QAction(tr("Paste As Block &Quote"), p_menu);
pbqAct->setToolTip(tr("Paste text from clipboard as block quote"));
connect(pbqAct, &QAction::triggered,
this, [this]() {
QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
QString text = mimeData->text();
QTextCursor cursor = textCursor();
cursor.removeSelectedText();
QTextBlock block = cursor.block();
QString indent = VEditUtils::fetchIndentSpaces(block);
// Insert '> ' in front of each line.
VEditUtils::insertBeforeEachLine(text, indent + QStringLiteral("> "));
if (VEditUtils::isSpaceBlock(block)) {
if (!indent.isEmpty()) {
// Remove the indent.
cursor.movePosition(QTextCursor::StartOfBlock);
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
}
} else {
// Insert a new block.
VEditUtils::insertBlock(cursor, false);
}
cursor.insertText(text);
setTextCursor(cursor);
});
p_menu->addSeparator();
p_menu->addAction(pbqAct);
}
void VMdEditor::insertImageLink(const QString &p_text, const QString &p_url) void VMdEditor::insertImageLink(const QString &p_text, const QString &p_url)
{ {
VInsertLinkDialog dialog(tr("Insert Image Link"), VInsertLinkDialog dialog(tr("Insert Image Link"),

View File

@ -236,6 +236,8 @@ private:
void initCopyAsMenu(QAction *p_before, QMenu *p_menu); void initCopyAsMenu(QAction *p_before, QMenu *p_menu);
void initPasteAsBlockQuoteMenu(QMenu *p_menu);
void insertImageLink(const QString &p_text, const QString &p_url); void insertImageLink(const QString &p_text, const QString &p_url);
HGMarkdownHighlighter *m_mdHighlighter; HGMarkdownHighlighter *m_mdHighlighter;