Browse Source

MarkdownEditor: support RichPaste as default

Le Tan 3 years ago
parent
commit
ecce8d13c1

+ 1 - 1
src/core/editorconfig.h

@@ -53,7 +53,7 @@ namespace vnotex
             TypeTable,
             TypeTable,
             TypeMark,
             TypeMark,
             Outline,
             Outline,
-            RichPaste,
+            AltPaste,
             FindAndReplace,
             FindAndReplace,
             FindNext,
             FindNext,
             FindPrevious,
             FindPrevious,

+ 14 - 0
src/core/markdowneditorconfig.cpp

@@ -78,6 +78,8 @@ void MarkdownEditorConfig::init(const QJsonObject &p_app, const QJsonObject &p_u
     }
     }
 
 
     m_editViewMode = stringToEditViewMode(READSTR(QStringLiteral("edit_view_mode")));
     m_editViewMode = stringToEditViewMode(READSTR(QStringLiteral("edit_view_mode")));
+
+    m_richPasteByDefaultEnabled = READBOOL(QStringLiteral("rich_paste_by_default"));
 }
 }
 
 
 QJsonObject MarkdownEditorConfig::toJson() const
 QJsonObject MarkdownEditorConfig::toJson() const
@@ -131,6 +133,8 @@ QJsonObject MarkdownEditorConfig::toJson() const
 
 
     obj[QStringLiteral("edit_view_mode")] = editViewModeToString(m_editViewMode);
     obj[QStringLiteral("edit_view_mode")] = editViewModeToString(m_editViewMode);
 
 
+    obj[QStringLiteral("rich_paste_by_default")] = m_richPasteByDefaultEnabled;
+
     return obj;
     return obj;
 }
 }
 
 
@@ -579,3 +583,13 @@ void MarkdownEditorConfig::setEditViewMode(EditViewMode p_mode)
 {
 {
     updateConfig(m_editViewMode, p_mode, this);
     updateConfig(m_editViewMode, p_mode, this);
 }
 }
+
+bool MarkdownEditorConfig::getRichPasteByDefaultEnabled() const
+{
+    return m_richPasteByDefaultEnabled;
+}
+
+void MarkdownEditorConfig::setRichPasteByDefaultEnabled(bool p_enabled)
+{
+    updateConfig(m_richPasteByDefaultEnabled, p_enabled, this);
+}

+ 5 - 0
src/core/markdowneditorconfig.h

@@ -145,6 +145,9 @@ namespace vnotex
         EditViewMode getEditViewMode() const;
         EditViewMode getEditViewMode() const;
         void setEditViewMode(EditViewMode p_mode);
         void setEditViewMode(EditViewMode p_mode);
 
 
+        bool getRichPasteByDefaultEnabled() const;
+        void setRichPasteByDefaultEnabled(bool p_enabled);
+
     private:
     private:
         friend class MainConfig;
         friend class MainConfig;
 
 
@@ -254,6 +257,8 @@ namespace vnotex
 
 
         // View mode in edit mode.
         // View mode in edit mode.
         EditViewMode m_editViewMode = EditViewMode::EditOnly;
         EditViewMode m_editViewMode = EditViewMode::EditOnly;
+
+        bool m_richPasteByDefaultEnabled = true;
     };
     };
 }
 }
 
 

+ 3 - 2
src/data/core/vnotex.json

@@ -201,7 +201,7 @@
                 "TypeTable" : "Ctrl+/",
                 "TypeTable" : "Ctrl+/",
                 "TypeMark" : "Ctrl+G, M",
                 "TypeMark" : "Ctrl+G, M",
                 "Outline" : "Ctrl+G, O",
                 "Outline" : "Ctrl+G, O",
-                "RichPaste" : "Ctrl+Shift+V",
+                "AltPaste" : "Ctrl+Shift+V",
                 "FindAndReplace" : "Ctrl+F",
                 "FindAndReplace" : "Ctrl+F",
                 "FindNext" : "F3",
                 "FindNext" : "F3",
                 "FindPrevious" : "Shift+F3",
                 "FindPrevious" : "Shift+F3",
@@ -451,7 +451,8 @@
             "//comment" : "imagelink/codeblock/math",
             "//comment" : "imagelink/codeblock/math",
             "inplace_preview_sources" : "imagelink;codeblock;math",
             "inplace_preview_sources" : "imagelink;codeblock;math",
             "//comment" : "view mode of edit mode: editonly/editpreview",
             "//comment" : "view mode of edit mode: editonly/editpreview",
-            "edit_view_mode" : "editonly"
+            "edit_view_mode" : "editonly",
+            "rich_paste_by_default" : true
         },
         },
         "image_host" : {
         "image_host" : {
             "hosts" : [
             "hosts" : [

+ 14 - 0
src/widgets/dialogs/settings/markdowneditorpage.cpp

@@ -122,6 +122,8 @@ void MarkdownEditorPage::loadInternal()
             m_editorOverriddenFontFamilyComboBox->setCurrentFont(font);
             m_editorOverriddenFontFamilyComboBox->setCurrentFont(font);
         }
         }
     }
     }
+
+    m_richPasteByDefaultCheckBox->setChecked(markdownConfig.getRichPasteByDefaultEnabled());
 }
 }
 
 
 bool MarkdownEditorPage::saveInternal()
 bool MarkdownEditorPage::saveInternal()
@@ -198,6 +200,8 @@ bool MarkdownEditorPage::saveInternal()
         markdownConfig.setEditorOverriddenFontFamily(checked ? m_editorOverriddenFontFamilyComboBox->currentFont().family() : QString());
         markdownConfig.setEditorOverriddenFontFamily(checked ? m_editorOverriddenFontFamilyComboBox->currentFont().family() : QString());
     }
     }
 
 
+    markdownConfig.setRichPasteByDefaultEnabled(m_richPasteByDefaultCheckBox->isChecked());
+
     EditorPage::notifyEditorConfigChange();
     EditorPage::notifyEditorConfigChange();
 
 
     return true;
     return true;
@@ -402,6 +406,16 @@ QGroupBox *MarkdownEditorPage::setupEditGroup()
         layout->addRow(fontLayout);
         layout->addRow(fontLayout);
     }
     }
 
 
+    {
+        const QString label(tr("Use Rich Paste by default"));
+        m_richPasteByDefaultCheckBox = WidgetsFactory::createCheckBox(label, box);
+        m_richPasteByDefaultCheckBox->setToolTip(tr("Use Rich Paste by default when pasting text"));
+        layout->addRow(m_richPasteByDefaultCheckBox);
+        addSearchItem(label, m_richPasteByDefaultCheckBox->toolTip(), m_richPasteByDefaultCheckBox);
+        connect(m_richPasteByDefaultCheckBox, &QCheckBox::stateChanged,
+                this, &MarkdownEditorPage::pageIsChanged);
+    }
+
     return box;
     return box;
 }
 }
 
 

+ 2 - 0
src/widgets/dialogs/settings/markdowneditorpage.h

@@ -88,6 +88,8 @@ namespace vnotex
         QCheckBox *m_editorOverriddenFontFamilyCheckBox = nullptr;
         QCheckBox *m_editorOverriddenFontFamilyCheckBox = nullptr;
 
 
         QFontComboBox *m_editorOverriddenFontFamilyComboBox = nullptr;
         QFontComboBox *m_editorOverriddenFontFamilyComboBox = nullptr;
+
+        QCheckBox *m_richPasteByDefaultCheckBox = nullptr;
     };
     };
 }
 }
 
 

+ 95 - 40
src/widgets/editors/markdowneditor.cpp

@@ -62,9 +62,6 @@
 
 
 using namespace vnotex;
 using namespace vnotex;
 
 
-// We set the property of the clipboard to mark that we are requesting a rich paste.
-static const char *c_clipboardPropertyMark = "RichPaste";
-
 MarkdownEditor::Heading::Heading(const QString &p_name,
 MarkdownEditor::Heading::Heading(const QString &p_name,
                                  int p_level,
                                  int p_level,
                                  const QString &p_sectionNumber,
                                  const QString &p_sectionNumber,
@@ -468,32 +465,56 @@ void MarkdownEditor::insertImageLink(const QString &p_title,
 
 
 void MarkdownEditor::handleCanInsertFromMimeData(const QMimeData *p_source, bool *p_handled, bool *p_allowed)
 void MarkdownEditor::handleCanInsertFromMimeData(const QMimeData *p_source, bool *p_handled, bool *p_allowed)
 {
 {
-    if (p_source->hasImage() || p_source->hasUrls()) {
-        if (p_source->hasImage()
-            || (!p_source->hasText() && !p_source->hasHtml())
-            || QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) {
-            // Change to Rich Paste.
-            QClipboard *clipboard = QApplication::clipboard();
-            clipboard->setProperty(c_clipboardPropertyMark, true);
-        }
+    m_shouldTriggerRichPaste = ConfigMgr::getInst().getEditorConfig().getMarkdownEditorConfig().getRichPasteByDefaultEnabled();
+
+    if (m_plainTextPasteAsked) {
+        m_shouldTriggerRichPaste = false;
+        return;
+    }
+
+    if (m_richPasteAsked) {
+        m_shouldTriggerRichPaste = true;
+        *p_handled = true;
+        *p_allowed = true;
+        return;
+    }
+
+    if (QGuiApplication::keyboardModifiers() == Qt::ShiftModifier) {
+        m_shouldTriggerRichPaste = !m_shouldTriggerRichPaste;
+    }
+
+    if (m_shouldTriggerRichPaste) {
         *p_handled = true;
         *p_handled = true;
         *p_allowed = true;
         *p_allowed = true;
+        return;
+    }
+
+    if (p_source->hasImage()) {
+        m_shouldTriggerRichPaste = true;
+        *p_handled = true;
+        *p_allowed = true;
+        return;
+    }
+
+    if (p_source->hasUrls()) {
+        *p_handled = true;
+        *p_allowed = true;
+        return;
     }
     }
 }
 }
 
 
 void MarkdownEditor::handleInsertFromMimeData(const QMimeData *p_source, bool *p_handled)
 void MarkdownEditor::handleInsertFromMimeData(const QMimeData *p_source, bool *p_handled)
 {
 {
-    QClipboard *clipboard = QApplication::clipboard();
-    if (!clipboard->property(c_clipboardPropertyMark).toBool()) {
+    if (!m_shouldTriggerRichPaste) {
         // Default paste.
         // Default paste.
-        // Give tips about the Rich Paste and Parse As Markdown And Paste features.
+        // Give tips about the Rich Paste and Parse to Markdown And Paste features.
         VNoteX::getInst().showStatusMessageShort(
         VNoteX::getInst().showStatusMessageShort(
             tr("For advanced paste, try the \"Rich Paste\" and \"Parse to Markdown and Paste\" on the editor's context menu"));
             tr("For advanced paste, try the \"Rich Paste\" and \"Parse to Markdown and Paste\" on the editor's context menu"));
         return;
         return;
-    } else {
-        clipboard->setProperty(c_clipboardPropertyMark, false);
     }
     }
 
 
+    m_shouldTriggerRichPaste = false;
+
     if (processHtmlFromMimeData(p_source)) {
     if (processHtmlFromMimeData(p_source)) {
         *p_handled = true;
         *p_handled = true;
         return;
         return;
@@ -516,9 +537,10 @@ bool MarkdownEditor::processHtmlFromMimeData(const QMimeData *p_source)
         return false;
         return false;
     }
     }
 
 
+    const QString html(p_source->html());
+
     // Process <img>.
     // Process <img>.
     QRegExp reg("<img ([^>]*)src=\"([^\"]+)\"([^>]*)>");
     QRegExp reg("<img ([^>]*)src=\"([^\"]+)\"([^>]*)>");
-    const QString html(p_source->html());
     if (reg.indexIn(html) != -1 && HtmlUtils::hasOnlyImgTag(html)) {
     if (reg.indexIn(html) != -1 && HtmlUtils::hasOnlyImgTag(html)) {
         if (p_source->hasImage()) {
         if (p_source->hasImage()) {
             // Both image data and URL are embedded.
             // Both image data and URL are embedded.
@@ -548,6 +570,24 @@ bool MarkdownEditor::processHtmlFromMimeData(const QMimeData *p_source)
         return true;
         return true;
     }
     }
 
 
+    // Parse to Markdown and Paste.
+    SelectDialog dialog(tr("Insert From Clipboard"), this);
+    dialog.addSelection(tr("Insert As Text"), 0);
+    dialog.addSelection(tr("Parse to Markdown and Paste"), 1);
+
+    if (dialog.exec() == QDialog::Accepted) {
+        int selection = dialog.getSelection();
+        if (selection == 0) {
+            // Insert as text.
+            m_textEdit->insertFromMimeDataOfBase(p_source);
+            return true;
+        } else if (selection == 1) {
+            // Parse to Markdown and Paste.
+            parseToMarkdownAndPaste();
+            return true;
+        }
+    }
+
     return false;
     return false;
 }
 }
 
 
@@ -957,6 +997,8 @@ void MarkdownEditor::scrollToHeading(int p_idx)
 
 
 void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_handled, QScopedPointer<QMenu> *p_menu)
 void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_handled, QScopedPointer<QMenu> *p_menu)
 {
 {
+    const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
+
     *p_handled = true;
     *p_handled = true;
     p_menu->reset(m_textEdit->createStandardContextMenu(p_event->pos()));
     p_menu->reset(m_textEdit->createStandardContextMenu(p_event->pos()));
     auto menu = p_menu->data();
     auto menu = p_menu->data();
@@ -970,8 +1012,7 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
 
 
     if (!hasSelection) {
     if (!hasSelection) {
         auto readAct = new QAction(tr("&Read"), menu);
         auto readAct = new QAction(tr("&Read"), menu);
-        WidgetUtils::addActionShortcutText(readAct,
-                                           ConfigMgr::getInst().getEditorConfig().getShortcut(EditorConfig::Shortcut::EditRead));
+        WidgetUtils::addActionShortcutText(readAct, editorConfig.getShortcut(EditorConfig::Shortcut::EditRead));
         connect(readAct, &QAction::triggered,
         connect(readAct, &QAction::triggered,
                 this, &MarkdownEditor::readRequested);
                 this, &MarkdownEditor::readRequested);
         menu->insertAction(firstAct, readAct);
         menu->insertAction(firstAct, readAct);
@@ -986,20 +1027,21 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
         QClipboard *clipboard = QApplication::clipboard();
         QClipboard *clipboard = QApplication::clipboard();
         const QMimeData *mimeData = clipboard->mimeData();
         const QMimeData *mimeData = clipboard->mimeData();
 
 
-        // Rich Paste.
-        auto richPasteAct = new QAction(tr("Rich Paste"), menu);
-        WidgetUtils::addActionShortcutText(richPasteAct,
-                                           ConfigMgr::getInst().getEditorConfig().getShortcut(EditorConfig::Shortcut::RichPaste));
-        connect(richPasteAct, &QAction::triggered,
-                this, &MarkdownEditor::richPaste);
-        WidgetUtils::insertActionAfter(menu, pasteAct, richPasteAct);
+        // Rich Paste or Plain Text Paste.
+        const bool richPasteByDefault = editorConfig.getMarkdownEditorConfig().getRichPasteByDefaultEnabled();
+        auto altPasteAct = new QAction(richPasteByDefault ? tr("Paste as Plain Text") : tr("Rich Paste"), menu);
+        WidgetUtils::addActionShortcutText(altPasteAct,
+                                           editorConfig.getShortcut(EditorConfig::Shortcut::AltPaste));
+        connect(altPasteAct, &QAction::triggered,
+                this, &MarkdownEditor::altPaste);
+        WidgetUtils::insertActionAfter(menu, pasteAct, altPasteAct);
 
 
         if (mimeData->hasHtml()) {
         if (mimeData->hasHtml()) {
             // Parse to Markdown and Paste.
             // Parse to Markdown and Paste.
             auto parsePasteAct = new QAction(tr("Parse to Markdown and Paste"), menu);
             auto parsePasteAct = new QAction(tr("Parse to Markdown and Paste"), menu);
             connect(parsePasteAct, &QAction::triggered,
             connect(parsePasteAct, &QAction::triggered,
                     this, &MarkdownEditor::parseToMarkdownAndPaste);
                     this, &MarkdownEditor::parseToMarkdownAndPaste);
-            WidgetUtils::insertActionAfter(menu, richPasteAct, parsePasteAct);
+            WidgetUtils::insertActionAfter(menu, altPasteAct, parsePasteAct);
         }
         }
     }
     }
 
 
@@ -1008,7 +1050,7 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
 
 
         auto snippetAct = menu->addAction(tr("Insert Snippet"), this, &MarkdownEditor::applySnippetRequested);
         auto snippetAct = menu->addAction(tr("Insert Snippet"), this, &MarkdownEditor::applySnippetRequested);
         WidgetUtils::addActionShortcutText(snippetAct,
         WidgetUtils::addActionShortcutText(snippetAct,
-                                           ConfigMgr::getInst().getEditorConfig().getShortcut(EditorConfig::Shortcut::ApplySnippet));
+                                           editorConfig.getShortcut(EditorConfig::Shortcut::ApplySnippet));
     }
     }
 
 
     if (!hasSelection) {
     if (!hasSelection) {
@@ -1018,25 +1060,38 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
     appendSpellCheckMenu(p_event, menu);
     appendSpellCheckMenu(p_event, menu);
 }
 }
 
 
-void MarkdownEditor::richPaste()
+void MarkdownEditor::altPaste()
 {
 {
-    QClipboard *clipboard = QApplication::clipboard();
-    clipboard->setProperty(c_clipboardPropertyMark, true);
-    m_textEdit->paste();
-    clipboard->setProperty(c_clipboardPropertyMark, false);
+    const bool richPasteByDefault = ConfigMgr::getInst().getEditorConfig().getMarkdownEditorConfig().getRichPasteByDefaultEnabled();
+
+    if (richPasteByDefault) {
+        // Paste as plain text.
+        m_plainTextPasteAsked = true;
+        m_richPasteAsked = false;
+    } else {
+        // Rich paste.
+        m_plainTextPasteAsked = false;
+        m_richPasteAsked = true;
+    }
+
+    // handleCanInsertFromMimeData() is called before this function. Call it manually.
+    if (m_textEdit->canPaste()) {
+        m_textEdit->paste();
+    }
+
+    m_plainTextPasteAsked = false;
+    m_richPasteAsked = false;
 }
 }
 
 
 void MarkdownEditor::setupShortcuts()
 void MarkdownEditor::setupShortcuts()
 {
 {
     const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
     const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
 
 
-    {
-        auto shortcut = WidgetUtils::createShortcut(editorConfig.getShortcut(EditorConfig::Shortcut::RichPaste),
-                                                    this);
-        if (shortcut) {
-            connect(shortcut, &QShortcut::activated,
-                    this, &MarkdownEditor::richPaste);
-        }
+    auto shortcut = WidgetUtils::createShortcut(editorConfig.getShortcut(EditorConfig::Shortcut::AltPaste),
+                                                this);
+    if (shortcut) {
+        connect(shortcut, &QShortcut::activated,
+                this, &MarkdownEditor::altPaste);
     }
     }
 }
 }
 
 

+ 7 - 1
src/widgets/editors/markdowneditor.h

@@ -126,7 +126,7 @@ namespace vnotex
 
 
         void handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_handled, QScopedPointer<QMenu> *p_menu);
         void handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_handled, QScopedPointer<QMenu> *p_menu);
 
 
-        void richPaste();
+        void altPaste();
 
 
         void parseToMarkdownAndPaste();
         void parseToMarkdownAndPaste();
 
 
@@ -225,6 +225,12 @@ namespace vnotex
         MarkdownTableHelper *m_tableHelper = nullptr;
         MarkdownTableHelper *m_tableHelper = nullptr;
 
 
         ImageHost *m_imageHost = nullptr;
         ImageHost *m_imageHost = nullptr;
+
+        bool m_shouldTriggerRichPaste = false;
+
+        bool m_richPasteAsked = false;
+
+        bool m_plainTextPasteAsked = false;
     };
     };
 }
 }