Browse Source

editor: add PasteAsBlockQuote menu action

Le Tan 7 years ago
parent
commit
e38ec22263
4 changed files with 86 additions and 7 deletions
  1. 26 0
      src/utils/veditutils.cpp
  2. 6 0
      src/utils/veditutils.h
  3. 52 7
      src/vmdeditor.cpp
  4. 2 0
      src/vmdeditor.h

+ 26 - 0
src/utils/veditutils.cpp

@@ -962,3 +962,29 @@ void VEditUtils::insertBlock(QTextCursor &p_cursor,
 
     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;
+}

+ 6 - 0
src/utils/veditutils.h

@@ -189,6 +189,12 @@ public:
     static void insertBlock(QTextCursor &p_cursor,
                             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:
     VEditUtils() {}
 };

+ 52 - 7
src/vmdeditor.cpp

@@ -3,6 +3,8 @@
 #include <QtWidgets>
 #include <QMenu>
 #include <QDebug>
+#include <QScopedPointer>
+#include <QClipboard>
 
 #include "vdocument.h"
 #include "utils/veditutils.h"
@@ -272,7 +274,7 @@ void VMdEditor::makeBlockVisible(const QTextBlock &p_block)
 
 void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
 {
-    QMenu *menu = createStandardContextMenu();
+    QScopedPointer<QMenu> menu(createStandardContextMenu());
     menu->setToolTipsVisible(true);
 
     VEditTab *editTab = dynamic_cast<VEditTab *>(parent());
@@ -281,11 +283,11 @@ void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
         const QList<QAction *> actions = menu->actions();
 
         if (textCursor().hasSelection()) {
-            initCopyAsMenu(actions.isEmpty() ? NULL : actions.last(), menu);
+            initCopyAsMenu(actions.isEmpty() ? NULL : actions.last(), menu.data());
         } else {
             QAction *saveExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/save_exit.svg"),
                                                tr("&Save Changes And Read"),
-                                               menu);
+                                               menu.data());
             saveExitAct->setToolTip(tr("Save changes and exit edit mode"));
             connect(saveExitAct, &QAction::triggered,
                     this, [this]() {
@@ -294,7 +296,7 @@ void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
 
             QAction *discardExitAct = new QAction(VIconUtils::menuIcon(":/resources/icons/discard_exit.svg"),
                                                   tr("&Discard Changes And Read"),
-                                                  menu);
+                                                  menu.data());
             discardExitAct->setToolTip(tr("Discard changes and exit edit mode"));
             connect(discardExitAct, &QAction::triggered,
                     this, [this]() {
@@ -303,15 +305,20 @@ void VMdEditor::contextMenuEvent(QContextMenuEvent *p_event)
 
             menu->insertAction(actions.isEmpty() ? NULL : actions[0], discardExitAct);
             menu->insertAction(discardExitAct, saveExitAct);
+
+            if (!actions.isEmpty()) {
+                menu->insertSeparator(actions[0]);
+            }
         }
 
-        if (!actions.isEmpty()) {
-            menu->insertSeparator(actions[0]);
+        QClipboard *clipboard = QApplication::clipboard();
+        const QMimeData *mimeData = clipboard->mimeData();
+        if (mimeData->hasText()) {
+            initPasteAsBlockQuoteMenu(menu.data());
         }
     }
 
     menu->exec(p_event->globalPos());
-    delete menu;
 }
 
 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)
 {
     VInsertLinkDialog dialog(tr("Insert Image Link"),

+ 2 - 0
src/vmdeditor.h

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