Browse Source

add toolbar for text editing

Bold, italic, underline, strikethrough, inline code.

Underline and strikethrough are not implemented yet.
Le Tan 8 years ago
parent
commit
f9f7a365f8

+ 7 - 0
src/resources/icons/bold.svg

@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <g>
+  <title>Layer 1</title>
+  <text stroke="#000000" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " font-weight="bold" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="24" id="svg_4" y="248.490375" x="-146.756839" stroke-width="0" fill="#000000">B</text>
+ </g>
+</svg>

+ 7 - 0
src/resources/icons/inline_code.svg

@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <g>
+  <title>Layer 1</title>
+  <text style="cursor: move;" fill="#000000" stroke-width="0" x="-146.756839" y="248.490375" id="svg_4" font-size="24" font-family="serif" text-anchor="middle" xml:space="preserve" font-weight="normal" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " stroke="#000000" font-style="normal">O</text>
+ </g>
+</svg>

+ 7 - 0
src/resources/icons/italic.svg

@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <g>
+  <title>Layer 1</title>
+  <text font-style="italic" stroke="#000000" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " font-weight="normal" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="24" id="svg_4" y="248.490375" x="-146.756839" stroke-width="0" fill="#000000">I</text>
+ </g>
+</svg>

+ 8 - 0
src/resources/icons/strikethrough.svg

@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <g>
+  <title>Layer 1</title>
+  <text fill="#000000" stroke-width="0" x="-146.756839" y="248.490375" id="svg_4" font-size="24" font-family="serif" text-anchor="middle" xml:space="preserve" font-weight="normal" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " stroke="#000000" font-style="normal">S</text>
+  <rect stroke="#000000" fill="#000000" stroke-width="5" x="94.999999" y="282" width="318.999997" height="21" id="svg_2" stroke-opacity="0"/>
+ </g>
+</svg>

+ 8 - 0
src/resources/icons/underline.svg

@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <g>
+  <title>Layer 1</title>
+  <text style="cursor: move;" font-style="normal" stroke="#000000" transform="matrix(16.72881317138672,0,0,16.72881317138672,2707.567729830742,-3759.186347961426) " font-weight="normal" xml:space="preserve" text-anchor="middle" font-family="serif" font-size="24" id="svg_4" y="248.490375" x="-146.756839" stroke-width="0" fill="#000000">U</text>
+  <rect stroke="#000000" stroke-opacity="0" id="svg_2" height="21" width="322.000016" y="422" x="91.999999" stroke-width="5" fill="#000000"/>
+ </g>
+</svg>

+ 2 - 2
src/utils/vvim.cpp

@@ -4241,8 +4241,8 @@ int VVim::blockCountOfPageStep() const
 void VVim::selectionToVisualMode(bool p_hasText)
 {
     if (p_hasText && m_mode == VimMode::Normal) {
-        // Enter visual mode.
-        setMode(VimMode::Visual);
+        // Enter visual mode without clearing the selection.
+        setMode(VimMode::Visual, false);
     }
 }
 

+ 7 - 0
src/vconstants.h

@@ -34,4 +34,11 @@ namespace DirConfig
 }
 
 static const QString c_emptyHeaderName = "[EMPTY]";
+
+enum class TextDecoration { None,
+                            Bold,
+                            Italic,
+                            Underline,
+                            Strikethrough,
+                            InlineCode };
 #endif

+ 7 - 0
src/vedit.cpp

@@ -826,3 +826,10 @@ void VEdit::setInputMethodEnabled(bool p_enabled)
         im->update(Qt::ImEnabled);
     }
 }
+
+void VEdit::decorateText(TextDecoration p_decoration)
+{
+    if (m_editOps) {
+        m_editOps->decorateText(p_decoration);
+    }
+}

+ 3 - 0
src/vedit.h

@@ -92,6 +92,9 @@ public:
 
     void setInputMethodEnabled(bool p_enabled);
 
+    // Insert decoration markers or decorate selected text.
+    void decorateText(TextDecoration p_decoration);
+
 signals:
     // Request VEditTab to save and exit edit mode.
     void saveAndRead();

+ 3 - 0
src/veditoperations.h

@@ -30,6 +30,9 @@ public:
     // Request to propogate Vim status.
     void requestUpdateVimStatus();
 
+    // Insert decoration markers or decorate selected text.
+    virtual void decorateText(TextDecoration p_decoration) {Q_UNUSED(p_decoration);};
+
 signals:
     // Want to display a template message in status bar.
     void statusMessage(const QString &p_msg);

+ 3 - 0
src/vedittab.h

@@ -68,6 +68,9 @@ public:
     // Request current tab to propogate its status about Vim.
     virtual void requestUpdateVimStatus() = 0;
 
+    // Insert decoration markers or decorate selected text.
+    virtual void decorateText(TextDecoration p_decoration) {Q_UNUSED(p_decoration);};
+
 public slots:
     // Enter edit mode
     virtual void editFile() = 0;

+ 93 - 1
src/vmainwindow.cpp

@@ -175,6 +175,7 @@ void VMainWindow::initToolBar()
 {
     initFileToolBar();
     initViewToolBar();
+    initEditToolBar();
 }
 
 void VMainWindow::initViewToolBar()
@@ -210,6 +211,90 @@ void VMainWindow::initViewToolBar()
     viewToolBar->addAction(expandViewAct);
 }
 
+static void setActionsVisible(QWidget *p_widget, bool p_visible)
+{
+    Q_ASSERT(p_widget);
+    QList<QAction *> actions = p_widget->actions();
+    for (auto const & act : actions) {
+        act->setVisible(p_visible);
+    }
+}
+
+void VMainWindow::initEditToolBar()
+{
+    m_editToolBar = addToolBar(tr("Edit Toolbar"));
+    m_editToolBar->setObjectName("EditToolBar");
+    m_editToolBar->setMovable(false);
+
+    m_editToolBar->addSeparator();
+
+    QAction *boldAct = new QAction(QIcon(":/resources/icons/bold.svg"),
+                                   tr("Bold"), this);
+    boldAct->setStatusTip(tr("Insert bold text or change selected text to bold"));
+    connect(boldAct, &QAction::triggered,
+            this, [this](){
+                if (m_curTab) {
+                    m_curTab->decorateText(TextDecoration::Bold);
+                }
+            });
+
+    m_editToolBar->addAction(boldAct);
+
+    QAction *italicAct = new QAction(QIcon(":/resources/icons/italic.svg"),
+                                     tr("Italic"), this);
+    italicAct->setStatusTip(tr("Insert italic text or change selected text to italic"));
+    connect(italicAct, &QAction::triggered,
+            this, [this](){
+                if (m_curTab) {
+                    m_curTab->decorateText(TextDecoration::Italic);
+                }
+            });
+
+    m_editToolBar->addAction(italicAct);
+
+    QAction *underlineAct = new QAction(QIcon(":/resources/icons/underline.svg"),
+                                        tr("Underline"), this);
+    underlineAct->setStatusTip(tr("Insert underlined text or change selected text to underlined"));
+    connect(underlineAct, &QAction::triggered,
+            this, [this](){
+                if (m_curTab) {
+                    m_curTab->decorateText(TextDecoration::Underline);
+                }
+            });
+
+    m_editToolBar->addAction(underlineAct);
+
+    QAction *strikethroughAct = new QAction(QIcon(":/resources/icons/strikethrough.svg"),
+                                            tr("Strikethrough"), this);
+    strikethroughAct->setStatusTip(tr("Insert strikethrough text or change selected text to strikethroughed"));
+    connect(strikethroughAct, &QAction::triggered,
+            this, [this](){
+                if (m_curTab) {
+                    m_curTab->decorateText(TextDecoration::Strikethrough);
+                }
+            });
+
+    m_editToolBar->addAction(strikethroughAct);
+
+    QAction *inlineCodeAct = new QAction(QIcon(":/resources/icons/inline_code.svg"),
+                                         tr("Inline Code"), this);
+    inlineCodeAct->setStatusTip(tr("Insert inline-code text or change selected text to inline-coded"));
+    connect(inlineCodeAct, &QAction::triggered,
+            this, [this](){
+                if (m_curTab) {
+                    m_curTab->decorateText(TextDecoration::InlineCode);
+                }
+            });
+
+    m_editToolBar->addAction(inlineCodeAct);
+
+    QAction *toggleAct = m_editToolBar->toggleViewAction();
+    toggleAct->setToolTip(tr("Toggle the edit toolbar"));
+    viewMenu->addAction(toggleAct);
+
+    setActionsVisible(m_editToolBar, false);
+}
+
 void VMainWindow::initFileToolBar()
 {
     QToolBar *fileToolBar = addToolBar(tr("Note"));
@@ -507,6 +592,7 @@ void VMainWindow::initMarkdownMenu()
 void VMainWindow::initViewMenu()
 {
     viewMenu = menuBar()->addMenu(tr("&View"));
+    viewMenu->setToolTipsVisible(true);
 }
 
 void VMainWindow::initFileMenu()
@@ -795,7 +881,10 @@ void VMainWindow::initDockWindows()
     toolBox->addItem(outline, QIcon(":/resources/icons/outline.svg"), tr("Outline"));
     toolDock->setWidget(toolBox);
     addDockWidget(Qt::RightDockWidgetArea, toolDock);
-    viewMenu->addAction(toolDock->toggleViewAction());
+
+    QAction *toggleAct = toolDock->toggleViewAction();
+    toggleAct->setToolTip(tr("Toggle the tools dock widget"));
+    viewMenu->addAction(toggleAct);
 }
 
 void VMainWindow::initAvatar()
@@ -1154,6 +1243,9 @@ void VMainWindow::updateActionStateFromTabStatusChange(const VFile *p_file,
     noteInfoAct->setEnabled(p_file && p_file->getType() == FileType::Normal);
 
     m_insertImageAct->setEnabled(p_file && p_editMode);
+
+    setActionsVisible(m_editToolBar, p_file && p_editMode);
+
     // Find/Replace
     m_findReplaceAct->setEnabled(p_file);
     m_findNextAct->setEnabled(p_file);

+ 6 - 0
src/vmainwindow.h

@@ -108,6 +108,9 @@ private:
     void initFileToolBar();
     void initViewToolBar();
 
+    // Init the Edit toolbar.
+    void initEditToolBar();
+
     void initMenuBar();
     void initFileMenu();
     void initEditMenu();
@@ -196,6 +199,9 @@ private:
     // Menus
     QMenu *viewMenu;
 
+    // Edit Toolbar.
+    QToolBar *m_editToolBar;
+
     QVector<QPixmap> predefinedColorPixmaps;
 };
 

+ 149 - 140
src/vmdeditoperations.cpp

@@ -241,10 +241,12 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
 
     case Qt::Key_B:
     {
-        if (handleKeyB(p_event)) {
+        if (modifiers == Qt::ControlModifier) {
+            decorateBold();
+            p_event->accept();
             ret = true;
-            goto exit;
         }
+
         break;
     }
 
@@ -259,19 +261,23 @@ bool VMdEditOperations::handleKeyPressEvent(QKeyEvent *p_event)
 
     case Qt::Key_I:
     {
-        if (handleKeyI(p_event)) {
+        if (modifiers == Qt::ControlModifier) {
+            decorateItalic();
+            p_event->accept();
             ret = true;
-            goto exit;
         }
+
         break;
     }
 
     case Qt::Key_O:
     {
-        if (handleKeyO(p_event)) {
+        if (modifiers == Qt::ControlModifier) {
+            decorateInlineCode();
+            p_event->accept();
             ret = true;
-            goto exit;
         }
+
         break;
     }
 
@@ -435,51 +441,6 @@ bool VMdEditOperations::handleKeyBackTab(QKeyEvent *p_event)
     return true;
 }
 
-bool VMdEditOperations::handleKeyB(QKeyEvent *p_event)
-{
-    if (p_event->modifiers() == Qt::ControlModifier) {
-        // Ctrl+B, Bold.
-        QTextCursor cursor = m_editor->textCursor();
-        if (cursor.hasSelection()) {
-            // Insert ** around the selected text.
-            int start = cursor.selectionStart();
-            int end = cursor.selectionEnd();
-            cursor.beginEditBlock();
-            cursor.clearSelection();
-            cursor.setPosition(start, QTextCursor::MoveAnchor);
-            cursor.insertText("**");
-            cursor.setPosition(end + 2, QTextCursor::MoveAnchor);
-            cursor.insertText("**");
-            cursor.endEditBlock();
-            m_editor->setTextCursor(cursor);
-        } else {
-            // Insert **** and place cursor in the middle.
-            // Or if there are two * after current cursor, just skip them.
-            cursor.beginEditBlock();
-            int pos = cursor.positionInBlock();
-            bool hasStars = false;
-            QString text = cursor.block().text();
-            if (pos <= text.size() - 2) {
-                if (text[pos] == '*' && text[pos + 1] == '*') {
-                    hasStars = true;
-                }
-            }
-            if (hasStars) {
-                cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
-            } else {
-                cursor.insertText("****");
-                cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2);
-            }
-            cursor.endEditBlock();
-            m_editor->setTextCursor(cursor);
-        }
-
-        p_event->accept();
-        return true;
-    }
-    return false;
-}
-
 bool VMdEditOperations::handleKeyH(QKeyEvent *p_event)
 {
     if (p_event->modifiers() == Qt::ControlModifier) {
@@ -493,95 +454,6 @@ bool VMdEditOperations::handleKeyH(QKeyEvent *p_event)
     return false;
 }
 
-bool VMdEditOperations::handleKeyI(QKeyEvent *p_event)
-{
-    if (p_event->modifiers() == Qt::ControlModifier) {
-        // Ctrl+I, Italic.
-        QTextCursor cursor = m_editor->textCursor();
-        if (cursor.hasSelection()) {
-            // Insert * around the selected text.
-            int start = cursor.selectionStart();
-            int end = cursor.selectionEnd();
-            cursor.beginEditBlock();
-            cursor.clearSelection();
-            cursor.setPosition(start, QTextCursor::MoveAnchor);
-            cursor.insertText("*");
-            cursor.setPosition(end + 1, QTextCursor::MoveAnchor);
-            cursor.insertText("*");
-            cursor.endEditBlock();
-            m_editor->setTextCursor(cursor);
-        } else {
-            // Insert ** and place cursor in the middle.
-            // Or if there are one * after current cursor, just skip it.
-            cursor.beginEditBlock();
-            int pos = cursor.positionInBlock();
-            bool hasStar = false;
-            QString text = cursor.block().text();
-            if (pos <= text.size() - 1) {
-                if (text[pos] == '*') {
-                    hasStar = true;
-                }
-            }
-            if (hasStar) {
-                cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
-            } else {
-                cursor.insertText("**");
-                cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
-            }
-            cursor.endEditBlock();
-            m_editor->setTextCursor(cursor);
-        }
-
-        p_event->accept();
-        return true;
-    }
-    return false;
-}
-
-bool VMdEditOperations::handleKeyO(QKeyEvent *p_event)
-{
-    if (p_event->modifiers() == Qt::ControlModifier) {
-        // Ctrl+O, inline codeblock.
-        QTextCursor cursor = m_editor->textCursor();
-        if (cursor.hasSelection()) {
-            // Insert ` around the selected text.
-            int start = cursor.selectionStart();
-            int end = cursor.selectionEnd();
-            cursor.beginEditBlock();
-            cursor.clearSelection();
-            cursor.setPosition(start, QTextCursor::MoveAnchor);
-            cursor.insertText("`");
-            cursor.setPosition(end + 1, QTextCursor::MoveAnchor);
-            cursor.insertText("`");
-            cursor.endEditBlock();
-            m_editor->setTextCursor(cursor);
-        } else {
-            // Insert `` and place cursor in the middle.
-            // Or if there are one ` after current cursor, just skip it.
-            cursor.beginEditBlock();
-            int pos = cursor.positionInBlock();
-            bool hasBackquote = false;
-            QString text = cursor.block().text();
-            if (pos <= text.size() - 1) {
-                if (text[pos] == '`') {
-                    hasBackquote = true;
-                }
-            }
-            if (hasBackquote) {
-                cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
-            } else {
-                cursor.insertText("``");
-                cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
-            }
-            cursor.endEditBlock();
-            m_editor->setTextCursor(cursor);
-        }
-        p_event->accept();
-        return true;
-    }
-    return false;
-}
-
 bool VMdEditOperations::handleKeyU(QKeyEvent *p_event)
 {
     if (p_event->modifiers() == Qt::ControlModifier) {
@@ -775,3 +647,140 @@ bool VMdEditOperations::insertTitle(int p_level)
     return true;
 }
 
+void VMdEditOperations::decorateText(TextDecoration p_decoration)
+{
+    if (p_decoration == TextDecoration::None) {
+        return;
+    }
+
+    m_vim->setMode(VimMode::Insert, false);
+
+    switch (p_decoration) {
+    case TextDecoration::Bold:
+        decorateBold();
+        break;
+
+    case TextDecoration::Italic:
+        decorateItalic();
+        break;
+
+    case TextDecoration::InlineCode:
+        decorateInlineCode();
+        break;
+
+    default:
+        qDebug() << "decoration" << (int)p_decoration << "is not implemented yet";
+        break;
+    }
+}
+
+void VMdEditOperations::decorateBold()
+{
+    QTextCursor cursor = m_editor->textCursor();
+    cursor.beginEditBlock();
+    if (cursor.hasSelection()) {
+        // Insert ** around the selected text.
+        int start = cursor.selectionStart();
+        int end = cursor.selectionEnd();
+        cursor.clearSelection();
+        cursor.setPosition(start, QTextCursor::MoveAnchor);
+        cursor.insertText("**");
+        cursor.setPosition(end + 2, QTextCursor::MoveAnchor);
+        cursor.insertText("**");
+    } else {
+        // Insert **** and place cursor in the middle.
+        // Or if there are two * after current cursor, just skip them.
+        int pos = cursor.positionInBlock();
+        bool hasStars = false;
+        QString text = cursor.block().text();
+        if (pos <= text.size() - 2) {
+            if (text[pos] == '*' && text[pos + 1] == '*') {
+                hasStars = true;
+            }
+        }
+
+        if (hasStars) {
+            cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 2);
+        } else {
+            cursor.insertText("****");
+            cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2);
+        }
+    }
+
+    cursor.endEditBlock();
+    m_editor->setTextCursor(cursor);
+}
+
+void VMdEditOperations::decorateItalic()
+{
+    QTextCursor cursor = m_editor->textCursor();
+    cursor.beginEditBlock();
+    if (cursor.hasSelection()) {
+        // Insert * around the selected text.
+        int start = cursor.selectionStart();
+        int end = cursor.selectionEnd();
+        cursor.clearSelection();
+        cursor.setPosition(start, QTextCursor::MoveAnchor);
+        cursor.insertText("*");
+        cursor.setPosition(end + 1, QTextCursor::MoveAnchor);
+        cursor.insertText("*");
+    } else {
+        // Insert ** and place cursor in the middle.
+        // Or if there are one * after current cursor, just skip it.
+        int pos = cursor.positionInBlock();
+        bool hasStar = false;
+        QString text = cursor.block().text();
+        if (pos <= text.size() - 1) {
+            if (text[pos] == '*') {
+                hasStar = true;
+            }
+        }
+
+        if (hasStar) {
+            cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
+        } else {
+            cursor.insertText("**");
+            cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
+        }
+    }
+
+    cursor.endEditBlock();
+    m_editor->setTextCursor(cursor);
+}
+
+void VMdEditOperations::decorateInlineCode()
+{
+    QTextCursor cursor = m_editor->textCursor();
+    cursor.beginEditBlock();
+    if (cursor.hasSelection()) {
+        // Insert ` around the selected text.
+        int start = cursor.selectionStart();
+        int end = cursor.selectionEnd();
+        cursor.clearSelection();
+        cursor.setPosition(start, QTextCursor::MoveAnchor);
+        cursor.insertText("`");
+        cursor.setPosition(end + 1, QTextCursor::MoveAnchor);
+        cursor.insertText("`");
+    } else {
+        // Insert `` and place cursor in the middle.
+        // Or if there are one ` after current cursor, just skip it.
+        int pos = cursor.positionInBlock();
+        bool hasBackquote = false;
+        QString text = cursor.block().text();
+        if (pos <= text.size() - 1) {
+            if (text[pos] == '`') {
+                hasBackquote = true;
+            }
+        }
+
+        if (hasBackquote) {
+            cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 1);
+        } else {
+            cursor.insertText("``");
+            cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
+        }
+    }
+
+    cursor.endEditBlock();
+    m_editor->setTextCursor(cursor);
+}

+ 13 - 3
src/vmdeditoperations.h

@@ -21,6 +21,10 @@ public:
     bool handleKeyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
     bool insertImageFromURL(const QUrl &p_imageUrl) Q_DECL_OVERRIDE;
 
+    // Insert decoration markers or decorate selected text.
+    // If it is Vim Normal mode, change to Insert mode first.
+    void decorateText(TextDecoration p_decoration) Q_DECL_OVERRIDE;
+
 private:
     void insertImageFromPath(const QString &title, const QString &path, const QString &oriImagePath);
 
@@ -32,10 +36,7 @@ private:
     // Key press handlers.
     bool handleKeyTab(QKeyEvent *p_event);
     bool handleKeyBackTab(QKeyEvent *p_event);
-    bool handleKeyB(QKeyEvent *p_event);
     bool handleKeyH(QKeyEvent *p_event);
-    bool handleKeyI(QKeyEvent *p_event);
-    bool handleKeyO(QKeyEvent *p_event);
     bool handleKeyU(QKeyEvent *p_event);
     bool handleKeyW(QKeyEvent *p_event);
     bool handleKeyEsc(QKeyEvent *p_event);
@@ -46,6 +47,15 @@ private:
     // Change the sequence number of a list block.
     void changeListBlockSeqNumber(QTextBlock &p_block, int p_seq);
 
+    // Insert bold marker or set selected text bold.
+    void decorateBold();
+
+    // Insert italic marker or set selected text italic.
+    void decorateItalic();
+
+    // Insert inline-code marker or set selected text inline-coded.
+    void decorateInlineCode();
+
     // The cursor position after auto indent or auto list.
     // It will be -1 if last key press do not trigger the auto indent or auto list.
     int m_autoIndentPos;

+ 7 - 0
src/vmdtab.cpp

@@ -665,3 +665,10 @@ VEditTabInfo VMdTab::createEditTabInfo()
 
     return info;
 }
+
+void VMdTab::decorateText(TextDecoration p_decoration)
+{
+    if (m_editor) {
+        m_editor->decorateText(p_decoration);
+    }
+}

+ 3 - 0
src/vmdtab.h

@@ -57,6 +57,9 @@ public:
 
     void requestUpdateVimStatus() Q_DECL_OVERRIDE;
 
+    // Insert decoration markers or decorate selected text.
+    void decorateText(TextDecoration p_decoration) Q_DECL_OVERRIDE;
+
 public slots:
     // Enter edit mode.
     void editFile() Q_DECL_OVERRIDE;

+ 5 - 0
src/vnote.qrc

@@ -111,5 +111,10 @@
         <file>resources/icons/vnote_update.svg</file>
         <file>utils/flowchart.js/flowchart.min.js</file>
         <file>utils/flowchart.js/raphael.min.js</file>
+        <file>resources/icons/bold.svg</file>
+        <file>resources/icons/italic.svg</file>
+        <file>resources/icons/underline.svg</file>
+        <file>resources/icons/strikethrough.svg</file>
+        <file>resources/icons/inline_code.svg</file>
     </qresource>
 </RCC>